首页
/ Files Retrieved

Files Retrieved

2026-09-04 13:52:24作者:裘晴惠Vivianne

Files Retrieved

List with exact line ranges:

  1. path/to/file.ts (lines 10-50) - Description of what's here
  2. path/to/other.ts (lines 100-150) - Description
  3. ...

Key Code

Critical types, interfaces, or functions:

interface Example {
  // actual code from the files
}

Architecture

Brief explanation of how the pieces connect.

Start Here

Which file to look at first and why.


四个小节各承担一种下游价值:

- **Files Retrieved**:带精确行号的文件清单。下游 worker 可以据此 `read` 到具体行段,而不是重新全文检索;
- **Key Code**:内联真实代码片段(接口、关键函数实现),使 planner/worker 在不打开文件的情况下也能拿到签名与结构信息,这是"压缩上下文"里信息保真度最高的部分;
- **Architecture**:组件如何衔接的简要叙述,弥补"碎片化事实"缺少全局视角的问题;
- **Start Here**:给执行者一个明确的切入点与理由,降低后续 Agent 的决策成本。

对比 [worker.md](https://gitcode.com/GitHub_Trending/pi/pi/blob/e266507b606b9552fa277252644054afd4384b11/packages/coding-agent/examples/extensions/subagent/agents/worker.md?utm_source=gitcode_repo_files) 的交接要求——"If handing off to another agent (e.g. reviewer), include: Exact file paths changed / Key functions/types touched (short list)"——可以看出仓库对子代理之间交接信息有一套统一的"最小充分信息"约定:精确路径 + 关键符号 + 简短描述。scout 的四段式格式正是这一约定在"读侧"的镜像。

## scout 如何被发现:Agent 加载与解析机制

`agents/` 目录里的 Markdown 文件不会自己生效,需要 subagent 扩展的发现逻辑来加载。核心实现在 [agents.ts](https://gitcode.com/GitHub_Trending/pi/pi/blob/e266507b606b9552fa277252644054afd4384b11/packages/coding-agent/examples/extensions/subagent/agents.ts?utm_source=gitcode_repo_files):

- **目录扫描**:`loadAgentsFromDir` 只收 `*.md` 文件与符号链接(这解释了后文"软链安装"方式为什么可行),读文件、解析 frontmatter 失败的文件会被静默跳过,"一个坏文件不能拖垮同目录其他 Agent",见 [agents.ts](https://gitcode.com/GitHub_Trending/pi/pi/blob/e266507b606b9552fa277252644054afd4384b11/packages/coding-agent/examples/extensions/subagent/agents.ts?utm_source=gitcode_repo_files#L62-L106);
- **frontmatter 校验**:`name` 与 `description` 必须为字符串,scout.md 两者齐备,因此能被收录;`tools` 经 `parseToolList` 归一化,`model` 仅接受字符串;
- **作用域合并**:`discoverAgents(cwd, scope)` 按 `user`(`~/.pi/agent/agents`)、`project`(从 cwd 向上查找最近的 `.pi/agents` 目录,见 [findNearestProjectAgentsDir](https://gitcode.com/GitHub_Trending/pi/pi/blob/e266507b606b9552fa277252644054afd4384b11/packages/coding-agent/examples/extensions/subagent/agents.ts?utm_source=gitcode_repo_files#L116-L126))、`both` 三种作用域加载,`both` 模式下项目级 Agent 会**按名字覆盖**同名用户级 Agent,见 [agents.ts](https://gitcode.com/GitHub_Trending/pi/pi/blob/e266507b606b9552fa277252644054afd4384b11/packages/coding-agent/examples/extensions/subagent/agents.ts?utm_source=gitcode_repo_files#L128-L147)。

另一个细节:Agent 是**每次调用时重新发现**的(README 的 Limitations 一节也明确写了 "Agents discovered fresh on each invocation"),因此你可以在会话中途编辑 scout.md 而无需重启。

## scout 被派发时发生了什么:从工具调用到 pi 子进程

主模型看到"Use scout to find all authentication code"这类指令后,会调用 subagent 扩展注册的同名工具。工具注册与三种模式(single / parallel / chain)的参数 schema 定义在 [index.ts](https://gitcode.com/GitHub_Trending/pi/pi/blob/e266507b606b9552fa277252644054afd4384b11/packages/coding-agent/examples/extensions/subagent/index.ts?utm_source=gitcode_repo_files#L459-L481)。真正拉起 scout 的是 `runSingleAgent`([index.ts](https://gitcode.com/GitHub_Trending/pi/pi/blob/e266507b606b9552fa277252644054afd4384b11/packages/coding-agent/examples/extensions/subagent/index.ts?utm_source=gitcode_repo_files#L272-L440)),它把 Agent 定义翻译为一组子进程命令行参数:

```typescript
const args: string[] = ["--mode", "json", "-p", "--no-session"];
const model = agent.model ?? dispatchDefaults.model;
if (model) args.push("--model", model);
if (inheritsDispatchConfig && dispatchDefaults.thinkingLevel) {
  args.push("--thinking", dispatchDefaults.thinkingLevel);
}
if (agent.tools && agent.tools.length > 0) args.push("--tools", agent.tools.join(","));

(引自 index.ts

对照 scout.md 的定义,逐条印证:

  1. --mode json -p --no-session:子进程以 JSON 模式、非交互(print)运行且不落会话。父进程逐行解析 stdout 上的 message_end / tool_result_end 事件,累积消息并实时统计 turns、input/output tokens、cache 读写、成本与上下文 token 数(index.ts)——这就是 TUI 里 3 turns ↑input ↓output RcacheRead WcacheWrite $cost ctx:N model 这行用量统计的来源;
  2. --model claude-haiku-4-5:frontmatter 中声明的模型直接落到 --model 参数;只有当 Agent 未声明模型时(inheritsDispatchConfig 为真)才继承派发会话的模型与 --thinking 等级;
  3. --tools read,grep,find,ls,bash:白名单以逗号拼接传入,scout 在子进程内只能调用这五个工具;
  4. 系统提示词经临时文件注入:scout 的 Markdown 正文会被写入系统临时目录下权限为 0o600prompt-<agent>.md 文件,再通过 --append-system-prompt <path> 传入(writePromptToTempFile),进程结束后文件与目录被清理;
  5. 任务作为位置参数:最后 args.push(\Task: ${task}`)` 把主会话下发的任务文本作为提示词内容传给子进程。

getPiInvocationindex.ts)则负责决定用哪个可执行文件拉起子进程:当前脚本存在时用 node/bun <script> 形式,否则回落到 pi 命令。中断路径上,父级 AbortSignal 触发后先 SIGTERM、5 秒后 SIGKILLindex.ts),对应 README 中"Ctrl+C propagates to kill subagent processes"的行为。

也就是说,scout 的"隔离上下文窗口"不是模拟出来的,而是一个真实的独立 pi 进程:它有自己的消息列表、自己的模型计费、自己的工具白名单,结束后只有最后一段 assistant 文本(getFinalOutput)和用量统计回到主会话。

scout 的战场:侦察—规划链式工作流

scout 的价值在它进入链条时最大化。subagent 示例的 prompts/ 目录提供了三个链式工作流预设:

提示词 流程 文件
/scout-and-plan <query> scout → planner scout-and-plan.md
/implement <query> scout → planner → worker implement.md
/implement-and-review <query> worker → reviewer → worker implement-and-review.md

implement.md 为例,其内容就是指示主模型用 chain 参数依次派发:

1. First, use the "scout" agent to find all code relevant to: $@
2. Then, use the "planner" agent to create an implementation plan for "$@"
   using the context from the previous step (use {previous} placeholder)
3. Finally, use the "worker" agent to implement the plan from the previous step
   (use {previous} placeholder)

链条中上下文如何流动?chain 模式下父进程逐步执行,每步开始前用正则把任务文本中的 {previous} 占位符替换为上一步的最终输出step.task.replace(/\{previous\}/g, previousOutput)index.ts)。于是 scout 的四段式侦察报告(文件清单、关键代码、架构、Start Here)原样成为 planner 的输入——planner 的提示词开头明确写着"You receive context (from a scout) and requirements",两个 Agent 的提示词是互相咬合的契约。链条在首个失败步骤即中止,并报告哪一步失败(Chain stopped at step Nindex.ts)。

scout 也支持并行扇出。例如"Run 2 scouts in parallel: one to find models, one to find providers"会走 tasks 数组并行模式:最多 8 个任务、4 个并发(MAX_PARALLEL_TASKS = 8MAX_CONCURRENCY = 4index.ts),每个任务流式汇报进度,返回给主模型的结果按任务截断至 50 KB(PER_TASK_OUTPUT_CAP),完整输出保留在工具详情中——对侦察类长输出这是一道保护主上下文的保险丝。

作用域与安全模型:scout 从哪儿来、是否可信

README 的 Security Model 一节给出的默认行为是:只加载用户级 Agent~/.pi/agent/agents/*.md)。scout.md 若要生效,按 README 的 Installation 一节软链到用户目录即可(仓库本身只读,以下命令在用户机器上执行):

# 软链扩展(必须放在含 index.ts 的子目录中)
mkdir -p ~/.pi/agent/extensions/subagent
ln -sf "$(pwd)/packages/coding-agent/examples/extensions/subagent/index.ts" ~/.pi/agent/extensions/subagent/index.ts
ln -sf "$(pwd)/packages/coding-agent/examples/extensions/subagent/agents.ts" ~/.pi/agent/extensions/subagent/agents.ts

# 软链 agents
mkdir -p ~/.pi/agent/agents
for f in packages/coding-agent/examples/extensions/subagent/agents/*.md; do
  ln -sf "$(pwd)/$f" ~/.pi/agent/agents/$(basename "$f")
done

# 软链 workflow prompts
mkdir -p ~/.pi/agent/prompts
for f in packages/coding-agent/examples/extensions/subagent/prompts/*.md; do
  ln -sf "$(pwd)/$f" ~/.pi/agent/prompts/$(basename "$f")
done
登录后查看全文
热门项目推荐
相关项目推荐