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  
            }
            userList = append(userList, user)  
        }()
    }
    return userList, nil  
}

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 的内部研究对这一现象提供了量化支撑:在 BrowseComp 浏览能力评测中,token 使用量单独解释了 80% 的性能差异(三个因素合计解释 95%,另外 15% 由工具调用次数和模型选择贡献),核心原因是每个 Agent 在干净的上下文窗口中执行,token 使用效率更高——这正是上下文污染(Context Rot)会拉低单 Agent 性能的直接证据。(来源:How we built our multi-agent research system,Anthropic Engineering Blog,2025-06-13)

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

缓解措施 效果 局限
在 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 研究系统实测(来源:How we built our multi-agent research system,Anthropic Engineering Blog,2025-06-13): - Claude Opus 4(Lead)+ Claude Sonnet 4(Workers)的多 Agent 系统,在内部研究评测中比单 Agent Opus 4 性能高出 90.2% - 在 BrowseComp 评测中,token 使用量单独解释了 80% 的性能差异——关键不在于模型更强,而在于每个 Agent 在干净的上下文中专注完成单一任务

AgentCoder 学术研究(来源:https://arxiv.org/pdf/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 编排模式选型:为什么是 Orchestrator-Workers

明确了 Multi-Agent 的优势之后,下一个问题是:选哪种编排模式?

Anthropic 定义了五种基础编排模式。逐一评估它们对 Go 代码审查场景的适用性:

模式 核心机制 对本场景的评估 适用?
模式一:Prompt Chaining 线性步骤序列,上一步输出是下一步输入 安全/并发/性能各维度之间没有依赖关系,不是顺序问题
模式二:Routing 分类输入,路由到某一个专门处理器 一次审查需要同时覆盖多个维度,而不是选择其中一个
模式三:Parallelization 多路并行,子任务预先固定 接近需求,但子任务固定,每次必须跑所有分支,无法按内容裁剪
模式四:Orchestrator-Workers 中央编排者动态分解任务,按需调度 Workers 在当前场景下最匹配——审查维度随代码内容动态决定
模式五:Evaluator-Optimizer 生成→评估→改进的迭代循环 代码审查是诊断任务,不是迭代生成任务

模式三与模式四的关键区别是本次选型最需要厘清的点。两者都支持并行,差异在于子任务的来源:

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

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

对 Go 代码审查而言,需要派发哪些 Agent 取决于被审查代码的内容

  • 代码只改了变量名 → 只需 Quality + Logic(2 个 Agent)
  • 代码引入了 go func + sync.WaitGroup → 还需 Concurrency + Error(4 个)
  • 代码包含 make([]*T, 0) + 批量函数名 → 还需 Performance(5 个)
  • 代码有 _test.go 变更 → 还需 Test(6 个)

这种"内容驱动的维度选择"无法在设计时预知,必须由编排者在运行时根据输入动态决策——这正是 Anthropic 对 Orchestrator-Workers 适用场景的定义:"无法提前预测需要哪些子任务,需要 Orchestrator 根据输入动态决策"

如果强行用 Parallelization,代价是每次审查都启动所有 7 个 Agent,一次 5 行变量名修改也要承担全量 Agent 的 token 消耗和延迟,性价比严重失衡。分诊本身就是 Orchestrator 最核心的价值。


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

选型已定,进入实施阶段。 §17 识别了注意力稀释问题,§17.3 确立了 Multi-Agent 方向,§17.4 在五种模式中选出了 Orchestrator-Workers。本章以 go-code-reviewer → 7-Agent 编排体系为贯通案例,回答下一个问题:如何把选型落地为一套可运行、可验证、可复用的架构? 所涉及的设计原则(垂直拆分、主会话负责编排、按需分诊、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 通过 skills: 字段在启动时自动加载领域知识。Agent 定义文件是轻量的(几十行提示词),审查知识保存在独立的 Skill 文件中,Agent 通过 frontmatter 中的 skills: 字段声明所依赖的 Skill——平台在 Agent 启动时自动注入完整 Skill 内容,无需运行时手动调用 Skill() 工具。不存在内容重复,Skill 文件可被多个 Agent 复用。

原则四(平台约束 + 工程决策):编排逻辑必须以 Skill 形式封装,在主会话执行

结论先行,推理如下:

平台约束:subagent 不能生成 subagent
  → 编排必须在主会话执行
  → 选项 A:每次用临时 prompt 编排?
      → 否:流程太复杂 + 不可复用
  → 选项 B:封装为 Skill,主会话调用
      → 是:复杂度可控 + 标准化 + 可复用
      → Skill 是唯一合适的载体

两层决策各有一个不可绕开的理由:

第一层:为什么编排不能由 subagent 执行(即不能配置为 .claude/agents/ 中的 agent 定义)? Claude Code 明确规定子代理不能生成子代理("Subagents cannot spawn other subagents")。如果把 go-review-lead 配置为 agent 定义文件,它被调用时会作为子代理运行,此时它对 Agent 工具发出的并行调用请求将被平台静默忽略——7 个垂直 Agent 退化为串行调用或根本不被派发。

第二层:排除 agent 定义后,为什么不直接在主会话用 prompt 来编排,而必须封装成 Skill? 理由有两个:

  1. 复杂度不可接受:编排流程是流水线+并行的混合模式——作用域识别→审查深度选择→编译预检→四阶段分诊→动态派发 N 个垂直 Agent 并行审查→去重汇总。把这个流程写成临时 prompt,篇幅将远超可接受范围,且极难维护。

  2. 无法复用:每次发起代码审查都要重新提供这段复杂 prompt。这是一个标准化流程,应当封装,而不是每次重写。

更深一层的洞察:把编排逻辑封装为 Skill,不只是工程上的务实决策——它正是 Skill-Agent 协作架构在本架构中的直接体现,且同时呈现在两个层次:

层次 角色 模式
宏观 主会话调用编排 Skill → Skill 派发 7 个子代理并行 → Skill 去重汇总 → 主会话展现 Skill 编排 Agents
微观 每个子代理加载自己专属的垂直审查 Skill 来执行任务 Agent 依赖 Skill

两个层次都在运行同一个 Skill-Agent 协作模式,架构在自身内部自洽:编排用的是 Skill,执行也用的是 Skill,而连接二者的是 Agent。这不是巧合, 而是一以贯之的 Skill-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 + 去重 + 按严重度排序
                         最终报告

实证验证:简化方案为何不可行

架构 C(7-Agent + 垂直 Skill)在直觉上可能显得过重——毕竟最好的架构不是最复杂的,而是最简单、最合适的。在最终确定该方案之前,我们实验性地尝试了两种更简单的替代路径,数据给出了否定答案。

实验一:单 Agent + Grep-Gated 协议

假设:在 go-code-reviewer 单 Agent 上下文中引入 Grep-Gated 执行协议(88 个 checklist 项,其中 66 个 grep-gated)+ 编译预检,就能机械性地消除注意力稀释,不需要 Multi-Agent 的上下文隔离。

结果:检出率 62%,与原始单 Agent 完全持平。Grep-Gated 协议有效减少了模型随意跳过机械检测项的情况,但没有解决核心问题——当上下文中同时存在多个维度的 checklist 时,High 级别发现仍会在语义分析阶段系统性地压制 Medium 级别发现。

实验二:3-Agent 精简编排

假设:Security、Concurrency、Error 三个维度在业务上高度关联,可以合并到同一子代理上下文中处理,在降低 token 成本的同时保持足够的检出率。

将 7-Agent 拆分为 3 个子代理:Security+Concurrency+Error 合并为一个,Performance+Quality 合并为一个,Logic+Test 合并为一个。

结果:检出率降至 69%,漏掉 4/13 个问题——4 个 High 级别的并发 bug 在合并上下文中压制了 Medium 级别的 Nil *User 错误,与最初单 Agent 里 High 并发压制 Medium 性能问题的机制完全相同。业务上"关联"的维度,在注意力竞争上与不相关的维度没有本质区别。

数据汇总

方案 检出率 重复率 Token 成本
原始单 Agent 8/13 (62%) 0% ~$0.03
单 Agent + Grep-Gated 8/13 (62%) 0% ~$0.03
3-Agent 精简编排 9/13 (69%) ~15% ~$0.05
7-Agent 优化(推荐方案) 15/15 (100%) 31.6% ~$0.08

核心机制

两次实验共同揭示了一个反直觉的规律:注意力稀释的驱动因素是严重度差异,而非主题相关性。只要一个上下文中同时存在 High 和 Medium 级别的发现,High 就会在语义分析阶段系统性地压制 Medium——无论这两个发现属于哪个业务维度。

由此得出:每个维度独立一个上下文,是消除注意力稀释的最小充分条件。少一个维度的隔离就会复现压制机制,漏报随之出现。

关于表中数字的说明

  • 15/15 与 §18.5 中的 13/13 不矛盾:13 是进入第三轮验证时基于前两轮已知问题集的"预期 Findings 数";第三轮完成后,7-Agent 架构又在同一基准代码中识别出 2 个前两轮未被捕获的新 Finding(含 §18.5 末尾摘录报告中的 REV-008 和 REV-009),使基准案例的最终总数升至 15。§18.1 汇总表中的 15/15 反映的是迭代完成后的最终检出结果;§18.5 中的 13/13 反映的是第三轮进入时的预期目标。

  • 31.6% 的计算方式:将 7 个 Agent 各自上报的 Finding 条数加总(含跨 Agent 重复上报同一问题的条数),记为 N_total;去重后得到 unique Finding 数,记为 N_unique。重复率 = (N_total - N_unique) / N_total。以当前基准案例为例:7 个 Agent 合计上报约 22 条 Findings,去重后得到 15 个 unique Findings,重复率 = (22 - 15) / 22 ≈ 31.6%。3-Agent 精简方案中约 11 条上报对应 9 个 unique Findings,重复率 ≈ 18%(表中取 ~15% 为近似值)。

31.6% 的跨 Agent 重复率不是浪费——它是多维度并行覆盖必然产生的代价,也是保证正确性的结构性冗余。7-Agent 架构不是过度设计,而是恰好满足需求的最简有效方案:如无必要,勿减实体。

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 未观察到明显的维度内注意力稀释;超过后,同维度内的 High Finding 开始对 Medium 级别项产生压制(本文 §18.5 轮次 2 的维度内稀释即为一例)。15 应视为经验起点,而非已验证的通用常数——不同模型版本、代码体量和 Skill 提示词结构均可能影响这一阈值,使用时应结合实际漏报率判断是否需要进一步拆分。

如果垂直 Skill 的 checklist 已超过 15 条,建议按以下路径决策:

  1. 先观察,再拆分:触发进一步拆分的依据是可重现的漏报症状,而不是条目数量本身。先通过实际审查验证是否已出现可观察的漏报,再决定是否拆分——过早拆分会引入不必要的架构维护成本。

  2. 按严重度分层,而非按主题细分:§18.1 实证验证表明,注意力稀释的驱动因素是严重度差异,而非主题相关性。如果超量的 checklist 中包含 High 级别项,将 High/Critical 项与 Medium/Low 项拆分到两个独立 Skill,往往比继续按技术主题细分更有效。

  3. 先 grep 化,再评估拆分必要性:Grep-Gated 协议将机械检测项从模型注意力预算中解放出来,等效延迟触发"超载"临界点。如果当前 checklist 中还有可 grep 化但尚未配置 pattern 的项,先完善覆盖——可能在不拆分的情况下消除漏报。

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 7 Worker Agent + 主会话 Skill 编排 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 的新问题

完成第一阶段改造后,架构已切换为主会话 Skill 编排 + 7 个 Worker Agent。由于尚未引入 Grep-Gated 协议,且原始分诊 heuristic 仍不完整,验证暴露了两个新问题:

问题一:分诊盲区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 个预期发现均被捕获,未观察到新的遗漏。 此外,7-Agent 架构在同一代码中进一步识别出 2 个前两轮未被发现的 Finding(REV-008 无界 goroutine、REV-009 Slice 未预分配均完整上报),使基准案例的最终总捕获数升至 15——即 §18.1 汇总表中的 15/15 (100%)。

slice pre-allocation 的完整轨迹:

轮次 状态 原因
轮次 1(单 Skill) 未发现 Performance checklist 注意力被 4 个 High 挤压
轮次 2(Multi-Agent v1) 未发现 performance Agent 未被分诊;维度内注意力竞争仍影响其他 Medium 问题
轮次 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 安装步骤、前置条件、用法说明(英文)

执行过程如下所示:

Step 1 — 作用域识别 + 审查深度选择 + 编译预检:主会话读取 diff,识别变更文件类型(Go 源码 / 测试文件 / 配置),选择审查深度(Strict / Standard),并运行编译预检。编译失败直接上报为 REV-001/REV-002,不阻断后续流程。

作用域识别+深度选择+编译预检

Step 2 — 分诊 + 并行派发:go-review-lead Skill 对 diff 执行模式匹配(sync import、go funcmake([]_test.go 等),据此决定需要激活哪些维度的 Worker Agent,并在同一条响应中并行派发所有选定 Agent。

分诊和派发

Step 3 — 整合子代理审查结果:7 个 Worker Agent 并行完成各自维度的审查后,主会话收集所有返回结果,按 Finding ID 去重(跨维度重复上报的同一问题合并为一条,取较高严重度),并提取各 Agent 的 Execution Status 行。

整合子代理返回的审查结果

Step 4 — 最终审查报告:主会话按严重度排序,输出标准化 Markdown 报告,包含 Executive Summary、Finding 列表(每条带维度标签和证据)、Execution Status 矩阵、Residual Risk 说明。

审查报告

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 是唯一同时满足"支持并行"和"子任务内容驱动"两个条件的选择;同一套评估框架可直接复用于其他任务类型的模式选型。