ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Agentic Harness Workflow:从对话式写码到AI工程化流水线

Agentic Harness Workflow:从对话式写码到AI工程化流水线 1. 这个框架要解决什么问题从“聊天式写码”到“工程化流水线”先用一个场景来说明痛点。你在终端里跑着一个AI编程助手让它“给某个模块加个导出功能”它唰唰写出几十行代码看起来没问题。你复制进工程跑测试挂了。你回头告诉它“这里报错了”它说“抱歉我修正一下”又输出一段。几次往返之后代码是能跑了但你压根不知道它动了哪些文件、改了什么逻辑、有没有把别的功能搞坏。如果这只是个小脚本还好一旦是多人协作的中大型项目这种“对话式开发”根本没法收场。我之前在一个中等规模的业务系统上试过这种方式效率提升确实有但代价是代码评审近乎失控。你没法在聊天记录里做code review也没法让AI助手“只改接口层不动核心逻辑”更没法要求它“跑完单测再提交”——因为对话式交互压根没有这些工程约束。后来我接触并实践了Agentic Harness Workflow框架的思路它其实是把AI编程从“即兴对话”变成“受控流程”。核心不是让AI写更多代码而是给AI套上一套工程化的工作流约束角色怎么分配、上下文怎么管理、任务怎么拆解、质量门禁怎么卡、人在哪个节点介入。这套思路解决的是“AI写得爽、人用着慌”的核心矛盾。说白了Agentic Harness Workflow框架是一个编排层。它不直接替代某个模型或IDE插件而是把“让AI写代码”这个粗放行为拆解成有边界、可审计、可回滚的工程步骤。适合谁用两类人最受益一类是团队里负责引入AI工具但被质量搞得焦头烂额的技术负责人另一类是个人开发者手里有几个项目想把AI从“玩具”变成“生产工具”但不知道怎么定规则。2. 核心设计思路拆解一个Agent不叫流程四个以上才叫体系2.1 为什么“单一提示词工程”撑不住复杂任务很多人以为让AI稳定输出就是提示词写得好。早期我也这么干给模型写一大段系统提示词把角色、语气、输出格式全规定了。实测下来短任务还行一碰到跨文件、多步骤、需要持续上下文的任务模型就开始“失忆”。它会忘记前面改了多少内容会重复生成已经推翻的代码段甚至会在某一步骤上钻牛角尖。问题不在模型智商在于“上下文窗口是有限的”。一次任务里塞的内容越多模型在每个步骤上的注意力就越分散。Agentic Harness Workflow的第一个设计原则就是不要试图让一个Agent完成所有事而是把任务拆成多个Agent接力完成。我在一个模拟项目X上做过对比同一个需求“给系统加一个带缓存的数据查询接口”用单Agent、超大提示词跑产出代码能用但代码里混着大量无关的参考实现用多Agent拆分流程跑每个Agent只负责一个子任务产出干净得多而且每个子任务都可单独验证。这个体验差异非常明显。2.2 Harness装配层充当了什么角色Harness这个词原本指“马具、挽具”引申义是把力量牵引到正确的方向上。在框架里Harness指的是“约束和编排AI行为的外壳”。它负责四件事任务规划把大需求拆成可执行的小步骤每个步骤有明确的输入和产出。上下文控制决定每个步骤让AI看到哪些信息、屏蔽哪些信息避免上下文污染。工具权限管理规定AI在什么阶段能读写文件、执行命令、调用测试框架。质量门禁在每个关键节点设置自动检查不通过就不允许进入下一步。想理解Harness可以把它类比成工厂生产线上的“工装夹具”。有了夹具一个毛坯件在每道工序上都被固定在该在的位置上加工精度才有保证。没有夹具你让同一个工人做所有工序他也能做但废品率完全靠手感。这套框架里的“夹具”就是给每个AI Agent定义好边界、工具集、检查清单。模型本身还是那个模型能力没变但在Harness约束下它的输出质量稳定性会显著提升。2.3 多Agent协作的分工逻辑我实际落地时把参与编码的Agent分成了四类对应流水线里的不同工位规划者Agent接收需求描述输出任务分解清单和实施顺序。它只做分析不动代码产出物是决策依据。实现者Agent按规划清单逐项写代码。它每做完一项就要停下来交验不一口气写完整个模块。审查者Agent对照任务清单检查代码差异重点看“有没有动不该动的区域”“有没有引入明显坏味道”。验证者Agent负责跑测试、执行静态检查把失败信息反馈给实现者迭代。这个分工方式一开始看着繁琐但实际跑起来之后会发现一个很关键的点审查者和验证者的存在把原来“人对代码负责”的压力部分转移到了流程自检上。当然人最终还是要把关的但这道流程能帮你过滤掉八成低级的AI幻觉问题。2.4 流程编排中的人工介入点设计不是所有节点都适合自动跑。我在实践中踩过一个坑——让Agent全自动跑完整个流程结果它在某一个困难节点上“自我感觉良好”生成了大量看起来合理但实际没用的代码流程全绿是因为测试断言写得不对。从那以后我养成了一个习惯在关键决策节点强制加入人工确认环节。框架里通常用两种机制实现人工介入硬门禁某个节点产出物必须由人工审核通过流程才能继续。适合放在架构设计完成后、大规模编码开始前。软门禁产出物自动检查通过即可继续但审核记录留档。适合放在低风险步骤比如生成单元测试、编写注释。好的Agentic Harness Workflow不是追求“无人化”而是追求“人的注意力花在值得花的地方”。3. 关键机制与配套工具选型3.1 上下文管理机制别让Agent“记不住事”实际运行中最大的坑就是上下文污染。一个Agent处理完任务A它的对话历史里全是关于任务A的细节。如果直接让它继续处理任务B它会把任务A的代码风格、变量名习惯带进来甚至引用已经过时的结论。框架在上下文管理上有个标准做法为每个子任务启动一次“干净会话”只注入与该子任务相关的背景信息。注意这里不是把上下文清空而是把“全局上下文”精简成“局部上下文”。比如实现者Agent在写某个接口时注入的是接口定义、调用方代码、数据模型说明而不是整个项目的所有文档。我在实际使用中建了一个最小化上下文模板包含四个部分项目架构说明不超过200字只讲分层和依赖方向当前任务的输入需求片段、相关文件路径可参考的现有代码风格示例一到两个代码块明确禁止事项比如“不能修改公共基础类”“必须遵循现有日志格式”这套模板在整体流程里效果极佳。上下文越聚焦Agent在子任务上的表现越接近“专注的工程师”而不是“什么都懂但什么都不精的万金油”。3.2 质量门禁的组成和配置思路质量门禁是整个框架里最提效的部分也是我最推荐的落地起点。质量门禁一般分四层语法层代码能编译、能通过linter。测试层单元测试和关键集成测试全部通过。静态检查层用工程里既有的静态分析规则扫描阻断“新增了警告级别问题”的提交。语义层由审查者Agent检查代码是否符合任务描述有没有实现偏差或过度实现。各层之间通常是串联关系前一层不通过后一层不启动。好处是每层反馈的失败信息会被自动汇总作为下一个迭代轮次的输入提示让Agent带着错误信息去修正而不是凭空猜测。我给一个简单示例配置一个Python项目的门禁流程用伪代码表示quality_gates: - name: syntax_check command: ruff check {changed_files} on_fail: stop_and_report - name: unit_tests command: pytest --maxfail1 {target_module} on_fail: return_to_implementer_with_feedback - name: static_analysis command: mypy {target_module} on_fail: stop_and_notify - name: semantic_review agent: reviewer requirement: output must align with task_acceptance_criteria注意这里的配置思路不是追求所有门禁都严格到极致而是“越便宜的检查放越前面”。语法检查毫秒级完成放在最前语义审查耗时最长放在最后。如果前面就挂了后面的所有成本都省下来了。3.3 工作流编排引擎怎么选这一步不是教条但我建议优先选择支持状态持久化和步骤重放的编排方案。原因很简单AI任务的不确定性决定了你一定会遇到“某一步挂了需要从中间重跑”的情况。我当时对比过三种路径直接用脚本串命令简单直接但重放某个历史步骤很难失败后人工干预不友好。用通用CI平台能解决持久化和重放问题但它天然适合“稳定任务”对AI这一步的“动态输入”支持不够灵活。用专门工作流引擎比如以图编排为理念的那类工具门槛略高但最贴合这套模式。它把每个Agent当作一个节点输入输出的流转、人工审批节点、失败重试策略都能配置。如果只是个人项目或小团队先别急着上重型引擎。我自己是从一个不到300行的Python脚本起步的核心就是一个状态字典、一个步骤列表、两个失败重试逻辑函数。跑通了整个流程之后再迁移到专用引擎。这套演进路径最稳。3.4 配套工具的轻量组合我目前的落地组合是模型服务走统一API网关、代码处理用Git工作区隔离、流程编排用Python脚本。模型端没有绑定某个具体厂商这样切换和对比模型成本极低。Git工作区隔离保证Agent动文件时不会直接把主分支搞脏所有变更都在临时分支上汇聚人工审核通过后再合入。这套组合里最值得说的一个细节每个Agent在执行任务前都会先执行一遍git status和git diff --stat把当前工作区的真实状态带进上下文。这一步对防止Agent“凭记忆写代码”极其有效——它能看到工作区真实长什么样就不会虚构文件路径或乱猜函数名。4. 实操从零搭建一个可用的Agentic Harness Workflow4.1 落地前的需求拆解想搭这套框架第一步不是写代码而是把“你想让AI替你做什么”说清楚。我提出一个要求每个子任务都必须是一个“可独立验证”的最小单元。什么叫可独立验证举个例子。如果你给Agent一个任务“优化系统性能”这个任务不可独立验证——什么叫优化好了跑分延迟多少算达标你没法给Agent一个清晰的验收标准。但如果你拆成“把某个高频查询接口的数据库访问次数从三次合并成一次”这就可验证了跑个日志统计访问次数降了就算完成。实际落地时我用的拆解套路是第一轮让规划者Agent产出任务清单人工审查并修正。第二轮针对每个子任务写出验收标准同样人工确认。第三轮把确认后的清单喂给实现者Agent逐一执行。这个“先花一小时把需求拆透再让AI干活”的模式远远快过“直接让AI干再反复纠正”的模式。很多人觉得拆解浪费时间实际这是整个流程里ROI最高的投入。4.2 从零搭建的流程脚本原理解析下面是一个核心执行循环的示意——当然实际工程里会比这复杂但核心骨架就是这些class HarnessWorkflow: def __init__(self): self.steps [] self.state {} self.agent_pool {} def add_step(self, step_name, agent_type, input_keys, output_key, gateNone): self.steps.append({ name: step_name, agent_type: agent_type, input_keys: input_keys, output_key: output_key, gate: gate, }) def run(self): current 0 while current len(self.steps): step self.steps[current] agent self.agent_pool[step[agent_type]] inputs {k: self.state[k] for k in step[input_keys]} response agent.execute(self.prepare_context(step, inputs)) if step[gate]: report step[gate].check(response) if not report.passed: self.handle_gate_failure(step, report) continue # 回到当前步骤重试不往下走 self.state[step[output_key]] response.output current 1 return self.state这个骨架里最关键的设计是handle_gate_failure的逻辑。你不能简单地重试因为同样的输入再喂给同一个Agent多半还是产出同样的结果。我的做法是把gate检查的失败报告追加到新的上下文里然后把“上下文版本号”加1让Agent能看到“这是第几次尝试、上次哪一步没通过”。这个机制类似人类的“带着批评去修改”而不是“无脑再做一遍”。上下文组织方面每次调用Agent前做一次上下文装配def prepare_context(self, step, inputs): base { project_arch: self.project_arch, task_description: step[name], inputs: inputs, } # 把历史失败信息并入但控制最大长度避免上下文爆掉 if step[name] in self.retry_history: base[retry_feedback] self.retry_history[step[name]][-3:] return base为什么只取最近三回失败信息因为失败次数超过三轮之后问题大概率不在Agent能力而在任务拆解或上下文质量本身。这时应该停下来调整子任务而不是继续烧Token。4.3 一个需求管理系统的实操记录我在某个虚构的“需求管理系统”项目上完整跑过一遍这套流程。需求是这样的“给订单模块加一个导出CSV的功能要求包含延迟到30天、导出文件做大小限制、并发导出时排队处理”。我先让规划者Agent拆解它给出四个子任务任务A新增导出服务接口定义入参出参。任务B实现CSV生成逻辑加入大小限制。任务C实现并发排队机制基于现有任务队列扩展。任务D补充单元测试和集成测试。我审查之后发现它的顺序是对的但漏了一个关键点导出权限校验。由于这个系统有角色权限体系任何新接口都应该默认接入权限校验。我在任务A里追加了一条验收标准“新接口必须与现有接口保持一致的自定义权限注解”。实现者Agent执行完任务A后审查者Agent检查时发现它写了一个新的权限校验逻辑绕过了现有统一封装。审查者拦截了这次产出反馈信息是“权限校验应复用已有注解而非新写逻辑”。实现者Agent带着反馈迭代了一轮产出符合要求。整个过程里质量门禁发挥了核心价值——它挡住了“技术上能跑但架构上不统一”的隐性坏味道。最终全部步骤跑完代码成功合入临时分支我人工review后发现一个问题任务C的并发排队逻辑在极端高并发场景下可能丢任务。这是Agent很难自行发现的多线程竞态问题也是人工介入节点的意义所在。我修正后合入主分支整个流程用时约三个小时如果没有框架约束纯聊天的模式我估计要花上一整天而且代码质量未必有人工review的保障。4.4 人工审核时该重点看什么很多人名义上有“人工审核”实际上就是看一眼“代码能不能跑”然后就点了通过。我在实操中沉淀了一个审核清单分享出来变更影响面这次提交动了哪些文件有没有不该动的公共文件用git diff --name-only先扫一遍。实现方式是否与现有架构一致有没有为吹新毛求疵而引入新依赖或新模式这是Agent最爱犯的错——不按现有代码风格走重新发明一套。边界条件是否覆盖空数据、超长输入、并发冲突、权限不足这四个边界最容易出问题。测试是否有效不要只看“测试通过了”点开测试代码看看断言是否真的抓到了关键行为。这套清单基本覆盖了我在框架落地过程中遇到的大部分返工场景。5. 实践中遇到的坑与排查记录5.1 上下文窗口溢出导致Agent“失忆”第一次跑一个大型重构任务时我让Agent直接带着整个项目的文件清单和架构文档干活结果跑了几个步骤后它开始编造文件路径——引用了一个根本不存在的老文件名。排查后发现它的上下文窗口被早期塞入了大量重复的代码片段真正重要的任务描述被挤出了注意力范围。解决办法是强制实施“每步骤上下文重建”。第二步开始不再延续上一步的完整对话而是“有损摘要关键上下文注入”。类似人的工作记忆你不能把一天的细节全记在脑子里但你可以带着“记住重点”和“查笔记”的习惯。5.2 Agent陷入“自我确认”循环某个子任务实现者Agent改完代码后自己跑了一轮验证觉得自己写得没问题反馈“完成”。但审查者Agent其实没有真正执行代码只是依据对话内容判断通过。这个场景尤其危险——因为AI的“自我确认”倾向非常强它会抱着自己的产出自圆其说这时候双Agent交叉审查也不完全可靠。我最终的做法是让验证者Agent必须运行真实命令并且把命令输出原样贴回上下文。如果它无法运行命令那这个节点必须由人来执行。再后来我干脆用脚本直接执行测试不让Agent自己判断“该不该跑测试”而是由流程引擎强制它跑。5.3 质量门禁把好代码误伤了有次门禁里的语义审查规则写得过于死板要求“所有新增公共方法必须有单元测试”结果一个纯静态工具函数被反复打回。这个函数是纯函数且逻辑极其简单加测试的成本远大于收益。流程反复重试四五轮Token烧了一堆最终得出一个“合理怀疑”门禁规则本身需要分层管理一些“应当遵守”的规则可以降级为“提醒但不阻断”。后来我把门禁分成了两类blocker门禁不通过绝不往下走和warning门禁通过但留警告记录。这个改动非常有效。它给流程增加了灰度容忍度避免了刚性规则带来的效率损耗。5.4 模型之间的能力差异被低估我一开始用的是同一个模型跑全部Agent后来发现不同角色对模型特性的要求差异很大。规划者Agent需要强大的全局推理能力审查者Agent需要缜密的差异比对能力实现者Agent则更看重代码生成速度。就实话说同一个模型很难在所有维度上同时优秀。把这四个角色映射到不同的模型整体效率和效果都有明显提升。不过这里有个注意点不同模型的输出格式不稳定必须要求所有Agent以结构化的JSON格式返回比如{summary: ..., changed_files: [...], tests_run: [...]}。这个格式统一是硬性要求否则下游步骤的解析会变成灾难。6. 我为什么最终坚定用这套流程我自己的体会是Agentic Harness Workflow真正改变的不是“代码生产速度”而是“AI参与工程的门槛”。以前我会担心AI引入的不可控性现在这种担忧被流程化解了相当大一部分。它有边界、有检查、有回放就算某一步错了也能知道错在哪一步、错因是什么、怎么针对性重跑。最后分享两个小建议。第一如果你正处在观望阶段不用急着买重型框架、搭复杂引擎先把“一个主流程脚本四个角色Agent三层门禁”跑起来用一个小项目验证流程的可行性再逐步增加控制节点。第二在流程里永远保留“旁路模式”——当Agent连续尝试三轮都失败时允许人工接管该步骤直接编写代码然后把代码贴回流程继续。AI是辅助不是取代工程化流程的最终目标是让整个开发过程更稳健而不是把人的判断力外包掉。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进