# 专家协作

Personal Bot 保留独立工作和团队工作。成员仍由 tmux 和独立 Pi 进程运行，各自保留原生 JSONL 上下文。主模型负责组织与验收，成员原文由代码同步，不需要主模型逐条转述。

## 独立工作

| pbot_agent action | 行为 |
| --- | --- |
| start | 新建上下文，可指定 name/provider/model/thinking/cwd/tools；有 message/prompts/files 时执行初始工作，否则只启动待命进程 |
| send | 向 agentId 发送 message；delivery 默认为 steer，followUp 排到当前工作之后 |
| rename | 修改名称，agentId 保持不变 |
| status/list | 查询状态或当前父会话的子会话；status 不读取报告正文，报告通过 read 获取 |
| read | 按 agentId、可选 cycleId 和 offset/limit 读取报告 |
| stop | 请求停止，保留历史 |
| resume | 用新 message 重启已停止子会话，不重放旧工作 |

每个父会话最多 50 个存活进程，包括待命进程。启动异步返回，不提供 wait。无任务 start 不请求模型，也不产生工作完成通知；停止未接过任务的进程不伪造失败周期。

start 支持 noExtensions、noSkills、noPromptTemplates 和 noContextFiles。noExtensions 默认 true，显式保留子入口及 Pi 内置 MCP、codemode、工具搜索；设为 false 时按 Pi 规则发现其他扩展。tools 遵循 Pi 原生选择。子入口只增加 pbot_team_message，不提供 pbot_agent 或 pbot_team 管理能力。

初始 files 相对工作区根目录解析。子入口在每份附件前标出绝对来源路径，保留 Pi 原生 read 的文本、图像及截断提示；未读完的附件由成员沿该路径续读。message 与 prompts 合并为一次输入，不继承父聊天历史。

初始模型与思考级别默认继承主会话；恢复时交由 Pi 使用保存的原生模型配置，不重新传入初始模型选项。模型不可用或缺少认证时仍遵循 Pi 的原生回退与错误行为。子会话从自己的 cwd 和 Pi agent dir 取得原生配置与认证，不继承父进程临时注册的模型或 MCP。环境与授权规则见[工具与执行](capability-design.md)。

## 原生会话与恢复入口

新建 agent 的 agentId 也是 Pi session ID。对话由 Pi 保存在原生 sessions 目录或其原生配置指定的位置，按子进程 cwd 归组；pbot 只保存控制记录和文件引用。无任务待命不伪造对话，也可能尚无 JSONL 文件。首次输入前固定路径，之后恢复只打开这个文件；文件缺失或不匹配时不新建空白替代。具体规则见[文件存储](file-storage.md)。

有对话后，成员会出现在相应项目的 `pi --resume` / `/resume` 列表，并支持 Pi 原生导出。`pi --continue` 可能选中最近活跃的子会话，不保证选中主会话；需要主会话时从列表中明确选择。

`/pbot agents` 的“进入 TUI”连接运行中的成员；成员已停止时，加载原会话并启动待命进程，不入队新要求、不调用模型、不重放旧工作。尚无对话文件的空会话仍以原 agentId 待命。运行中不另开进程同时写同一 JSONL。停止后从原生列表打开属于普通 Pi 对话，不恢复 pbot 成员身份或团队资格；模型工具 `pbot_agent resume` 仍用于携新要求继续工作。

## 团队与两种策略

一个团队固定一组成员，限于同一工作区、同一父 session 的可操作分支。一个 agent 最多属于一个未关闭团队。加入团队不创建新进程，关闭团队也不停止成员；换人时关闭旧团队，再用原 agent 创建新团队。

| mode | 执行规则 |
| --- | --- |
| roundRobin | 按成员顺序发言；上一位完成且原文保存后，才安排下一位；并发固定为 1 |
| parallel | 同轮成员按并发上限工作，可直接 post/read；本轮所有答复保存后再进入下一轮 |

默认 2 轮、15 分钟。轮数为 1–10；parallel 默认并发为成员数与 2 的较小值，可调到 1–成员数。期限可设 1–86400 秒。总发言请求数不超过成员数乘轮数，普通 post 不增加请求。

这是有界并行轮次，不是任意点名唤醒的自由 swarm。首版不提供 ask、自动返回处理、热增减成员、跨团队私信或任务 DAG。轮内研究、实现、计算与审查方法由角色和技能决定。

### 工具

| pbot_team action | 行为 |
| --- | --- |
| create | name、brief、members[{agentId, role}]；仅建团队，不启动模型 |
| list/status | 查看归属、成员、当前批次、activeCount 及 unresolved 请求 |
| read | afterSeq/limit 读取公共记录；单条长消息用 seq/offset/limit |
| run | teamId、instruction、mode，可选 rounds/maxConcurrent/timeoutSeconds；开展新批次 |
| pause | 停止新增安排和领取，已领取请求继续收尾 |
| close | 已暂停或结束且没有在途工作时关闭，保留历史；不阻塞等待 |

run 要求全部成员空闲、无未消费的私人输入，并已加载可用的团队入口与通信工具。条件不满足时返回原因，不在后台等待成员就绪。team-ready 标记仅表示接入能力，不证明模型认证或业务能力可用。

主会话与成员通过 pbot_team_message read/post 通信。post 参数为 teamId、text、可选 replyTo，正文最多 24000 字符；不允许指定 sender。成员 post 必须属于其当前团队工作，主会话可在暂停时补充信息。所有发言公开，没有私密 to 信箱。

### 使用顺序

1. 用 pbot_agent start 创建待命成员，或选择已有空闲成员。
2. 用 pbot_team create 指定成员、职责与共同目标。
3. 确认成员就绪，再 run，例如：
   `{ action: "run", teamId: "...", instruction: "分别核对证据，下一轮回应分歧", mode: "parallel", rounds: 2, maxConcurrent: 2 }`。
4. 主会话不逐条转发消息。批次结束或暂停后，用 read 核对成员原文及实际产物。
5. 继续讨论须显式 run 新批次。需要私人工作时，先 pause 并等待 activeCount 为 0；必要时 stop 成员，再 send/resume。

运行中的团队占用全部成员，已领取但尚未收尾的请求也占用对应成员。私人 steer/followUp 均返回 TEAM_BUSY，不另建私人等待队列。其他未被占用的 agent 可以同时独立工作。

## 原文、上下文与公开范围

团队公共记录独立于各自私人会话。新团队请求通过原有 inbox 投递；before_agent_start 注入已署名的公共原文，运行中在 turn_end 安全边界追加消息，不请求额外 continuation。空闲成员在下一次团队请求时取得信息，私人工作不自动注入新群消息。

成员任务、团队背景、自动注入的公共消息和批次通知使用 Markdown 文档。团队背景按共同目标和成员职责分节，保留身份与轮次；本批次要求仅在成员任务输入中给出，避免在系统简报中重复。公共消息按 seq 分节，列出作者、回复关系与来源，正文放入保留原文的代码区块，包含代码围栏的正文也不会破坏区块边界。成员原文中的 JSON 保留原样。

read 的文本结果也使用 Markdown，同时保留工具的结构化结果。nextOffset 非空表示该条正文未读完，用同一 teamId、seq 和 offset 续读；nextAfterSeq 用于后续消息。自动注入按实际 Markdown 长度限制上下文，并用 remainingFromSeq 标明未包含的消息，从 afterSeq: remainingFromSeq - 1 继续读取。不能将展示片段当作完整记录。Pi 压缩不删除公共记录。

只自动公开本次团队请求正常结束后的最终答复，不广播完整历史、推理或原始工具输出。人工输入混入周期时标记 mixed 并暂停团队，不自动公开混合答复；此前显式 post 的内容保留。成员信息与人工子会话输入都不扩大原用户授权。

共享上下文不是保密隔离。成员可能已经知道私人资料；暂停、关闭或创建另一团队不会清除其记忆。需要独立复核或保密边界时使用新 agent。Bash、MCP 和扩展也不是宿主沙箱。

## 周期与保存

| 标识 | 含义 |
| --- | --- |
| agentId | 持续上下文 |
| requestId | 一条父侧输入；团队关联另存，不改变旧 AgentMessage |
| cycleId | 从工作开始到 agent_settled 的周期，包含内部多次 agent_start、工具与自动恢复 |
| teamId / runId | 团队 / 一批有限轮次，不与 Task Conductor 的标识混用 |
| seq | 团队内公共消息顺序 |

接收、执行完成、公开答复和业务验收是不同事实。函数返回、accepted、custom entry 或 UI 查看都不证明模型已理解。idle 不表示上轮成功，finished 不表示任务通过验收或达成共识。

历史报告使用固定叶节点；后续工作不覆盖旧报告。团队先保存 requestId 关联，再写原 inbox；同 ID 不重复增加序号。普通锁竞争仅重试当前进程中已知尚未发布的输入，reload 丢弃这份临时等待，不自动补发。I/O 错误使当前文件实例停止后续写入与投递。

存储责任与位置见[文件存储](file-storage.md)。0.2.0 保留现有控制字段，但不兼容旧会话位置。0.1.x 记录原地保留，不迁移或接管；先在旧版停止成员，再更新并新建 agent。

## 通知、归属与生命周期

主 agent 收到的独立子会话结果通知，以及 pbot_agent、pbot_team 和 pbot_team_message 的文本结果均使用 Markdown。列表、状态、工作周期和报告分节展示，报告保留原文；通知中的报告最多展示 2000 字符，完整内容通过 read 分页读取。工具的 structuredContent、details 与 read 收据保持原有契约。

独立周期的 read 结果进入当前分支后领取该周期通知，包括只读取部分正文的情况。nextOffset 非空时，以同一 agentId、返回的 cycle.cycleId 和 nextOffset 续读，避免默认最新周期发生变化；status 不领取通知。团队关联周期不重复发个人完成通知；主模型只收到批次结束、暂停和收尾状态。普通 post 不唤醒主模型。团队通知按 teamId/runId/状态去重，UI 或工具 read 不领取模型通知。

团队与成员均绑定父 session/分支。失去归属时暂停新安排，不向当前主分支投递结果。fork 不接管旧团队；返回原分支不会自动恢复旧批次。公共记录与外部工作不会随树导航回滚。

| 事件 | 行为 |
| --- | --- |
| 独立周期完成 | 保持 idle，可继续对话 |
| 主 reload | 保留子进程，但暂停团队；可补交付已完成结果，不续排旧批次 |
| 主中断 | 暂停团队新增安排，已领取工作默认收尾 |
| 主退出或切换 session | 先暂停团队，再按原有约 5 秒宽限清理子进程 |
| 成员 stop/异常退出/代次变化 | 暂停依赖它的批次，保留记录，不自动 resume |
| 子 reload | 暂停团队；未完成周期或仅有领取标记的请求记为 interrupted，不重跑 |
| 到达期限 | 停止新安排和领取；子入口尽力中断自身未被人工接管的团队工作 |
| 恢复主 session | 恢复记录与通知，不自动启动旧工作 |

pause 返回时可能仍有在途请求。unresolved 区分排队、已接收、未公开、未知结果与中断等状态；只有进程确已停止或请求已经结束，才能解除在途占用。结果未知时查原生报告和外部状态，不能将新批次视为重试许可。中断不保证撤销已发生的外部副作用。

## UI 与验证边界

/pbot agents 提供状态列表、进入子 TUI、补充要求、重命名和停止，不再提供单独的报告查看或恢复并继续菜单。报告仍可通过 pbot_agent read 获取。/pbot teams 提供团队状态、公共记录分页、post、新批次、pause、close，以及相同的成员菜单。无 TUI 时通过同样的结构化工具使用，不支持 attach。

后台扫描遇到短暂的 `.control` 锁竞争时，在下一次扫描重试；连续至少 5 秒仍无法取得锁，包括主会话中断后暂停团队仍被锁阻塞的情况，会保留 UI 错误并通知模型。暂停未成功时，通知明确说明暂停尚未确认。报告或控制记录读取失败也会通知模型。同一持续故障在当前分支去重；恢复要求升级时补发一次通知。主会话中断期间延后投递，恢复输入后再通知。

通知按实际服务状态说明恢复方式：锁释放后自动恢复扫描；可恢复的读取错误先排障，修复后由后台重试；团队服务或协作存储已停用时，修复文件仍不能恢复当前实例，须请用户在当前 Pi 会话执行 `/reload`。重载前不反复调用 pbot_team，可通过 pbot_agent list/status/read 核对仍可读取的成员状态与报告；重载后再用 pbot_team status/read 核对团队。成功扫描后清除故障状态。通知不重发任务、不删除锁，命令和工具的错误仍直接返回。

选择成员后，操作菜单的“进入 TUI”选项直接标明返回快捷键，选中后立即进入，不再二次确认。团队成员入口使用相同流程。默认 tmux 绑定下，普通终端按 Ctrl+B 后按 d 脱离子会话；主会话已在 tmux 中时，按 Ctrl+B 后按小写 l 切回上一个会话。自定义绑定以自己的 tmux 配置为准。返回不会停止成员，不要用 /exit 代替返回。

Pi 1.4.0 的本地 SDK、实际无认证 Pi/tmux 进程、文件并发与恢复测试已覆盖基础契约。未使用假模型或模拟 provider。2026-10-28 在 0.1.3 上的真实模型双成员冒烟已通过两种策略的单轮通信、原文引用与主通知；0.2.0 的原生存储调整及 Pi 1.4.0 升级仅做本地 SDK/无认证进程验证，未追加真实模型调用；异构模型、多轮讨论、长期使用与交互 TUI 尚未验收，详见[验证](validation.md)。单轮通过不证明一般协作质量或外部操作恰好一次。
