AI Agent 研发工作流的设计与实现

我用 Agent 处理需求时,通常会先让它读需求、查代码、整理实现方案,再开一个新会话做 Review。等方案里的遗漏补齐、需要我决定的取舍确认下来,才进入开发。

这套做法让我更容易在写代码前发现问题,也带来了一项额外工作:我要负责把每一步接起来。

分析结束后,我得把方案复制给 Review Agent,补上原始需求和项目约束。Review 提出问题,再把意见送回分析会话。方案改了几轮,还得确认开发 Agent 拿到的是最后一版。一项需求还没开始写代码,我已经在几个窗口之间转发了不少内容。

有一次切窗口时,我突然觉得有点好笑:Agent 在分析和写代码,我成了它们之间的消息队列。

于是,我开始把这套操作整理成工作流。想解决的问题很具体:让系统记住任务进行到哪里、下一步该交给谁、哪些地方要等我确认,减少人工转发和重复补充上下文。

先把分析、Review 和决策分开

最开始使用两个 Agent,是因为我对同一个 Agent 自查方案的结果不太放心。

我的使用感受是,一旦前面的讨论定下了方向,后续检查也容易沿着这个方向展开。换一个新会话,重新给出原始需求、项目约束和待审方案,至少能让检查从另一份上下文开始。

因此,我给两边安排了不同的任务。分析 Agent 负责查找相关代码,说明改动范围、实现思路和验收条件;Review Agent 对照需求检查方案,追问兼容性、失败路径和测试依据,必要时自己回到代码里核对。

这种“生成结果,再评价并反馈”的循环,也出现在 Anthropic 介绍的 evaluator-optimizer 模式中。它能否发挥作用,依赖于清楚的评价标准和有用的反馈。换一个 Agent,并不能自动证明方案正确。Building effective agents 对这一模式有更完整的说明。

在这套流程里,Review 通过后还会停一次,由我确认是否开始开发:


flowchart TD
    I["收到需求"] --> A["需求分析"]
    A --> R["独立 Review"]
    R -->|需要修改| A
    R -->|通过| H["我来确认"]
    H -->|调整方案| A
    H -->|开始开发| D["开发"]
    D --> C["代码 Review"]
    C -->|存在问题| D
    C -->|通过| V["验证与交付"]

Review 可以指出某个方案会改变现有交互、增加兼容成本,或者超出原始需求,但这些信息还需要有人做取舍。是否接受这些变化,我希望自己决定。

这里的人工确认有明确的输入:经过 Review 的方案、尚未解决的问题,以及需要选择的事项。确认之后,开发才有一个相对清楚的范围。

多一轮 Review 也会增加耗时和调用成本。这套流程更适合影响范围较大、约束较多的需求;局部的小改动可以保留更短的路径,不必每次都走完所有阶段。

把阶段流转交给工作流

一开始,我想过把常用 Prompt 存成模板:分析一份、Review 一份、开发一份,用的时候选出来就行。

但即使每份 Prompt 都准备好了,我仍然要回答几个问题:

  • 当前阶段需要哪些输入,结束时要留下什么产物?
  • Review 通过后去哪里,退回后修改哪一份方案?
  • 哪一步可以自动继续,哪一步要等待人工决定?
  • 执行中断后,怎样判断还能不能接着做?

这些判断属于整项任务的调度。把它们都写进 Prompt,就等于要求当前 Agent 一边完成任务,一边解释和维护后续流程。

我更希望把职责分开:Agent 完成当前阶段并提交结果,工作流根据结果和规则决定下一步。这样调整流程时,可以直接修改阶段关系;调整分析或 Review 方法时,则修改对应阶段的 Prompt。

为了把这些信息放在一起,我把一项从需求理解走到开发交付的任务叫作 Issue。它是这套工作流里的任务载体,可以独立于 GitHub Issue 存在。原始需求、当前阶段、各轮产物和执行状态都归到同一个 Issue 下。

一次阶段执行可能被退回,也可能因为进程异常重新运行。因此,“当前处于哪个阶段”和“这个阶段运行过几次”需要分别记录。回看任务时,既要知道现在该做什么,也要知道每一轮留下了什么结果。

下面用 YAML 示意前半段流程,字段用于说明阶段之间的关系。这里只展开到进入开发,后续代码 Review 和验证对应上面的流程图:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
stages:
- id: requirement-analysis
agent: requirement-agent
next: requirement-review

- id: requirement-review
agent: review-agent
approved: human-confirmation
revision_required: requirement-analysis

- id: human-confirmation
type: manual-gate
approved: implementation
revision_required: requirement-analysis

- id: implementation
agent: development-agent

其中最容易混淆的是两次“通过”:方案 Review 通过,意味着进入人工确认;人工确认通过,才意味着开始开发。把这两个条件写在不同阶段里,流程的边界就清楚了。

工作流还需要一个可判断的阶段结论。仅凭“整体看起来不错”这样的回复,很难可靠地决定分支;明确的通过、退回或未完成状态,才适合作为流转依据。

交接产物,也交接判断依据

手工转发时,最顺手的办法是把上一段聊天记录整个复制过去。内容很多,但下一个 Agent 仍然需要判断:哪一个方案才是最终版本,哪些猜测已经被否定,哪些问题还没验证。

所以,我更倾向于让每个阶段交付一份可以独立阅读的产物,再按需提供工具输出和讨论记录。不同阶段要交接的重点也不同:

阶段 交接时需要说清楚的内容
需求分析 目标与范围、相关代码、实现方案、风险和验收条件
方案 Review 通过或退回的结论、问题依据、下一轮需要补齐的内容
开发实现 实际改动、验证方式与结果、未完成事项和已知问题

这里要压缩的是重复和过时的讨论,判断依据仍然要留下。例如,方案写了“保持兼容”,就应该能找到它考虑了哪些调用方;开发结果写了“测试通过”,就需要交代执行过什么、覆盖到哪里。

Review Agent 也需要原始需求和项目约束。如果它只能看到分析 Agent 的摘要,一旦摘要漏掉了某项要求,后续检查就可能跟着漏掉。代码 Review 则还要对准实际待审的代码和 diff,不能只看开发 Agent 对自己工作的描述。

方案修改几轮后,每轮产物可以分别保存,但要明确当前采用哪一版、对应哪一轮 Review。保留历史方便追溯,交给下一阶段的输入仍然需要有清楚的版本。

我会用一个很直接的问题检查交接是否充分:关掉这个会话,只看提交的结果和引用的材料,还能不能接着往下做?如果下一步仍然依赖“前面聊过,你应该记得”,交接就还没完成。

用 worktree 管代码,用 tmux 管进程

文档能够在阶段之间传递后,还需要给 Agent 一个执行任务的环境。进入代码开发时,工作目录和进程生命周期都会影响任务能否继续。

给每次执行准备独立目录

只读的分析任务可以共享代码目录。我目前的做法是为每次 Agent 执行准备独立的 Git worktree,让它的文件操作与我正在使用的目录分开。

worktree 复用同一个仓库的 Git 对象,每个工作树有自己的工作目录、索引和 HEAD;分支引用等仓库数据仍然共享。这也是它与重新 clone 一份仓库的重要区别,具体行为可以参考 git-worktree 官方文档。

1
2
3
4
5
6
主仓库
├── 我正在使用的目录
└── Agent Worktrees
├── issue-101-analysis
├── issue-101-development
└── issue-102-development

目录分开后,还要知道每个阶段基于哪一版代码。worktree 本身不会替工作流固定审查对象;要复查某轮分析或 Review,仍然需要对应的提交,以及涉及未提交改动时的 diff。

这种隔离主要解决工作目录里的修改互相干扰。并行执行时,测试占用的端口、访问的数据库和外部服务,还需要分别考虑。

让终端连接与执行进程分开

我使用的 Agent 是长时间运行的交互式命令行程序。如果它的生命周期跟着浏览器连接走,关闭页面就可能打断任务。

目前的实现用 tmux 托管 Agent 进程,浏览器负责连接终端。tmux 支持客户端分离后保留会话中的程序,之后再重新连接,这是它的官方入门文档介绍的基本用法。

这样,浏览器断开后,Agent 可以继续在原来的终端中运行。我回来时可以重新接上去查看输出,必要时也能手工接管。

这项能力依赖 tmux 服务和宿主机继续运行。如果 Agent 已经退出,或者宿主机发生故障,怎样恢复仍然是工作流需要处理的问题。

四类状态,需要分别判断

把工作流、worktree 和 tmux 接在一起以后,一次阶段执行至少涉及四类状态:


flowchart TB
    J["一次阶段执行"] --> S["工作流状态
当前阶段与处理结果"] J --> G["代码状态
基准提交与实际改动"] J --> T["终端与进程状态
tmux 会话及 Agent 进程"] J --> E["Agent 会话状态
可继续使用的上下文"]

它们会各自变化。worktree 还在,Agent 进程可能已经退出;tmux 会话还在,里面的 Agent 可能正在等待输入;终端重新连上了,也不能据此判断某个阶段已经完成。

Agent 会话能否继续,还取决于所用工具对上下文恢复的支持。终端会话的存在和 Agent 对话的可恢复性,需要分别判断。

同样,进程正常退出只说明这次命令执行结束了。它可能完成了修改,也可能只完成了分析,或者留下了尚未解决的问题。工作流要决定是否进入下一阶段,必须检查阶段产物和验证结果。

因此,我要求开发 Agent 结束前提交结构化结果,说明修改了哪些文件、执行了哪些验证、哪些测试通过,以及还有什么问题没有解决。没有执行的验证也需要明确留下,后续才能判断交付范围。

这些结果既服务于下一轮 Review,也服务于我自己。再次打开任务时,我需要能区分“代码已经写完”“代码已经检查过”和“需求已经验收”。

目前完成了什么

目前,需求分析、独立 Review、worktree 隔离、tmux 托管和结构化结果已经接进了流程。一项需求可以从分析走到开发,我不用再守着几个窗口转发每一步的结果。

这个实现让我更清楚地看到了几部分的分工:worktree 提供工作目录,tmux 保留交互式执行环境,阶段产物承接上下文,工作流管理它们之间的流转。每一部分都有用途,也都有自己负责不到的地方。

中断恢复和环境清理还没有处理完整,目前只有初步设计。

恢复时,要判断代码、进程、Agent 会话和阶段记录各自停在哪里,再决定继续执行还是重新开始。清理时,则要确认改动和必要产物已经保留,避免为了释放目录把还需要检查的内容一起删掉。这些问题需要在后续实现中验证。

我最初只是想少复制几次 Prompt,最后整理出来的是一项需求从分析、审查到开发的交接方式。下一次处理需求时,只要我能直接看到当前结果、做必要的决定,再把执行交还给系统,就不用继续充当 Agent 之间的消息队列了。

延伸阅读


AI Agent 研发工作流的设计与实现
https://blog.phlin.cn/2026/08/09/ai-agent-workflow/
作者
phlin
发布于
2026年8月9日
许可协议