PiAgent 系列 7:pi-subagents 工作流编排
上篇介绍了如何自定义 agent 以及 pi-subagents 的三个设计约束:
systemPromptMode: replace、子 agent 不能自由嵌套、以及contact_supervisor反向通道。这些约束决定了 pi-subagents 的编排风格,多 agent 协作主要靠文件交接,复杂流程由父 session 显式编排。本文在此基础上,介绍两种核心编排模式:Parallel 并行与 Chain 链式,以及工作流的保存、复用、管理和诊断。
Parallel:并行编排
Parallel 是最简单的编排形式:多个 agent 同时跑,互不干扰。
基础并行
/parallel \
reviewer "审查安全性" \
-> reviewer "审查性能" \
-> reviewer "审查可维护性"
三个 reviewer 同时开始,互不干扰。所有结果汇总后一条消息返回主会话。
共享任务
/parallel scout researcher -- 深度分析支付模块
scout 扫代码 + researcher 线上搜,同一个任务,两种角度,并行完成。
差异化配置
/parallel \
reviewer[model=deepseek-v4-pro,skills=security] "审查安全性" \
-> reviewer[model=deepseek-v4-flash] "审查代码风格"
同一个 agent 类型,不同模型和技能承担不同子任务。
并行结果的传递
并行步骤的子 agent 结果按以下格式汇总,用分隔线区分:
=== Parallel Task 1 (reviewer) ===
...审查结果...
=== Parallel Task 2 (reviewer) ===
...审查结果...
如果 parallel 是 chain 里的一步,汇总文本会作为整步的 {previous} 传给下一步。
并行适合彼此独立的任务;一旦任务之间存在先后依赖,比如必须先分析、再计划、最后实施,就要用到 Chain。
Chain:流水线与文件协同
Chain 是 pi-subagents 中设计最精巧的部分。同一个 chain 可以用三种形式表达,分别适合临时执行、长期复用和动态生成任务:
| 方式 | 格式 | 适用场景 |
|---|---|---|
命令 /chain |
一行命令,-> 连接 |
临时跑,快速试 |
.chain.md 文件 |
Markdown,## agent 标题 + 配置行 |
保存复用,长期维护 |
.chain.json 文件 |
JSON,chain 数组 |
动态扇出(任务数量不固定时) |
三种写法都对应同一套执行模型:命令最直观,.chain.md 适合沉淀为可复用的工作流,.chain.json 支持 expand 动态扇出,这是前两种做不到的。
下面先用命令行讲解核心概念,再介绍内联并行组和动态扇出,最后讲保存复用。
为什么用文件而非上下文传递?
由于子 agent 使用 systemPromptMode: replace,它不会主动维护 Pi 的上下文。如果把前一个 agent 的完整输出直接内联进下一个 agent 的 task,上下文会快速膨胀,假设 scout 生成的 context.md 有 4000 token,planner 生成的 plan.md 有 3000 token,每次都内联,到 worker 时前两步输出已经占了 7000 token,很容易撞上上下文墙。
用文件交接的好处:
- 按需读取,worker 只需看 context.md 和 plan.md,不被无关历史淹没
- 结构化交接,文件内容是专门为下一步编排的,不是纯日志
- 可命名引用,chain 中用
as:命名步骤,后续用{outputs.name}精确获取
文件流转示意
scout
│
│ 输出 → context.md
▼
planner
│
│ 读取 context.md
│ 输出 → plan.md
▼
worker
│
│ 读取 context.md + plan.md
│ 实施
▼
reviewer
│
│ 读取 plan.md
▼
这三个文件在链路中的角色:
| 文件 | 产出者 | 消费者 | 内容 |
|---|---|---|---|
| context.md | scout, context-builder | planner, worker | 入口点、核心类型、数据流、风险、外部依赖 |
| plan.md | planner | worker, reviewer | 分步计划、涉及文件、验证方法 |
| progress.md | worker(自动维护) | reviewer | 当前进度:完成了啥、还没做啥、阻塞在哪 |
基础用法
/chain scout "扫描 auth 模块" -> planner "出方案" -> worker "实施"
每一步默认可以通过 {previous} 拿到上一步的完整输出。但如果上一步产出了文件,更推荐用 reads 显式读取,避免上下文膨胀:
/chain \
scout[as=ctx,output=ctx.md] "分析 auth 的数据流和入口点" \
-> planner[reads=ctx.md,as=plan,output=plan.md] "基于 {outputs.ctx} 制定重构计划" \
-> worker[reads="ctx.md+plan.md"] "按 plan 实施,验证后汇报"
可用变量:
| 变量 | 含义 |
|---|---|
{task} |
chain 的原始 task |
{previous} |
上一步(或上次并行组)的完整输出 |
{outputs.ctx} |
名为 ctx 的步骤的输出 |
{chain_dir} |
chain 的临时工作目录 |
内联并行组
Chain 中的一步可以是一个并行组,用 () 包裹,| 分隔:
/chain \
scout "扫描项目" \
-> (reviewer "审查安全性" | reviewer "审查性能" | reviewer "审查架构") \
-> worker "修复所有审查发现的问题"
执行顺序:scout 先跑完 → 三个 reviewer 同时开始 → 全部完成 → 三份审查结果汇总为一步 → worker 拿到汇总结果开始修复。
并行组支持三个选项:
(revA "task1" | revB "task2" | revC "task3")[concurrency=2,failFast,worktree]
| 选项 | 效果 |
|---|---|
concurrency=2 |
同时最多跑 2 个,第三个排队等待 |
failFast |
任意一个子 agent 失败就立刻停止全组 |
worktree |
每个子 agent 在独立 git worktree 中运行,文件互不污染 |
worktree 特别适合多个 reviewer 同时做代码改动的场景,正常的并行会互相覆盖文件,worktree 让每个 reviewer 在独立的 worktree 上操作,互不影响。
动态扇出
当任务数量不固定时,比如 scout 发现了 7 个需要重构的文件,用 .chain.json 做数据驱动的扇出:
{
"name": "dynamic-review",
"chain": [
{
"agent": "scout",
"task": "找出需要重构的文件,返回 {\"items\":[{\"path\":\"...\",\"reason\":\"...\"}]}",
"as": "targets"
},
{
"expand": {
"from": { "output": "targets", "path": "/items" },
"item": "f",
"maxItems": 8
},
"parallel": {
"agent": "reviewer",
"task": "审查 {f.path},重构原因:{f.reason}"
},
"collect": { "as": "reviews" },
"concurrency": 4
},
{
"agent": "worker",
"task": "综合 {outputs.reviews} 修复所有问题"
}
]
}
scout 返回结构化列表 → expand 按列表项动态生成 N 个 reviewer → collect 收集结果命名为 reviews → worker 合成修复。maxItems 硬限制生成数量,防止任务数量失控。
保存与复用
编排好的链路可以存为 .chain.md,后续一句命令调用,这既是 chain 的第三种表达方式,也是复用工作流的推荐做法。
存放优先级:
| 优先级 | 路径 |
|---|---|
| 项目(推荐) | .pi/chains/*.chain.md |
| 用户 | ~/.pi/agent/chains/*.chain.md |
每个 ## agent-name 是一个步骤。标题后可以接 config 行:
---
name: review-flow
description: 审查并修复的完整工作流
---
## scout
phase: Context
label: 扫描代码
as: context
output: context.md
分析代码中的 {task}
## planner
phase: Planning
label: 制定计划
reads: context.md
as: plan
output: plan.md
基于 {outputs.context} 制定实施计划
## worker
phase: Implementation
label: 实施
reads: context.md, plan.md
按计划实施 {task}
步骤级字段说明:
| 字段 | 说明 |
|---|---|
phase |
步骤分组名(进度展示用) |
label |
可读的步骤名 |
as |
命名输出,后续 {outputs.name} 引用 |
output |
输出写入的文件 |
reads |
预读文件 |
model |
覆盖模型 |
skills |
覆盖技能 |
progress |
开启进度追踪 |
执行:
/run-chain review-flow -- 重构用户认证
也支持自然语言:「Run the review chain on this branch.」
编排定义好之后,接下来就是运行时的管理与诊断。
Agent 的管理与诊断
日常使用中有几个命令比较常用:
| 命令 | 作用 |
|---|---|
/subagents-doctor |
诊断配置是否正常 |
/subagents-models [agent] |
查看各 agent 当前使用的模型映射 |
/subagents-fleet |
查看所有前台/后台运行中的子 agent |
/subagent-cost |
汇总父 + 所有子 agent 的 token 和费用 |
除了命令,也可以用工具调用管理 agent 定义:
# 列出所有可用 agent
Show me the available subagents.
# 禁用某个内置 agent
subagent({ action: "disable", agent: "context-builder" })
# 恢复
subagent({ action: "enable", agent: "context-builder" })
disable/enable 本质上是在 settings.json 写入/删除 agentOverrides 中的 disabled 字段,持久生效。
启动前预览
默认行为是直接启动。如果想先审查要跑的配置再放行,可以加上 clarify: true:
subagent({ agent: "worker", task: "重构 auth", clarify: true })
会弹出 TUI 界面,供你预览和编辑,选模型、调 thinking、改 task、切换前台/后台。Enter 确认执行,Esc 取消。适合第一次跑复杂编排时先确认一遍。
补充能力
除了编排与诊断,pi-subagents 还有两个值得知道的补充能力:给子 agent 注入专属扩展,以及为角色开启持久记忆。
子 Agent 专属扩展
subagentOnlyExtensions 字段允许注册只在子 agent session 里加载的扩展,主 session 不受影响。适合给某个角色注入专属工具而不污染全局:
subagentOnlyExtensions: ./tools/child-only-audit.ts
持久记忆
可以为角色配置独立的持久化记忆文件,子 agent 每次启动时会加载之前积累的角色笔记:
memory:
scope: project # project(跟项目走)或 user(跨项目共享)
path: security-reviewer # 文件名,存储在 agent-memory/ 目录下
项目级存储在 .pi/agent-memory/security-reviewer/MEMORY.md,用户级在 ~/.pi/agent/agent-memory/security-reviewer/MEMORY.md。有写入工具的 agent 会被提示"可以追加记录",只读 agent 只能看到历史记录。
总结
| 主题 | 要点 |
|---|---|
| Parallel | 多个 agent 同时跑,适合彼此独立的子任务 |
| Chain | 多步骤流水线,靠文件交接传递上下文 |
| 内联并行组 | Chain 中的一步可以是并行组,支持并发数、failFast、worktree |
| 动态扇出 | .chain.json + expand 适合任务数量不固定的场景 |
| 保存复用 | .chain.md 存到项目或用户目录,用 /run-chain 调用 |
| 管理诊断 | /subagents-doctor、-models、-fleet、-cost |
| 补充能力 | subagentOnlyExtensions 与 memory |
至此,pi-subagents 的进阶内容就介绍完了:上一篇讲单个 agent 怎么定制和它的底层约束,本篇讲多个 agent 怎么编排、管理和复用。把这两篇结合起来,你就可以根据项目需求定制专属角色,并把它们组装成稳定、可复用的工作流。