Skip to content

第 5 章 · 会话管理:恢复与分支

本章目标:理解 pi 会话的存储结构与树形本质,掌握恢复/命名/分叉/克隆全套操作,能在同一会话里安全地"回到过去"尝试不同方案。

5.1 会话存在哪里

会话以 JSONL 文件自动保存,按工作目录归档:

text
~/.pi/agent/sessions/--<path>--/<timestamp>_<uuid>.jsonl

<path> 是工作目录路径(/ 替换为 -)。每个 JSONL 文件不是线性日志,而是一棵消息树:每条记录带 idparentId,当前活跃位置是树的叶子节点——这正是"in-place 分支"(不复制文件就能开岔)的数据结构基础。会话格式已迭代到 v3(v1 线性结构会在加载时自动迁移)。

bash
# 快速查看某个会话文件的内容形态
head -3 ~/.pi/agent/sessions/--Users-you-demo--/*.jsonl | python3 -m json.tool 2>/dev/null | head -20

每行是一个带 type 字段的 JSON 对象:用户/助手消息、模型切换、思考等级变更、标签、压缩摘要、分支摘要、扩展条目等都各是一种条目类型。

5.2 恢复会话的四种姿势

bash
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 命名:让历史可检索

bash
pi --name "重构认证模块"        # 启动时命名(-n 同义)
text
/name 重构认证模块      # 会话中改名

命名会话在 /resumepi -r 中更容易被找到,配合 Ctrl+N 过滤可以快速定位长期任务。团队协作场景建议约定命名规范(如 任务号-简述)。

5.4 分支:在同一棵树上尝试不同方案

这是 pi 会话系统最有价值的能力。典型场景:让智能体改一段复杂逻辑,结果不满意——不必撤销重来,直接分叉。

/tree —— 原地导航整棵会话树

text
├─ 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 会话整理习惯建议

  1. 一个任务一个会话,启动即 --name,避免巨型混合会话撑爆上下文(压缩机制见第 6 章);
  2. 大改动前先 /clone 一份,相当于给对话现场做快照;
  3. 用 Shift+L 在关键决策点打标签,事后用 labeled-only 过滤模式快速复盘;
  4. 定期清理 ~/.pi/agent/sessions/ 下废弃实验会话(或在 /resume 里 Ctrl+D 走回收站);
  5. 需要分享/存档时用 /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 切换分支时的上下文,正确的说法是?

🛠️ 动手实践

  1. 找一个历史会话执行 /tree,切到三步之前重问一个问题,观察新分支的生成与原分支的保留。
  2. /name 给当前项目最近三个会话按"日期-主题"规范重命名,再用 Ctrl+N 过滤验证效果。
  3. 对一次失败的修改尝试使用 /tree 的分支摘要功能(自定义侧重点),对比有无摘要时后续对话的质量差异。

进入下一章:上下文压缩 Compaction 与 Context Files,学会驯服无限增长的上下文。