Pi 会话分支摘要本地化设计与扩展实现
1. 这篇讲什么
分析 Pi Coding Agent 在执行会话树分支切换(/tree 回溯)时生成英文摘要的底层机理,并基于官方 session_before_tree 扩展生命周期事件,设计并落地全局中文摘要指令替换方案。
2. 问题背景与现象
在中文技术研发与文档撰写会话中,当用户使用 /tree 切换并回溯分支会话时,Pi 会在会话历史中插入一段 <summary> 节点作为上下文压缩记忆。
虽然对话全程使用中文,但自动生成的摘要仍强制采用英文结构与英文标题:
<summary>
The user explored a different conversation branch before returning here.
Summary of that exploration:
## Goal
[What was the user trying to accomplish in this branch?]
## Constraints & Preferences
- [Any constraints, preferences, or requirements mentioned]
...
原生英文摘要虽然逻辑准确,但在中文语境下存在阅读门槛。全中文结构化 Prompt 旨在提供零摩擦的阅读体验,确保技术复盘时的信息获取效率。
3. 源码机制探针
Pi 为完全开源项目(官方仓库:earendil-works/pi)。经查阅其核心源码实现,厘清了分支摘要生成的底层机制:
3.1 默认 Prompt 硬编码
在核心模块 packages/coding-agent/src/core/compaction/branch-summarization.ts:258 中,Pi 定义了默认的常量模板 BRANCH_SUMMARY_PROMPT:
const BRANCH_SUMMARY_PROMPT = `Create a structured summary of this conversation branch for context when returning later.
Use this EXACT format:
## Goal
[What was the user trying to accomplish in this branch?]
## Constraints & Preferences
- [Any constraints, preferences, or requirements mentioned]
- [Or "(none)" if none were mentioned]
## Progress
### Done
- [x] [Completed tasks/changes]
### In Progress
- [ ] [Work that was started but not finished]
### Blocked
- [Issues preventing progress, if any]
## Key Decisions
- **[Decision]**: [Brief rationale]
## Next Steps
1. [What should happen next to continue this work]
Keep each section concise. Preserve exact file paths, function names, and error messages.`;
无论当前系统环境语言或用户交互语言为何,系统默认均使用该英文模板组装提示词,投递至摘要模型。
3.2 官方扩展劫持链路与时序流向
在分支切换确认后、发起模型摘要调用前,Pi 内核会通过事件总线向扩展层广播生命周期事件。整体协作时序如下:
4. 方案设计与选型
针对本地化需求,存在三种技术路线:
| 方案 | 原理 | 优点 | 缺点 | 结论 |
|---|---|---|---|---|
| A. 源码补丁 | 直接 patch npm 全局安装包代码 | 最彻底,不依赖插件系统 | 直接改写内核源码,宿主升级后即失效 | ❌ 废弃 |
| B. 扩展提供 summary | 扩展中拦截并自行调用外部模型完成摘要 | 自由度最高 | 产生额外模型配置负担,破坏内置 token 预算与流式控制 | ❌ 废弃 |
| C. 指令完全置换(本方案) | 利用 session_before_tree 注入 replaceInstructions: true,内核据此彻底覆盖内置英文模板为中文 Prompt | 复用 Pi 内核所有重试、预算截断与已鉴权模型调用能力;只依赖公开事件契约,宿主升级不易失效 | 仅在有对应事件支持的 Pi 版本中生效 | ✅ 采用 |
5. 核心机制契约与工程化交付
5.1 最小扩展契约(Minimal Contract)
根据方案 C 的决策,扩展的职责仅限于在事件触发时完成指令拦截与替换,绝不介入底层的模型推理与网络通信。
核心契约仅需在 session_before_tree 阶段返回控制元组:
pi.on("session_before_tree", async () => {
return {
replaceInstructions: true, // 必填:声明彻底覆盖默认英文模板
customInstructions: CHINESE_BRANCH_SUMMARY_PROMPT // 注入等价中译模板
};
});
5.2 提示词结构设计
中文 Prompt 采用与 Pi 原生模板1:1 同构的翻译策略,以保持总结的逻辑密度与阅读体验。
设计要求:
- 骨架一致:保留
## 目标、## 约束与偏好、## 进展、## 关键决策、## 下一步五个板块; - 层级统一:维持二级标题结构,利用 Markdown 折叠特性提升可读性。
5.3 实现源码
完整实现见开源仓库:
6. 架构启示:改指令不改引擎
本方案沉淀出的“改指令不改引擎(Instruction Replacement over Engine Takeover)”模式具有长期的可复用价值:
- 最小侵入性:当宿主(Harness)已具备完备的预算管理、重试与网络流水线时,扩展应优先寻找“提示词/参数替换点”,而非“逻辑替代点”;
- 向前兼容性:扩展应只依赖宿主公开的事件与参数契约,不触碰其内部实现;契约保持稳定时,宿主的内部重构与版本升级都不需要扩展跟着改;
评论