01 · 当 AI 学会按规矩办事——规范驱动 Agent 工作流总览系列第 1 篇学完本篇你能理解“规范驱动 Agent 工作流”是什么、为什么需要它用 5 个核心抽象Run / Stage / Manifest / Gate / Profile描述任意一个 Agent 流水线现在就能动手花 10 分钟搭一个最小可跑的分阶段 可审批AI 任务执行器。0. 翻车现场你肯定见过场景换一个所有人都熟的——“让 AI 帮我重构一个老 Python 模块”“把这个legacy_order.py文件重构一下拆成 service / repo 两层加上类型注解补单元测试。”你扔给 Cursor / Claude Code / 任意 AI 助手结果通常是直接开冲上来就写代码写到一半发现没看db_session.py的依赖类型对不上。半截烂尾80% 写完了剩下 20% 反复修你也说不出来是哪一步歪了。越改越乱你说这里不对它改 A 又改坏 B上下文越来越长。没法复盘成功了你也复述不出来它到底做了哪些决策。没法暂停会话一断下次从零开始前面 50 轮全丢。根因只有一个你把 AI 当超长 prompt 里的执行器没把它当流水线来设计。这一篇要回答的问题怎么把让 AI 改一个真实仓库做成可控、可暂停、可回放的工程化流程1. 核心立场流水线不是聊天框如果你熟悉 CI/CDJenkins、GitHub Actions那就好办了——规范驱动 Agent 工作流 把 AI 编码做成 CI/CD。❌ 聊天框模式 ✅ 流水线模式 ┌────────────────┐ ┌────────────────────────────┐ │ 一个超长 │ │ 阶段 1 → 阶段 2 → ... → N │ │ system prompt │ │ ↓ ↓ │ │ │ │ 产物 1 产物 2 │ │ AI 自由发挥 │ │ ↓ ↓ │ │ │ │ 审批门 审批门 │ │ 输出 一坨 │ │ │ └────────────────┘ │ 状态可查 / 失败可重跑 / │ │ 中断可恢复 / 全程可复盘 │ └────────────────────────────┘CI/CD 的执行体是 shell 脚本规范驱动 Agent 工作流的执行体是 LLM。别的全一样——分阶段、出产物、卡审批、可恢复。动手 30 秒打开你常用的 AI 编码工具回想最近一次让它做大型重构的对话。数一下那次任务跨了几个阶段每个阶段的产物存在哪如果中途断了你怎么恢复答不上来的越多越说明你需要这套东西。2. 五个核心抽象背下来够用一辈子不管哪个具体的 Agent 框架Aladdin / LangGraph / CrewAI / 自己写的看到下面这五个抽象就能秒懂抽象一句话类比Run一次任务执行实例有唯一 IDGitHub Actions 的一次 workflow runStagerun 内部的一个阶段需求/设计/实现/验证…CI 流水线里的一个 jobManifest记录这个 run 走到哪了的状态文件数据库里的task表那一行Gate阶段之间的审批闸门PR review / CI manual approvalProfile适配不同技术栈的可换插件Docker 镜像变体python:3.11 vs node:20┌─────────────────────────── 一个 Run ────────────────────────────┐ │ │ │ Stage 1 ─► [Gate] ─► Stage 2 ─► [Gate] ─► ... │ │ ↓ ↓ │ │ 产物 1 产物 2 │ │ │ │ ┌───────────────────────────────────────────────────────────┐ │ │ │ ManifestYAML 文件 │ │ │ │ run_id: 20260630-abc123 │ │ │ │ current_stage: Stage 2 │ │ │ │ lifecycle: AWAITING_APPROVAL │ │ │ │ artifacts: { stage1: ./design.md, stage2: ... } │ │ │ └───────────────────────────────────────────────────────────┘ │ │ ▲ │ │ │ 通过 Profile 注入这次用什么技术栈 │ │ │ │ └───────────────────────┼──────────────────────────────────────────┘ │ ┌───────┴────────┐ │ Profile (YAML) │ │ - 编译命令 │ │ - 阶段实现者 │ │ - 模板路径 │ └────────────────┘记住这张图。后面 4 篇都是在它的某一格里深挖。动手 30 秒在你电脑上随便建个目录写个manifest.yamlrun_id:my-first-runcurrent_stage:designlifecycle:RUNNINGartifacts:{}这就是 Run Manifest 的最小形态。一行 Pythonyaml.safe_load(open(manifest.yaml))就能读它。3. 一个完整流程长什么样把上面五个抽象串起来就是一个完整 Agent 流水线。下面是一个通用版不限技术栈┌──────────────────────────────────────────────┐ 用户需求 ──────► │ 规范驱动 Agent 工作流 │ │ │ │ ┌────────┐ ┌────────┐ ┌────────┐ │ │ │ S1 │ ─► │ S2 │ ─► │ S3 │ │ │ │ 需求 │ │ 设计 │ │ 任务 │ │ │ │ 整理 │ │ 文档 │ │ 拆解 │ │ │ └────┬───┘ └────┬───┘ └────┬───┘ │ │ │ │ │ │ │ [审批门] [审批门] [审批门] │ │ ▼ ▼ ▼ │ │ └─────►──────┴──────►──────┘ │ │ │ │ ┌────────┐ │ │ │ S4 │ ◄── 唯一允许改业务代码的阶段│ │ │ 实现 │ │ │ └────┬───┘ │ │ ▼ │ │ ┌─────────────── S5 验证回环 ─────────────┐ │ │ │ S5.1 静态审计 ─► S5.2 编译 ─► S5.3 跑│ │ │ └─────────────────────┬─────────────────┘ │ │ │ │ │ ┌─────────┴────────┐ │ │ ▼ ▼ │ │ PASS ─► S6 总结 失败 ─► 回 S4 ─┐│ │ ││ │ 不确定/卡住 ──► HITL人在回路──────┘│ └──────────────────────────────────────────────┘ ▲ │ ┌────────────────────┴──────────────────────┐ │ 全程读写runs/run_id/manifest.yaml │ │ 唯一的项目档案袋状态机的真相源 │ └───────────────────────────────────────────┘HITL Human-In-The-Loop人在回路AI 拿不准 / 信息不足 / 状态冲突时主动停下等人而不是硬猜着往下走。这是这套方法论的灵魂之一。三个最关键的不变量记住就行S4 是唯一允许写业务代码的阶段——之前只能产出规范需求文档、设计文档、任务清单。S5 是验证回环——静态审计 → 编译 → 跑通必须串行不能合并。任何阶段之间都可能卡审批AI 自己不能开闸。动手 30 秒拿你最近做过的一个 AI 任务套到这张图上。哪几步是你心里默默做了的把它们显式地命名出来——这就是开始工程化的第一步。4. 关键设计把下一步做什么从 LLM 手里拿走这是整套方法论里最值得偷的一招。反例把流程描述写在 system prompt 里让 LLM 自己判断我现在该走哪一步。❌ 反例vibe coding 常见做法 ┌──────────────────────────────────────┐ │ 超长 system prompt │ │ 你是 AI 工程师先写需求 │ │ 再写设计再写代码…… │ │ 如果失败就回到实现阶段…… │ │ │ │ LLM 自己判断状态 │ │ LLM 自己决定跳转 │ │ │ │ ⚠ 状态飘忽 / 逻辑漂移 / 上下文爆炸│ └──────────────────────────────────────┘正例把下一步走哪做成一个确定性函数LLM 只能调用、不能改写。✅ 正例规范驱动 ┌──────────────────────────────────────┐ │ prompt 只说你现在做 S2 设计 │ │ │ │ 下一步走哪───┐ │ │ ▼ │ │ ┌────────────────────────────────┐ │ │ │ next_action() ← 纯函数 │ │ │ │ 读 manifest.yaml │ │ │ │ 按规则判断 │ │ │ │ 返回枚举值 │ │ │ └────────────────┬───────────────┘ │ │ ▼ │ │ RUN_STAGE / WAIT_APPROVAL / │ │ BLOCKED / COMPLETE │ │ │ │ │ LLM 严格照办 ◄───┘ │ └──────────────────────────────────────┘关键点返回值是枚举值不是自然语言。LLM 只能按枚举值行动不能理解出第六种可能。4.1 看一段简化版的伪代码下面是一个最小可运行的next_action()60 行 Python不依赖任何框架# next_action.py - 一个 Agent 流水线状态机的心脏importyamlfromenumimportEnumfrompathlibimportPathclassAction(str,Enum):RUN_STAGERUN_STAGE# 可以进入下一阶段WAIT_APPROVALWAIT_APPROVAL# 等待人工审批BLOCKEDBLOCKED# 状态异常停下COMPLETECOMPLETE# 全部完成# 阶段顺序写死在状态机里不让 LLM 自己想STAGES[S1_requirements,S2_design,S3_tasks,S4_implement,S5_verify,S6_summary]defnext_action(run_dir:Path)-dict:manifestyaml.safe_load((run_dir/manifest.yaml).read_text())curmanifest[current_stage]lifecyclemanifest[lifecycle]gatesmanifest.get(approval_gates,{})# 1. 流程已经完成ifcurSTAGES[-1]andlifecycleCOMPLETED:return{action:Action.COMPLETE,reason:all stages done}# 2. 当前阶段还没完成 → 继续干当前阶段iflifecycleRUNNING:return{action:Action.RUN_STAGE,target_stage:cur,reason:stage in progress}# 3. 当前阶段产物已出等审批iflifecycleAWAITING_APPROVAL:gate_statusgates.get(cur,{}).get(status,pending)ifgate_statusapproved:next_idxSTAGES.index(cur)1return{action:Action.RUN_STAGE,target_stage:STAGES[next_idx],reason:f{cur}approved, advance}else:return{action:Action.WAIT_APPROVAL,target_stage:cur,reason:gate not approved}# 4. 状态异常return{action:Action.BLOCKED,reason:funknown lifecycle:{lifecycle}}这就是规范驱动 Agent 工作流最核心的那 60 行代码。可以扩展加更多阶段、加 profile、加重试但骨架就是这样。动手 10 分钟即时满足版把上面 60 行存成next_action.py创建runs/test01/manifest.yaml内容current_stage:S1_requirementslifecycle:AWAITING_APPROVALapproval_gates:S1_requirements:{status:approved}跑frompathlibimportPathfromnext_actionimportnext_actionprint(next_action(Path(runs/test01)))你应该看到{action: RUN_STAGE, target_stage: S2_design, reason: S1_requirements approved, advance}把status: approved改成pending再跑一次。状态变成WAIT_APPROVAL。恭喜——你刚才手写了一个 Mini-Aladdin的核心。5. Core 与 Profile 的边界“骨头” vs “肌肉”最后一个概念第 4 篇会展开。┌─────────────────────────────────────────┐ │ Core │ ← 骨头 │ 流程不变量 / 状态机 / Approval Gate│ 所有任务通用 └─────────────────┬───────────────────────┘ │ profile_path 注入 ▼ ┌─────────────────────────────────────────┐ │ Profile │ ← 肌肉 │ ┌──────────┐ ┌──────────┐ ┌────────┐ │ │ │ Python │ │ Java │ │ Go │ │ 不同技术栈 │ │ profile │ │ profile │ │profile │ │ 完全不同 │ └──────────┘ └──────────┘ └────────┘ │ │ - 编译命令pytest / mvn / go test │ │ - 模板路径自家代码模板 │ │ - 阶段实现者调哪个 sub-agent │ └─────────────────────────────────────────┘这就是设计模式里的**开闭原则OCP**在 Agent 系统里的体现核心流程对修改关闭、对扩展开放。新接一个技术栈 写一份 profile。Core 一行不动。动手 30 秒你现在做的项目如果要让 AI 跑同一套流程需要哪些技术栈相关的命令比如pytest -v是 Python 的npm run test是前端的——把这些写进 profilecore 永远只调profile.test_command。6. 核心要点回顾如果只能记三件事复杂任务要切阶段不要一个 prompt 干所有。切成 S1 → S2 → … → S6每段独立可审批可重跑。状态要有真相源用文件YAML/JSON当唯一真相源不要让 LLM 自己记。决策权要拿出来next_action()这种结构化裁决函数比让 LLM 自己想下一步做什么靠谱十倍。7. FAQ你大概率会问的 7 个问题Q1这套东西和直接用 LangGraph / CrewAI 有啥区别LangGraph / CrewAI 给你的是框架提供执行引擎、节点定义、消息协议。这一篇讲的是方法论——它们是正交的。你完全可以用 LangGraph 实现规范驱动 Agent 工作流关键是要有 Run / Stage / Manifest / Gate / Profile 这五个抽象而不是只把节点连起来就完事。Q2所有 AI 任务都要用这套吗写个一次性脚本也用不用。判断标准任务是否要跨多轮、产物是否要复用、失败是否要回滚。一次性问答、简单生成不需要。但凡你想第二天还能复盘的任务都值得上。Q3状态机限制了 LLM 的灵活性会不会让结果变差恰恰相反。LLM 的灵活在语义生成上很值钱在流程控制上是灾难。你让它写代码很灵活让它判断现在该编译还是该先 review它就开始胡说。把它擅长的留给它把它不擅长的拿走——结果会更好不会更差。Q4Approval Gate 每步都卡审批那不还是人工干活可以配auto模式让审批自动通过也可以只在关键阶段卡比如 S4 实现完之后必卡前面阶段全 auto。重点不是必须人工是必须留一个能让人介入的口子。生产环境出 bug 的时候你会感谢这个口子。Q5Manifest 文件被 LLM 误改了怎么办这就是为什么所有写入必须通过run_manifest.py——脚本里做参数校验schema 不对就拒绝写。把能改的入口收窄到一个LLM 只能调命令、不能直接编辑文件。这一招在工程上叫DAO 模式Data Access ObjectAI 系统里同样有效。Q6我自己怎么从 0 搭一个三步走第一周把第 4 节的 60 行代码扩到 200 行加上init/stage-start/stage-complete/gate-event命令第二周接一个 LLMClaude / GPT让它每次行动前先调next_action()根据返回值决定 prompt第三周加 profile 系统、加 sub-agent开始拆S5 验证回环。后面 4 篇会带你过一遍。Q7这套东西有什么明显的缺点 / 不适合的场景三个冷启动成本高写 profile、定义阶段、调 prompt前期投入比 vibe coding 大几倍。任务简单或一次性的别上。调试链路长流程出错时你要查 manifest、查 gate、查 stage artifacts 三个地方比看一坨对话窗口累。不擅长开放式探索阶段是预定义的。如果任务本身需要先到处看看再决定怎么做硬切阶段反而拧巴。8. 下一篇预告02 · 状态机与 Run Manifest——把下一步做什么从 prompt 手里拿走我们会把第 4 节那个 60 行的next_action()扩展到150 行的完整最小版包括init/stage-start/stage-complete/gate-event/sync-result五个命令的具体实现状态字段current_stage / lifecycle / waiting_for / resume_from的语义和读写时机如何让 LLM 读懂状态——一个让 prompt 看得懂 manifest 的小技巧。读完你能直接在自己项目里跑起来一个最小版状态机。系列写作承诺Prompt 工程线除了架构拆解每一篇额外开一节Prompt 拆解——挑当篇主题对应的源码 prompt 段落逐句注释为什么这么写。读完整个系列你会同时学到两件事架构线怎么设计一个 Agent 流水线Run / Stage / Manifest / Gate / ProfilePrompt 线怎么把工程规则写进 prompt让 LLM 真的听话意图分类、硬边界、必读顺序、不变量声明……