4 分钟阅读

Pi Agent Sessions:把一次对话变成可回溯的工作树


很多 Coding Agent 的“继续上次任务”,本质上只是把聊天记录接回来。

Pi Agent 的 Sessions 不太一样。它不是只保存一条线性的对话,而是把会话保存成一棵可以继续、回看、分叉、克隆、压缩和导出的工作树。

如果你经常让 Agent 做重构、排障、方案对比,Sessions 这块值得单独看。

Sessions 到底存在哪里

Pi 会自动把对话保存到:

1
~/.pi/agent/sessions/

并且按工作目录组织。每个 session 是一个 JSONL 文件,内部是树状结构,而不是简单的一串消息。

这意味着你在同一个项目里做过的尝试、绕过的路、回滚到的节点,都可以被留在 session 里。下一次回来时,不一定只能从最后一条继续,也可以从中间某个节点重新出发。

常用启动参数可以先记这几个:

1
2
3
4
pi -c                 # 继续最近一次 session
pi -r                 # 浏览并选择历史 session
pi --no-session       # 临时模式,不保存 session
pi --name "my task"   # 启动时设置 session 名

1
2
pi --session <path|id> # 使用指定 session 文件或部分 ID
pi --fork <path|id>    # 从指定 session 分叉出新 session

进入交互模式后,用 /session 可以查看当前 session 文件、session ID、消息数、token 和 cost。

这些命令解决的不是同一个问题

Pi 的 session 命令很多,但可以按使用场景理解:


你想做什么用什么
找回之前的任务/resumepi -r
开一个全新上下文/new
给当前任务起个好找的名字/name <name>
查看当前会话信息/session
在当前会话树里跳转/tree
从历史用户消息创建新会话/fork
把当前活跃分支复制成新会话/clone
压缩旧上下文/compact [prompt]
导出 HTML/export [file]
上传为私有 GitHub gist 并获得可分享 HTML 链接/share

我觉得最关键的是:/tree/fork/clone 不是同义词。


/tree:在同一个 session 里走分支

Pi 官方文档里明确说,Sessions 是树。每个 entry 都有 idparentId,当前位置是 active leaf。

这就像一次工程任务里,你先让 Agent 走方案 A,发现有风险;再回到更早的用户问题,让它走方案 B。两个路径都还在,只是 active leaf 不同。


flowchart TD
    A[原始问题] --> B[Agent 第一次回答]
    B --> C[方案 A]
    C --> D[方案 A 的结果]
    B --> E[方案 B]
    E --> F[方案 B 的结果]

/tree 适合在同一个 session 文件里保留这些替代路径。它更像“在一棵工作树里切换节点”,不是新建一份记录。

选中不同类型的节点时,行为也不同:

  • 选中 user 或 custom message:Pi 会移动到该消息的父节点,把这条消息放回编辑器,你可以改写后重新提交,从而创建新分支。

  • 选中 assistant、tool、compaction 等非用户消息:Pi 会移动到该节点,编辑器保持为空,你可以直接从那里继续。
  • 选中根用户消息:会把 leaf 重置为空对话,并把原始 prompt 放回编辑器。

这个设计对“我刚才那个提示词没写好,想从那里重来”特别有用。

/fork/clone:需要新文件时再用

/tree/fork/clone 的差异可以这样记:


功能输出典型用途
/tree仍在同一个 session 文件在当前任务里探索替代路径
/fork创建新的 session 文件从更早的用户消息另开一条线
/clone创建新的 session 文件复制当前活跃分支,继续做后续实验

如果你只是想在一个任务里对比 A/B 两种修法,用 /tree 就够了。

如果你希望把某条路径独立成一个新任务,后面单独命名、分享或继续,那就用 /fork/clone


命名、搜索、删除:别让历史会话变成垃圾堆

Sessions 多了之后,命名非常重要。

你可以在会话中执行:

1
/name Refactor auth module

也可以启动时直接命名:

1
2
pi --name "Refactor auth module"
pi --name "CI audit" -p "Review this build failure"

/resumepi -r 会打开当前项目的 session picker。在里面可以搜索、切换路径显示、切换排序方式、只看已命名会话、重命名和删除。

删除时,如果系统里有 trash CLI,Pi 会优先使用它,而不是直接永久删除文件。

分支摘要:切走之前,给旧路留一张便签

还有一个容易被忽略的细节:当 /tree 从一个分支切到另一个分支时,Pi 可以把被离开的分支总结一下,并把摘要挂到新位置。

你可以选择:


  • 不生成摘要
  • 使用默认 prompt 总结
  • 用自定义重点说明来总结

这对长任务很实用。你不需要完整重放旧分支,也能保留“那条路为什么走不通”“已经确认过哪些事实”“有哪些代码线索”。

怎么用更顺手

我的建议是:

  • 重要任务启动时就用 --name 命名,不要等历史堆起来再找。

  • 日常继续用 pi -c,找旧任务用 pi -r
  • 探索替代方案先用 /tree,需要独立沉淀时再 /fork/clone
  • 上下文太长时用 /compact [prompt],把旧内容压成更可控的摘要。
  • 需要复盘或交接时用 /export;需要分享 HTML 链接时再考虑 /share

Pi 的 Sessions 不是单纯的“聊天记录保存”。它更像 Agent 时代的任务日志:保留上下文、保留分支、保留成本信息,也保留你和 Agent 一起试错的路径。对编码 Agent 来说,这件事很关键。因为真正复杂的工程任务,很少是一条直线做完的。