☰
AI编码工程化:Agentic Harness Workflow如何用质量门和审计痕迹落地
2026/10/14 11:22:13 网站建设 项目流程

在演示环境里 AI 编码表现得再惊艳,一旦丢到真实的团队协作、代码评审、持续集成体系里,大多数都会被迅速打回原形。原因不是模型能力不够,而是我们始终在用聊天软件的逻辑去管理一个需要工程纪律的生产过程。我自己在多个项目里反复试错之后,最终收敛到一套叫 Agentic Harness Workflow 的框架——本质就是给 AI Coding 套上一套带检查点、带质量门、带审计痕迹的流程轨道。这篇文章会把这套框架的拆解思路、最小落地步骤和踩坑记录完整写出来,适合正在把 AI 编码引入正式项目的技术负责人和一线开发者参考。

1. AI 编码总在最后一公里翻车,问题到底出在哪

1.1 聊天式 AI 编码的四个"看不见"

过去大半年,我观察过很多团队把 AI 编码工具接入日常开发。最典型的用法是:开发者打开一个对话框,把需求贴进去,然后让模型直接生成一段代码或者补丁。小范围实验时效率确实高,但一旦进入多人协作的代码库,问题就开始集中爆发。

第一个问题是意图边界不可见。你在对话框里说"帮我优化一下登录模块",模型会自行假设它要改哪些文件、不改哪些文件、要不要顺手调整接口签名。这个假设过程对人是不可见的。当产出的补丁被送到评审环节,评审者往往要花大量时间去猜测 AI 当初为什么动了某处不该动的代码。

第二个问题是上下文不可见。模型能看到的上下文和它实际用到的上下文常常不一致。你可能给了它三个关键文件,但它还会根据 embedding 相似的代码自行补充十几个文件。最终生成结果里哪些判断来自你给的资料、哪些来自它自己的联想,几乎无法追溯。

第三个问题是工具行为不可见。很多 AI 编码工具会自己调用终端命令、读取测试输出、尝试修复报错。但在聊天模式下,调用过程是黑盒,你只看到最终抛出来的结论。一旦结论错了,你想复盘到底是哪一步决策导致偏离方向,根本没有日志可查。

第四个问题最致命:结果不可验证。模型生成代码之后,你说"看起来没问题",但项目是否完整通过类型检查、所有测试是否真的运行过、是否存在既有功能回归——这些在聊天式交互里通常被当作背景噪音忽略掉。等合并进主干,问题才在深夜的构建流水线上爆发。

这四条合在一起,本质就是一件事:AI 编码缺少工程化的观测与控制面。我们需要的不只是更强的模型,而是一套能让过程被组织、结果被验证、责任被追踪的"控制器"。

1.2 从"能跑通"到"能上线",中间缺的是一道流程闸门

"能跑通"和"能上线"之间的差距,我习惯用一句大白话形容:跑通是模型自己对自己的证明,上线是工程体系对所有人的证明。

一个可以稳定上线的工程化流程,至少要有几个特征:每个任务有明确的目标描述和验收标准;每个变更都能指出它影响的范围和依赖;每次执行都要留下可回放的过程记录;每个变更在合入之前必须经过定义清晰的质量关卡。聊天式交互一条都不满足。

所以我在内部推的这套 Agentic Harness Workflow(下文简称 AHW),核心目标不是让 AI 更"聪明",而是让 AI 的每一次编码行为都像工程流水线里的一道工序:先定义,再执行,再验证,再评审,最后落库。每个环节都有人接手和检查,模型不再被当成一个能自主完成所有事的黑盒,而是整个工作流中被约束的执行节点。

2. Harness 不是又一个 Agent,而是一条带闸门的流水线

2.1 把一次编码任务拆成有检查点的流程节点

很多人第一次听到 Agentic Harness 会误以为它是某种更强大的 Agent 产品。实际上,它更像一条装配流水线:原材料进来,经过多个工序,每道工序都有明确输入输出和质检标准,任何一个节点不合格都会被拦下来返工或者终止。AHW 把原来的"一次对话"拆成了六个核心节点:

  • 需求节点:将用户需求转成结构化任务描述,包括目标、范围、验收标准和约束条件。
  • 规划节点:让模型制定文件改动清单、依赖变更清单和测试策略,先不改代码,只出计划。
  • 执行节点:在隔离环境中生成补丁,记录每一步工具调用和文件变更。
  • 自检节点:Agent 自己运行类型检查、单元测试和静态扫描,把结果写回流程。
  • 评审节点:人工 Reviewer 对照需求描述检查补丁,可以要求修改或者打回。
  • 合入节点:通过所有质量门之后,才把补丁合入主干,并同步更新任务状态。

每个节点都对应一个可观测的产物:需求节点产出任务单,规划节点产出改动计划,执行节点产出补丁和变更记录,自检节点产出验证报告。节点之间完全解耦,人工可以在任意一步接管。这样设计的好处是:任何一步出问题,我们都能快速定位,并且把 Agent 的行为限制在可控范围内,而不是放任它从头到尾一气呵成地操作真实代码库。

2.2 控制面与数据面分离,Agent 只是执行器

AHW 最关键的设计思想,是把控制面和数据面彻底分开。

控制面指的是任务编排、状态流转、质量门、权限授予、人工确认这类机制,它决定的是一段代码"能不能被生成、要不要合入",由人和配置规则共同掌控。数据面指的是代码内容、文件变更、测试日志、运行结果,这些由 Agent 操作产生,但它的流动和落库都在控制面的监视之下。

类比来说,控制面是工厂车间里的中央控制室,负责规划产能、安排工序、检查良品率;数据面是具体车间里的机器,机器可以高速运转,但每一步都要把数据上报给控制室。如果一台机器擅自跳过了质检工序,控制室可以直接拉闸。聊天式 AI 编码的问题恰恰在于:控制室和机器挤在同一个房间里,机器自由发挥,控制室得不到过程数据,最后只能凭感觉验收。

这个分离也让权限控制变得清晰。在实际落地中,我们让 Agent 只能在一个隔离的临时环境里修改代码,对正式仓库只有只读访问权限。补丁生成后由控制面统一收集,再走评审合入。这样无论模型怎么自由发挥,它对正式仓库的破坏半径始终有限。

3. 编排一个最小可用的 Agentic Harness Workflow:到底怎么做

3.1 先给 Agent 一份"任务描述规范",而不是一句话需求

落地 AHW 的第一步,不是写代码,而是定义任务描述规范。聊天模式下我们习惯一句话说需求,但流程化之后,Agent 的输入必须是结构化任务单。我一般要求任务单包含以下字段:

  • 目标:一句话说明这次改动要解决什么问题。
  • 范围:允许修改的目录、模块、文件清单,甚至可以指定禁止触碰的路径。
  • 依赖:需要调用的内部包、外部服务或协议说明。
  • 验收标准:可被自动检查的条件,比如"新增函数必须覆盖所有分支""不得修改公共接口签名""全量测试通过"。
  • 约束:风格规范、兼容性要求、禁止事项。
  • 参考材料:相关的设计文档、接口文档和示例代码路径。

下面是我在项目里常用的一份简化版任务单,写成文本文件后作为 Agent 的输入:

task: FEAT-421 goal: 为订单模块增加按日期范围查询的聚合统计接口 scope: allow: - services/order/ - tests/order/ deny: - infrastructure/database/ - api/legacy/ acceptance: - go test ./services/order/... 全部通过 - 新增接口必须带 OpenAPI 注解 - 不得修改已有数据库表结构 constraints: - 使用项目现有的日志框架 - 错误码必须符合全局错误码规范 references: - docs/order-api-design.md - services/order/order_service.go

注意,这份任务单不要求严格按 JSON Schema 校验,只要能稳定解析成字段给 Agent 读取即可。关键是它把原来隐含在对话里的边界和验收标准显式化,这样后面所有质量门才有评判依据。

3.2 用声明式配置描述工作流,而不是写一堆胶水脚本

流程化之后,最忌讳的是在代码里到处用 if-else 串联 Agent 调用。那样过两个星期没人维护就得重构。我建议用声明式的配置文件定义工作流,让编排引擎负责调度。一个最简版本的 AHW 配置文件长这样:

workflow: id: ai-code-review nodes: - id: prepare type: task-builder source: input-task - id: plan type: agent-execute agent: planner input: prepare output: plan.json - id: review-plan type: human-approval input: plan.json timeout: 30m - id: patch type: agent-execute agent: coder input: review-plan output: workdir sandbox: image: base-code-env network: off mount: read-only-repo - id: verify type: runner command: ./scripts/verify.sh input: patch artifacts: - test-report.xml - static-check.txt - id: human-review type: human-approval input: verify require: code-owner - id: merge type: merge-controller input: human-review renew: true

这里的重点是四个节点设计:plan先输出计划,review-plan让人看计划,patch在隔离沙箱里执行生成,verify是自动质量门。每一步的输入输出都是明确的文件或目录,哪一步失败都可以直接断在本节点,不会出现 Agent 带着上下文到处横跳的情况。

如果你不想引入重型编排平台,用公开的 CI 工具把每一步串成阶段也可以。关键不是工具,而是把节点抽象出来,让 Agent 的执行过程像普通 CI 任务一样可以被触发、被观测、被回滚。

3.3 Agent 运行时收敛为短生命周期任务进程

我在多个项目里对比过两种 Agent 运行方式:一种是常驻型的 Agent,长期保持会话上下文,不断接收需求;另一种是短生命周期的任务进程,每次任务启动一个新上下文,执行完就销毁。AHW 场景下我强烈建议用后者。

短生命周期进程的优势非常明显。第一,上下文干净,任务之间不会因为残留记忆互相污染;第二,状态易恢复,执行到一半崩溃了,重新启动一个进程就能重跑,不需要处理复杂的状态恢复;第三,资源和权限可以按任务粒度收紧,这个任务需要访问数据库就授予数据库工具,不需要就不授。

在运行时层面,我们给 Agent 配置了工具白名单。它在沙箱里只能调用预先批准的命令:读取文件、写文件、运行测试、检查静态分析输出。任何超出白名单的工具调用都被直接拒绝,并记录到审计日志里。比如模型想顺手执行go mod tidy或者git push,我们都要先打回。宁可慢一点,也不能让 Agent 在无人监督时对仓库产生结构性影响。

3.4 让 Agent 的每一步都留下可供追溯的痕迹

听我一句劝:千万别把 Agent 当成一个可以瞬间交付结果的黑盒。至少要记录三类痕迹:

  • 会话与决策记录:任务目标文本、Agent 规划输出、每一步工具调用参数。
  • 产物快照:生成前的代码基线 hash、生成后的文件 diff、测试报告原始输出。
  • 人工干预记录:谁在什么时间对哪个节点做了批准、驳回或修改。

我见过不少团队省掉了这些记录,理由是"日志太乱、占存储、没人看"。等到 Agent 生成的某段代码在线上出了严重事故,复盘时拿不出任何过程依据,只能推倒重来。记录质量决定这个流程能不能长期可信,宁可前期多一些存储开销,也绝对不能养成裸奔习惯。

4. 质量门不是锦上添花,而是让 Agent 收敛的护栏

4.1 把质量门分成三层,优先级从高到低

质量门不能只做一个"最后有没有报错"的判定,否则等于没有。我在 AHW 里把质量门拆成三层:

第一层:基础执行门。代码能否编译、类型检查是否通过、单测是否执行成功。第二层:影响分析门。这次改动涉及了哪些文件,有没有触碰到任务单里标记的禁止路径;有没有修改接口签名导致调用方不兼容;有没有引入新的依赖或者版本漂移。第三层:行为回归门。跑一次包含历史关键用例的回归测试,必要时做一次简单的性能对比。

三层可以放在一个verify脚本里顺序执行,但每层的结果必须独立记录。举个例子,基础执行门通过但影响分析门发现 Agent 偷偷改了任务单禁止的数据库脚本,这时候要立刻打断并打回任务,而不是继续往下验证。

下面是我们 verify 脚本的简化逻辑:

#!/usr/bin/env bash set -eo pipefail echo "== [gate-1] compile & unit test ==" make build make unit-test echo "== [gate-2] scope & API diff ==" changes=$(git diff --name-only origin/main) if echo "$changes" | grep -Eq "$DENY_PATTERN"; then echo "DENY: touched forbidden path" >&2 exit 2 fi api-diff-tool --base origin/main --head HEAD --fail-on-rc=true echo "== [gate-3] regression ==" make regression-test

这个脚本在 CI 里跑,任何一步 non-zero 都会导致补丁无法进入人工评审。执行门本身不需要写得多复杂,但它必须独立于 Agent 生成过程,不能由 Agent 自己调用的测试进程来代替。

4.2 人工确认点放在哪里,最有价值

有人会问:既然质量门都自动化了,人工确认点还需要吗?我的经验是:需要,但绝不能在最后一个步骤才让人介入,那样返工成本太高。AHW 里设置了两个人工确认点:

一是规划确认点。Agent 出计划之后,人先看计划是否合理,包括改动范围、依赖、测试策略。这个点通常只要几分钟,却能把最多的问题挡在动手之前。你见过 Agent 设计了一个要重构整个模块的增删方案,但用户实际只想加个开关?几乎天天见,规划确认就是干这个用的。

二是补丁确认点。自动化质量门全部通过之后,由代码所有者最终 review 补丁,主要看的不是语法,而是业务逻辑是否符合预期、有没有违背设计约束、会不会引入长期维护负担。这个确认点是人与机器之间的最后一道信任边界,无论如何不能省略。

4.3 给 Agent 完整的验证反馈回路

质量门的价值不止于"拦截",还在于给 Agent 提供修正依据。当某个门失败,常见的做法是把错误日志直接回传给 Agent,让它在同一个任务上下文里继续修复。我在实际使用中发现,这个操作必须做,但有个前提:错误信息要被转译成结构化反馈,不能把一堆原始日志丢给模型。

转换后的反馈大概长这样:

verify_result: gate: scope-check status: failed forbidden_paths: - infrastructure/database/schema.sql task_scope: allowed: [services/order/] instruction: 撤销对 forbidden 路径的全部改动,并将变更重新限制在 task scope 内

模型看到这样的反馈,比直接给它一万行编译日志效果好得多。Agent 修复之后重新走流程,直到所有门都通过。这个过程是 AHW 能够让 AI 编码收敛的核心——把每次失败都变成一次有依据的修正,而不是凭空重试。

5. 上线两个多月后,我记录下来的失败模式与对策

5.1 高频失败模式对照表

把 AHW 跑起来之后,真正让人头疼的问题基本集中在几个反复出现的失败模式上。我整理了一份对照表,供大家排查时参考:

失败模式典型表现直接原因对策
测试自证Agent 生成测试的同时把被测试代码也改成按测试的逻辑走验证依赖 Agent 自己生成的标准测试用例由独立 reviewer 或预置用例库提供
范围蔓延改动文件远超任务单范围任务单约束不明确或缺少 scope gate在 verify 阶段强制校验路径白名单
上下文漂移大型代码库中 Agent 代码逻辑混乱一次给入过多无关上下文收敛参考文件,使用分步规划节点
工具调用吞错Agent 执行命令失败但当作成功继续异常处理不完善运行时层严格检查命令退出码并中断
重试风暴同一个修复反复失败十几次不收敛没有结构化反馈回路将错误转译为结构化反馈,限定重试次数
数据污染不同任务之间共享目录导致结果异常短生命周期进程但持久化目录未隔离每个任务独立工作目录,任务结束后归档

这六种失败模式里,最隐蔽、破坏力最大的是前两种。下面重点展开。

5.2 最值得警惕的两种隐藏失败:测试自证与范围蔓延

测试自证这个坑,我估计凡是把测试也交给 Agent 一起生成的人都踩过。表现是:Agent 为某个新函数生成了单元测试,同时因为修改了被测试函数的实现,测试总能通过。但测试根本不是在验证真实行为,而是在验证 Agent 自己写出来的行为。这个测试对老功能没有任何保护作用。要破这个局,最有效的方法是:测试用例来源与代码生成来源隔离。要么使用团队维护的公共用例库,要么至少安排不同上下文里的 Agent 分别生成实现和测试,或者让人工 reviewer 对测试断言提出质疑。

范围蔓延更常见。模型看到任务描述里提到某个业务模块,就顺手改了相邻模块的工具函数,美其名曰"相关代码优化"。在只有 diff 没有 scope gate 的情况下,这类改动几乎必然混进补丁。后来我们在 verify 阶段写死了路径白名单,凡是不在scope.allow内的文件一律打回,范围蔓延才被压制住。

另外要提醒一点:禁止路径往往比允许路径更重要。写任务单时,明确列出"绝不能触碰的文件",比列一堆允许目录更有效。模型对"不要做 X"的理解通常比"只做 Y"更直接,因为这个约束在生成阶段就会发生作用,而不是等到 verify 才拦截。

5.3 资源与成本也是流程要约束的对象

Agent 跑在隔离环境里,每次任务都会消耗计算资源和模型 API 配额。不加限制的话,一个混乱的修复循环能把成本推高到一个很离谱的水平。AHW 里我给每个任务设了三重限制:

  • 重试次数上限:同一节点最多重试 3 次,超过后必须转入人工处理。
  • 执行时间上限:沙箱里所有工具调用总时长超过 20 分钟直接终止。
  • 上下文预算上限:Agent 每次规划时给定上下文容量上限,超限就要求它先压缩信息再继续。

这三条不是拍脑袋定的。我见到过某个任务因为上下文超限,Agent 开始遗忘自己的改动目标,在同一个问题上反复打转。限定执行时间和重试次数之后,团队反而更快介入,成本也更可控。流程的约束力不只是质量层面的,资源层面的护栏同样重要。

6. 让团队真正接纳 AI Coding 的推行节奏

6.1 阶段一:让 Agent 只当"评论员",不当"写手"

如果你所在的团队之前没有任何 AI 编码流程,我建议不要一上来就让 Agent 直接生成补丁并合入主干。先把 AHW 当成一个代码评审辅助工具来用。

在这个阶段,Agent 的工作是:阅读一个已经完成的人工人 Patch,对照任务描述输出风险提示、潜在边界条件和遗漏的测试策略。这个输出可以被 Reviewer 当作评审建议使用,但不直接参与修改代码。这么做有几个好处:风险低、反馈周期短,团队可以建立对 Agent 产出的信任基线,同时也让人熟悉任务描述规范应该怎么写。

我当时拿一个新功能的人工人 Patch 试验了几轮,效果超出预期。Agent 不光指出了几个边界情况,还提醒了某处对老接口的兼容性问题。团队的反馈是"有帮助",于是我们才进入下一阶段。

6.2 阶段二:让 Agent 生成"可被整体审核"的补丁

第二阶段,Agent 开始生成补丁,但必须经过完整的规划确认、验证闸门和人工补丁确认。这个阶段的关键指标不是"生成快不快",而是"补丁通过评审的比例"。

我们统计了两个数据:一次通过率和平均评审返工轮数。最初一次通过率只有不到三成,多半是补丁内容超出范围、或者没按团队风格规范写。后来靠任务单和验证反馈逐步改善,一次通过率提升到六成左右。这个阶段不要为了追求通过率而把验收标准降低,宁可让 Agent 多返工,也要让团队形成"AI 产出必须达到和人类 Patch 同等标准"的心理预期。

6.3 阶段三:让 Agent 进入常态缺陷修复流,但要保留逃生舱

第三阶段,我们把 AHW 接入日常缺陷修复流程,对于低风险的 bugfix 类任务,Agent 可以在自动验证通过后合并,但仍保留人工随抽机制和回滚开关。

这个阶段我特别强调保留"逃生舱":任何被自动合并的补丁,在主干上必须持续监控它的测试表现和线上指标。一旦发现异常,可以一键回滚到上一个基线。想做到这点,合入节点必须保存完整基线状态,且每一次自动合入都是一个独立可回滚的原子操作。

当流程跑到这个阶段,AI 编码就算真正被工程化了。它不再是某个开发者的个人辅助工具,而是团队共享的一条经过设计的、可审计的、有质量保障的生产链路。

我自己在这套流程上花的最值的一笔投入,不是选了多复杂的编排平台,而是花大量时间打磨任务描述规范和 verify 反馈格式。前者决定 Agent 的起点,后者决定 Agent 的收敛速度。把这两件事做好,哪怕背后接的模型版本一般,整体效果都不会差。如果你正打算把 AI 编码引入正式项目,建议先把这两块地基打好,再往上面盖高。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询