Pi Agent 学习笔记:对话怎样保存、分支与恢复

hello 我是逆境不可逃

用 Agent 处理一个任务,往往要经历多轮讨论和工具调用。有时做到一半需要退出,有时发现方案不合适,想回到前面换个方向。会话管理要解决的,就是这些记录如何保存,以及继续任务时应该取出哪些内容。

Pi 把会话组织成带有父子关系的记录。这种结构既能保留不同尝试,也能从中提取当前分支的上下文。

回到前面继续,对话会形成分支

假设一段对话已经发展到 D:

text 复制代码
A:提出需求
→ B:明确约束
→ C:讨论方案一
→ D:完善方案一

现在想回到 B,尝试方案二。删除 C、D 会丢失之前的讨论;直接在 D 后面续写,又会把方案一的内容继续带给模型。

Pi 可以把当前续写位置移回 B,让新记录接在 B 后面:

text 复制代码
A:提出需求
└─ B:明确约束
   ├─ C:讨论方案一
   │  └─ D:完善方案一
   └─ E:要求尝试方案二
      └─ F:讨论方案二 ← 当前续写位置

每条记录有自己的编号,也记录父节点,也就是它接在哪条记录后面。C 和 E 的父节点都是 B,于是它们形成两个不同方向。

切换分支本身不会删除旧记录。C、D 不再属于当前路径,但仍然可以用于查看和比较。

保存顺序与对话顺序可以不同

Pi 用 JSONL 文件保存会话。可以把它理解为每行一条记录,行内保存该记录的类型、内容和关联信息。

从 B 分支后新增 E,文件中的顺序可能是:

text 复制代码
保存顺序:A、B、C、D、E
E 的父节点:B
当前对话路径:A → B → E

文件中排在 E 前面的是 D,但 E 并不接着 D。承接关系由父节点决定,不能靠行号猜测。

普通的消息追加会把新记录接到当前续写位置,再把当前位置推进到新记录。会话文件建立后,新增记录通常追加到末尾,不必每次重写全部历史。新会话的首次落盘还存在延迟写入逻辑,因此不能把"内存里已有记录"理解成"此刻一定已写入文件"。

这种组织方式把两个需求分开了:文件按产生顺序保存记录,对话按父子关系形成分支。

保存的全部历史,不等于模型看到的上下文

继续看前面的会话树。当前在 F,暂不考虑压缩或分支摘要,模型需要的路径是:

text 复制代码
A → B → E → F

Pi 从当前记录往前查找父节点,再调整为从早到晚的顺序,构造这一条路径。C、D 留在会话历史中,但不会因为保存在同一个文件里,就自动混进当前分支。

这样可以避免模型把方案一与方案二的决定混在一起。

Pi 也支持分支摘要:把离开分支中的有用信息整理成摘要,再接入新分支。例如方案一已经确认某种依赖不可用,这条结论可能值得带到方案二。带入的是明确的摘要记录,而不是把其他分支的全部消息拼进来。

会话中还可以记录模型切换、压缩等信息。它们用于恢复设置或构造上下文,并不全都作为普通聊天文本发送给模型。

恢复会话,恢复的是什么

重新打开会话时,Pi 读取已经保存的记录,重建索引和续写位置,再按所选路径构造上下文。恢复的依据是文件中的历史,而不是模型自己记住了上次的对话。

对 Agent 来说,只保存用户和模型的文字还不够。工具请求及其结果也关系到后续判断:

text 复制代码
用户:读取配置文件
模型:请求读取工具
工具:返回文件内容
模型:根据内容解释配置

丢掉工具结果,就会失去"当时实际读到了什么"的依据。恢复这些消息后,模型才能利用先前观察继续处理任务。

不过,加载历史中的工具请求,并不会自动重新执行它。否则,历史里每一次追加配置、创建工单,都可能在恢复时再发生一遍。记录过去的动作,与调度新的动作,是两个不同步骤。

历史记录与当前文件状态要分开看

假设昨天工具成功修改了配置,今天另一个程序又修改了同一文件。会话里保存的"修改成功"仍然描述昨天的操作,却不能保证文件今天还是那个样子。

因此,用旧记录回答"昨天为什么这样改"是有依据的;回答"文件现在是什么内容",通常需要重新读取。

同样,回到旧对话节点不会自动把项目文件恢复到当时的版本。需要恢复文件时,还要依靠 Git、备份或其他文件版本机制。

还有一种更难处理的情况:会话里有工具请求,却没有对应结果。下面是一个可能的故障场景:

text 复制代码
工具已经追加配置
→ 程序意外退出
→ 成功结果尚未写入会话

缺少结果只能说明当前证据不完整,不能直接判定操作没有发生。恢复任务时,应先检查目标文件或外部系统,再决定是否重试。尤其是追加、创建等有副作用的操作,盲目重试可能造成重复。

会话保存和业务文件修改没有天然组成一个事务。这个边界决定了恢复流程不能只看聊天记录,还要在必要时重新确认外部状态。

用测试核对分支与恢复

本地运行了仓库已有的两组会话测试,共 47 个用例通过。测试使用构造的消息与临时会话文件,不请求真实模型。

其中几项直接对应前面的讨论:

  • 从旧节点分支后,新记录的父节点指向分支起点,原来的子节点仍然保留。
  • 同一份记录包含两条路径时,构造上下文只取指定路径。
  • 带有工具结果、压缩摘要和分支摘要的会话写入文件后,可以重新打开并保留测试断言中的记录及用量信息。

这些测试验证了记录结构和正常文件重载。它们不代表工具执行与会话落盘具备原子性,也不代表恢复会话会还原项目文件。

会话树保存了不同尝试,父节点关系决定当前讨论沿哪条路径继续。真正恢复任务时,还要结合工具结果和当前外部状态,判断哪些已经完成、哪些需要重新确认。


相关推荐
huaweichenai1 小时前
spring boot使用hutool实现调用外部接口
java·spring boot
泡海椒1 小时前
Java 后端最优 PDF 导出方案:jquick-pdf 项目引入与快速测试
java·开发语言·pdf
阿飞7662 小时前
订单超时自动关单:RabbitMQ 延迟队列 + 定时任务"双保险"实践
java
二炮手亮子2 小时前
使用云服务+hermes+mino模型 我用微信操控服务器自己编程并部署实操
java·语言模型·ai编程
她的男孩2 小时前
安全同事找我要"上周所有登录失败记录",我查完数据库:一条都没有
java·后端·架构
m0_587383002 小时前
本地同城无人机作业接单系统源码:架构拆解与抢单调度实现
java·小程序·架构·需求分析
FantanLee2 小时前
面试级「分布式 ID 设计方案」
java
青春易逝丶2 小时前
Maven
java·maven
吠品2 小时前
纯HTML+ECharts构建交互式数据看板:实现思路与踩坑记录
java·服务器·数据库