AI 学习笔记(九):在开发工具里落地自动化工作流(从任务触发到结果回写)
上一篇我们把 MCP 与 Agent 的最小实践跑通了,解决的是“模型怎么拿到工具能力”。
这一篇继续 Phase 3,但问题从“会不会调工具”切到更贴近日常开发的一层:
怎么把 AI 接进开发工具,让任务从触发一路走到执行和结果回写,而且中间可追踪、可停止、可复用。
这一步很关键。MCP 负责的是协议层,让 Host、Client、Server 以及工具、资源、提示模板能对接起来;但它并不替你决定任务什么时候开始、上下文怎么拼、结果写回哪里。真正把自动化做稳,仍然要靠宿主侧的工作流设计。
这篇仍然只讲最小可落地方案,不追求“全自动研发平台”。
目标只有 3 个:
- 有清晰的任务入口
- 有稳定的执行编排
- 有明确的结果回写
1. 先把问题拆对:协议层不等于自动化层
如果把“模型能调工具”直接等同于“自动化已经做完”,后面通常很快会踩坑。
因为开发工具里的自动化,至少还要回答 4 个问题:
- 谁来触发
是开发者手动下命令、IDE 里的 hook、Issue/PR 事件,还是定时任务? - 给模型什么上下文
是整个仓库、最近 diff、失败日志,还是一段任务描述? - 哪些动作允许自动执行
只能读?能写草稿?还是可以直接改生产数据? - 结果落到哪里
是本地文件、PR 评论、Issue 评论,还是知识库文档?
上一篇讲的 MCP 在这里依然重要,但它主要解决的是“能力如何暴露给模型”。
自动化工作流真正要补的是这一层:
- Trigger:任务入口
- Context Packer:上下文装配
- Orchestrator:步骤编排
- Executor:工具执行
- Writer:结果回写
一句话记住:
MCP 负责把工具接进来,自动化 Runner 负责决定什么时候启动、给它什么上下文、结果写回哪里。
2. 最小链路先固定成 5 段
很多自动化失控,不是模型不够强,而是“触发、执行、回写、确认”全部混在一起。
我更推荐先固定成下面这条最小链路:
| 环节 | 最小职责 | 常见坑 |
|---|---|---|
| Trigger | 生成统一任务输入 | 每个入口字段都不一样 |
| Context Packer | 只收集本次任务需要的上下文 | 把整个仓库一股脑塞给模型 |
| Orchestrator | 控制步骤、超时、重试、停止 | 没有 maxTurns 和超时 |
| Executor | 调模型、MCP、本地脚本或 API | 让模型直接拥有高风险写权限 |
| Writer | 回写结构化结果与状态 | 只回一大段不可执行的文字 |
这个拆法的好处是:
- 入口可以换,但核心编排不用重写
- 工具可以换,但回写接口不用推倒
- 以后从 CLI 迁到 Hook、再迁到 Webhook,也不会整条链路一起重做
3. 任务入口怎么选:先手动,再规则,最后异步
开发工具里的入口很多,但不建议一开始就“事件全自动”。
更稳的顺序通常是:
- 手动命令
例如npm run ai:task -- --type pr_review --pr 123 - 工具内 Hook
例如在用户提交任务前补上下文,或在写文件后自动跑一次测试 - 异步事件
例如给 Issue 打上ai-ready标签后,后台自动起任务并写回评论
这个顺序的核心不是保守,而是为了先把边界做清楚。
例如 Claude Code 的 hooks 可以在 UserPromptSubmit、Stop、PostToolUse 这些生命周期点插入命令,适合补上下文、做后置校验、把本地自动化接进工作流;GitHub Actions 则很适合承接“Issue 被加标签后异步执行并回写结果”这种后台任务。
我的建议很简单:
- 本地研发先从手动触发开始
- 需要补充上下文或做后置校验时,再上 Hook
- 任务开始超过几十秒、需要排队或要和代码托管平台联动时,再做 异步事件驱动
4. 上下文装配:别喂整个仓库,只喂本次任务需要的 4 类输入
自动化失败的另一个高频原因,是把上下文当成“越多越好”。
实际上在开发工具场景里,大多数任务只需要 4 类输入:
- 任务载荷
例如 Issue 编号、PR 编号、当前命令参数、目标输出路径 - 仓库规则
例如项目约束、目录规范、允许写入的位置 - 局部证据
例如最近 diff、失败测试、构建日志、目标文件片段 - 回写目标
例如写回 Issue 评论、本地报告文件,还是只做dry-run
入口参数建议统一成一个 JobInput,不要每个入口自己发明字段:
1 | interface JobInput { |
统一 JobInput 的价值很大:
- 入口从 CLI 换成 Webhook 时,编排层不用改
- 回写从本地文件换成平台评论时,执行层不用改
- 以后要做重试、排队、幂等,也有稳定主键可以挂
5. 一个可直接复用的最小 Runner
下面这份代码只做 5 件事:
- 生成
jobId和traceId - 收集本次任务最少上下文
- 调一次受控 Agent
- 把结果写回平台或文件
- 落一份机器可读状态
1 | // tools/automation/job-runner.mjs |
这段代码刻意没有追求“写得多高级”,但已经把自动化最重要的约束放进去了:
- 有统一
JobInput - 有
jobId/traceId - 有步骤状态
- 有工具白名单
- 有
maxTurns/timeoutMs - 有结果回写
很多时候,你真正缺的不是第二十个工具,而是第一条能稳定跑通的流水线。
6. 长任务不要阻塞交互,结果回写最好分两份
一旦任务变成“全仓扫描”“大 diff 审查”“批量文档修订”,同步执行就很容易把交互拖死。
这时候更稳的做法是:
- 前台只负责创建任务
- 后台异步执行
- 完成后再把结果回写回来
这类场景里有三个很实用的做法:
- Hook 异步化
适合本地开发时把测试、格式检查、摘要生成挂到工具生命周期后面 - 平台后台任务
适合 Issue、PR、CI 失败这类本来就天然异步的场景 - 模型层后台执行
如果模型调用本身就很长,可以让模型层用后台模式跑完后再通知宿主
例如 OpenAI 的 Background mode 允许把请求作为后台任务启动,再轮询状态;如果你不想主动轮询,也可以接 webhook,在 response.completed 等事件到来时再继续回写链路。
真正落地时,我建议把结果分成两份:
- 给人看的摘要
放 PR / Issue 评论里,3 到 5 行就够 - 给程序读的状态
放 JSON 或报告文件里,记录jobId、traceId、步骤、耗时、工具和结果状态
这样排查问题时不会只剩下一段“看起来说了很多、实际没法自动处理”的自然语言。
7. 一个很实用的触发方式:Issue 打标签,后台执行后回写评论
如果你已经在用 GitHub 管理任务,一个非常顺手的最小方案是:
- 给 Issue 打上
ai-ready - GitHub Actions 被触发
- 后台执行
job-runner - 用
gh issue comment把摘要写回
触发器本身可以非常薄:
1 | name: ai-issue-job |
这套做法的优点很明确:
- 触发条件清楚
- 执行天然异步
- 平台自带任务记录
- 回写位置离任务本身很近
如果你现在还不想接平台事件,也完全可以把第一步替换成 npm run ai:issue -- --issue 456,剩下的编排和回写逻辑不变。
8. 别漏这 6 个工程细节
8.1 幂等
同一个任务重跑时,最好带固定 jobId 或 operationId。
如果你接 webhook,还要能按事件 ID 去重,避免重复回写。
8.2 权限分级
至少分三层:
read-onlywrite-safewrite-critical
高风险动作默认不要开放给自动化直写。
8.3 dry-run
本地开发默认先走 dry-run,只生成摘要、报告或草稿评论。
等流程稳定后,再放开 safe-write。
8.4 可观测性
至少记录这些字段:
traceIdjobIdsteptoolNamelatencyMsresultStatus
没有这些字段,后面几乎没法排障。
8.5 人在回路
MCP 官方在工具设计上也强调 human in the loop。
凡是会真实改代码、改配置、发消息、改工单状态的动作,都应该保留人工确认点。
8.6 长任务异步确认
如果你用了后台任务或 webhook,接收端应该尽快返回成功状态,把真正的执行放到后台。
回写时再通过评论、状态文件或第二个事件把结果补回来。
9. 一条更稳的演进路线
如果你准备把开发工具里的自动化慢慢做起来,我更推荐按下面这个顺序:
- 先做手动触发 + 本地
dry-run - 再做统一
JobInput+ 固定 5 步编排 - 再接 Hook,自动补上下文和后置校验
- 再接 Issue / PR / CI 事件,让任务异步执行
- 最后再考虑共享 MCP 服务、队列、长期记忆、多执行器
这个顺序的重点不是“功能最全”,而是每一步都能独立带来收益,而且不会过早把系统做复杂。
总结
把 AI 自动化真正落进开发工具,重点从来不是“先做一个万能 Agent”,而是先把下面四件事做稳:
- 触发清楚
- 上下文收敛
- 执行可停
- 结果可回写
如果你只做一件事,我最推荐的是:
统一 JobInput、固定 5 步编排、同时保留人类可读摘要和机器可读状态。
这三件事做稳了,再去增加更多工具、更多策略、更多入口,复杂度才会可控。
下一篇开始进入 Phase 4:本地模型与云模型怎么协作,才能在成本、延迟和可用性之间做更稳的工程取舍。