第 5 章 · 会话管理:恢复与分支
本章目标:理解 pi 会话的存储结构与树形本质,掌握恢复/命名/分叉/克隆全套操作,能在同一会话里安全地"回到过去"尝试不同方案。
5.1 会话存在哪里
会话以 JSONL 文件自动保存,按工作目录归档:
~/.pi/agent/sessions/--<path>--/<timestamp>_<uuid>.jsonl<path> 是工作目录路径(/ 替换为 -)。每个 JSONL 文件不是线性日志,而是一棵消息树:每条记录带 id 与 parentId,当前活跃位置是树的叶子节点——这正是"in-place 分支"(不复制文件就能开岔)的数据结构基础。会话格式已迭代到 v3(v1 线性结构会在加载时自动迁移)。
# 快速查看某个会话文件的内容形态
head -3 ~/.pi/agent/sessions/--Users-you-demo--/*.jsonl | python3 -m json.tool 2>/dev/null | head -20每行是一个带 type 字段的 JSON 对象:用户/助手消息、模型切换、思考等级变更、标签、压缩摘要、分支摘要、扩展条目等都各是一种条目类型。
5.2 恢复会话的四种姿势
pi -c # 继续当前目录最近一次会话
pi -r # 启动时打开会话选择器
pi --session <path|id> # 直接指定会话文件路径或部分 UUID
pi --no-session # 临时模式,本次对话不落盘交互内对应 /resume(选择器)、/new(新会话)。用 /session 可随时查看当前会话的文件路径、会话 ID、消息数、token 与费用。
选择器里的管理操作:
| 按键 | 功能 |
|---|---|
| 直接输入 | 搜索会话 |
| Ctrl+P / Ctrl+S | 切换路径显示 / 排序方式 |
| Ctrl+N | 只看命名过的会话 |
| Ctrl+R / Ctrl+D | 重命名 / 删除(有 trash CLI 时移入回收站) |
5.3 命名:让历史可检索
pi --name "重构认证模块" # 启动时命名(-n 同义)/name 重构认证模块 # 会话中改名命名会话在 /resume 与 pi -r 中更容易被找到,配合 Ctrl+N 过滤可以快速定位长期任务。团队协作场景建议约定命名规范(如 任务号-简述)。
5.4 分支:在同一棵树上尝试不同方案
这是 pi 会话系统最有价值的能力。典型场景:让智能体改一段复杂逻辑,结果不满意——不必撤销重来,直接分叉。
/tree —— 原地导航整棵会话树
├─ user: "帮我优化这个函数"
│ └─ assistant: "方案A:缓存计算结果..."
│ ├─ user: "试试方案B吧..." ← 切到这条即可从这继续
│ └─ user: "还是回滚到A再优化..."- 双击 Escape 或
/tree打开;↑/↓ 导航,Ctrl+←/→ 折叠展开或跨分支跳转; - Shift+L 给条目打书签标签,Shift+T 显示标签时间戳;
- Ctrl+O 循环过滤模式:default → no-tools → user-only → labeled-only → all(默认值可用设置项
treeFilterMode配置); - 选中一条 user 消息:光标移到它的父节点、把该消息放回编辑器供修改重发 → 形成新分支;选中 assistant 等非 user 条目则直接从那里继续。
/fork 与 /clone —— 开出新会话文件
| 特性 | /tree | /fork | /clone |
|---|---|---|---|
| 产出 | 同一会话文件 | 新会话文件 | 新会话文件 |
| 视角 | 完整树 | 用户消息选择器 | 当前活跃分支 |
| 典型用途 | 原地探索多个方案 | 从早期提示另起炉灶 | 继续前先备份当前进度 |
CLI 侧也有对应入口:pi --fork <path|id> 把已有会话分叉成新文件。
切分支时的上下文丢失与补救
/tree 切走一条分支时,被离开分支的细节不再位于活跃上下文中。pi 提供分支摘要(branch summary):提示时可选"不摘要 / 默认摘要 / 自定义侧重点",把旧分支的关键信息浓缩后附在新位置。
5.5 会话整理习惯建议
- 一个任务一个会话,启动即
--name,避免巨型混合会话撑爆上下文(压缩机制见第 6 章); - 大改动前先
/clone一份,相当于给对话现场做快照; - 用 Shift+L 在关键决策点打标签,事后用 labeled-only 过滤模式快速复盘;
- 定期清理
~/.pi/agent/sessions/下废弃实验会话(或在/resume里 Ctrl+D 走回收站); - 需要分享/存档时用
/export(HTML/JSONL 文件)或/share(私有 GitHub gist 链接)。
本章小结
- 会话是
~/.pi/agent/sessions/--<path>--/下的 JSONL 树文件,id/parentId 构成分支能力的基础; - 恢复四件套:
-c最近会话、-r选择器、--session <path|id>定点恢复、--no-session不留痕; /tree原地分支 + 标签 + 过滤是方案探索利器;/fork、/clone用于拆出新文件;- 切分支会丢上下文,用 branch summary 弥补;
- 命名 + 克隆快照 + 标签复盘是三条实用整理纪律。
🧪 随堂测验
点击你认为正确的选项。答错时会展示正确答案与原因解析。
1. pi 会话文件的底层结构是?
2. 想"原地探索同一问题的多个解法并把它们留在同一个会话里",应优先使用?
3. /resume 选择器中按下 Ctrl+D 会发生什么?
4. 关于 /tree 切换分支时的上下文,正确的说法是?
🛠️ 动手实践
- 找一个历史会话执行
/tree,切到三步之前重问一个问题,观察新分支的生成与原分支的保留。 - 用
/name给当前项目最近三个会话按"日期-主题"规范重命名,再用 Ctrl+N 过滤验证效果。 - 对一次失败的修改尝试使用
/tree的分支摘要功能(自定义侧重点),对比有无摘要时后续对话的质量差异。
进入下一章:上下文压缩 Compaction 与 Context Files,学会驯服无限增长的上下文。