piagent_
← ~/guides

子 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-flowspi-tmux-orchestratordsh-pi-agentpi-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 指南里讲过的同一条无头接口。实现复用了父会话的 getAgentDirCONFIG_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(scoutplannerreviewerworker)以及三套工作流 prompt(implementscout-and-planimplement-and-review),分别放在 agents/prompts/ 下。

参考实现里:MAX_PARALLEL_TASKS = 8MAX_CONCURRENCY = 4PER_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 都由同一个 defaultProjectTrustinstallation-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 把审计员作为一个全新的、不带任何扩展的 pi RPC 进程 spawn 出来。审计员拿到 read / grep / find / ls / bash 这几个工具有意全开的能力,但它看不到实施那一侧的对话或父状态——「实现」与「验证」之间的隔离由进程边界强制。

四个项目共同的模式:一个独立的 pi 进程、一份隔离的上下文、把结构化结果返回给父会话。官方 subagent 示例是正确的起点,其它一切都是它的包装。

什么时候不该用子 agent

子 agent 不是默认。简单的回答、明显的 shell 命令、小修改、快速单文件查找,留在父会话里更便宜也更清楚。委派的代价是 spawn 一个 pi 子进程的开销,加上用 JSON 模式把请求和结果来回搬家的样板代码。只有当下一步会让父会话变得嘈杂、昂贵或难以信任时,才用子 agent——而不是反过来。

一份小小的委派清单

  • 决定是用户级 agent 还是项目级 agent。用户级始终加载;项目级需要 agentScope: "both",并保留 confirmProjectAgents 默认值。
  • 在 frontmatter 里固定 agent 的工具集。一个能 writeeditscout 失去了只读的初衷;即便是官方自带的 scout 示例,也保留了 bash 做只读探查,但完全不放 write / edit
  • 固定模型。不同的 agent 应该用不同的模型——scout 不需要最贵的前沿模型。
  • 让用量可见。每次委派的任务都应该返回 usage,让父会话把它汇总进页脚与 /session
  • 接通中止。Ctrl+C 必须能传播到正在跑的子进程;中途拿到的部分结果不应该污染父会话上下文。

延伸阅读