通用 agent 和编码 agent 差在哪?
本课一问:第 3 课说,编码任务有一样别处少有的东西——测试,每一轮都能拿到客观的反馈。除此之外,一个「编码 agent」和一个什么都做的通用 agent,到底差在哪?是另一套循环吗?
这一课先不碰:Hermes 的记忆(A6)、审批与沙箱(A3、A4);不同编码 agent 之间的差别(A1–A9 的对照带)。
从已有出发
本课的六个对照物里,只有 Hermes(pin 56dc01d9)不是编码 agent:它是 Nous Research 做的通用个人 agent,能接消息平台、管日程、调各种工具,写代码只是它会做的事之一。它的默认身份说明是这样写的:
贯穿任务在这里换个问法:如果在 parse_date 的任务仓里打开 Hermes,它会把自己当成编码 agent 吗?
先自己设计:看到 .git 就切
最直接的规则:当前目录是 git 仓库,就注入编码守则;不是,就当通用助手。拿本课构造的几个目录试一下(文件清单是实跑时的真实目录):
- ① 朴素方案
- ② 它在哪失败
- ③ 改进方案
| 目录 | 有 .git | 有 .py | 朴素规则判定 |
|---|---|---|---|
| 本课任务仓 parse_date 单独拷进一个空目录(没有 .git,没有清单文件) | — | ✓ | general |
| 同上,先 git init | ✓ | ✓ | coding |
| 同上,不 git init,只加一个 AGENTS.md | — | ✓ | general |
| 一个只有 notes.md 的笔记仓,git init 过 | ✓ | — | coding |
Hermes 的判定多看了几样东西:会话从哪来(消息平台上的聊天不算写代码)、项目标记(清单文件、AGENTS.md 等,往上找几层)、git 仓库里有没有代码文件(挡掉只 git init 过的笔记)。它修掉了笔记仓那个误报;单独拷出来的任务仓它同样判不出来(没有任何标记),而且它自己还会从上级目录「借」到标记——下面逐个实跑。
它什么时候切到编码姿态
判定写在一个函数里:
把 pin 上的 agent/coding_context.py 原样加载(只把一个跑 git 的辅助函数换成等价的 subprocess 调用),在临时目录里复制本课的任务仓、按用例加 .git 或 AGENTS.md,逐个问它判成什么:
| 用例 | 会话来源 | coding_context | 判定 | 注入编码守则 | 工作区快照 | 收窄工具集 | 降级的技能类别 |
|---|---|---|---|---|---|---|---|
| 本课任务仓 parse_date 单独拷进一个空目录(没有 .git,没有清单文件) | cli | auto | general | — | — | — | — |
| 同一个任务仓,原地(在本课项目 04-实践项目/tasks/ 下面) | cli | auto | coding | ✓ | ✓ | — | — |
| 同上,先 git init | cli | auto | coding | ✓ | ✓ | — | — |
| 同上,不 git init,只加一个 AGENTS.md | cli | auto | coding | ✓ | ✓ | — | — |
| 同一个任务仓,但会话来自 telegram | telegram | auto | general | — | — | — | — |
| 一个只有 notes.md 的笔记仓,git init 过 | cli | auto | general | — | — | — | — |
| 任务仓 + git init,配置 coding_context: focus | cli | focus | coding | ✓ | ✓ | coding | 18 |
| 任务仓(无 .git),配置 coding_context: on | cli | on | coding | ✓ | — | — | — |
| 任务仓 + AGENTS.md,配置 coding_context: off | cli | off | general | — | — | — | — |
读这张表的三个地方:① 前两行是同一个任务仓:单独拷进空目录,判成 general;原地放在本课项目里,判成 coding——判定函数往上走了 3 层,在项目根找到了 requirements.txt,于是工作区快照的根目录写的是项目根,不是任务仓本身(见下面的快照原文);② git init 过的笔记仓(只有 .md)仍是通用:光有 .git 不够,要有代码文件;③ 只有 focus 那一行收窄了工具集、降级了 18 个非编码技能类别——默认的 auto 只动 system prompt。
原地那一行实际注入的工作区快照(本机路径已换成占位符):
Workspace (snapshot at session start — re-check with `git` before acting on it):
- Root: <project>
- Project: requirements.txt
加了 AGENTS.md 的那一行:
Workspace (snapshot at session start — re-check with `git` before acting on it):
- Root: <repo>
- Context files: AGENTS.md
切过去,改了什么
模块开头的文档把设计说得很清楚:编码姿态是一份数据(profile),由 system prompt、工具集选择、子 agent 委派这几处各自读取;模式在会话开始时只解析一次、之后不变,因为中途改 system prompt 会让前缀缓存失效(A6、A8 会细讲)。
注入的那段编码守则有 2,626 个字符,用本课项目模型的 tokenizer 数约 577 token 证据等级 · 实验验证 由对比实验得出的经验结论,只在出处写明的模型、数据和规模下成立。换了条件可能不再成立,引用时要带上实验设置。 本条Qwen3-8B 的 tokenizer 计数(gen_a00_workflow_agent.py);Hermes 实际用哪家模型,token 数会不同。 出处Hermes · CODING_AGENT_GUIDANCE(pin 56dc01d9) ↗需联网 。它写的是一个编码 agent 该有的规矩:
所以,差在哪
| 通用姿态 | 编码姿态(auto,默认) | 编码姿态(focus,可选) | |
|---|---|---|---|
| 循环 | 同一个 | 同一个 | 同一个 |
| system prompt | 默认身份说明 | + 编码守则(约 577 token)+ 工作区快照 | 同 auto |
| 工具集 | 平台默认 | 平台默认(不动) | 收窄到 coding + 已启用的 MCP |
| 技能索引 | 全部 | 全部 | 18 个非编码类别只留名字 |
| 什么时候决定 | 会话开始 | 会话开始,之后不变 | 会话开始,之后不变 |
「共享同一个循环」是从代码结构读出来的:姿态只是一份被各处读取的数据,循环代码里没有为编码另写一条路 证据等级 · 有理论动机 有数学或机制上的理由说明它可能有效,但没有证明它一定更好。最后是否采用,仍然要看实验。 本条源码直证的是:posture 由 RuntimeMode 这一处解析、被 prompt 构建、工具集选择、委派读取(coding_context.py:8-28);「循环本身不变」是调研分析者的归纳(A 报告 A0 #8),本课沿用并标注。 出处Hermes · coding_context.py 模块说明(pin) ↗需联网 。调研和设计卡原来写的是「只改三处:system prompt、工具集、技能索引」,对照 pin 源码要加一个限定:默认的 auto 只改 system prompt,后两处要用户显式打开 focus 才改 证据等级 · 有理论动机 有数学或机制上的理由说明它可能有效,但没有证明它一定更好。最后是否采用,仍然要看实验。 本条源码直证:toolset_selection 在 config_mode != focus 时返回 None(:517-518);compact_skill_categories 同样只在 focus 下非空(:582-584)。上面的实跑表与此一致。 出处Hermes · coding_context.py:505-584(pin) ↗需联网 。
说到底,编码 agent 和通用 agent 的差别,主要不在循环里,而在它看到的东西:一份告诉它先读后改、用工具改、改完跑测试的守则;一份告诉它根目录在哪、分支是什么、有哪些清单与上下文文件的快照;以及编码这个领域本身提供的东西——能自动验证的测试。Anthropic 在《Building effective agents》的附录里给编码 agent 的理由也是这些:方案能用自动化测试验证、agent 能拿测试结果当反馈反复改、问题空间结构清楚、产出质量能客观衡量 证据等级 · 有理论动机 有数学或机制上的理由说明它可能有效,但没有证明它一定更好。最后是否采用,仍然要看实验。 本条官方的经验性归纳。 出处Anthropic · Building effective agents · Appendix 1B Coding agents ↗需联网 。
两者同名、同一家公司,但没有技术血缘。Hermes Agent 的源码里还专门警告:Hermes 3 与 Hermes 4 模型不是 agentic 的,缺少 agent 工作流需要的工具调用能力,建议换用别的模型(hermes_cli/model_switch.py:206-211,原文见岔路 B1) 证据等级 · 有理论动机 有数学或机制上的理由说明它可能有效,但没有证明它一定更好。最后是否采用,仍然要看实验。 本条源码直证(pin 56dc01d9)。「没有技术血缘」由调研《Hermes与Pi身份核实》确认。 出处Hermes · model_switch.py(pin 56dc01d9) ↗需联网 。
证据三问
| 问 | 本课的回答 |
|---|---|
| ① 它解决什么问题? | 一个通用 agent 进到代码仓库时,自动拿到编码需要的守则与工作区信息,不必另写一套编码 agent |
| ② 为什么可能有效? | 编码任务的差别主要在上下文(守则、快照、测试),不在控制流;把差别做成会话开始时解析一次的数据,既不改循环,也不破坏前缀缓存 证据等级 · 有理论动机 有数学或机制上的理由说明它可能有效,但没有证明它一定更好。最后是否采用,仍然要看实验。 本条设计动机取自模块文档(Cache safety 一节),是作者的陈述。 出处Hermes · coding_context.py Cache safety(pin) ↗需联网 |
| ③ 实验上呢? | 判定逻辑在临时目录里原样实跑 9 个用例(上表);没有「开不开编码姿态」对任务成功率影响的公开数据 证据等级 · 实验验证 由对比实验得出的经验结论,只在出处写明的模型、数据和规模下成立。换了条件可能不再成立,引用时要带上实验设置。 本条实跑的是 pin 上的判定函数本身,不是 Hermes 整个 agent;用例是本课构造的输入,判定结果由原代码算出。 出处Hermes · _detect_profile_name(pin) ↗需联网 |
演进地图:你在这里
- 解决了只调一次模型,每一步都写在代码里:可预期、好测、便宜。卡在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。姿态在会话开始解析一次,中途不变。
一句话
回主线
模型决定下一步的那个循环,到底长什么样? → A1 循环
或者先做本章的实验课:4 个任务,先预测、再看两条轨道的真实结果。
你可能会问
- 「本课项目 miniagent 是通用 agent 还是编码 agent?」 编码 agent:它的 system prompt 与工具(读文件、改文件、跑命令)从一开始就是为改代码写的,没有姿态切换。它的 v2 提示词里那条「改完必须重跑测试」,和 Hermes 守则里「确认测试通过再宣布完成」是同一类规矩。
- 「判定往上找 6 层,不会误判吗?」 会,上表第二行就是:任务仓放在项目目录里,快照的根目录成了项目根。Hermes 为此跳过了家目录和系统临时目录,但挡不住「任务仓套在另一个项目里」这种情况。
- 「为什么不每一轮重新判定?」 因为判定结果写进了 system prompt 的稳定前缀:中途一改,之后每一轮的前缀缓存都要重建。Hermes 的
/coding开关因此只在下一个会话生效。A6 会用本课项目的真实录制算这笔缓存账。