资讯动态

Agentic Harness Workflow:让AI编码从聊天式走向工程化流水线

发布时间:2026/10/21 23:02:45 来源:尧图企业网站定制
1. 为什么“让 AI 写代码”这件事需要一套工程化框架过去一年多我陆陆续续在几个真实项目里把 AI 编码工具用了个遍。最开始的新鲜感过去之后留下的其实是一堆很现实的问题同一个需求今天让它写能跑明天换个会话就写崩改一个函数它顺手把旁边三个不相关的文件也动了上下文一长它开始“忘记”之前定下的接口约定更别提多人协作时每个人手里的提示词风格完全不一样产出的代码像出自五个不同团队。这些问题的根源其实不在于模型够不够聪明而在于我们把 AI 当成了一个“聊天对象”而不是一个“工程环节”。聊天是随意的、一次性的、没有契约的而工程是有流程、有约束、有验收标准的。Agentic Harness Workflow 框架要解决的核心矛盾就是把这件随意的聊天行为套进一套可复现、可审查、可回滚的工程化流程里。“Harness”这个词在工程语境里原本指“线束、约束装置”引申过来就是给一个能力强但方向不定的东西套上缰绳和轨道。Agentic 指的是让 AI 具备一定的自主决策与多步执行能力。两者合在一起意思很直白给具备自主性的 AI 编码代理套上一套能约束它、引导它、验证它的工作流骨架。这套框架适合谁我认为有三类人收益最明显。第一类是已经在日常开发里重度使用 AI 编码、但被“不可复现”折磨的独立开发者第二类是想把 AI 编码引入团队、却担心代码质量和协作混乱的技术负责人第三类是把 AI 编码当成产品能力、需要把它封装成稳定流水线的平台工程师。哪怕你只是刚上手理解这套思路也能让你少走很多弯路因为它讲的不是某个工具的用法而是一种组织 AI 工作的方法论。接下来我会从整体设计思路、核心环节拆解、完整实操流程、常见问题排查四个层面把这套框架掰开揉碎讲清楚。里面涉及的目录结构、配置样例、验收清单都是我实际跑过之后沉淀下来的你可以直接抄作业也可以按自己项目的情况裁剪。2. 框架整体设计与思路拆解2.1 从“对话式编码”到“流水线式编码”的范式转变传统对话式编码的模型是这样的人给一段自然语言描述AI 返回一段代码人复制粘贴、运行、报错、再贴回去。这个循环里人既是需求方又是编译器又是测试员还是版本管理员。AI 只承担了“生成文本”这一小段剩下的全压在人身上。项目一小还好项目一大人的注意力就成了瓶颈。Agentic Harness Workflow 把这个循环重新切分了。它把一次完整的编码任务拆成若干个有明确输入输出的阶段每个阶段由 AI 代理在受控环境下执行阶段之间通过结构化的产物文件、补丁、测试报告传递而不是靠聊天记录传递。人从“每一步都盯着”变成“在关键节点做验收和决策”。这个转变带来的最大好处是可复现性。因为每个阶段的输入是明确的、产物是落盘的所以同一个任务在同样的起点上跑两遍结果应该高度一致。这一点在团队协作里价值极高——你不需要再解释“我当时是怎么问它的”因为流程本身就是文档。2.2 为什么选择“约束优先”而不是“自由优先”很多 AI 编码方案走的是“自由优先”路线给 AI 最大的自主权让它自己规划、自己决定改哪些文件、自己决定怎么验证。听起来很美好但实测下来自由度越高跑偏的概率越大。一个典型场景是你让它修一个空指针它可能顺手重构了整个模块还引入了两个新依赖。Harness 框架的设计哲学恰恰相反是约束优先。它先划定边界再在边界内给 AI 自主权。具体体现在三个层面文件边界每个任务明确声明允许修改的文件范围超出范围的操作直接拒绝。接口边界任务开始前先冻结接口契约函数签名、数据结构、API 路径AI 只能实现不能改契约。验证边界每个阶段结束必须通过预设的检查编译、单测、静态扫描不通过就回退重来。这种设计牺牲了一部分“惊喜感”换来的是稳定和可控。对于生产项目来说这个交换非常划算。我个人的经验是在 AI 编码里可预测性比创造力重要得多因为创造力应该由人来提供AI 负责的是把人的意图准确、完整地落地。2.3 框架的四个核心角色划分为了让流程清晰我把整个框架里的参与者分成四个角色每个角色职责单一互不越界角色职责由谁承担规划者 Planner把需求拆成可执行的任务清单定义验收标准AI 代理 人工确认执行者 Executor在约束范围内生成代码补丁AI 代理验证者 Verifier运行测试、静态检查、对比契约自动化脚本裁决者 Arbiter决定通过、回退还是升级人工人工 规则引擎这个划分的关键在于验证者和执行者必须分离。如果让同一个 AI 既写代码又判断自己写得对不对它几乎总会说“没问题”。把验证交给独立的自动化脚本才能形成真正的闭环。裁决者保留人工是因为有些边界情况机器判断不了比如“这个改动虽然测试过了但业务语义上不对”。2.4 与常见方案的对比与取舍市面上常见的 AI 编码组织方式大致有三类我把它们和 Harness 框架放在一起对比方便你判断该选哪条路方案类型典型特征优势短板纯对话式单轮或多轮聊天上手快、灵活不可复现、难协作单代理自主式一个代理自主规划执行自动化程度高易跑偏、难审查多代理协作式多个代理分工覆盖复杂任务协调成本高、易死循环Harness 工作流阶段化 约束 独立验证稳定、可复现、可审查前期搭建有成本Harness 框架其实吸收了多代理协作式的分工思想但用固定阶段替代了代理之间的自由协商从而避免了“两个代理互相扯皮”的死循环。它的代价是前期要花时间定义阶段、契约和检查项但一旦搭好后续每个任务的边际成本会大幅下降。我的实测数据是搭建期大约投入两到三天之后每个中等复杂度任务的返工率从原来的四成降到了一成以内。3. 核心环节拆解与实操要点3.1 任务契约把模糊需求变成可执行规格整个框架的起点是任务契约。它是一份结构化文档把“我想要什么”翻译成机器和人都能验收的规格。一份合格的任务契约至少包含五个字段目标描述一句话说清要达成什么避免“优化一下”这种模糊词。允许修改范围列出文件或目录白名单。接口契约涉及的函数签名、数据结构、外部依赖版本。验收标准可执行的检查项比如“单测全绿”“编译无警告”。回退策略失败时是重试、缩小范围还是升级人工。我踩过的一个坑是早期我图省事验收标准只写“功能正常”。结果 AI 交上来的代码确实“能跑”但边界条件全没处理。后来我把验收标准改成具体的断言列表比如“输入为空时返回默认值”“并发调用不产生竞态”产出质量立刻上了一个台阶。验收标准写得越具体AI 的自由发挥空间就越合理这不是限制它而是给它明确的目标。提示任务契约建议用 YAML 或 JSON 存储方便脚本读取和版本管理。不要写在聊天记录里那样无法追溯。3.2 上下文装配给 AI 喂对信息比喂多信息更重要很多人以为给 AI 的上下文越多越好恨不得把整个仓库塞进去。实测下来这是反效果的上下文越长模型对关键信息的注意力越分散越容易忽略真正的约束。Harness 框架的做法是按需装配上下文每个任务只加载三类信息契约相关文件任务要改的文件及其直接依赖。接口定义被调用和被实现的接口签名。历史决策记录之前对同类问题的处理约定避免重复踩坑。装配过程由一个脚本自动完成根据任务契约里的文件白名单反向解析依赖图只拉取必要节点。这样既控制了 token 消耗又保证了信息密度。我做过对比同样一个任务全仓库上下文和按需装配上下文前者平均要 8 万 token 且经常跑偏后者 1.5 万 token 且一次通过率明显更高。3.3 执行与补丁生成让改动可审查、可回滚执行阶段的核心产物不是“一段代码”而是一个补丁。这个区别很关键。如果 AI 直接改文件你很难知道它到底动了什么如果它输出一个标准格式的补丁比如统一 diff 格式你就可以先审查、再应用、出问题还能一键回滚。我在框架里强制要求执行者输出补丁并且补丁必须满足三个条件只包含白名单内的文件、不修改接口契约、每个改动块附带一句意图说明。意图说明看起来是小事但在审查时特别有用——你能快速判断这个改动是不是“顺手多改的”。实测中加了意图说明之后我审查补丁的速度大概快了一倍因为不用再逐行猜它为什么这么改。注意补丁应用前一定要先做一次“干跑”dry run确认能干净应用。我遇到过补丁因为行号偏移应用失败、结果把代码改乱的情况干跑能提前拦住这类问题。3.4 独立验证把“我觉得对”变成“证据表明对”验证阶段是整个框架的信任基石。它的原则是执行者不能自证清白。验证由独立的脚本完成至少覆盖四类检查编译/构建检查代码能不能过编译依赖有没有冲突。单元测试契约里声明的测试用例是否全绿。静态扫描有没有引入明显的坏味道比如超长函数、重复代码。契约一致性接口签名、数据结构是否和契约一致。这四类检查里我认为契约一致性检查最容易被忽略但价值最高。因为 AI 很擅长“表面满足、暗中改契约”——比如你要求它实现一个返回数组的函数它可能偷偷改成返回对象然后调用方也跟着改最后整个链路都偏了。加一道契约比对就能把这类问题挡在合并之前。3.5 裁决与回退失败不是终点而是分支验证不通过时框架不会简单地“重试”。它进入裁决分支根据失败类型走不同路径失败类型处理策略编译/测试失败携带失败日志回退到执行阶段重试最多 N 次契约不一致直接拒绝要求重新对齐契约超出修改范围拒绝并告警人工确认是否扩大范围多次重试仍失败升级人工附带完整过程记录这个分支设计避免了“无限重试烧 token”的陷阱。我设的重试上限是 3 次超过就升级人工。实测下来绝大多数失败在前两次重试内能解决剩下的基本是契约本身有问题机器再试也没用必须人来重新定义任务。4. 完整实操流程与关键环节实现4.1 目录结构让流程有物理载体框架落地第一步是把目录结构定下来。我用的结构是这样的你可以直接参考project/ ├── harness/ │ ├── contracts/ # 任务契约 │ │ └── task-001.yaml │ ├── context/ # 装配后的上下文快照 │ ├── patches/ # 生成的补丁 │ ├── reports/ # 验证报告 │ └── decisions/ # 裁决记录 ├── src/ # 实际源码 └── tests/ # 测试用例把流程产物和源码分开存放好处是源码目录保持干净流程产物可以单独做版本管理和清理。contracts目录是核心每个任务一份契约文件命名带序号方便追溯。reports和decisions是审计依据出问题时能完整还原“当时发生了什么”。4.2 任务契约的编写样例下面是一份我实际用过的契约样例做了脱敏处理task_id: task-001 goal: 为数据处理模块增加空输入保护返回默认空结果 allowed_paths: - src/data/processor.py - tests/test_processor.py interface_contract: function: process_records signature: process_records(records: list) - list behavior: records 为空时返回空列表不抛异常 acceptance: - pytest tests/test_processor.py -k empty_input 全绿 - 编译无新增警告 - 函数签名与契约一致 rollback: max_retries: 3 on_exhaust: escalate这份契约里allowed_paths限定了改动范围interface_contract冻结了签名和行为acceptance给出了可执行的验收命令。写这份契约大概花了我五分钟但它省下的返工时间远超这个投入。契约写得越像一份可执行的规格说明AI 的执行就越接近你的预期。4.3 上下文装配脚本的实现思路上下文装配脚本的核心是依赖解析。我用 Python 写了一个简化版思路是从契约里的allowed_paths出发解析每个文件的 import 语句递归收集直接依赖但只保留一层深度避免上下文爆炸。import ast from pathlib import Path def collect_deps(file_path, depth1): if depth 0: return set() deps set() tree ast.parse(Path(file_path).read_text()) for node in ast.walk(tree): if isinstance(node, ast.Import): for alias in node.names: deps.add(alias.name) elif isinstance(node, ast.ImportFrom): if node.module: deps.add(node.module) return deps def assemble_context(allowed_paths): context {} for p in allowed_paths: context[p] Path(p).read_text() for dep in collect_deps(p): dep_file resolve_module_to_file(dep) if dep_file and dep_file not in context: context[dep_file] Path(dep_file).read_text() return context这段代码的关键点是只收集一层依赖。我试过收集两层结果上下文体积翻了三倍但通过率没有明显提升反而因为噪声变多而下降。一层深度是个比较稳的平衡点。resolve_module_to_file需要你根据项目结构自己实现把模块名映射到文件路径。4.4 补丁生成与应用的标准流程执行阶段我要求 AI 输出统一 diff 格式的补丁。生成之后应用流程分三步走干跑校验git apply --check patch.diff确认能干净应用。应用补丁git apply patch.diff应用到工作区。记录快照把应用后的文件状态存一份到harness/patches/方便回滚。这里有个细节值得说我习惯在应用补丁前先git stash或提交当前工作区保证有一个干净的基线。这样一旦补丁出问题git checkout .就能一键回到应用前的状态。回滚能力是这套框架敢让 AI 自动改代码的底气没有它任何自动化都是冒险。4.5 验证脚本的检查项配置验证脚本我拆成四个独立函数每个返回明确的通过/失败状态和日志def check_build(): result run(python -m compileall src/) return result.returncode 0, result.stderr def check_tests(test_expr): result run(fpytest {test_expr}) return result.returncode 0, result.stdout def check_contract(contract): sig inspect_signature(contract[interface_contract][function]) expected contract[interface_contract][signature] return sig expected, fexpected {expected}, got {sig} def check_scope(allowed_paths): changed get_changed_files() out_of_scope [f for f in changed if f not in allowed_paths] return len(out_of_scope) 0, fout of scope: {out_of_scope}四个检查里check_scope是我最看重的。它确保 AI 没有越界改动。实测中越界改动是导致“改一处崩三处”的头号原因加上这道检查之后这类事故基本绝迹。check_contract则防止接口被暗中篡改两者配合构成了框架的安全网。4.6 裁决记录与迭代优化每次任务结束后裁决结果会写入harness/decisions/格式包含任务 ID、结果、失败原因、重试次数。这些记录积累起来之后可以做一件很有价值的事分析失败模式。比如我发现某类任务总是因为“契约描述不清”而失败那下次写契约时我就会更注意那个字段的表述。我大概跑了三十多个任务之后总结出一个规律失败原因里契约问题占六成上下文问题占两成模型能力问题只占两成。这个数据说明与其纠结换哪个模型不如把契约和上下文这两件事做好。这也是 Harness 框架的核心价值所在——它把优化的重心从“模型”转移到了“流程”。5. 常见问题与排查技巧实录5.1 补丁应用失败怎么办补丁应用失败是最常见的问题通常有三个原因行号偏移、文件已被其他改动污染、编码格式不一致。排查顺序建议这样走先看git apply --check的报错信息它会指出具体哪一行对不上。如果是行号偏移尝试用git apply --3way做三方合并成功率会高一些。如果是文件被污染先git stash清理工作区回到干净基线再应用。编码问题比较隐蔽确认源文件和补丁都是 UTF-8 无 BOM。我踩过最深的一个坑是AI 生成的补丁里混入了全角空格肉眼完全看不出来但应用就是失败。后来我在验证脚本里加了一道“补丁字符集检查”专门扫非 ASCII 空白字符这类问题就再没出现过。5.2 AI 反复改不对同一个地方这种情况通常不是模型笨而是上下文里缺少关键信息。比如它一直改不对某个函数可能是因为它没看到这个函数的调用方约定。排查方法是把失败日志和当前上下文一起看找出“它不知道但需要知道”的信息补进上下文装配规则里。另一个可能是契约本身有歧义。我遇到过契约写“返回合理默认值”AI 理解成返回 None我期望的是返回空列表。这种歧义机器解决不了只能人来把契约写死。契约里的每个形容词都值得警惕“合理”“适当”“优化”这类词最好都换成具体描述。5.3 验证通过但代码质量差这是最危险的情况因为自动化检查全绿但代码实际上不可维护。常见表现是函数超长、重复逻辑、命名混乱。解决办法是在验证阶段加一道静态质量门禁比如限制函数行数、圈复杂度、重复率。这些指标可以用现成的静态分析工具跑把阈值写进契约的验收标准里。我的经验是质量门禁不要设太严否则会频繁误伤。我一般设函数不超过 80 行、圈复杂度不超过 15、重复率不超过 5%。超过阈值不直接拒绝而是标记为“需人工复核”这样既拦住了明显问题又不会因为死板规则卡住合理改动。5.4 多任务并行时的冲突处理当多个任务同时跑可能会改到同一个文件产生冲突。框架层面的处理原则是同一文件同一时间只允许一个任务修改。实现方式可以简单粗暴——用一个锁文件记录当前被占用的文件任务开始前先申请锁结束后释放。如果确实需要并行改同一文件那就得把任务拆得更细或者串行执行。我试过让两个任务并行改同一个模块的不同函数结果补丁互相覆盖排查了半天。后来老老实实串行虽然慢一点但省心得多。在 AI 编码里稳定性永远优先于吞吐量。5.5 常见问题速查表现象可能原因排查动作补丁应用失败行号偏移/文件污染/编码问题干跑校验、三方合并、字符集检查反复改不对上下文缺失/契约歧义补上下文、消歧义验证过但质量差缺质量门禁加静态检查阈值并行冲突同文件多任务加文件锁、串行化无限重试缺重试上限设 max_retries 并升级人工这张表我贴在项目文档里团队新人遇到问题先查表能自己解决八成以上的常见故障。剩下两成再找人沟通成本也低很多。6. 我在这套框架上的一些个人体会跑了一段时间之后我最大的感受是AI 编码的上限不取决于模型而取决于你给它搭的轨道。同样的模型在随意聊天里产出参差不齐在 Harness 框架里却能稳定输出可用的补丁。这个差距不是模型变聪明了而是流程把它的能力约束到了正确的方向上。另一个体会是关于“人机分工”的。这套框架并没有让人退出编码而是让人从“写代码”转向“定义问题”和“验收结果”。写契约、定验收标准、分析失败模式这些工作其实比写代码更考验工程判断力。我甚至觉得能把任务契约写清楚的人本身就是好工程师因为那意味着他真正想明白了要做什么。最后分享一个我最近在试的扩展方向把裁决记录喂回给规划者让它根据历史失败模式自动优化契约模板。目前还在小范围试验初步看能减少一部分重复性的契约编写工作。这个方向后续如果有稳定结果我再单独整理一篇。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑