Skip to content

Skill-Agent 协作架构篇:从单 Skill 到 Multi-Agent 编排

核心结论:当一个 Skill 同时承载的任务维度过多时,高优先级任务会系统性压制低优先级任务的执行——即使 Skill 明确禁止跳过也无效。这是 LLM 的结构性限制,不能通过加强提示词消除,只能通过架构手段解决。解法是 Skill-Agent 协作:将重度 Skill 拆分为聚焦单一维度的垂直 Skill,各由独立 Agent 在隔离上下文中执行;配合 Grep-Gated 执行协议,将 75% 的检查项转为规则驱动的预扫描,进一步降低维度内的概率性遗漏。

目录


17. 注意力稀释:架构问题,不是提示词问题

17.1 注意力稀释的规律(以代码审查 Skill 为例)

单 Skill 同时处理多个维度时,高优先级任务会天然抢占模型注意力,导致低优先级任务被系统性遗漏——这不是偶发错误,而是可复现的结构性失效,代码审查场景尤为典型。

以 Go 代码审查为例,以下代码交给 go-code-reviewer Skill 处理:

func getBatchUser(ctx context.Context, userKeys []*UserKey) ([]*User, error) {
    userList := make([]*User, 0)  // ← 无容量预分配

    var wg sync.WaitGroup
    for i, u := range userKeys {
        if u == nil { continue }
        wg.Add(1)
        go func() {
            defer wg.Done()
            user, err := redis.GetGuest(ctx, u.Id)
            if err != nil {
                log.WarnContextf(ctx, "no found guest user: %v", u)
                continue  // ← goroutine 内 continue,编译错误
            }
            userList = append(userList, user)  // ← 数据竞争
        }()
    }
    return userList, nil  // ← 缺少 wg.Wait()
}

Skill 发现了 4 个 High 级并发缺陷(编译错误、数据竞争、goroutine 泄漏、循环变量捕获),但漏报了一个 Medium 级性能问题

// 实际代码(错误)
userList := make([]*User, 0)

// 应该写成(已知上界 len(userKeys),应预分配容量)
userList := make([]*User, 0, len(userKeys))

这完全符合 Skill 的 Performance checklist 中"Slice Pre-allocation"检查项。Skill 本身也明确规定:

Execute ALL checklist categories regardless of how many High findings have already been identified

但模型仍然漏报了。人工指出遗漏后,模型立即识别并承认:

"当 4 个 High 级别的并发缺陷占据了注意力后,我在走 Performance checklist 时不够仔细,错误地将这个问题归入了'可忽略的小问题'而没有正式报告。"

关键发现:问题不在于模型"不会"——指出后立即承认,说明它具备识别能力。问题在于单次调用中同时处理 5 个审查维度,High 级别 Findings 天然更"吸引"注意力,压缩了模型分配给其他维度的认知资源。

17.2 根因:上下文窗口的注意力竞争

单 Agent 加载重度 Skill 时,上下文窗口承载了所有维度的知识、全部代码,以及已发现的 Findings:

[单个 Agent 的上下文窗口]
┌─────────────────────────────────────────┐
│ go-code-reviewer SKILL.md(全量知识)    │
│ ├── 安全规则(SQL 注入、XSS...)         │
│ ├── 并发规则(竞态、死锁、泄漏...)      │
│ ├── 性能规则(预分配、N+1...)           │  ← 被挤压
│ ├── 错误处理规则(wrap、nil check...)   │  ← 被挤压
│ └── 质量规则(命名、结构...)            │  ← 被挤压
│                                         │
│ 已发现的 Findings:                       │
│ ├── [High] REV-001 编译错误 ←────────┐  │
│ ├── [High] REV-002 数据竞争 ←────────┤  │ 注意力集中在这里
│ ├── [High] REV-003 goroutine 泄漏 ←──┤  │
│ └── [High] REV-004 循环变量捕获 ←────┘  │
│                                         │
│ Performance checklist:                   │
│   Slice Pre-allocation → ??? (未检查)    │  ← 注意力不足
└─────────────────────────────────────────┘

Anthropic 的内部研究对这一现象提供了量化支撑:在多 Agent 研究系统评测中,token 使用量解释了 80% 的性能差异,核心原因是每个 Agent 在干净的上下文窗口中执行,token 使用效率更高——这正是上下文污染(Context Rot)会拉低单 Agent 性能的直接证据。

这不是提示词写法的问题,是架构问题。 已尝试的缓解措施如下:

缓解措施 效果 局限
在 Skill 中强调"不可跳过 checklist" 部分有效 规则本身也在同一上下文中竞争注意力
写入 Memory"High findings 不能跳过其余 checklist" 下次有帮助 无法根本解决单上下文多维度的注意力竞争
增加 checklist 的强制性语言 有限改善 LLM 的注意力机制是概率性的,无法仅靠指令稳定覆盖

这些措施仅能把执行遗漏概率从高降为中,无法消除。迭代篇(§15-16)已记录这一上限:在规则层的最终修复率约为 67%,仍有系统性残差。本篇给出架构层的根本解法。

17.3 为什么 Multi-Agent 是正确方向

17.3.1 Multi-Agent 的精确定义与四大机制

Multi-Agent 架构是指多个 AI Agent 在明确的角色分工和协作协议下,协同完成一个复杂任务。每个 Agent 拥有独立的上下文窗口、专用的工具集和清晰的职责边界。

这与软件工程中的微服务演进高度类似:

软件演进 AI Agent 演进
单体应用代码库太大,难以维护 单体 Agent 上下文窗口积累太多,性能下降
单点故障影响全局 单个维度失误影响整条审查链路
无法独立扩展模块 无法为不同任务选择最优模型
职责边界模糊 Agent 角色混乱导致输出质量下降

就像单体应用最终需要被拆分为微服务一样,单体 Agent 在任务足够复杂时,也需要被拆分为多个专职 Agent。

Multi-Agent 对 Go 代码审查场景的四大优势机制:

优势 机制 对本场景的意义
专注的上下文窗口 每个 sub-Agent 在全新、干净的上下文中运行,不受其他维度 Findings 污染 并发审查发现 4 个 High 不会影响性能审查对 make([]*User, 0) 的敏感度
深度专业化 每个 Agent 的系统提示聚焦单一领域,工具集精简 Security Agent 只看安全缺陷;Performance Agent 只看性能问题——无需兼顾其他
多视角质量保障 多个 Agent 独立评估,彼此不知道其他 Agent 的 Findings 并发、错误、性能审查各自独立得出结论,交叉验证相互强化
灵活的模型配置 主会话(编排 Skill)用强模型做分诊和汇总,Workers 用快速模型执行审查 主会话负责分诊 + 去重,Workers 使用 Haiku/Sonnet 控制成本

第一个优势直接对应本文的核心问题:当单个上下文窗口同时持有多个高严重度 Findings 时,模型对低优先级检查项的覆盖率会系统性下降。这是提示词难以修复的结构性缺陷——Multi-Agent 通过让每个维度在独立上下文中运行,显著降低了跨维度的注意力竞争。

17.3.2 实证数据:Anthropic + AgentCoder

Anthropic 多 Agent 研究系统实测(来源:Anthropic Engineering Blog, 2025): - Claude Opus 4(Lead)+ Claude Sonnet 4(Workers)的多 Agent 系统,在内部研究评测中比单 Agent Opus 4 性能高出 90.2% - Token 使用量解释了 80% 的性能差异——关键不在于模型更强,而在于每个 Agent 在干净的上下文中专注完成单一任务

AgentCoder 学术研究(来源:arXiv:2312.13010): - 多 Agent 代码生成(Programmer + Test Designer + Test Executor)在 HumanEval 上达到 96.3% pass@1,单 Agent SOTA 为 90.2% - 使用更少的 token(56.9K vs 138.2K)达到更高的准确率,证明专业化分工可以同时提升质量和效率

这组数据揭示了一个反直觉的结论:Multi-Agent 的优势不来自"用了更多算力",而来自让每个 Agent 在干净的上下文中做更专注的事

17.3.3 架构换模型:降低对顶尖推理模型的依赖

§17.3.2 的实证数据指向一个值得单独提炼的结论:Multi-Agent 架构不仅仅是"用便宜的模型做同样的事"——而是用更便宜的模型,做更好的事

配置 模型 审查质量(基准案例) 漏报数
单 Agent Opus 4 4 High,漏报 1 Medium 1
Multi-Agent Orchestrator-Workers Sonnet 4 Workers + Sonnet Lead 全部捕获 13/13 0

为什么更便宜的模型 + 更好的架构能超越更强的模型 + 单 Agent?

根因在于任务结构与模型能力的匹配度。Opus 在单一聚焦任务上的表现确实优于 Sonnet——但当它被要求在同一个上下文中同时覆盖 5 个独立维度时,注意力稀释会系统性拉低它在每个维度上的实际发挥。而 Sonnet 在只负责一个维度(如仅审查并发问题)时,专注度接近满状态,不受跨维度注意力竞争的影响。

换一种说法:对于多维度任务,Sonnet × N 个聚焦 Agent 的组合效能,可以超过 Opus × 1 个泛化 Agent。

成本权衡

维度 单 Opus Agent Multi-Agent Sonnet Workers
单次推理成本 高(Opus 约为 Sonnet 定价的 5–10 倍) 低(每个 Worker 用 Sonnet/Haiku)
总 token 消耗 低(单次调用) 高(多个并行 Agent 累计)
整体账单 中(token 更多但单价更低,近似持平)
审查质量 有注意力稀释风险 更全面、更稳定

多 Agent 并行虽然累计 token 消耗更高,但每次推理调用使用的是更低价位的模型。两者相抵,整体账单往往近似持平,而质量却显著提升。

核心洞察:这一结论改变了模型选型的思路框架。传统问法是"我应该用哪个最强的模型?"——更好的问法是"我的任务架构,能否把模型从需要同时擅长多件事,改造成只需专精一件事?"如果能,次优模型配合优质架构往往优于顶尖模型配合平凡架构。

对于遭遇注意力稀释的场景,这意味着:你不需要等待更强大的下一代模型来解决漏报问题——架构重构是在现有模型上更可控、更可预期的解法

17.4 五种编排模式全景:各有所长,各有所用

明确了 Multi-Agent 的优势之后,面临的下一个问题是:选哪种编排模式? 本节系统性梳理五种基础模式,帮助 Skill 设计者为不同任务找到最合适的架构,而不只是为代码审查场景做选型。

Anthropic 定义了五种基础编排模式,按子任务决策时机和执行结构分类:

模式 核心机制 子任务来源 执行结构
Prompt Chaining 步骤线性传递,A 的输出是 B 的输入 固定线性序列 顺序
Routing 分类输入,路由到唯一的专门处理器 固定分支,取其一 排他选择
Parallelization 预先固定的多条路并行执行,聚合结果 固定集合,全部执行 并行
Orchestrator-Workers 编排者动态决定需要哪些 Workers 运行时决定,按需执行 动态并行
Evaluator-Optimizer 生成→评估→改进,直到满足阈值 固定两角色,迭代循环 循环

模式一:Prompt Chaining(提示词链)

核心:步骤 A 的输出直接成为步骤 B 的输入,形成线性管线,每一步都在前一步的基础上加工。

适用条件:任务有明确的顺序依赖关系;步骤间存在信息单向传递;每步的输出质量直接影响下一步。

后端开发典型场景:接口驱动的代码生成管线

从 OpenAPI 规范出发,逐步生成完整代码链路:

OpenAPI 规范(输入)
[Step 1:接口解析 Agent]
  输出:Go struct 和接口类型定义
[Step 2:代码生成 Agent]
  输入:Step 1 的 struct  →  输出:handler + service 骨架
[Step 3:测试生成 Agent]
  输入:完整代码  →  输出:集成测试
完整代码 + 测试(输出)

每一步依赖前一步的输出;handler 必须引用已存在的 struct,测试必须针对已知的接口结构。类似场景还有:数据库迁移辅助(分析现有 schema → 生成迁移 SQL → 生成回滚 SQL → 生成变更文档),步骤之间有单向依赖。

对代码审查的评估:✗ 不适用。安全/并发/性能各审查维度之间没有顺序依赖,不需要 A 的输出喂给 B。


模式二:Routing(路由)

核心:对输入分类,路由到最合适的专门处理器。每个请求只走一条路径,不同类型的输入走完全不同的处理逻辑。

适用条件:输入类型可以被明确分类;不同类型需要完全不同的处理方式;每次请求只需要其中一种处理。

后端开发典型场景:多语言代码审查路由

根据文件扩展名路由到对应语言的 Skill,每次请求只走一条路:

代码文件(输入)
[Classifier:检测文件类型]
       ├─ .go  → [Go 审查 Skill]     ← 本项目的专项规则
       ├─ .py  → [Python 审查 Skill] ← 不同的 checklist 和 reference
       ├─ .ts  → [TypeScript 审查 Skill]
       └─ .sql → [SQL 审查 Skill]

另一个典型场景:SQL 操作类型路由——将 SQL 语句按操作类型分流,因为读优化和写安全是完全不同的问题域:

SQL 语句
  ├─ SELECT        → [读性能 Agent](关注 Index Scan、rows 数量)
  ├─ INSERT/UPDATE → [写安全 Agent](关注事务隔离、锁范围、幂等性)
  └─ DDL           → [迁移安全 Agent](关注零停机方案、回滚计划)

对代码审查的评估:✗ 不适用。一次 Go 代码审查需要同时覆盖安全、并发、性能等多个维度,而不是从中选一个。


模式三:Parallelization(并行化)

核心:将任务拆分为预先固定的多个子任务,全部并行执行,最后聚合结果。子任务集合在设计时就已确定,每次输入都执行完整的 N 路。

适用条件:子任务之间相互独立;无论输入内容如何,这几项检查都需要执行;完成时间取决于最慢的子任务。

后端开发典型场景一:多格式文档同步生成

对同一个服务接口,同时生成多种格式的产出——三条路完全独立,无论接口定义是什么内容,总是同时执行:

服务接口定义(输入)
       ├─→ [中文 README Agent]  → README.zh-CN.md
       ├─→ [英文 README Agent]  → README.md
       └─→ [OpenAPI Agent]      → openapi.yaml

后端开发典型场景二:固定合规扫描流水线

每次 PR 合并都必须跑完全部三项,没有例外——这三项检查与代码内容无关:

PR 代码(输入)
       ├─→ [许可证合规 Agent]  → 第三方依赖许可证问题
       ├─→ [依赖安全 Agent]    → CVE 漏洞列表
       └─→ [编码规范 Agent]    → 规范违反列表

这是 Parallelization 最适合的场景:固定的、必须全量执行的检查集合,与输入内容无关。

Parallelization 与 Orchestrator-Workers 的本质区别

Parallelization:
  代码 → [固定派发: Security + Concurrency + Performance + ...] → 汇总
  子任务在设计时确定,每次审查都跑完整的 N 路

Orchestrator-Workers:
  代码 → [Lead Agent 分析 diff] → 动态决策 → 按需派发 K 路(K ≤ N)→ 汇总
  子任务在运行时确定,根据代码内容决定需要哪些维度

对代码审查的评估:△ 接近但不是最优。若代码只改了变量名,Parallelization 仍会启动全部 8 个 Agent,每次约 $0.16;Orchestrator-Workers 只需 2 个 Agent,约 $0.02。


模式四:Orchestrator-Workers(编排者-工作者)

核心:中央编排者分析输入,在运行时动态决定需要哪些 Workers 以及各自的任务边界,然后并行调度,最后汇总。子任务列表不在设计时固定,由编排者根据具体输入决策。

适用条件:所需子任务取决于输入内容,无法在设计时预知;不同输入需要不同的处理组合;需要一个"理解全局、分配任务"的协调角色。

后端开发典型场景一:内容驱动的代码审查(本文案例详见 §18)

根据代码内容决定派发哪些维度的审查 Agent:

代码 diff(输入)
[Lead Agent 分诊]
       ├─ 有 go func / sync      → 派发 Concurrency Agent
       ├─ 有 make([], 0) + append → 派发 Performance Agent
       ├─ 有 _test.go 变更       → 派发 Test Agent
       ├─ 始终派发               → Quality + Logic Agent
       └─ 无 SQL/HTTP 模式       → 跳过 Security Agent(记录原因)

5 行变量名修改:2 个 Agent;引入并发和性能问题的 PR:5 个 Agent——动态分配,按需付出成本。

后端开发典型场景二:自适应 Bug 修复管线

Lead Agent 分析 bug 影响面,动态决定需要哪些修复动作——修复范围完全取决于 bug 性质:

Bug 报告(输入)
[Lead Agent 分析影响范围]
       ├─ 涉及数据库操作 → 派发 DB 修复 + 迁移 Agent
       ├─ 涉及 API 接口  → 派发接口修复 + 契约更新 Agent
       ├─ 测试需要补充   → 派发测试补全 Agent
       └─ 跨模块传播    → 额外派发文档更新 + 通知 Agent

对代码审查的评估:✅ 最优解。"需要派发哪些 Agent 取决于被审查代码的内容"——这正是 Anthropic 对 Orchestrator-Workers 适用场景的定义:"无法提前预测需要哪些子任务,需要 Orchestrator 根据输入动态决策"


模式五:Evaluator-Optimizer(评估者-优化者)

核心:生成→评估→改进的迭代循环,直到满足质量阈值或达到迭代上限。评估结果决定是否继续迭代,以及如何改进。

适用条件:初版输出质量不稳定,需要迭代精化;有可操作化的质量标准(能判断"通过/不通过");迭代改进有收益,且能在几轮内收敛。

后端开发典型场景一:SQL 查询自动优化

执行计划有明确的"好/坏"判断标准(Index Scan vs Seq Scan),评估可机械化,是 Evaluator-Optimizer 的理想场景:

业务查询需求(输入)
[生成 Agent] → 初版 SQL
[评估 Agent] ← 执行 EXPLAIN,检查执行计划
       ├─ 通过(Index Scan,rows 估算 ≤ 阈值)→ 输出 SQL
       └─ 不通过(Seq Scan 或 rows 超限)
       [优化 Agent] → 重写 SQL 或建议添加索引
              └─→ 循环(上限 3 轮)

后端开发典型场景二:测试覆盖率自动补全

用实际测试运行结果作为评估依据,驱动迭代生成直到覆盖率达标:

待测函数代码(输入)
[生成 Agent] → 初版测试代码
[评估 Agent] ← 运行 go test -race -cover
       ├─ 通过(覆盖率 ≥ 80%,无 data race)→ 输出测试代码
       └─ 不通过(标注未覆盖的代码路径)
       [补全 Agent] → 针对未覆盖路径补充边界测试
              └─→ 循环(上限 2 轮)

后端开发典型场景三:API 设计质量迭代

以 checklist 通过率作为评估标准,驱动接口定义的迭代精化:

功能需求(输入)
[设计 Agent] → 初版接口定义
[评估 Agent] ← REST 规范 checklist + 安全 checklist + 向后兼容检查
       ├─ 通过(所有 checklist 项 ✅)→ 输出接口定义
       └─ 不通过(列出具体不符合项)
       [改进 Agent] → 修订接口定义
              └─→ 循环(上限 2 轮)

Evaluator-Optimizer 的关键权衡:每次迭代增加延迟和 token 消耗,适合输出质量对业务影响重大、且有可操作化评估标准的场景。若评估标准模糊(如"代码可读性"),容易陷入无效循环。

对代码审查的评估:✗ 不适用。代码审查是诊断任务,应如实反映代码现状——"改进审查报告"和"修复被审查的代码"是不同的任务,不应在 Evaluator-Optimizer 循环中混淆。


选型决策树

面对一个新的 Multi-Agent 任务,如何选型?

步骤之间有顺序依赖(A 的输出是 B 的输入)?
  是 → Prompt Chaining
  否 ↓

输入可分类,且每次只需一种处理方式?
  是 → Routing
  否 ↓

需要迭代精化,且有可操作化的质量阈值?
  是 → Evaluator-Optimizer
  否 ↓

无论输入内容如何,总是执行固定的几条路?
  是 → Parallelization
  否 → Orchestrator-Workers(子任务取决于输入内容,运行时动态决定)

对 Go 代码审查场景的最终选型:需要派发哪些 Agent 取决于被审查代码的内容(有并发才需要 Concurrency Agent,有 make([], 0) 才需要 Performance Agent),这是典型的"子任务在运行时决定"场景,决策树终点指向 Orchestrator-Workers。§18 展示了完整的实施与验证过程。


18. Skill-Agent 协作架构:设计、实施与验证

本章以 go-code-reviewer → 7-Agent 编排体系为贯通案例,演示 Orchestrator-Workers 架构的完整实施路径。所涉及的设计原则(垂直拆分、主会话负责编排、按需分诊、Grep-Gated 协议)不局限于代码审查场景,适用于任何遭遇注意力稀释的重度 Skill。

18.1 三种架构对比(决策矩阵)

架构 特点 已知问题 推荐度
A:单 Skill 1 个 Agent 加载全量审查知识,一次调用完成所有维度 注意力稀释;High Findings 系统性压制其他维度;已证实漏报 基础场景
B:Multi-Agent 无 Skill 7 个垂直 Agent 仅靠提示词,无 Skill 加载;主会话负责编排 上下文干净,但缺少领域审查规则;只能依赖 AI 通用知识;可能漏掉项目特定规则 不推荐
C:Multi-Agent + 垂直 Skill 主会话加载 go-review-lead Skill 负责分诊与汇总;7 个垂直 Agent 各自加载领域 Skill 设计和维护成本略高 ✅ 推荐

架构 C 的核心原则:

原则一:每个 Agent 只加载一个维度的 Skill。Performance Agent 的上下文中主要只有性能相关知识和待审查代码,没有其他维度的规则,也不接收其他 Agent 的 Findings。这会显著提高它把注意力放在 Performance checklist 上的概率。

原则二:主会话(编排角色)不审查代码。主会话加载 go-review-lead Skill 后扮演编排角色,只做分诊和汇总,不加载任何垂直审查 Skill,不直接分析代码逻辑。若主会话自己也做审查,它的发现会影响对其他 Agent 结果的汇总判断——和重度 Skill 是同一个问题。

原则三:垂直 Agent 通过 Skill 工具按需加载知识。Agent 定义文件是轻量的(几十行提示词),审查知识保存在独立的 Skill 文件中,Agent 在运行时通过 Skill() 工具加载。不存在内容重复,Skill 文件可被多个 Agent 复用。

原则四(平台约束):编排必须由主会话执行,不能由 subagent 执行。Claude Code 明确规定子代理不能生成子代理("Subagents cannot spawn other subagents")。因此 go-review-lead 只能以 Skill 形式运行在主会话,不能配置为 .claude/agents/ 中的 agent 定义文件——否则它会作为子代理运行,Agent 工具调用将被平台忽略,并行步骤被跳过。

完整架构全景(主会话 Skill 编排 + 7 个垂直 Agent):

                      PR Diff / 代码片段
              [主会话 + go-review-lead Skill]
                   职责:分诊 + 派发 + 汇总
                   加载 go-review-lead Skill
                   不加载垂直审查 Skill
                   不直接审查代码
                     Phase 1-4: 分诊
                     grep + 模式匹配,判断涉及哪些维度
    ┌────────┬────────┬───────┼───────┬────────┬────────┐
    ↓        ↓        ↓       ↓       ↓        ↓        ↓
[Security][Concurr][Perf] [Error] [Quality] [Test] [Logic]
  Agent    Agent   Agent  Agent   Agent    Agent   Agent
    │        │       │      │       │        │       │
 加载安全  加载并发 加载性能 加载错误 加载质量  加载测试 加载逻辑
  Skill    Skill   Skill  Skill   Skill    Skill   Skill
    │        │       │      │       │        │       │
 独立审查  独立审查 独立审查 独立审查 独立审查  独立审查 独立审查
    └────────┴────────┴───────┴───────┴────────┴────────┘
                        主会话汇总
                   合并 Findings + 去重 + 按严重度排序
                         最终报告

18.2 Skill 拆分指南(以 go-code-reviewer 为例)

拆分判断标准

信号 是否应该拆分
Skill 的 checklist 覆盖 3 个以上独立维度 是——维度间会互相抢注意力
单次审查经常产生 5+ 个 High Findings 是——High Findings 越多,其他维度被挤压越严重
审查后用户经常指出"这个应该发现但没发现" 是——典型的注意力稀释症状
Skill 只覆盖 1 个维度,且 checklist < 15 项 否——上下文负担不大,单 Agent 足够

目录结构(以 go-code-reviewer 为例):

skills/
├── go-security-review/SKILL.md      # SQL 注入、XSS、密钥泄露、权限
├── go-concurrency-review/SKILL.md   # 竞态、goroutine 泄漏、死锁、WaitGroup
│   └── references/go-concurrency-patterns.md
├── go-performance-review/SKILL.md   # 预分配、N+1、索引、内存
│   └── references/go-performance-patterns.md
├── go-error-review/SKILL.md         # 错误包装、资源关闭、panic 处理
├── go-quality-review/SKILL.md       # 命名、结构、lint 规则、注释规范
├── go-test-review/SKILL.md          # 测试覆盖率、断言质量、测试隔离
└── go-logic-review/SKILL.md         # 业务逻辑、边界条件、nil、错误传播

# go-review-lead 以 Skill 形式运行在主会话,不在 .claude/agents/ 中
# 主会话通过 Skill 工具加载 skills/go-review-lead/SKILL.md

.claude/agents/                      # 仅包含 7 个垂直 Worker Agent
├── go-security-reviewer.md          # 加载 go-security-review
├── go-concurrency-reviewer.md       # 加载 go-concurrency-review
├── go-performance-reviewer.md       # 加载 go-performance-review
├── go-error-reviewer.md             # 加载 go-error-review
├── go-quality-reviewer.md           # 加载 go-quality-review
├── go-test-reviewer.md              # 加载 go-test-review
└── go-logic-reviewer.md             # 加载 go-logic-review

checklist 上限原则:每个垂直 Skill 的 checklist 项不超过 15 条。如果超过,说明该维度还可以继续拆分。这一上限并非任意设定——15 条以内的 checklist 在独立上下文中仍然处于模型注意力可覆盖的范围,超过则重新引入维度内的稀释风险。

18.3 分诊机制(go-review-lead Skill 在主会话中执行)

两级分诊

分诊分两个层次,层次之间成本差异悬殊:

Level 1:文件类型分诊(无需 LLM,用 grep 即可)

# 有 .go 文件变更?      → 进入 Level 2
# 有 _test.go 变更?     → 派发 go-test-reviewer
# 有 go.mod 变更?       → 派发 go-security-reviewer(依赖审查)
# 有 .sql / migration?  → 派发 go-security-reviewer

Level 2:内容分诊(Haiku 快速扫描 diff,约 $0.001/次)

diff 包含 go func / channel / sync  → Concurrency Agent
diff 包含 make([] + 零容量            → Performance Agent
diff 包含 sql.Rows / tx.Begin        → Error + Security + Performance Agent
函数名含 Batch / Multi / GetAll      → Performance Agent

Level 1 不消耗 token。两级合计每次分诊成本可忽略不计。

四阶段分诊逻辑(Phase 1–4)

Phase 扫描对象 典型触发规则
Phase 1:Import 扫描 所有变更文件的 import 块 "sync" → Concurrency;"database/sql" → Security + Error + Performance
Phase 2:Diff Pattern 扫描 仅新增/修改行 make(\[\] 零容量 + append( 共现 → Performance;go func → Concurrency
Phase 3:文件路径 heuristic 变更文件的路径和函数名 auth/handler/ → Security;函数名含批量语义 → Performance
Phase 4:变更范围评估 diff 整体结构 新增 .go 文件 → 强制派发 Error;go.mod 变更 → 对新依赖重跑 Phase 1

无兜底派发原则:若某 Agent 未被任何阶段触发,则跳过并明确记录原因——而不是无差别地全量启动。这是分诊机制最核心的价值。

成本对比

方案 简单风格 PR 复杂并发 PR 全方位重构
全量 7 Agent(无分诊) ~$0.16 ~$0.16 ~$0.16
分诊 + 按需派发 ~$0.02 ~$0.07 ~$0.10
原始单 Skill ~$0.03 ~$0.03(但漏报) ~$0.03(但漏报)

按需调度在简单 PR 上节省约 80% 成本,在复杂 PR 上成本与全量启动持平,但审查质量显著优于单 Skill 方案。

注:以上成本为近似估算,基于 Claude Haiku 4.5 / Sonnet 4.6 的 2026-03 官方定价,实际成本还受代码量(token 数)影响,仅作数量级参考。

18.4 Grep-Gated 执行协议(核心创新)

问题本质的重新认识

首轮 Multi-Agent 架构(§18.5 轮次 2)暴露了一个根本性的设计失误:把模型当成了人类代码审查员。人类审查员读 checklist,然后用"眼睛"扫代码,靠注意力和经验发现问题。模型也在被迫做同样的事——用"注意力"扫描 checklist,然后在代码中寻找匹配。这种方式的问题在于,模型的注意力是概率性分配的;而 grep 对显式模式的检出更接近规则驱动的机械扫描。

模型不是人,它有工具可以用。

核心解法:工具辅助检测(tool-assisted detection)+ 模型判断(model judgment)。对于有明确语法特征的 checklist 项,让模型先用 grep 机械扫描,再对 HIT 结果做语义确认。只有真正需要推理的语义项,才交给模型全量分析。

执行流程(分步说明)

对每个 sub-agent,执行流程变为:

1. 通过 Skill 工具加载对应领域 Skill(checklist + 规则 + grep pattern)
2. 识别目标文件(或将裸代码片段写入 $TMPDIR/review_snippet.go)
3. 对所有 grep-gated checklist 项,按 Skill 中提供的 pattern 执行 grep
4. grep HIT  → 模型做语义确认(true positive vs false positive)
5. grep MISS → 自动标记 NOT FOUND,跳过语义分析,不上报主会话
6. 无 grep pattern 的项(纯语义项)→ 模型全量推理
7. 只上报 FOUND 项
8. Execution Status 中包含审计行:Grep pre-scan: X/Y items hit, Z confirmed

主会话汇总各 sub-agent 的报告后,根据审计行核查覆盖率,而不是盲目信任"没报告 = 没问题"。

覆盖率统计

7 个 Skill、86 条 checklist 项,其中 65 条(75%)可 grep 化:

Skill 总条数 Grep 化 纯语义
go-concurrency-review 14 13 1
go-performance-review 12 10 2
go-error-review 12 12 0
go-security-review 16 14 2
go-quality-review 12 8 4
go-test-review 10 8 2
go-logic-review 10 0 10
合计 86 65 (75%) 21 (25%)

在当前设计中,75% 的检查项转化为了规则驱动的预筛选,模型的注意力可以更多集中在剩余 25% 的语义项上。

宽门槛设计原理

Grep-Gated 协议的 pattern 设计采用宽门槛策略:宁有 HIT 假阳性,不漏 MISS 假阴性

  • go\s+func 这一 pattern 同时触发 6 个并发审查项,产生大量 HIT
  • false positive 交给模型在语义确认阶段过滤,成本可接受
  • MISS 会直接跳过语义分析,一旦漏检就不再有任何机会补救

这种不对称性决定了 pattern 宁宽勿严:漏检的代价(遗漏真实 bug)远大于误触发的代价(多一次语义确认)。

复合 pattern 设计:缺失保护检测

对于"应该有 A 但没有 B"的缺失类问题,使用复合 pattern

# CONC-14: 无界 goroutine 创建(有并发但无限流控制)
grep pattern:go\s+func
AND NOT:SetLimit|semaphore|maxConcurrency|worker.*pool

# PERF-01: Slice 未预分配(有 make 但无容量参数)
grep pattern:make\(\[\][^]]+,\s*0\)   → 检测零容量
AND NOT:第三个参数存在

复合 pattern 使"缺少防护"类问题可被 grep 机械检出,而不再依赖模型注意力去发现"不存在的东西"——这恰恰是注意力最容易疏漏的场景。

go-logic-review 的特殊处理

go-logic-review 覆盖业务逻辑、边界条件、合同违反、nil 安全等问题,这些问题没有稳定的语法特征,无法用 grep 预筛选。该 Skill 的所有 10 条 checklist 项均为纯语义分析,使用专用执行模板:

## Execution Order

After invoking the skill:
1. Identify target files (from dispatch prompt)
2. All checklist items are semantic-only — no grep pre-scan applicable
3. Apply full model reasoning to each item
4. Report FOUND items only
5. Include: `Semantic-only skill: 10/10 items evaluated`

这是协议的合理边界:grep 只适用于有语法特征的问题,强行 grep 化语义项会产生大量无意义 MISS,反而降低覆盖率的可信度。

18.5 三轮迭代验证

用同一段 getBatchUser 代码(§17.1 所示)进行三轮完整验证,每轮在上一轮的架构基础上改进。

三轮对比总览

指标 轮次 1:单 Skill 轮次 2:Multi-Agent v1 轮次 3:Multi-Agent + Grep-Gated
架构 1 Agent + 重度 Skill 8 Agent 误配(Lead 作为 agent,并行派发受阻) 7 Worker Agent + 主会话 Skill 编排 + Grep-Gated 协议
派发 Agent 数 1 4(跳过 performance) 5(含 performance)
High Findings 4 7 7
Medium Findings 1(漏报 1) 2(漏报 4+) 6
Slice Pre-allocation ❌ 未发现 ❌ 未发现(performance 未被分诊) ✅ REV-009 正式上报
Unbounded Goroutines ❌ 仅在 Residual Risk ⚠️ 有时遗漏 ✅ REV-008 正式上报
总 Findings 捕获 8/9(漏 1) 不稳定 13/13

轮次 1:单 Skill 的失效

单 Skill 调用发现了 4 个 High 并发缺陷,但 Slice Pre-allocation 漏报。模型事后承认原因是 Performance checklist 的注意力被 High Findings 挤压。这是本次改造的起点。

轮次 2:Multi-Agent v1 的新问题

完成 1 Skill → Multi-Agent 的初步改造后(此阶段 Lead 误配为 agent 定义,并行派发受平台约束而受阻),验证发现两个新问题:

问题一:分诊盲区go-review-lead 的 Phase 2 原始触发条件只对"已有 capacity 参数的 make"触发,而 make([]*User, 0) 恰好是没有 capacity 的情况——规则反向匹配失败,go-performance-reviewer 被直接跳过。代码以裸片段提交也导致 Phase 3 的文件路径 heuristic 无效。

问题二:维度内注意力稀释。即便 go-concurrency-reviewer 被正确分诊并派发,当上下文中存在多个 High 级别的编译错误和数据竞争时,"无界 goroutine 创建"这类 Medium 级别的问题仍会被模型降低优先级,最终只出现在 Residual Risk 中,而不是作为正式 Finding 上报。

架构已经将不同审查维度隔离到独立上下文,但在同一个 Agent 的上下文内,多个 High 级别 Findings 仍然会压制 Medium 级别的项。注意力稀释问题在垂直维度内部依然存在。第一轮架构改造的汇总报告如下(摘录关键差异部分):

- Skipped skills: go-performance-reviewer (no hot-path loops or DB patterns)
                  ← 分诊盲区导致跳过

Residual Risk:
2. Unbounded goroutine spawning: ... Not flagged as a finding since expected
   batch size is unknown ...    ← 未正式上报,藏在 Residual Risk 中

Summary: 7 High / 2 Medium / 1 Low.

轮次 3:Multi-Agent + Grep-Gated 的验证通过

针对分诊盲区,修正 Phase 2 触发条件(同时检测零容量 make),并在 Phase 3 补充批量语义函数名 heuristic(getBatchUser 直接命中)。针对维度内注意力稀释,引入 Grep-Gated 执行协议。

验证结果:在当前基准案例中,13 个预期发现均被捕获,未观察到新的遗漏。

slice pre-allocation 的完整轨迹:

轮次 状态 原因
轮次 1(单 Skill) 未发现 Performance checklist 注意力被 4 个 High 挤压
轮次 2(Multi-Agent v1) 未发现 → Residual Risk performance Agent 未被分诊;维度内仍有注意力竞争
轮次 3(Multi-Agent + Grep-Gated) REV-009 [Medium] 正式上报 make([]*User, 0) 被 grep pattern 机械命中,无法被注意力稀释

最终报告(摘录):

- Dispatched: go-concurrency-reviewer, go-performance-reviewer,
              go-error-reviewer, go-quality-reviewer, go-logic-reviewer
- Triage: make([]*User, 0) + append( + getBatchUser 批量语义命中 Phase 2+3

[Medium] Missing Slice Pre-allocation — Repeated Reallocation in Batch Hot Path
- ID: REV-009 (original: PERF-001)
- Evidence: userList := make([]*User, 0) — zero capacity, no second argument.
  Grep hit: make([]*User, 0) at L10. Function name getBatchUser signals batch hot path.
- Recommendation: userList := make([]*User, 0, len(userKeys))

[Medium] Unbounded Goroutine Spawning — Resource Exhaustion Under Large Batches
- ID: REV-008 (original: CONC-005)
- Evidence: goroutine count scales linearly. No SetLimit, semaphore, or worker pool
  present. Grep: go\s+func HIT AND NOT SetLimit|semaphore MISS.

Summary: 7 High / 6 Medium — 13/13 expected findings captured.

至此,改进闭环完整成立:单 Skill 注意力稀释 → Multi-Agent 架构改造 → 分诊盲区修复 → Grep-Gated 协议引入 → 13/13 全部捕获。

18.6 完整实现参考

本章描述的 Multi-Agent 架构已作为可运行文件发布在本仓库,可直接部署到 Claude Code 环境:

内容 路径 说明
Orchestrator Skill skills/go-review-lead/SKILL.md 主会话编排逻辑:分诊规则、汇总格式、报告规范(以 Skill 形式运行,不在 agents/ 目录中)
7 个垂直审查 Skill skills/go-{concurrency,performance,error,security,quality,test,logic}-review/SKILL.md 各维度的 checklist、Grep-Gated pattern、输出格式
7 个 Agent 定义文件 outputexample/go-review-lead/agents/ 可直接复制到 .claude/agents/ 的垂直 Worker Agent 定义文件(不含 go-review-lead)
部署指引 outputexample/go-review-lead/README.md 安装步骤、前置条件、用法说明(英文)

18.7 常见问题

Q:跨维度问题(如无界 goroutine = 并发 + 性能)如何处理?

允许两个 Agent 从各自角度同时报告同一问题。主会话在汇总时去重合并,取较高严重度,合并证据。交叉报告比遗漏好——去重的成本远低于漏报的代价。REV-008(无界 goroutine)正是由 Concurrency Agent 从并发维度正式上报,兼有 Performance 语义,两者合并为一条 Finding,严重度取较高的 Medium。

Q:所有重度 Skill 都应该拆分吗?

不是。判断标准:覆盖 3 个以上独立维度、单次经常产生 5+ 个 High Findings、或用户反复反馈漏报,才值得拆分。如果 Skill 只有单个维度且 checklist < 15 条,上下文负担不大,单 Agent 足够,不需要引入 Multi-Agent 的设计和维护成本。

Q:go-review-lead Skill 应该让主会话用什么模型运行?

Sonnet 足够。分诊(模式匹配)和汇总(合并排序)不需要深度推理。用 Opus 做分诊是过度配置。垂直审查 Agent 用 Sonnet,特别复杂的架构级审查可以考虑 Opus。

Q:Lead 应该配置为 Skill 还是 .claude/agents/ 中的 Agent 文件?

必须是 Skill,不能是 agent 定义文件。原因是平台的硬约束。

Claude Code 官方文档在多处明确规定:子代理不能生成子代理("Subagents cannot spawn other subagents. If your workflow requires nested delegation, use Skills or chain subagents from the main conversation.")。其后果是:

调用方式 Lead 运行在 能否派发 Worker 实际结果
主会话加载 go-review-lead Skill 主对话(非子代理) ✅ 可以 7 个 Worker 并行运行
主会话启动 go-review-lead Agent 子代理 ❌ 不可以 Agent 工具调用被平台忽略,并行步骤跳过

正确的部署方式:不要在 .claude/agents/ 中创建 go-review-lead.md。主对话通过 Skill 加载 go-review-lead 后,由主对话本身执行分诊和 Worker 派发。7 个垂直审查 Agent(.claude/agents/go-*-reviewer.md)保留为 agent 定义,它们是被主对话派发的 Worker,自身不再派发子任务。

Q:Grep-Gated 的 grep MISS 会不会漏掉真实问题?

会,这是协议的已知权衡。grep MISS 代表 pattern 未命中,自动标记 NOT FOUND 并跳过语义分析。因此 pattern 的设计至关重要——宽门槛原则(宁多 HIT 不漏 MISS)和复合 pattern(有 A 且无 B)是两个核心设计手段,用于最大化覆盖率同时保持 pattern 的稳定性。

18.8 降级与错误处理

Multi-Agent 架构引入了额外的故障点——单 Skill 只会整体失败,而 7 个 Worker Agent 并行时,任何一个都可能出现超时、Skill 加载失败或返回格式错误。

故障类型 主会话处理方式
sub-agent 超时(> 120s) 标记该维度为 SKIPPED (timeout),继续汇总其他维度结果
sub-agent 返回空 Findings 正常,视为该维度无发现,在 Execution Status 中记录 0 findings
sub-agent 返回格式错误 标记为 PARSE_ERROR,在 Residual Risk 中注明"X 维度未完成,建议单独重跑"
Skill 文件缺失(加载失败) sub-agent 自行报告错误,主会话在 Execution Status 中注明

核心原则:部分成功优于全量失败。 主会话应始终输出当前已有的发现,而不是因为一个 Agent 失败就放弃整份报告。

如果关键维度(如 Concurrency)的 Agent 失败,在报告尾部加注:

[Residual Risk] go-concurrency-reviewer did not complete (timeout).
Concurrency dimension not covered in this review — recommend re-running
with: "使用 go-concurrency-reviewer agent 审查 <file>"

18.9 成本模型与适用范围

适用范围

场景 推荐架构 原因
单维度 Skill,checklist < 15 条 单 Skill 无注意力竞争,无需多 Agent 开销
多维度 Skill,已观察到漏报 Multi-Agent + 垂直 Skill 跨维度注意力竞争,需要隔离上下文
高频轻量审查(如变量名修改) 分诊后按需派发(2–3 Agent) 成本约 $0.02,远低于全量启动
关键路径全量审查 全量 7 Agent 成本约 $0.10–0.16,质量最优

成本结构

  • 分诊成本(Level 1 grep + Level 2 Haiku):约 $0.001/次,可忽略
  • 每个 Worker Agent(Haiku,单文件):约 $0.005–0.015
  • 主会话汇总(Sonnet):约 $0.01–0.02
  • 典型完整审查(5 个 Worker):约 $0.05–0.10

适用范围的边界

本文的结论强度应限定在以下范围内:Go 代码审查场景;以 getBatchUser(并发/goroutine 类)为主案例,以 ListLayout(安全/ORM/设计类)为跨域追加案例;当前 7 个垂直 Skill + go-review-lead Skill(主会话编排)实现;当前 Grep-Gated checklist 覆盖率(65/86,约 75%)。

尚未充分验证的场景包括:其他编程语言、超大 diff、跨文件复杂依赖、不同模型版本下的稳定性,以及多案例上的误报率和漏报率统计曲线。

如果 Skill 只有单个维度且 checklist < 15 条,不必升级为 Multi-Agent 架构——单 Agent 在上下文负担可控时,是更简单、更低成本的选择。架构升级的触发条件是可观察的漏报症状,而不是维度数量的绝对阈值。


本篇关键结论回顾:注意力稀释是 LLM 在单上下文多维度场景下的结构性限制,提示词强化只能缓解,无法根本解决。Skill-Agent 协作架构通过两个正交手段解决这一问题:Multi-Agent(Orchestrator-Workers 模式)消除跨维度注意力竞争;Grep-Gated 协议将 75% 的检查项转为规则驱动的预扫描,降低维度内的概率性遗漏。两者结合,在 go-code-reviewer 的基准案例中实现了 13/13 的完整捕获。五种编排模式(§17.4)为不同任务结构提供了系统性的架构选型参考,Orchestrator-Workers 只是其中最适合"内容驱动、动态子任务"场景的一种。