AI 编码工作流的设计

74 阅读21分钟

在日常的研发中,直接向大模型输入”帮我实现这个功能”或“修复这个 Bug”,往往会陷入“生成代码 -> 与原有需求方案偏差/技术方案偏差/编译报错 -> 修复偏差/修复报错 -> 完成本轮开发”的问题,如何能保证单轮对话AI的完成质量?这种问题的根源在于:缺少必要的上下文约束、缺乏明确的决策边界,以及模型在自审时难以克服的“确认偏误”(Confirmation Bias)。

本文将分享在设计AI 研发工作流(dev-workflow 与 bugfix-workflow)的一点心得。本文将重点讨论流程中的决策链构建、状态机约束、Agent 角色分工,以及为什么在复杂工程中必须引入主 Agent、独立 Agent 与 subAgent 协同作战。


一、为什么需要结构化工作流?

在复杂工程中,编写代码只是整个研发链路的末端。未理清需求背景与边界就直接编码,极易导致设计偏离。因此,我们的工作流划分为明确的几个阶段,每个阶段对应特定的角色与责任:

flowchart TD
    Phase0[Phase 0: 背景分析] --> Phase1[Phase 1: 架构与方案]
    Phase1 --> Phase2[Phase 2: 代码实现]
    Phase2 --> Phase3[Phase 3: 独立审查]
    Phase3 --> Phase4[Phase 4: 证据验证]
    Phase4 --> Phase5[Phase 5: 交付与归档]

阶段与角色定义

阶段角色核心职责为什么不能跳过
Phase 0Context Analyst梳理已有需求、相关代码关系及外部依赖(如硬件协议、接口规范)避免已经忘记已有的需求细节;避免模型幻觉或忽视既有的上下文约束
Phase 1Planner设计状态流、定义模块边界、制定技术方案与验收标准在动代码前冻结架构决策,确保实现路径透明
Phase 2Coder按照已确认的方案编写或重构代码严格在限制的工程范围内修改,禁止超出方案随意发挥
Phase 3Reviewer独立检查代码 Diff,审查竞态条件、内存泄漏与边界异常打破“自写自审”的思维定势,提供客观审查视角
Phase 4Tester对照验收标准执行静态检查、核对现有证据并列出必要的人工验证项依靠客观证据而非“看起来没问题”的假设来确认交付
Phase 5Delivery Coordinator汇总变更、审查结论、验证范围与后续事项,按需更新文档避免局部结论分散,确保交付状态可追溯

二、状态机:用确定性对抗模型的随意性

大模型在长会话中极易产生“上下文漂移”——例如在未确认需求细节时就开始生成代码,或者在审查失败后盲目跳过修复。

为此,我们在工作流中引入了状态机与阻断机制(Checkpoint):

stateDiagram-v2
    [*] --> ContextAnalysis
    ContextAnalysis --> BackgroundPending: 背景梳理完成
    BackgroundPending --> Planning: 背景审批通过
    BackgroundPending --> ContextAnalysis: 补充背景
    Planning --> ProposalPending: 方案与验收标准完成
    ProposalPending --> Coding: 方案审批通过 (Approval)
    ProposalPending --> Planning: 修订方案
    Coding --> ImplementationPending: 实现与静态检查完成
    ImplementationPending --> Reviewing: 实现验证与放行
    ImplementationPending --> Coding: 实现反馈
    Reviewing --> ReviewFixing: 审查未通过 (带证据列表)
    ReviewFixing --> Reviewing: 定点修复后复核
    Reviewing --> Testing: 独立审查通过
    Testing --> VerificationFixing: 验证发现问题
    VerificationFixing --> Testing: 定点修复后复验
    Testing --> Delivery: 已执行检查通过,待人工项已披露
    Delivery --> [*]: 汇总交付与归档

阻断机制的三条硬性规则:

  1. 关键决策分别放行:背景、方案、实现分别对应 Checkpoint #0、#1、#2。背景确认后才能规划,方案确认后才能编码,实现结果经验证与放行后才能进入独立审查。每次放行只推进当前关卡可以合法的进入下一阶段。
  2. 审查与验证失败次数上限:Phase 3 与 Phase 4 分别记录连续失败次数,达到 3 次时强制暂停,交由人类工程师干预;返修不重置次数,防止模型进入无限自我修补死循环。
  3. 证据驱动的可靠交付:进入交付阶段前,必须给出实际执行的静态检查、可用日志、截图或其他验证证据,并逐条标明验收状态。仍需编译、运行或真机确认的项目必须明确列出,不得以主观描述或静态结果代替运行结论。

三、深入理解多 Agent 架构:主 Agent、独立 Agent 与 SubAgent 的协同哲学

在 AI 工作流的演进中,单 Agent 的局限性日益凸显:当任务变得宏大、上下文变得冗长时,单一上下文中的模型会面临注意力分散、逻辑混淆和严重的确认偏误。因此,引入多 Agent 协同架构势在必行。

但在实践中,我们必须明确区分它们的职责与存在价值:

1.什么是主 Agent (Main Agent)?

  • 角色定位:整个任务的“项目经理”与“核心主脑”。
  • 职责与使命:
    • 负责掌控总体进度、维护核心上下文(如原始需求、架构方案、主交付物)。
    • 驱动状态机从 Phase 0 稳步流转至 Phase 5。
    • 统筹全局,根据需要向外分派子任务,并对子 Agent 提交的结果进行汇总、核实与仲裁。
  • 为什么不可或缺:没有主 Agent,任务会陷入群龙无首的碎片化状态;它是保障整条研发流水线逻辑连贯的唯一锚点。

2.什么是独立 Agent(如独立 Reviewer Agent)?

  • 角色定位:拥有独立任务上下文的“外部专家”。
  • 为什么需要它(打破确认偏误):
    • 在传统的单 Agent 模式下,写代码的 Agent 和审查代码的 Agent 是同一个。当它“自己审自己”时,由于历史上下文里充满了“我刚才是这样想的”、“这个逻辑我觉得没问题”的心理暗示,模型会下意识地为自己的代码辩护,从而漏掉诸如竞态条件、边界异常等隐蔽 Bug。
    • 独立 Agent 拥有独立的上下文边界。它读取最新背景、“需求契约”、“架构方案”、“实际代码 Diff”及必要的代码上下文,不继承完整的编码对话和实现者的自我评价。它需要知道业务前因后果,但不被前面的实现推导牵着走,从而降低确认偏误的影响。

3.什么是 SubAgent?

  • 角色定位:由主 Agent 动态派生、专门处理特定繁重子任务的“特种兵”(如证据调查 subAgent)。
  • 为什么需要它(解耦与噪声治理):
    • 上下文污染治理:在排查复杂 Bug(如蓝牙通信失败、数据同步异常)时,往往伴随着几兆大小的运行日志或多张界面截图。如果全部喂给主 Agent,会迅速耗尽主会话的上下文窗口并引入大量噪音。
    • 并行调查与降本增效:subAgent 可以在独立任务上下文中对海量日志、时序数据或接口契约进行深度挖掘,过滤掉无关信息后,只向主 Agent 提交结构化的事实摘要和关键证据。对彼此独立的调查按需并行,有助于保护主 Agent 的注意力并提升复杂任务的排查效率;实际收益仍取决于任务规模与交接成本。

四、让 Agent 真正进入工作流:从角色分工到交付闭环

明确角色之后,还需要把这些角色放回真实的研发任务中,建立一条清晰的协作链:谁负责推进、交接什么、何时进入下一阶段,以及失败后如何处理。

关键在于,每个阶段都要解决一个不同的问题,并向下一阶段交付可核对的结果。角色分工只有与输入、输出、权限和失败处理绑定起来,才能成为真正可执行的工作流。

1. 先分清两个维度:工作职责与协作方式

前文提到的角色,实际上处在两个不同的维度:

  • Context Analyst、Planner、Coder、Reviewer、Tester:描述“当前要承担什么职责”。它们分别关注背景、方案、实现、审查和验证。
  • 主 Agent、独立 Agent、SubAgent:描述“由谁组织任务、如何划分上下文、如何委派工作”。

因此,五种工作职责并不意味着每次都要启动五个 Agent。在这套设计中,主 Agent 默认承担 Context Analyst、Planner、Coder、Tester 及最终汇总Delivery Coordinator;独立 Reviewer Agent 在 Phase 3 使用独立任务上下文审查;证据调查 SubAgent 则在日志分析、时序还原等工作确实复杂时按需介入。

一个 SubAgent 也可以承担独立 Reviewer 的职责,前提是它使用独立的审查上下文,且没有参与本次实现或诊断结论的形成。这里的“独立”,强调的是审查视角与上下文边界;“SubAgent”强调的是任务的委派关系。两者并不是互斥的产品类型。

人类工程师则保留业务目标、方案取舍和阶段放行的决策权。主 Agent 可以组织推进,但不能代替人类确认需求,也不能替独立 Reviewer Agent宣布审查通过。

2. 各阶段如何接力?

Phase 0:Context Analyst 先确认“我们究竟要解决什么问题”

  • 输入:用户描述、已有需求、相关代码、历史决策,以及能够取得的接口、设备协议或故障资料。
  • 工作内容:还原功能目标,区分当前行为与目标行为,整理影响范围、必须保留的规则和关键未知。
  • 交付物:背景分析和背景说明,原有的需求是什么;对于 Bug 修复,还要形成包含“触发条件、预期结果、实际表现、证据来源”的故障基线。
  • 交接条件:人类工程师确认背景与问题边界后,再进入方案阶段。背景确认只表示双方理解一致,不代表故障原因已经定位。

例如,用户反馈“蓝牙重连失败”,Context Analyst 需要先弄清:需求中连接是如何建立的、为什么现在没有建立、连接成功后页面没有更新,还是切换设备后旧连接仍在回调。这几种现象看起来相似,修复方向却完全不同。

为什么需要这一阶段:模型很容易把用户描述中的现象直接当成原因。如果没有故障基线,后续即使代码写得正确,也可能修复了另一个问题。

Phase 1:Planner 把背景转成“可实现、可审查、可验证的方案”

  • 输入:已确认的背景与边界、相关代码关系,以及必要的调查证据。
  • 工作内容:明确修改范围与不修改范围,设计状态流、模块职责、异常处理和兼容策略,列出实现任务及验收标准。
  • 交付物:技术方案与验证契约。验证契约说明每条验收标准准备如何核对,需要什么证据,以及哪些项目依赖人工或真机验证。
  • 交接条件:人类工程师确认方案后,Coder 才能开始修改代码。

在 bugfix-workflow 中,主 Agent 还要先承担 Investigator 的职责,交叉核对代码与故障证据,再以 Planner 的身份设计修复。证据不足时,应明确本轮是继续取证还是实施修复,不能把一个猜测包装成已经确认的根因。

为什么需要这一阶段:方案让“模型打算怎么改”在编码前变得可见;验收标准则提前定义“怎样才算完成”,避免模型写完代码后再挑选有利于自己的完成条件。

Phase 2:Coder 在已确认的边界内完成实现

  • 输入:已确认的方案、允许修改的模块或文件范围、项目规范及验收标准。
  • 工作内容:读取相关代码,按任务清单实现,复用已有能力,并执行允许范围内的轻量静态检查。
  • 交付物:实际代码 Diff、变更文件列表、静态检查结果,以及与原方案的偏差说明。
  • 交接条件:主 Agent 汇总实现结果,人类工程师完成当前关卡的实现验证与放行后,再交给独立 Reviewer。

如果编码过程中发现方案依赖的接口不存在,或者现有生命周期无法支撑原设计,Coder 需要把事实和影响反馈给主 Agent,更新相关方案与验收标准。涉及实质性取舍时,由人类工程师确认,不能顺手扩大范围或更换目标。

为什么需要这一阶段的权限约束:模型常常会在实现一个功能时顺便重构周边代码。限制 Coder 的修改范围,可以控制 Diff 的规模,也让后续审查更容易识别真正影响行为的变更。

Phase 3:独立 Reviewer检查“目标是否实现,工程上是否可靠”

  • 输入:最新背景、已确认方案、验收标准、实际代码 Diff、必要的调用上下文及项目规范。
  • 工作内容:同时进行需求正确性与工程正确性审查。前者检查有没有做错目标、遗漏规则或越出范围;后者检查协程与生命周期、异步竞态、异常处理、资源释放等工程问题。
  • 交付物:审查结论与问题列表。问题应包含代码位置、触发条件、具体影响及判断依据。
  • 交接条件:审查通过后进入验证;未通过则由主 Agent 核实问题、组织 Coder 定点修复,再交回独立 Reviewer 复核。

Reviewer 不直接接管业务实现。这样可以保留“提出问题—修复问题—复核结果”的责任链,避免审查者一边改代码,一边为自己的修改作出通过结论。

为什么必须保留独立上下文:主 Agent 切换一句“现在我是 Reviewer”,并不会清除它之前的实现思路。独立 Reviewer 需要基于需求、方案和代码重新作出判断,而不是延续 Coder 的自我解释。

注意:如果开发或修复的问题很简单,则单独开一个Reviewer Agent是没有必要的,可直接在主Agent中审查。

Phase 4:Tester 对照验收标准核对“哪些结果已经得到证据支持”

  • 输入:审查后的最新实现、验证契约、故障基线,以及对应版本的日志、截图或其他可用验证资料。
  • 工作内容:逐条核对验收标准,检查原始触发场景、相邻正常路径与相关边界,区分已通过、已失败和待人工验证的项目。
  • 交付物:验证报告,写明实际执行的检查、证据来源、未执行项及原因,必要时附上人工回归清单。
  • 交接条件:已知失败项进入定点返修;具备充分证据的项目才能标记通过,尚未运行的项目保留为待验证。

在Android 工程约束下,AI 默认执行静态检查、逻辑核对和现有证据分析,不主动编译项目,也不新增测试用例;编译、运行与真机验证按人工验证清单或后续明确授权处理。因此,Tester 必须明确区分“静态检查通过”与“真机行为已验证”,不能用前者代替后者。

为什么审查后还需要验证:Reviewer 判断的是代码是否存在可识别的问题;Tester 核对的是验收目标是否有证据支撑。尤其在设备通信场景中,回调顺序、硬件状态和网络环境都可能让代码阅读与实际表现产生差距。

Phase 5:Delivery Coordinator汇总交付,保留可继续追踪的上下文

  • 输入:最终实现、审查报告、验证报告及必要的背景或需求记录。
  • 工作内容:汇总改动范围、关键决策、验证结论、未解决问题和后续事项;按任务需要更新相关文档。
  • 交付物:可以追溯到文件与证据的交付说明,以及明确的待人工验证清单。
  • 完成边界:如果仍有真机或硬件项目未验证,应明确标记“实现与静态验证已完成,运行行为待验证”,不能笼统宣布全部通过。

为什么需要统一收尾:多个 Agent 的局部结论只有经过主 Agent 汇总,才能回答用户真正关心的问题:改了什么、解决了什么、凭什么这样判断、还剩什么没有确认。

3. SubAgent 如何参与,又为什么不负责整条流程?

证据调查 SubAgent 通常在 Phase 0 或 Phase 1 介入;Phase 4 如果需要复杂的修复前后对照,也可以复用。它的任务应当足够具体,例如:

分析指定设备在这一轮重连中的日志,按时间顺序整理断开、重试、连接回调与页面状态更新;区分已经观察到的事实与尚未证实的原因,并给出关键日志位置。

SubAgent 返回的应是时间线、关键证据、结论适用范围与未决问题。主 Agent 再把这些事实与业务背景、代码关系交叉核对,形成诊断或方案。

这条边界非常重要:调查 Agent 提供证据,主 Agent 组织决策,独立 Reviewer 审查实现。参与过诊断的调查 Agent 不兼任同一任务的独立 Reviewer,避免它在审查时继续维护自己的前期判断。

同时,独立上下文并不天然意味着工作目录或设备也被隔离。多个 Agent 共用工程或设备时,仍需明确文件所有权和操作顺序;同一台设备的页面操作、配对或取证应由一个执行者统一负责,避免调查过程相互干扰。

4. 举例用一次蓝牙重连故障串起整条链路

假设用户反馈:切换设备后,页面偶尔显示“已连接”,但当前设备实际上没有连接成功。 以下是一个假设性的处理过程:

  1. Context Analyst 确认目标:切换设备后,页面只反映当前目标设备的连接状态;正常重连能力需要保留。背景与边界由人类工程师确认。
  2. 调查 SubAgent 整理证据:时间线显示,旧设备的成功回调晚于设备切换到达,随后页面状态被更新。但这一先后关系仍需与代码调用链核对,不能只凭日志就宣布根因成立。
  3. Planner 制定方案:核对后确认旧会话回调能够写入当前状态,于是规划会话标识校验、旧任务取消与状态归属约束;验收标准同时覆盖旧回调被忽略、当前连接正常成功、失败状态正确展示。
  4. Coder 完成实现:修改已确认的连接与状态更新路径,提交 Diff 和静态检查结果,经过实现关卡放行。
  5. 独立 Reviewer 提出质疑:成功回调增加了会话校验,失败回调是否也会污染新会话?页面退出后,超时任务是否仍然能够更新状态?确认的问题由 Coder 返修,再交回复核。
  6. Tester 核对结果:对照同一组触发条件,检查对应修复版本的证据;旧版本日志只作为故障基线。没有取得真机结果的项目,明确留在人工验证清单中。
  7. Delivery Coordinator汇总交付:说明修复路径、审查结论、已验证范围和剩余事项,让后续验证可以沿着同一组验收标准继续。

这一过程中,工作流逐步回答了七个问题:目标是什么、现象是什么、原因依据是什么、准备如何修改、实现是否有遗漏、结果是否有证据、还有哪些未知。 任何一步出现关键缺口,都能定位到具体责任与交付物,而不必让模型从头重新猜测。

5. 为什么 dev-workflow 与 bugfix-workflow 共用骨架,却需要不同入口?

对比维度dev-workflowbugfix-workflow
核心目标实现已确认的新行为,或在保持外部行为的前提下重构恢复原本应当成立的行为
背景重点用户场景、需求价值、功能边界与现有能力原始需求、当前有效规则、异常偏差与故障基线
方案依据需求约束、现有架构与技术取舍代码与故障证据的交叉核对、原因判断与最小修复范围
验收重点新目标是否实现,原有能力是否受影响原始故障是否消除,相邻正常路径是否保留

两条流程共用阶段、审批与独立审查,可以减少重复规则;分别定义背景和方案的关注点,则能防止模型把“修复问题”顺手扩大成“重新设计功能”,或者把真正的新增需求误当成局部补丁。

6. 这套流程的必要性:把错误拦在更早、更清楚的位置

结构化工作流会增加背景整理、方案说明和独立交接的成本,但它要减少的是错误决策进入代码后,反复实现、反复排查、反复回滚的成本。

  • 背景阶段拦截目标错误:避免把设计行为当成 Bug,或把用户现象误当成故障原因。
  • 方案阶段拦截决策错误:在代码生成前暴露状态流、模块边界和验收条件的问题。
  • 实现阶段拦截范围失控:让每一处修改都能对应已确认的任务,减少无关重构与额外风险。
  • 独立审查拦截实现遗漏:引入没有参与编码推导的视角,检查需求偏差与工程缺陷。
  • 证据验证拦截虚假完成:把“看起来合理”“静态检查通过”和“运行行为已验证”分开记录。
  • 主 Agent 收尾拦截交接丢失:保留结论、依据和未决事项,让下一轮工作能够接续。

这些机制不能保证模型永远不犯错,但能让错误更早暴露、影响范围更容易控制、完成结论更容易核实。对于设备通信、异步状态和跨模块改动,这种可追溯性正是工作流的主要价值;对于简单任务,则可以压缩报告与调查规模,避免为了角色数量而增加无效协作。


五、上下文隔离与 Token 消耗控制策略

引入多 Agent 和 subAgent 架构时,必须警惕 Token 爆炸与交接失控的问题。合理的架构设计能够在可控的协作成本下换取更高的确定性:

  1. 精准交接,禁止全量复制: 主 Agent 委派 subAgent 或独立 Agent 时,传递目标、必要背景、约束条件、相关代码与 Diff、结构化契约,避免把数万行历史对话全文透传。必要背景应足以理解任务,精简上下文不能以遗漏需求边界为代价。
  2. 只返回事实摘要,不返回原始探索过程: 子 Agent 在解析了大量日志或进行了多轮代码检索后,只向主 Agent 返回结构化的结论与关键证据(如文件行号、关键日志原文),并注明事实、推断与未知。原始探索资料保留在子上下文或调查记录中,便于主 Agent 按需回查。
  3. 按需启用,避免过度设计:
    • 单 Agent 即可处理的轻量任务:无需进入完整研发流程的机械性单文件修改、局部 UI 文案调整或短日志解读,可以由主 Agent 直接完成;不必为了角色齐全而额外拆分任务。
    • 开启多 Agent 协同:进入本文两条结构化工作流时,Phase 3 保留独立 Reviewer;额外的调查 SubAgent 则按需启用,例如需要关联多次运行的日志、还原复杂时序,或跨多个独立领域(如 API 契约与底层通信协议)展开调查。是否委派取决于工作量与任务独立性,不按日志行数机械划分。

六、 总结

结构化工作流的核心,在于把对 AI 的信任建立在制度和约束上,而不是大模型的偶然表现上。

  1. 通过分阶段角色与阻断状态机,把控需求到代码的每一个决策点,用确定性对抗模型的随意性。
  2. 通过主 Agent 贯穿 + 独立 Agent 审查,维持任务的整体连贯,并降低模型自我确认偏误带来的遗漏。
  3. 通过明确的输入、交付物和返修路径,让各类 Agent 的职责形成闭环,确保“背景—方案—实现—验证”始终围绕同一个目标。
  4. 通过证据调查 subAgent 隔离噪声、通过验证报告披露未知,保护主上下文的干净与高效,让复杂工程的 AI 辅助研发具备可追溯、可核实的交付基础。

注:本文结合项目实践和我的想法和经验由AI生成,我负责把关和修改。如有错误欢迎批评指正。