oh-my-pi 编码代理中的 scout 侦察子代理:只读代码库快速调研与压缩交接协议详解
【免费下载链接】oh-my-pi⌥ Coding agent with the IDE wired in项目地址: https://gitcode.com/GitHub_Trending/oh/oh-my-pi
导读
scout是 oh-my-pi 编码代理(coding-agent)内置的一款"侦察兵"子代理,专为探索性代码库研究、快速代码分析和广度模式搜索而设计。它以只读方式高速扫描仓库,并把调研结果压缩成结构化、可供其他 Agent 直接消费的交接信息,避免下游代理重新通读整个代码库。本文以 scout 代理提示词 为骨架,逐字段拆解其 frontmatter 配置、JSON 输出契约、执行守则,并结合 agents.ts、executor.ts、spawn-policy.ts 等源码说明其实际生效机制,帮助读者理解并复用这一"低成本、高保真、可交接"的调研模式。
一、scout 的定位:为什么要一个只读侦察子代理
在一个由多个子代理协作的编码代理系统中,最昂贵的往往是大模型重新读取代码。当主代理需要了解某个模块的现状时,如果每次都完整通读整个仓库,上下文窗口与 token 成本都会快速失控。
scout 的出现正是为了解决这个问题。从 scout.md 的 frontmatter 可以看到它的自我定位:
description: MUST be used for exploratory codebase research, rapid code analysis, and broad pattern searches. Fast read-only scout returning compressed context for handoff.三个关键词构成了 scout 的全部使命:
- 探索性研究:面对不熟悉的仓库,先派 scout 摸清结构;
- 快速代码分析:秒级定位关键文件、类型、函数与依赖关系;
- 广度模式搜索:大量使用 grep/glob 做模式匹配,而不是逐个文件精读。
它产出的不是"我看了什么"的过程记录,而是"你接下来该知道什么"的压缩上下文(compressed context),供后续 agent 直接消费。
二、frontmatter 配置逐字段解析
scout 的完整配置以 YAML frontmatter 形式写在文档头部,系统通过 frontmatter 模板 将name、description、model、thinkingLevel等字段渲染成标准代理定义,再由 parseAgent 解析并缓存。各字段含义如下:
| 字段 | 值 | 作用 |
|---|---|---|
name | scout | 代理唯一标识,供spawns策略与任务分发引用 |
description | 见上 | 说明适用场景,作为主代理选择子代理的决策依据 |
tools | read, grep, glob, web_search | 只读工具集:精确读文件、正则搜索、glob 找文件、联网检索 |
model | @smol | 使用轻量小模型运行,保证低成本与高速度 |
thinking-level | medium | 中等思考强度,介于"快速查找"与"深度推演"之间 |
read-summarize | false | 关闭读取摘要管线,read 返回原始内容而非压缩摘要 |
2.1 工具集:四件套支撑"广度优先"
scout 只被授予四个工具,全部是只读的:
- read:读取文件关键段落;
- grep:正则搜索,做广度模式匹配;
- glob:按文件名模式定位候选文件;
- web_search:必要时检索外部公开资料辅助理解。
注意这里没有 bash、write、edit 等任何可能改变系统状态的工具,与文档<critical>段的只读约束互相印证。从 executor.ts 可以看到,当agent.readSummarize === false时,执行器会向 read 工具注入read.summarize.enabled: false配置,即 scout 读到的是文件的真实原文,而不是经过摘要压缩的内容——这对需要产出精确path:line引用的侦察任务至关重要。
2.2 model: "@smol" 与 thinking-level: medium
@smol是项目内置的轻量模型档位。在 agents.ts 中,另一个使用@smol的内置代理sonic被描述为"strictly mechanical updates or data collection",可见这一档位面向机械、批量、低推理需求的任务。scout 同样受益于小模型的低成本,但通过thinking-level: medium保留了一定的分析能力,使其既能秒级完成搜索,又足以梳理架构关系。
2.3 请求预算:100 次软上限
在 executor.ts 的SOFT_REQUEST_BUDGET中,scout 与 sonic 均被分配了 100 次请求的软预算(默认档位为 200)。也就是说 scout 一轮运行中最多驱动约 100 次 assistant 请求;逼近预算时会注入收尾提示,超支时会被强制收敛到一次yield,确保部分发现也能以真实报告的形式回流。这是对"快速侦察"定位的执行层保障。
三、输出协议:一份可交接的压缩上下文
scout 的产出不是自由文本,而是一份结构化 JSON。frontmatter 中通过output.properties定义了严格的 schema,这是它与普通"读代码然后写总结"最本质的区别。
3.1 必填字段
summary: type: string description: Brief summary of findings and conclusions files: type: array elements: path: string # 项目相对路径,可带 :12-34 行号区间 description: string # 该文件相关内容 architecture: type: string description: Brief explanation of how pieces connect- summary:调研结论与判断的简短总结,供下游代理快速决策;
- files:关键文件清单,每项包含项目相对路径(可附带
:12-34这样的行号区间锚点)和该文件承载的内容说明。这实际上是一份"可信索引",让下游代理可以精确跳转,无需重新定位; - architecture:各部件如何连接的整体解释,回答"这段代码是怎么串起来的"。
3.2 可选字段 report
report: type: string description: The complete deliverable when the task asks for a report, table, enumeration, or per-item audit — full markdown at the depth requested当任务要求报告、表格、枚举或逐项审计时,完整交付物放在report字段中,以所请求深度的完整 Markdown 呈现(含表格、path:line锚点、函数签名、代码摘录)。文档明确强调:report绝不是 summary 的重复,summary已经承担了概要职责;只有快速查询时才允许省略report。
这个设计把"概要"与"完整交付物"分离:summary 始终简短以便交接,report 按需全量以完成任务,两者互不挤占上下文。
四、执行守则:directives / thoroughness / procedure / critical
scout 文档正文给出了四条行为守则,共同定义了它的工作方式。
4.1 directives:搜索优先、并行执行、空结果不放弃
- You MUST use tools for broad pattern matching / code search as much as possible. - You SHOULD invoke tools in parallel—this is a short investigation, and you are supposed to finish in a few seconds. - If a search returns empty results, you MUST try at least one alternate strategy (different pattern, broader path, or AST search) before concluding the target doesn't exist.三条硬性要求:
- 能搜索就不精读:尽量用 grep/glob 做广度匹配,而不是盲目打开文件;
- 必须并行调用工具:这是一次"几秒钟内结束"的短调研,串行等待不可接受;
- 空结果必须换策略:换不同的正则、扩大路径范围,或改用 AST 搜索,至少尝试一种替代方案后才能下"目标不存在"的结论——避免假阴性误报。
4.2 thoroughness:从任务推断深度,默认 medium
- Quick: Targeted lookups, key files only - Medium: Follow imports, read critical sections - Thorough: Trace all dependencies, check tests/types.scout 不预设固定深度,而是从任务推断:
- Quick:只做定点查找,看关键文件;
- Medium(默认):跟进 import,读取关键段落;
- Thorough:追踪全部依赖,并检查测试与类型定义。
4.3 procedure:标准四步流程
1. Locate relevant code using tools. 2. Read key sections. NEVER read full files unless they're tiny. 3. Identify types/interfaces/key functions. 4. Note dependencies between files.四步可归纳为"定位 → 精读 → 提炼 → 关联":先用工具定位,再只读关键片段(除非文件很小,绝不整文件通读,这也是 token 控制的核心),然后提炼类型、接口、关键函数,最后记录文件间依赖。
4.4 critical:绝对只读 + 坚持到底
You MUST operate as read-only. You NEVER write, edit, or modify files, nor execute any state-changing commands, via git, build system, package manager, etc. You MUST keep going until complete.两条底线:
- 严格只读:绝不写、编辑、修改任何文件,也不通过 git、构建系统、包管理器等执行任何改变状态的命令;
- 坚持完成:除非任务被明确终止,否则必须运行到产出完整结果。
从源码看,这一约束是双重保险:一方面工具清单里根本没有写类工具;另一方面 executor.ts 的注释还揭示了一个细节——所有只读 scout 都不具备hub工具,因而永远无法接收 hub 分发的信息,从机制上杜绝了只读代理参与信息分发链路。
五、源码视角:scout 在编码代理中的完整调用链
scout 并非独立文档,它被编译期嵌入并在会话运行时按需拉起。其完整生命周期如下。
5.1 编译期嵌入与解析
在 agents.ts 中,scout.md 与其他内置代理(reviewer、security-reviewer、task 等)一起通过 Bun 的import ... with { type: "text" }在构建期嵌入:
{ fileName: "scout.md", template: scoutMd },加载时由buildAgentContent将正文渲染、经 frontmatter 模板组装,再由parseAgent解析 frontmatter 生成AgentDefinition,结果缓存于bundledAgentsCache,后续通过getBundledAgent("scout")/getBundledAgentsMap()按名取用。
5.2 会话层的可用性判定
在 agent-session.ts 中,会话通过#isScoutAvailable()判断 scout 是否可派发:
return this.#scoutAllowedBySpawnPolicy && !disabledAgents?.includes("scout");即 scout 可用需要同时满足:会话的 spawn 策略允许(scoutAllowedBySpawnPolicy,可在配置中通过scoutAllowedBySpawnPolicy项设定),且未被task.disabledAgents禁用。该可用性状态还会通过scoutAvailable字段注入系统提示词,让主代理知道自己能否派 scout 出去。
5.3 spawn 策略的解析
spawn-policy.ts 提供了isScoutSpawnable作为独立判定函数:先检查disabledAgents是否包含 scout,再通过resolveSpawnPolicy解析父代理的spawns声明——允许列表为空列表(未启用)或不允许 scout 时返回 false,允许列表包含 scout 或完全不受限(*)时返回 true。
典型的允许场景见 reviewer.md:reviewer 的 frontmatter 声明spawns: scout,即代码评审代理可以派出 scout 先行侦察相关代码,再基于侦察结果进行评审——这是"侦察 → 评审"协作流水线的直接证据。
5.4 运行期的预算与 read 行为
运行期由 executor.ts 负责约束:scout 请求软预算为 100 次(见上文 2.3 节);同时因其read-summarize: false,执行器为其注入read.summarize.enabled: false,保证侦察读取的是原文而非压缩摘要。
六、与其他内置代理的分工协作
在 agents.ts 的EMBEDDED_AGENT_DEFS中,scout 与以下代理并列内置:
| 代理 | 定位 | 与 scout 的关系 |
|---|---|---|
scout | 只读快速侦察,输出压缩交接信息 | 本文主角 |
reviewer | 代码评审 | spawns: scout,评审前先派 scout 侦察 |
security-reviewer | 安全评审 | 可复用 scout 的只读侦察结果 |
task | 通用多步任务子代理,spawns: "*"、model: "@task" | 可自由派发 scout 做前置调研 |
sonic | 低推理机械更新/数据收集,model: "@smol" | 与 scout 共享轻量模型档位 |
从 spawn-policy.ts 看,会话默认的 spawn 代理是task(DEFAULT_SPAWN_AGENT),而 scout 通常作为 task/reviewer 的下游侦察员被派发。一个典型的多代理流水线是:task 规划 → scout 侦察压缩上下文 → 主代理基于 files/architecture 精确跳转 → 针对性编辑,整个过程 scout 只读且不产生中间垃圾信息。
七、扩展思路:如何自定义一个"侦察型"子代理
理解了 scout 的机制后,读者可以在自己的编码代理中复刻这一模式。核心配方即 scout 文档呈现的五要素:
- frontmatter 声明只读工具集:
tools: read, grep, glob(可按需加入 web_search); - 选择轻量模型与中等思考:
model: "@smol"+thinking-level: medium; - 关闭摘要管线保真:
read-summarize: false,确保读到原文; - 定义结构化输出契约:用
output.properties固定summary/files(带path:line锚点)/architecture,并按需开放report; - 固化执行守则:搜索优先、并行调用、空结果换策略、按任务推断 thoroughness、严格只读。
若要注册自定义代理,可参考 agents.ts 中EMBEDDED_AGENT_DEFS的写法——每个条目由fileName、可选frontmatter(经 frontmatter.md 模板渲染)与template(正文)组成。
结语
scout 是 oh-my-pi 编码代理中"以最小成本换取最大信息增量"的典型设计:轻量模型、只读工具集、关闭摘要的原文读取、结构化 JSON 输出,再叠加 100 次请求软预算与强制收尾机制,使它能在几秒内完成一次仓库侦察并产出一份可供下游代理直接消费的"压缩交接上下文"。无论是想理解大型代码库的协作式调研架构,还是想在自己的 Agent 系统中复刻"侦察-交接-执行"流水线,scout.md 连同 agents.ts、executor.ts、spawn-policy.ts 都是值得精读的参考实现。
【免费下载链接】oh-my-pi⌥ Coding agent with the IDE wired in项目地址: https://gitcode.com/GitHub_Trending/oh/oh-my-pi
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考