子 agent 与任务委派
最后更新: 2026年8月27日
$ pi –delegate
TL;DR。 Pi 子 agent 是父会话为一段有边界的工作 spawn 出来的独立 pi 进程,它跑在隔离的上下文窗口里。官方 subagent 示例扩展 注册一个 task 工具,支持三种模式——{ agent, task } 单跑、{ tasks: [...] } 并行(最多 8 个、并发 4)、{ chain: [...] } 串行链(每一步可引用 {previous})。Agent 是位于 ~/.pi/agent/agents/(用户级)或 .pi/agents/(项目级,通过 agentScope: "both" 显式开启)的 Markdown 文件;frontmatter 声明系统提示、可用工具集与模型。父会话收到结构化输出、按任务的用量统计(轮数 / token / 成本 / 上下文),并通过 Ctrl+C 中止。第三方项目(pi-flows、pi-tmux-orchestrator、dsh-pi-agent、pi-goal-list-loop-audit)都建立在同一套原语之上:spawn 一个全新的 pi 子进程,让它把结果返回来。
本文先讲官方扩展,再讲信任模型与配置开关,最后讲生态里其它项目如何包装同一套思路。参考来源:Extensions reference,以及 subagent 示例。
什么是子 agent
子 agent 是父会话为单一有边界任务启动的独立 pi 进程。由于它跑在自己的进程、自己的上下文窗口里,父会话的对话可以专注于决策本身,而不会被子任务打开过的每一个文件污染。子 agent 在工程上有三个关键属性:
- 隔离的上下文。 每个子 agent 一上来是一个干净的窄上下文:父会话累积的工具调用历史、临时读取、对话上下文都不会渗到子 agent 的 prompt 里。子 agent 看到的只有「委派给它的任务」、「agent 的系统提示」、以及当前工作目录。
- 流式输出。 父会话可以实时看到子 agent 的工具调用与进度,而不是只等最终答案。并行模式下,所有正在跑的任务同时流式输出。
- 用量统计。 每个子 agent 返回它的
usage(输入 / 输出 / 缓存读 / 缓存写 / 成本 / 轮数),父会话把它显示在页脚里,并汇总到会话总用量中。
一个直接的工程后果:本来会让父会话膨胀到 50 个文件的重构,委派出去之后只回一份 diff。
官方 subagent 扩展
Pi 仓库在 packages/coding-agent/examples/extensions/subagent 下提供了一份参考实现。它注册一个 task 工具,参数形态决定模式:
// Single:一个 agent,一个 task
{ agent: "scout", task: "Find all authentication code in /src" }
// Parallel:最多 8 个任务,并发 4
{
tasks: [
{ agent: "scout", task: "Find model definitions" },
{ agent: "scout", task: "Find provider implementations" }
]
}
// Chain:串行,每一步可以引用 {previous}
{
chain: [
{ agent: "scout", task: "Map the auth surface" },
{ agent: "planner", task: "Plan a refactor for {previous}" },
{ agent: "worker", task: "Implement the plan from {previous}" }
]
}
实现内部把每个子 agent spawn 为一个独立的 pi 进程,通过 JSON 模式读取它的输出——也就是 rpc-and-json-mode 指南里讲过的同一条无头接口。实现复用了父会话的 getAgentDir、CONFIG_DIR_NAME 常量,以及 markdown 主题渲染。
Agent 的定义
Agent 是带 frontmatter 的 Markdown 文件,而不是 TypeScript 模块。发现约定是:
| 位置 | 范围 | 默认行为 |
|---|---|---|
~/.pi/agent/agents/*.md |
用户级 | 始终加载 |
.pi/agents/*.md |
项目级 | 通过 agentScope: "both" 显式开启 |
一个最简的 agent 文件长这样:
---
name: scout
description: "Fast recon, returns compressed context"
tools: [read, grep, find, ls]
model: claude-haiku-4-5
---
You are a read-only scout. Inspect the codebase for the requested information and return a compressed summary. Do not modify any files.
Frontmatter 声明 agent 名称、一句话描述、可用工具集和模型。body 是系统提示。subagent 示例自带四个示例 agent(scout、planner、reviewer、worker)以及三套工作流 prompt(implement、scout-and-plan、implement-and-review),分别放在 agents/ 和 prompts/ 下。
参考实现里:MAX_PARALLEL_TASKS = 8、MAX_CONCURRENCY = 4、PER_TASK_OUTPUT_CAP 单任务 50 KiB。超过 50 KiB 的输出在送进父会话上下文之前会被截断。条目超过 COLLAPSED_ITEM_COUNT = 10 后,TUI 会折叠显示,需要点击展开——长并行跑的结果也能保持可读。
信任与范围
项目级 agent 落在仓库里,可以指示模型读取文件、运行 bash 命令,或做父模型能做的任何事。参考实现因此默认只加载 用户级 agent(~/.pi/agent/agents/)。要启用项目级 agent,可以在配置工具时传 agentScope: "both"(或 "project")。仅对你信任的仓库这样做。
一旦 agentScope: "both" 启用,工具在不可信项目上跑项目级 agent 之前会弹一次确认。受信任项目跳过这次确认。要彻底关闭确认(在完全可信的环境里),把 confirmProjectAgents 设为 false。
整个信任机制与 pi 在项目本地状态上的一贯做法一致:项目本地的扩展、技能、agent、prompt 都由同一个 defaultProjectTrust 与 installation-and-updates 指南里介绍的 --approve / --no-approve 开关把关,agent 并没有独立于其它项目本地资源的信任通道。
在 pi 里跑子 agent
在 pi 会话中,父 LLM 在用户请求匹配到委派工作时调用 task 工具。从用户视角:
> Scout the codebase for everything related to authentication.
pi 把这件事委派给 `scout`,再把侦察结果返回。你不需要写 agent 名字或 JSON——它会从意图里挑。
要更显式,可以直接点名:
> Use scout to find the authentication entrypoints.
> Use task with {"agent": "scout", "task": "find auth entrypoints"}
如果任务更广、需要先规划:
> Document login, refresh, and session storage. Have overwatch review
> the breakdown before the research starts.
评审员可以要求有限度的修订,工人只在分解拿到 PASS 之后才开始。
Ctrl+C 会沿着父子链路向下传播——subagent 扩展把 process.kill 接到了父会话的中止信号上,长跑的并行扫描可以被干净地取消。
同一套原语的扩展
官方扩展是最朴素的实现。同一套原语——spawn 一个独立的 pi 进程,让它把结果返回——是整个多 agent 生态的基石:
pi-flows注册一个flow工具,提供 15 种委派模式(single、parallel、chain、evaluate、vote、route、orchestrate、graph、loop、search、workflow、worktree,以及若干 presets)。它在之上加了预算约束(成本 / token 上限)、OpenInference 形态的 JSONL trace、返回结果的契约校验,以及/flows report查看器。pi-tmux-orchestrator在一个六格 tmux 网格里做同样的委派,再加一个 Unix 域套接字 broker。实现者、评审员和可选探针各自跑成pi子进程,broker 仪表盘实时显示工作流、角色、模型、用量与最新元数据。dsh-pi-agent把一个无头pi --mode rpc --no-session子进程作为 DSH 的AgentFactory跑。每个 DSH 会话由此由 pi 子进程驱动;插件同时暴露一行SubagentProvider,让tool-subagent配合provider: pi在每次委派时 spawn 一个全新的pi -p <task>子进程。pi-goal-list-loop-audit把审计员作为一个全新的、不带任何扩展的piRPC 进程 spawn 出来。审计员拿到read/grep/find/ls/bash这几个工具有意全开的能力,但它看不到实施那一侧的对话或父状态——「实现」与「验证」之间的隔离由进程边界强制。
四个项目共同的模式:一个独立的 pi 进程、一份隔离的上下文、把结构化结果返回给父会话。官方 subagent 示例是正确的起点,其它一切都是它的包装。
什么时候不该用子 agent
子 agent 不是默认。简单的回答、明显的 shell 命令、小修改、快速单文件查找,留在父会话里更便宜也更清楚。委派的代价是 spawn 一个 pi 子进程的开销,加上用 JSON 模式把请求和结果来回搬家的样板代码。只有当下一步会让父会话变得嘈杂、昂贵或难以信任时,才用子 agent——而不是反过来。
一份小小的委派清单
- 决定是用户级 agent 还是项目级 agent。用户级始终加载;项目级需要
agentScope: "both",并保留confirmProjectAgents默认值。 - 在 frontmatter 里固定 agent 的工具集。一个能
write或edit的scout失去了只读的初衷;即便是官方自带的 scout 示例,也保留了bash做只读探查,但完全不放write/edit。 - 固定模型。不同的 agent 应该用不同的模型——
scout不需要最贵的前沿模型。 - 让用量可见。每次委派的任务都应该返回
usage,让父会话把它汇总进页脚与/session。 - 接通中止。Ctrl+C 必须能传播到正在跑的子进程;中途拿到的部分结果不应该污染父会话上下文。
延伸阅读
- Extensions——事件、自定义工具、项目信任、
agentScope - RPC Mode——子 agent 在底层使用的
pi --mode rpc接口 packages/coding-agent/examples/extensions/subagent——官方参考实现,含scout、planner、reviewer、worker示例 agent 与配套工作流 prompt- Pi 的 RPC 与 JSON 模式——无头调用的配套指南
- Pi 的安装与更新——覆盖
defaultProjectTrust、~/.pi/agent/目录布局与--approve覆写