首页
/ caveman 中的 cavecrew-investigator:一个只读代码定位子代理及其压缩输出契约

caveman 中的 cavecrew-investigator:一个只读代码定位子代理及其压缩输出契约

2026-09-03 16:10:03作者:明树来

本文以 agents/cavecrew-investigator.md 这一子代理定义文件为核心,完整拆解 caveman 项目中 cavecrew-investigator 的定位职责、只读工具边界、path:line — symbol — note 压缩输出契约与拒绝策略,并结合 skills/cavecrew/SKILL.md 决策指南、src/hooks/cavecrew-model-overrides.js 模型覆盖实现及其测试,说明该子代理如何在 Claude Code 等宿主代理中落地、如何被调用与如何配置模型。读完后你可以直接复用这套"定位—汇报—停止"的子代理契约设计,理解压缩工具结果对主上下文预算的节省机制。

它是什么:cavecrew 三人组中的"侦察兵"

caveman 是一套主打 token 节省的 Claude Code skill 体系,其中 cavecrew 由三个输出经过"原始人式压缩"的子代理组成。仓库根目录 CLAUDE.md 的模块索引对它的定义是:

agents/cavecrew-investigator.md — Read-only locator subagent (haiku). Output contract: path:line — symbol — note.

它与另外两位成员的分工(见 skills/cavecrew/SKILL.md):

子代理 职责 典型场景
cavecrew-investigator 只读代码定位 "X 在哪里定义 / 谁调用了 Y / 列出 Z 的所有使用"
cavecrew-builder 1–2 个文件的手术式编辑,3+ 文件直接拒绝 范围明确的 typo 修复、单函数重写
cavecrew-reviewer 单行式、带严重度标记的 diff/文件审查 "review 这个 PR / 我的 diff"

它与 Anthropic 的默认 Explore 代理做的是同一类工作,区别在于返回给主线程的工具结果是被压缩过的SKILL.md 中给出的量化对比是:一次普通 Explore 可能返回 2k tokens 的散文,而同样结论从 cavecrew-investigator 返回约 700 tokens——子代理的工具结果会被原样注入主上下文,这个差距在单次会话中委派 20 次时就是"上下文耗尽"与"完成任务"的区别。

定义文件逐行解读:frontmatter 决定权限与模型

cavecrew-investigator 的完整定义见 agents/cavecrew-investigator.md(插件分发副本在 plugins/caveman/agents/cavecrew-investigator.md,两份内容一致)。frontmatter 四项各有明确含义:

name: cavecrew-investigator
description: >
  Read-only code locator. Returns file:line table for "where is X defined",
  "what calls Y", "list all uses of Z", "map this directory". Output is
  caveman-compressed so the main thread eats ~60% fewer tokens than
  vanilla Explore. Refuses to suggest fixes.
tools: [Read, Grep, Glob, Bash]
model: haiku
  • description:这段描述本身也是"原始人压缩风格"的范例——它同时声明了输入问题类型(where/what calls/list uses/map directory)、输出特性(caveman 压缩,主线程省 ~60% token)和边界(Refuses to suggest fixes)。宿主代理在做委派决策时,正是靠这段描述判断该任务是否适合派给它。
  • tools: [Read, Grep, Glob, Bash]:注意这里有 Bash,比 docs/technical/exploration-and-delegation.md 中描述的 fastcontext 探索器(仅 Read/Glob/Grep,"cannot edit files or run commands")多了一项。后文"工具策略"一节解释这项 Bash 被限定在哪些命令上。
  • model: haiku:定位是纯检索任务,不需要最强的推理模型,默认钉在 haiku 上以进一步压低单次委派成本。这个默认值可被环境变量覆盖,见后文"模型覆盖"一节。

正文第一行是全局语体指令:"Caveman-ultra. Drop articles/filler/hedging. Code/symbols/paths exact, backticked. Lead with answer."——省掉冠词、填充词与含糊措辞,但代码、符号、路径必须精确且加反引号,答案先行。这是压缩输出契约能成立的前提:省的是自然语言外壳,不是事实精度。

职责边界:Locate. Report. Stop.

文档中 "Job" 一节只有一句话:Locate. Report. Stop. Never edit, never propose fix.(定位、汇报、停止。绝不编辑,绝不提出修复方案。)

这条边界有两层工程意义:

  1. 输出纯净性:子代理返回的内容直接进主上下文。如果定位结果里混入"我建议在 X 处添加防御性判空"之类的修复建议,主线程会把这些 prose 一并吞掉,压缩收益被稀释。只给证据,不给意见。
  2. 与 builder 的职责切分:需要动手时,investigator 不是"顺便修一下",而是触发拒绝语把任务交出去(见下节)。这与 SKILL.md 的反模式提醒一致:不要对已知文件的编辑任务先派 investigator 再派 builder,也不要指望 investigator 对 5 文件重构给出可行方案——builder 会直接回 too-big.,浪费一轮。

输出契约:主线程可以依赖的格式

这是整个定义文件的核心。"Output" 一节规定了四套规则,全部以可解析的结构化形式表达:

<path:line> — `<symbol>` — <≤6 word note>
<path:line> — `<symbol>` — <≤6 word note>
  1. 行格式:每行是 路径:行号 — 反引号包裹的符号 — 不超过 6 个词的注释SKILL.md 强调这个格式"Always file-path-first, line-number-attached, backticked symbols. Safe to grep with path:\d+"——即主线程或自动化脚本可以直接用 path:\d+ 这样的正则从结果中抽取引用,这是"压缩但不失机器可读"的关键设计。
  2. 分组头:结果行 ≥3 行时,用一个单词的分组头归类,限定在 Defs: / Refs: / Callers: / Tests: / Imports: / Sites: 六个词内。命中仅 1 行时不加头。
  3. 零命中:统一返回 No match.,禁止猜测或编造位置(这与 fastcontext 探索器"无结果时必须回 no relevant locations found 而非虚构引用"的证据规则同源,见 exploration-and-delegation.md 的 Evidence rules 一节)。
  4. 总计行:末行给出计数,如 2 defs, 5 refs.;0 或 1 时省略。

文档内置示例:一次完整的定位汇报

定义文件末尾给了一个 Q/A 示例,问题用原始人体:"where symlink-safe flag write?"(符号链接安全的标志位写操作在哪?),返回:

Defs:
- hooks/caveman-config.js:81 — `safeWriteFlag` — atomic write w/ O_NOFOLLOW
- hooks/caveman-config.js:160 — `readFlag` — paired reader
Callers:
- hooks/caveman-mode-tracker.js:33,87
- hooks/caveman-activate.js:40
Tests:
- tests/test_symlink_flag.js — 12 cases
2 defs, 3 callers, 1 test file.

这个示例同时展示了契约的全部要素:多行时按 Defs/Callers/Tests 分组、同行可并多个行号(:33,87)、note 控制在 6 词内("atomic write w/ O_NOFOLLOW")、末行总计。值得注意的是示例中引用的 tests/test_symlink_flag.js 在当前仓库确实存在(tests/test_symlink_flag.js),说明示例取材自本仓库真实功能;但示例中的 hooks/ 前缀与行号是示意性路径(本仓库对应实现位于 src/hooks/ 下),引用时应以实际检索结果为准。

工具策略:Bash 只用于"更快的检索"

"Tools" 一节把四个工具的分工压成一句话:

Grep for symbols/strings. Glob for paths. Read only specific ranges. Bash for git log -S/git grep/find when faster.

拆开看:

  • Grep 负责符号与字符串匹配——"X 在哪定义"、"谁引用 Y"的第一手段;
  • Glob 负责路径模式匹配——"map this directory" 类问题;
  • Read 限定"only specific ranges":只读具体行区间,避免把整个文件灌进子代理上下文(子代理上下文同样有预算,虽然最终不占主线程);
  • Bash 白名单化:只允许 git log -S(pickaxe 搜索符号引入/删除的提交)、git grepfind 这类比逐文件 Grep 更快的检索命令。这与 cavecrew-reviewer 的同类约束(Bash only for git diff/git log -p/git show. No mutating commands.)风格一致:Bash 权限存在,但语义上被围栏在"只读检索"内。

从源码结构看,这类约束是靠 prompt 围栏而非系统权限实现的——tools frontmatter 中的 Bash 是宿主代理(Claude Code)侧的真实权限,围栏是否被遵守依赖模型遵循指令;这也是 SKILL.md 提醒"Isolation is mechanism, not outcome guarantee"(隔离是机制,不是结果保证)的原因。

拒绝策略与 Auto-clarity

"Refusals" 一节规定了两条固定拒绝语:

被问到 返回
让它修 bug Read-only. Spawn cavecrew-builder.
让它做设计 Read-only. Spawn cavecrew-builder or use main thread.

拒绝语本身就是可被主线程解析的结构化信号(builder 的终态行如 too-big. / regressed. 同理),主线程拿到后可以直接路由给 cavecrew-builder 或留在主线处理,不需要再花一轮澄清。

"Auto-clarity" 一节是三条 cavecrew 共享的安全阀:

Security warnings, destructive ops → write normal English. Resume after.

遇到安全警告或破坏性操作时,临时切回正常英文措辞(因为碎片化原始人文体在安全语境下可能被误读),说完再恢复压缩风格。SKILL.md 将其泛化为三个触发条件:安全警告、不可逆操作确认、以及"片段歧义可能被误读"的任何输出。

落地实现:CAVECREW_INVESTIGATOR_MODEL 覆盖机制

frontmatter 里 model: haiku 只是默认值。skills/cavecrew/README.md 说明:investigator 与 reviewer 默认钉在 haiku,builder 没有 model: 行(用 API 会话默认模型);启动宿主代理前设置环境变量即可逐代理覆盖,取值就是任何 Claude Code agent frontmatter 里能用的模型名(haikusonnetopus):

环境变量 作用对象
CAVECREW_INVESTIGATOR_MODEL cavecrew-investigator
CAVECREW_BUILDER_MODEL cavecrew-builder
CAVECREW_REVIEWER_MODEL cavecrew-reviewer

这个覆盖不是靠重发布 agent 文件,而是靠 SessionStart 钩子现场打补丁。实现见 src/hooks/cavecrew-model-overrides.js

  • AGENT_ENV_MAPCAVECREW_INVESTIGATOR_MODEL 映射到 agents/cavecrew-investigator.md(第 26 行),由 caveman-activate.js 在 SessionStart 早期调用;
  • 核心函数 patchFrontmatterModel(content, modelValue) 只做 frontmatter 内的 model: 行操作:已有 model: 行则原位替换,没有则在 tools: 行后(或收尾 --- 前)插入;同时保留文件原始行尾(CRLF/LF),避免在 Windows 上制造混合行尾;
  • 安全护栏:空值/含控制字符的值 → 静默 no-op;文件不存在或布局不符 → 静默 no-op;insideGitWorkTree() 会向上最多 64 层找 .git,若插件根目录位于 git 工作树内(即这是源码检出而非安装副本)则整体跳过——否则每次开会话都会改写被跟踪的 agents/*.md、弄脏工作区;
  • 所有文件系统错误静默失败,"never block session start"。补丁持久化到插件更新或重装为止,且只改 model: 一行,prompt 正文保持原样,后续上游更新仍可正常生效。

测试覆盖见 tests/test_cavecrew_model_overrides.js,用 INVESTIGATOR_FM 构造真实 frontmatter 片段,验证如"investigator 的 model: haiku 被替换为 opus 时,旧行消失、正文不丢失"等用例。

安装与分发:它装到哪里

从源码结构看,这份 agent 文件有三个分发通道:

  1. Claude Code 插件:插件市场以仓库根为 source(见 CLAUDE.md 中"skills/ is auto-discovered wholesale"一节),agents/cavecrew-investigator.md 随插件整体发现,安装后落在 ~/.claude 配置目录下,模型覆盖钩子也只在这一布局中生效;
  2. opencodebin/install.jsOPENCODE_AGENT_FILES 列表(第 699 行)包含 cavecrew-investigator.md 等三个文件,安装时会拷贝到 opencode 的 agents 目录,skills/cavecrew 目录同列;
  3. 插件包内副本plugins/caveman/agents/cavecrew-investigator.md 与源文件内容一致,随 cavecrew skill 一起打包(OPENCODE_SKILL_DIRS/HERMES_SKILL_DIRS 均含 cavecrew)。

与其他代理的协作模式

investigator 很少单独工作。SKILL.md 的 Chaining patterns 给出三种编排:

  • Locate → fix → verify(最常见):investigator 返回站点列表 → 主线程挑 1–2 个站点把精确 path:line 交给 builder → reviewer 审计 diff;
  • Parallel scout(检索面很宽时):一条消息里并行 spawn 2–3 个 investigator,从不同角度(defs / callers / tests)分头检索,主线程聚合;
  • Single-shot edit(位置已知时):跳过 investigator,直接给 builder 精确 path:line

对应的反模式清单同样值得记住:不知道文件就别直接派 builder(否则主线程要耗 token 传递上下文);不要拿 investigator→builder 链路去做多文件重构;不要在 investigator 输出上期待散文——它是结构化、乃至"简短到近乎隐晦"的,人类要直接读时请自己转述。

小结

cavecrew-investigator 是一个以"输出契约"为产品形态的子代理:frontmatter 声明只读工具面与 haiku 默认模型,正文用 12 行左右的原始人文体锁定"定位—汇报—停止"的行为边界,四套输出规则(行格式、分组头、零命中、总计行)保证结果既能被 LLM 主线程低成本消费、也能被 path:\d+ 正则机器解析;拒绝语与 auto-clarity 则分别处理"越界请求"和"安全表达"两类边缘情形。配合 CAVECREW_INVESTIGATOR_MODEL 的 frontmatter 热补丁机制与插件/opencode 双通道分发,它构成了一套可复制的模式:当你想给任何 LLM 宿主代理加一个"低 token 侦察兵"时,可以照这份文件的骨架——权限面、语体指令、输出契约、拒绝语、安全阀——逐一落位。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.12 K
2.72 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
528
588
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
906
1.83 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
854
1.34 K
docsdocs
暂无描述
Markdown
891
5.78 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.53 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.34 K
1.45 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
987
506
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
540
384