工作流还是 Agent:什么时候需要 agent,什么时候一段代码就够?
主线定位
- 上游 · LLM 课 C12 第 8 课:从答题到做事:agentic RL 把模型训练到会写一段「调用工具」的文字。可它写出来的只是文字——谁去执行、结果怎么送回去,是模型外面那层程序(harness)的事。
- 本章 · A0 编排选择:在写 harness 之前,先问一个更早的问题——这个任务需要 agent 吗?「让模型决定下一步」不是免费的,有些任务一段写死的代码就够了。
- 下游 · A1 循环:决定用 agent 之后,「模型决定下一步」的那个循环到底长什么样、什么时候停。
整门课的主线:一次任务在 harness 里经过哪些环节
这门课从 0 搭一个编码 agent(本课项目 miniagent,Python,在 案例库/从0打造编码Agent/04-实践项目/),每一章回答一个问题、给项目加一个里程碑、给同一个任务的 trace 长出一段。上面那条累计数据流,就是十章的顺序。
| 章 | 这一章的问题 | 贯穿任务的 trace 长出的一段 | 项目里程碑 |
|---|---|---|---|
| A0 编排选择(本章) | 什么时候需要 agent,什么时候一段代码就够? | 同一任务的两条轨道:代码决定每一步 vs 模型决定每一步 | M0 workflow 基线 + 判别标准 |
| A1 循环 | 模型只会吐文字,它怎么改你的文件?什么时候停? | 骨架:messages[] 每轮的增长、停止原因、轮数 | M1 最小循环 |
| A2 工具系统 | 模型怎么说清「改哪里」? | 每次 edit_file 与各家 edit 引擎的裁决 | M2 search-replace edit |
| A3 权限与审批 | 它要执行 rm -rf 怎么办? | 每次调用在各家权限语义下放行、问人还是拦下 | M3 一种权限语义 |
| A4 沙箱与隔离 | 规则拦不住一个自己写文件的 Python 脚本,谁拦? | 每条命令在系统调用层是否被拦 | M4 sandbox-exec |
| A5 上下文 | 对话太长装不下怎么办? | 每轮上下文大小、压缩在哪一轮触发 | M5 机械裁剪 + 阈值 |
| A6 记忆与会话 | 明天它还记得吗? | 会话树:第二天的新会话、记忆注入、一次 fork | M6 |
| A7 子 agent | 一个 agent 忙不过来、或需要别人把关时,怎么分工? | 子 agent 分支:独立预算、摘要回流 | M7 |
| A8 模型接入与计费 | 换模型、控成本怎么办? | 线缆层:流式事件、首 token 时间、账单 | M8 |
| A9 验证与评测 | 怎么知道它好不好? | 判决:verifier 结果、多次重复的通过率、失败标签 | M9 接 Harbor |
这门课拿什么当标尺:全部源码都钉在固定版本(只读副本在 github/pins/,页面上的行号一律以它为准)。教学蓝本是 learn-claude-code 0dcafa2(17 章)与 CoreCoder v0.7.0 / v0.4.0;生产对照是 Pi 31b513e3、Codex 8cabf5a、OpenCode v1.18.32 和通用 agent Hermes 56dc01d9。页面上的数字只有三种来源:本课项目的真实录制(本机 Qwen3-8B-MLX-4bit)、从钉住的源码搬进浏览器实跑的算法、带日期与出处的公开资料。没有「为了好讲编的一组数」。
本章问题链
每一课只回答一个问题;上一课的失败,逼出下一课的问题。表里的数字都由录制数据现算。
| 课 | 这一课的问题 | 朴素方案在哪个真数字上失败 | 一句话 |
|---|---|---|---|
| 第 1 课 | 修好 test_parse_date,最朴素的程序怎么写? | 单次调用、整文件覆写:T2 workflow 轨 2 / 4;parse_date 重跑露出 datetime.date(2024, 2, 5) != datetime.date(2024, 3, 5) | 单次调用只能用你喂给它的信息,修 bug 需要的信息往往要边做边找 |
| 第 2 课 | 多加几步、加分支,能覆盖所有情况吗? | agent 轨 4 个任务走出 4 条不同的工具序列;同一配置重跑 4 次(seed 1 / 2 / 3 / 1)也走出 4 条 | workflow 的边在设计时画好,agent 的边在运行时长出来 |
| 岔路 | agency 是训练出来的,还是编排出来的? | 同一模型只把 harness 从 v1 换成 v2(主要是一条完成规则),贯穿任务 10 种配置的通过从 1 次变成 5 次 | 会不会决定下一步靠训练;在哪儿让它决定、决定到什么程度,靠编排 |
| 第 3 课 | 把「下一步做什么」交给模型,要付什么代价? | 一律用 agent:workflow 已能解决的任务上 token word_freq ×5.3、leap_year ×4.5;同配置同 seed 重跑,2 / 4 个任务中途分叉 | 把决定权交给模型,换来适应性,付出 token、时间与可预期性 |
| 岔路 | 通用 agent 和编码 agent 差在哪? | Hermes 的姿态判定:同一个任务仓,单独拷出来判成 general,放在项目目录里判成 coding | 通用 agent 变成编码 agent,不换循环,换的是它看到的说明、工具与工作区 |
| 实验课 | 同 4 个任务,workflow 与 agent 双轨真跑 | 录制前写下的预测对 3 / 4 | 先写标准、再跑两条轨道、逐项对照,错在哪里比对了几个更有用 |
演进地图
- 解决了只调一次模型,每一步都写在代码里:可预期、好测、便宜。卡在T2 workflow 轨 2 / 4 通过。parse_date 只改了报错指到的那一行,重跑才露出第二处(
datetime.date(2024, 2, 5) != datetime.date(2024, 3, 5));slugify 的回复只有函数片段,兜底规则把 130 字符的片段当整份文件写回(原文件 365 字符),丢了import re。 - 第一代 加步骤、加分支:五种 workflow 模式 prompt chaining · routing · parallelization · orchestrator-workers · evaluator-optimizer解决了每一类失败补一条预先写好的路径:测试没过就带着新报错再来一次(评估者是测试的退出码)、回复格式不对就拒绝写回。卡在分支要在设计时写出来,可真实路径是在运行时长出来的:T2 agent 轨 4 个任务走出 4 条不同的工具序列;同一配置重跑 4 次 parse_date(seed 1 / 2 / 3 / 1),走出 4 条。
- 解决了边在运行时长出来:T2 agent 轨 3 / 4 通过,包括 workflow 没修好的 parse_date 与 slugify。卡在代价:workflow 已经能解决的任务上 token word_freq ×5.3、leap_year ×4.5,其中 word_freq 的 agent 反而没修好;同配置、同 seed 重跑,2 / 4 个任务在中途分叉。
- 解决了录制前写下三条标准并逐个预测,录制后对照:预测对 3 / 4。卡在预测错的 slugify 不是任务本身需要 agent,而是 workflow 自己的写回规则出了错(回复没有
FILE:标记时的兜底)。每条轨道每个任务只跑 1 次:只能当例子,不能当比率。 - 解决了编排形状固定的部分(并行审查、逐条验证、断点续跑)写进脚本;模型只决定「要不要调这个 workflow、传什么参数」。卡在同一个仓库里两种说法并存:README
:11与:41说 agency 来自训练、不是编排;:239说编排形状固定就写进代码。界线画在哪,没有实验回答。 - 解决了同一个循环,识别出代码工作区后注入编码说明(约 577 token,Qwen3 tokenizer 计)与工作区快照;focus 模式才会收窄工具集与技能索引。卡在判定靠文件标记:本课任务仓单独拷出来(README.md、dateparse.py、test_dateparse.py,没有 .git)在默认 auto 下被判成 general;放在项目目录里原地跑,却因为往上 3 层有个
requirements.txt被判成 coding。姿态在会话开始解析一次,中途不变。
贯穿任务:修好 test_parse_date
全课的贯穿任务是项目任务仓里的 tasks/parse_date:让失败的 test_parse_date 通过,测试文件不许改。dateparse.py 埋了两处 bug(DD/MM/YYYY 分支把日和月解包反了;月份名分支少了 + 1),而且按顺序暴露:测试在第一条失败的断言处就停,修掉第一处、重跑,才看得见第二处。
这一章是 trace 的「种子」:同一个任务跑两条轨道,录成 T2。
- workflow 轨(
miniagent/workflow.py,里程碑 M0):跑测试 → 把报错和全部非测试源文件发给模型 → 按FILE:块整文件覆写 → 重跑。5 步全由代码决定,模型只被调用一次。 - agent 轨(
miniagent/loop.py,harness v2,里程碑 M1):模型每一轮决定调哪个工具,或者停;上限 30 轮。
大纲原本要 5 个任务(t00–t04,含「跨文件」「需要装依赖」两类);项目现有的是 4 个,那两类还没建,这是已知缺口。T2 就用这 4 个如实录制,每条轨道每个任务跑 1 次(seed 1):
| 任务 | 是什么 | workflow | agent |
|---|---|---|---|
parse_date | 贯穿任务:两处 bug 按顺序暴露 | ✗ · 3,081 token | ✓ · 8 轮 · 21,687 token |
slugify | 一处正则 + 首尾去 -,docstring 写明规格 | ✗ · 3,727 token | ✓ · 13 轮 · 54,301 token |
word_freq | 三处规格缺口都写在 docstring 里,测试一次只暴露一个 | ✓ · 4,290 token | ✗ · 6 轮 · 22,852 token |
leap_year | 补功能:照 docstring 实现 is_leap_year | ✓ · 2,020 token | ✓ · 5 轮 · 9,091 token |
数据:src/data/project/agent-t2-workflow.json(2026-09-26 导出;Qwen/Qwen3-8B-MLX-4bit,本机 mlx_lm.server;耗时受本机其他任务影响,只能粗看,token 与轮数可比);本章派生数据 src/data/precomputed/a00-workflow-agent.json(生成脚本同目录:workflow 单次调用的逐段 token 账、整文件覆写的重放、孪生运行的分叉点、Hermes 姿态判定的原实现实跑)。
三层交互
| 层 | 本章里的组件 | 在哪一课 |
|---|---|---|
| 概念动画 | 控制权光谱:smolagents 六档,同一个修 bug 任务画成六张控制流图,边色 = 谁决定,代码骨架同色联动;五种 workflow 与 agent 的 small multiples,有录制的两格用 T2 走一遍 | 第 1、2 课,岔路 B1 |
| 算法模拟器(真算法、小数据) | 路径树:真实运行的工具调用序列逐条插进前缀树,浏览器里现算不同路径数、分叉点、要预先写出的判断数;先猜再揭示 | 第 2 课、实验课 |
| 真数据 | workflow 轨逐步回放(代码与真实状态联动,token 逐段与服务端一致);双轨并排;同配置同 seed 的孪生运行按轮对齐;同配置只换 seed 的三次运行并排;Hermes 姿态判定的实跑结果 | 第 1、3 课,岔路 B2,实验课 |
项目推进:里程碑 M0 · workflow 基线与判别标准
对应 04-实践项目/MILESTONES.md 的「A0 · M0」。代码在 miniagent/workflow.py,测试在 tests/test_workflow.py,录制脚本 scripts/record_t2.py。代码 AI 来写,决策你来做。
- 写 3 条判别标准,写在录制之前、录制之后不改。项目写下的是:①修复需要的信息是否全在「报错 + 被测源文件」里;②下一步是否取决于运行时才出现的输出(修完一处才暴露下一处、要装的依赖名只在报错里);③改动范围能否预先确定(文件确定、整文件覆写可行)。你可以照抄,也可以改——但要能对 4 个任务逐条判。
- 对每个任务先预测哪条轨道够用,再用 T2 验证。项目的预测:parse_date 需要 agent,其余三个 workflow 够(第 3 课、实验课)。
- workflow 的写回规则:回复没按
FILE:格式时,是兜底写回还是拒绝?项目现在兜底(只有一个源文件、只有一个代码块就当整份文件),slugify 就栽在这条规则上(第 1 课)。
验收标准(全部可测;括号里是本章开发时在项目里核对的现状):
.venv/bin/python -m unittest tests.test_workflow:固定五步、只调一次模型、step 全部decided_by = code;回复无法解析时不改文件;写测试文件被拒;整文件覆写的字符数与真实 diff 行数并排记录(2026-09-26 实跑:7 个用例全过)。- 每个任务在基线状态下都有失败的测试、用参考解都能通过:
.venv/bin/python -m unittest tests.test_tasks(2026-09-26 实跑:2 个用例全过,覆盖现有 4 个任务)。 - T2:4 个任务各有 workflow 与 agent 两条 trace,
.venv/bin/python -m miniagent validate traces/t2-*.jsonl全部 OK(2026-09-26 实跑:8 条全部 OK),导出agent-t2-workflow.json。 - 预测与实际逐项对照,写出预测错的任务与原因:项目在 MILESTONES.md 与 README「T2 双轨」里写了(预测对 3 / 4,错的是 slugify:模型没按
FILE:格式回复,兜底规则把函数片段当整份文件写回,丢了import re)。设计卡要的独立DECISIONS.md项目里还没有。 - 设计卡要求的「跨文件」「需要装依赖」两类任务还没建:第 2 课关于「下一步取决于报错里才出现的依赖名」的论证,目前只能用 parse_date 的第二处 bug 代替。
坑与带走
本章拦截的误解| 误解 | 纠正 | 在哪一课 |
|---|---|---|
| workflow 是落后的 agent | 官方把两者都归为 agentic systems,建议先找最简单的方案;T2 里 workflow 修好的两个任务只用了 word_freq 4,290、leap_year 2,020 token | 第 1 课 |
| agent 和 workflow 二选一 | 是光谱:smolagents 分六档;routing、orchestrator-workers 这两种 workflow 里已经有模型决定的边 | 第 2 课 |
| 有 while 循环就是 agent | 看谁决定转不转、下一步做什么:「测试没过就再来」由退出码决定,仍是 workflow | 第 2 课 |
| agency 来自训练,所以 workflow 没用 | 那是 learn-claude-code README 的立场;同一个仓库的 s16 又说「编排形状固定就写进代码」 | 岔路 B1 |
| 官方明确反对用框架 | 原文是「建议先直接调 API」,依据是与几十个团队合作的经验,调研 2-1 非满票,不能当实测证据 | 第 3 课 |
| 同一个 seed 就能复现一次运行 | 同配置同 seed,2 / 4 个任务中途分叉:测试输出里差了几个 token | 第 3 课 |
| Hermes Agent 是给 Hermes 3/4 模型配的 | 两者没有技术血缘,Hermes Agent 的源码还警告 Hermes 3/4 模型不适合做 agent | 岔路 B2 |
| 症状 | 后果 | 怎么办 |
|---|---|---|
| 整文件覆写后测试通过,但文件别处也被改了 | 引入回归,diff 很难审 | 看 diff;A2 换成唯一片段锚定 |
| 回复没按约定格式,兜底规则把片段当整份文件写回 | 丢掉没提到的行:slugify 365 → 130 字符,丢了 import re,测试全部报错 | 格式不对就拒绝写回、报错重来;或者干脆换成 edit(A2) |
| 用 agent 跑路径固定的任务 | token 翻几倍,结果还可能更差(word_freq ×5.3、leap_year ×4.5,word_freq 的 agent 没修好) | 按判别标准先选轨道 |
| 拿一次运行的耗时比快慢 | 本机同时有别的负载,数字不可比 | 比 token 与轮数;耗时只粗看 |
| 把「先直接调 API」当实测结论引用 | 论证失据 | 标「轶事性、2-1 非满票」 |
| 把 learn-claude-code 的「agency is learned」当定论 | 否定了官方当一等公民的 workflow | 与官方分类并陈 |
带走这些句子(各课「一句话」):
- 单次调用只能用你喂给它的信息,修 bug 需要的信息往往要边做边找。
- workflow 的边在设计时画好,agent 的边在运行时长出来。
- 会不会决定下一步靠训练;在哪儿让它决定、决定到什么程度,靠编排。
- 把决定权交给模型,换来适应性,付出 token、时间与可预期性。
- 通用 agent 变成编码 agent,不换循环,换的是它看到的说明、工具与工作区。
- 先写标准、再跑两条轨道、逐项对照,错在哪里比对了几个更有用。
深入这一章
按你愿意花的时间选。每条都在 2026-09-26 实际打开核对过;站外链接需联网。
🎮 想更直观 10–30 分钟
🔬 想吃透原理 1–3 小时
📄 想读原文 按需
我替你排除了什么:Lilian Weng《LLM Powered Autonomous Agents》(2023-06,写于原生工具调用普及之前,组件划分偏学术)· Hugging Face Agents Course 在 YouTube 上的「官方」视频 aS-Sp8q8F_Y(上传频道是第三方,来源存疑)· B 站营销标题的合集视频(「748 集」「七天从小白到大神」一类)· 知乎、公众号上的二手解读(本轮无法核对原文)· 批评「workflow / agent 二分法」的 Medium(MAA1)与 Towards AI 文章(原文没有单独核查,本章只借它们的观点方向、不引措辞;光谱的一手依据改用 smolagents 文档)· 把《Building effective agents》里点名的框架清单当成「官方推荐框架」的解读(原文只是列举,且清单已被静默更新过)。