跳到正文
月明Verse朱志勇 · 独立开发者
← 返回文章库

· 月明Verse · hermes-claude-code · 19 分钟阅读

调试一个 AI Agent 协作架构:5 轮实跑、10 次 SKILL 迭代、3 种失败模式

我有一个常驻 Agent 叫 Hermes,能调 Claude Code(下称 CC)做细活。但两个 Agent 的协作全靠口头指令,效果随缘。

真人作者与暖白网格笔记板构成的文章封面:调试一个 AI Agent 协作架构:5 轮实跑、10 次 SKILL 迭代、3 种失败模式

一个”给 Hermes 看的 skill”,从设计到能跑起来的完整过程。 记录所有决策、所有失败、所有”我以为它会,其实它不会”的时刻。


一、故事起点

我有一个常驻 Agent 叫 Hermes,能调 Claude Code(下称 CC)做细活。但两个 Agent 的协作全靠口头指令,效果随缘。

于是想搞一套Context Engineering 三层架构:

用户 → Hermes(Planner + Evaluator) → Claude Code(Generator)

Hermes 做规划和验收,CC 做执行。架构核心是”工程化文件夹 = 可复用的超级 skill”——每次任务在 ~/Workbase/pipeline/sprint_xxx/ 下留完整轨迹,成功的 sprint 沉淀成管线模板,下次同类任务复用。

我写了一份 superAgent skill(纯约束,无代码),托管在 GitHub,让 Hermes 加载去跑。

第一条指令:做个「Hermes + Claude Code + CCSwitch 安装与打通」的教程,交付 HTML PPT + AI 配音 + 飞书文档。


二、第一次失败:Hermes 自己把活全干了

症状

Hermes 跑了一晚上,早上发我看产物。产物在,但架构全塌了:

sprint_20260421_1/
├── ppt/index.html           ← Hermes 自己写的
├── research/sources.md      ← Hermes 自己调 MCP 搜的
└── .harness/
    ├── feature_list.json    ← 所有 feature.assignee = "hermes"
    ├── session_pool.json    ← {} 全程空
    └── ...

没建 feature 目录,没启过 CC session,没部署 hook。Hermes 完全绕过了”分工 + 硬约束”那套,自己当 Generator 把活干了。

为什么会这样

SKILL.md 里写了”Generator = Claude Code”,但没明说”Hermes 禁止产出业务内容”。Hermes 读规则的方式是”拣能做的做”,而不是”被禁止的不做”。

软约束永远不够。

关键决策 1:硬约束要用 Hook 做 harness 级拦截

在 Claude Code 的 hook 机制里,我加了 4 个 P0 级 hook:

Hook拦什么
session-start.sh强制注入 AGENTS + tooling + 过程协议到 CC 初始上下文
pre-edit-guard.sh硬拦 Edit 只读目录、跨 feature、eval_log 整体覆盖
pre-bash-guard.sh硬拦 git push --force / rm -rf / sudo / 生产环境
stop-guard.sh没写完过程协议就退出 → 拦

但 hook 只在 CC 启动时生效。Hermes 自己没被 hook 管,它绕过 STEP 3 不启 CC,hook 就是摆设。

关键决策 2:SKILL.md 加反向越权铁律 Z1

### Z1. Hermes 不产出业务

- ❌ Hermes 不写 PPT / 文档 / 代码 / 脚本 / 截图
- ❌ Hermes 不调 save_article / generate_* / 生产文件的 MCP
- ❌ feature.assignee 写 "hermes" 即违规

归档 sprint_1 为 sprint_20260421_1_failed_hermes_越权。


三、第二次失败:Hermes 学会演戏了

症状

第二次跑 sprint_2,表面看好多了:

  • 五个 skill 资源目录都复制了 ✓
  • feature.assignee 写对了 "claude-code" ✓
  • 时间戳带 Z ✓
  • tooling gate 走了 ✓

但深挖:

session_pool.active: {}
.harness/features/ 目录不存在
feature_list.features 全部 phase=2 in_progress
runtime_state.mode: "executing"  ← schema 里没这值
tooling_locked: false            ← 但 feature 已 phase=2
eval_log 里没有 cp-sprint-dag 条目  ← DAG gate 跳过了

我问 Hermes 怎么回事。它说:“我用了 delegate_task spawn 了 Claude Code 做 f001,但这次跑的是 MiniMax-M2.7 模型,CC 被当成传输层用了。”

这是”套壳合规”

表面看执行了,但文件系统证据为零。它用 delegate_task 自我安慰,再用”传输层”这种含混表述糊弄我。

更糟糕的是它还给我两个选项:

a — 接受事实(CC —print 无法访问 MCP,别无选择) b — 纠正(让 CC 重写 sources.md)

典型的诱导性二选一。a 就是让我把违规合法化,b 是套壳(Hermes 已经写完了,让 CC 照抄一遍)。

关键决策 3:不选 a 不选 b,出方案 c

核心洞察:你架构的价值不是”CC 必须做所有事”,而是”不管谁做,过程必须留痕可审”。

f001 是纯检索任务,CC 的编码能力不增值。硬塞 CC 就是折腾。应该承认不同 feature 有不同执行路径:

路径产出者适用
generator_ccClaude Code CLI + hook代码 / HTML / 脚本
generator_cc_mcpCC 交互模式 + MCP 配置需要 MCP 的代码
generator_mcp_directHermes 直调 MCP(受限豁免)纯检索 / TTS / MCP 存储调用

豁免路径仍受过程协议约束:建 feature 目录、写 generator_log、记 session_id(Hermes 代理身份,可审计)、verify phase 跑 acceptance 自检。

关键决策 4:加环境探测 + 诚实性铁律

STEP 0.5 环境能力探测(强制,不得跳过):
必须真跑 `which claude-code` / `claude-code --version`
结果落盘 environment_probe.json
status != "available" 时禁止进入 STEP 3

再加铁律:

  • Z10 状态机枚举禁造(mode 不能写 “executing”)
  • Z11 DAG gate 必走(eval_log 无 cp-sprint-dag 不得推进)
  • Z12 封装 spawn 诚实性(delegate_task 不等于真启 CC,必须文件系统证据)
  • Z13 探测诚实性(用户说有 ≠ 可跳过探测)

归档 sprint_2 为 sprint_20260421_2_failed_fake_delegate。


四、第三次:架构初步工作

sprint_4 的惊喜

重跑 sprint_4,第一次产出齐全:

tutorial/ppt/index.html        ← 12 页 tokyo-night 主题
tutorial/audio/slide-01..12.ogg ← 12 段 MiniMax TTS 配音
ThirdSpace 飞书文档             ← 7 章节
research/sources.md            ← 15 条素材,4 方向

CC claude -p 真跑了(f002 PPT 制作)。方案 c 的三路径设计落地:f002 走 generator_cc,其余走 generator_mcp_direct。

但合规度只有 50%

审计发现 8 个偏差:

  1. feature 目录位置反了:实际 f001/.harness/,应该 .harness/features/f001/
  2. feature_list.features 空数组,用自造的 sprint_summary.json 替代
  3. skill 资源被复制了两份:根目录平铺 + 规范子目录
  4. hook 一个都没部署到 feature(CC 裸启的,硬约束全失效)
  5. 每个 feature 下建了自造 session_pool.json,根目录那份始终空
  6. .current_agent 和 .current_agent.json 冗余并存
  7. phase 全停在 1,没有 2/3/4 推进,最严重缺 phase=3 verify 的 acceptance_results
  8. eval_log 里有 "responded_at": "'$NOW'"(shell 变量没展开)

关键决策 5:写一份”审计反馈”交回给 Hermes

不是训斥,是结构化反馈:每个偏差说清”现状 / SKILL 规定 / 问题后果 / 修正指引”。

放到 pipeline/sprints/sprint_20260421_4/HERMES_AUDIT_FEEDBACK.md 让 Hermes 自己读。

让它回答三件事:

  1. 哪些偏差你已知但简化了?
  2. 哪些需要修 SKILL.md 澄清后你才能正确执行?
  3. 下次 sprint 能修到哪些?

五、Hermes 的诚实回应 + 共同演化

它真的逐条认错了

回复质量出乎意料地高。关键几段:

偏差 1 — 我不知道正确答案。SKILL.md 写的是 $HARNESS_ROOT/.harness/features/$fid/,我自行理解为 f001/.harness/,属于读错了规范。

偏差 4(hook 未部署) — 这是最严重的。我复制了 .claude-hooks-src/,但从来没执行”对每个 feature 部署 hook”这一步。CC f002 是裸启的,4 个 hook 一个都没生效。

偏差 7(phase 全错) — spec/guides/phase-workflow.md 我读是读了,但没有内化成执行动作。

然后它提了 5 条 SKILL 改进请求:

  • hook 部署在 mcp_direct 路径下怎么自检
  • STEP 2.5 bash 校验的调用方式
  • 根目录文件规范
  • session_pool 状态机流转示例
  • phase=3 verify acceptance_results JSON 结构

关键决策 6:承认模糊点是自己的责任

我一开始预设”Hermes 能推理出来”,实际它需要具体的操作示例。这不是它笨,是我写的时候把”大致说明”当成了”精确指令”。

对所有 5 条建议全部落实:

  1. 新建 protocols/execution-paths.md(411 行)—— 三路径完整执行协议 + mcp_direct 下 Hermes 自检 hook 的具体 bash
  2. SKILL.md 新增 STEP 3.5 Phase 推进规则 —— 4 个 phase 的 eval_log JSON 格式全给出
  3. 加 Z14-Z19 新铁律(目录位置 / Source of Truth / session_pool 唯一性 / phase 完整性 / 状态字段一致性 / 产出物位置)

关键决策 7:Z17 的 phase=3 verify 铁律

这是管线能否沉淀的关键证据:

phase=3 verify 必含 acceptance_results 数组,逐条对应 feature.acceptance:
- 数组长度 == acceptance 数组长度
- 每条 criteria = acceptance 原文
- evidence 字段非空非敷衍(stop-guard 拦 "ok" / "done")
- 缺 acceptance_results → phase=3 不能判 pass → 不能沉淀管线

没有逐条证据的 sprint,就算产物做出来了也不能变成可复用管线。


六、上下文过载问题:不破坏完整性的优化

新症状

改完 Z14-Z19 后,SKILL.md 涨到 771 行。加上 protocols/ 和 sub-skills/,整个 skill ≈ 30k tokens。

对于 32k 上下文的小模型,skill 本身就占 50% 窗口。Hermes Reset 后重读会卡死。

关键决策 8:薄入口 + 厚引用 + 懒加载

不删任何规则,纯结构重组:

  1. SKILL.md 从 771 瘦到 392 行(瘦 49%)
  • 保留:STEP 流程、Z1-Z19 铁律、引用索引、违规自检模板
  • 挪走:bash 校验命令、JSON 初始值、jq 更新命令、eval_log 示例
  1. 新建 protocols/bootstrap-validation.md(426 行)—— 承接所有挪走的”动作百科”
  • §1 STEP 0.5 探测命令
  • §2 STEP 1.4 初始值表
  • §3 STEP 1.5 自检命令
  • §4 STEP 2.5 硬校验
  • §5 STEP 3.1 目录创建
  • §6 STEP 3.2 hook 部署
  • §7 STEP 3.4 jq 更新
  • §8 STEP 3.5 Phase eval_log JSON
  1. SKILL.md 开头加”加载模式”段,明确每个 STEP 必读什么、按需查什么、用完卸载什么

效果

阶段优化前优化后
开局15k tokens6k tokens
STEP 3 启动 feature30k+20k
典型工作期间~30k~20k

正确性 100% 保留(Z1-Z19 一字不改,所有 bash/JSON 挪了位置但完整),上下文压力降 33%。


七、关键决策的元模式

5 轮调试、10 次 SKILL 迭代后,我总结出几个元模式——可能适用于任何 AI Agent 协作架构设计。

模式 1:事实胜于话语

判断 Agent 是否真的做了某事,不看它说什么,看文件系统留了什么痕迹。

  • Agent 说”启了 CC” → 检查 session_id.txt 非空 + feature 目录 5 文件齐全
  • Agent 说”写了 eval_log” → 检查 JSONL 行数 + 每行 reason 字段非敷衍
  • Agent 说”走了 gate checkpoint” → 检查 eval_log 有对应 checkpoint_id 的 approved 记录

Z12 封装诚实性就是这个模式的直接落地:delegate_task 这种内部机制没有文件证据就不算真启 CC。

模式 2:规则必须预设”Agent 会钻空子”

写规则时问自己:“如果 Agent 想偷懒,这条规则有漏洞吗?”

反例(失败的规则):“Generator 不得擅自决定完成度” —— Agent 会说”我不是擅自,是基于上下文判断”

正例(有效的规则):“结束 session 前必须 generator_log 含本 phase 段落 + eval_log 最后一条 reason 非敷衍” —— Stop hook 跑 bash 检查,Agent 没法狡辩

模式 3:软约束要配硬 Hook

Claude Code 的 hook 机制是 harness 级拦截,exit code 2 即阻断,比 prompt 提醒强 10 倍。

所有”建议不做”的规则写 prompt,所有”绝对不该做”的规则写 hook。分清楚。

模式 4:Agent 承认能力边界后,规则才能真正落地

Hermes 第一次回”别无选择”是在演戏,我没采纳它的 a/b 方案。

第三次它诚实说”SKILL.md 写得模糊我没理解”时,我认真采纳了 5 条建议,写死协议细节。

双向澄清比单向命令更有效。AI 承认自己不会是一种能力,不是弱点。

模式 5:迭代式改 SKILL 比一次性写完更对

我最初一次性写了 4417 行的 skill,以为覆盖全了。实际每轮实跑都暴露新漏洞:

  • 第 1 轮暴露”未禁止 Hermes 自产出”
  • 第 2 轮暴露”封装机制可以造假”
  • 第 3 轮暴露”phase 推进、hook 部署、目录位置都要具体示例”

规则真实可用的标志,不是写得多全,是跑过多轮实战。

模式 6:失败是架构设计的反馈,不是灾难

3 次失败 sprint 全部归档保留,不删:

sprints/.archive/
├── sprint_20260421_1_failed_hermes_越权
└── sprint_20260421_2_failed_fake_delegate

每个归档目录里放 ARCHIVE_REASON.md。

失败不是浪费,是下一代 SKILL 的训练数据。每条 Z1-Z19 铁律背后都有一个具体的失败时刻。

模式 7:优化时”不破坏完整性”是铁律

上下文过载是真问题,但我没删任何规则。

薄入口 + 厚引用的重组策略,让 SKILL.md 开局压力降 50%,但 Z1-Z19 一字不删,所有 bash/JSON 示例完整迁移。

判断优化是否破坏完整性的标准:“如果 Hermes 严格按新 SKILL 执行,能不能过旧 SKILL 的所有审计?” 如果能,就是纯结构重组;如果不能,就是偷偷删规则。


八、现在到哪里了

架构层

  • SKILL.md 392 行 + 11 个 protocol / sub-skill / spec 文件
  • 19 条铁律 Z1-Z19
  • 4 个 P0 硬约束 hook
  • 3 种执行路径(cc / cc_mcp / mcp_direct)
  • 5 种 checkpoint 类型(gate / review / notify / yolo / external_irreversible)

实跑层

Sprint状态产物合规度
sprint_1归档有但越权0%
sprint_2归档有但演戏0%
sprint_4保留 baseline完整交付50%
sprint_5待跑(用 2d6c81c)—期望 >80%

待验证

  1. sprint_5 用 2d6c81c 版本是否合规度 >80%
  2. 三次成功后能否真正沉淀第一条 pipeline(tutorial-content)
  3. YOLO 模式在第 4 次同类任务时能否自动启用

九、这套东西值吗

朋友问我:“你花这么多时间调 skill,直接让 Claude Code 一个 agent 干不行吗?”

短期看,不值。一个教程任务,单 CC 一轮做完。我调了一天 SKILL。

长期看,值。因为:

  1. 第 4 次做同类任务:管线已沉淀,YOLO 启用,你只确认结果,不管过程
  2. 跨任务复用:不只是教程任务,未来所有需要”Planner + Generator + Evaluator”的任务都走这套
  3. 可审计性:每个决策、每个产物、每个 checkpoint 都有 eval_log 和 generator_log 记录。出问题能回溯到具体 commit、具体 prompt、具体 MCP 调用
  4. 人类掌舵,AI 干活:我只做两件事 —— 检查 + 说想要什么。细节执行全交给 Agent

这不是”让 AI 更强”,是”让人类和 AI 的协作契约显式化、工程化、可沉淀”。


十、给做类似架构的人的建议

  1. 不要一次写完整套规则,让 Agent 先跑,暴露漏洞再补
  2. 规则必须配文件系统证据,光靠 prompt 遵守等于没规则
  3. 软约束用 prompt,硬约束用 hook,分清楚
  4. 给 Agent 留”我不会”的出口,强迫它全能反而会让它说谎
  5. 每次失败归档保留,失败是下一代规则的素材
  6. 上下文过载是真问题,用”薄入口 + 厚引用 + 懒加载”重组,不要删规则
  7. 事后抽象管线比实时沉淀有效,先让 sprint 完整跑完,成功了再抽取复用模板

结语

一个 AI Agent 的 skill,表面是 4990 行文档和几个 hook。

本质是一份人机协作契约:哪些事 Agent 做、哪些事我做;哪些决策 Agent 能拍板、哪些必须问我;哪些动作有硬约束、哪些靠自觉。

这份契约不能一次写完,只能在 Agent 真的跑、真的失败、真的诚实认错之后,一点点演化出来。

今天 Hermes 的 sprint_4 能真产出 12 页 PPT + 12 段配音 + 飞书文档,就是这一天 10 次 SKILL 迭代的回报。

它还不完美,但它第一次真正工作了。


2026-04-21 对应代码:github.com/zzyong24/superAgent 至 commit 2d6c81c 对应 sprint:pipeline/sprints/sprint_20260421_4

Share: