教程文档【免费下载链接】how-pi-agent-worksPi Agent 原理与实现项目地址https://gitcode.com/gh_mirrors/ho/how-pi-agent-works点击查看免费下载你是否好奇 AI Agent 是如何记住我们之前说过的话的how-pi-agent-works 是一个中文的 Pi Agent 原理与实现教程项目它用 JSONL 文件 会话树 分支切换的组合完整解决了 Agent「记住历史」的问题。本文带你彻底搞懂 JSONL 会话树的实现原理以及分支切换如何让 Agent 回到任意历史节点重新探索。 为什么 AI Agent 的记忆不是简单数组对 Agent 来说会话session不只是「聊天记录」它承担着三个职责保存历史支持断点续作支持从早期节点重新探索另一条路径比如换个方案再试一次为上下文构建、压缩和导出提供结构化材料。线性数组只能应对「接着聊」一旦需要「回到上一轮换一种问法」引用位置会瞬间错乱。docs/concepts/sessions.md 对此做了系统阐述会话必须是一棵树而不是一条线。 为什么选择 JSONL 存储会话JSONLJSON Lines的格式是每一行一个独立的 JSON 对象。一个真实的会话文件长这样{type:session,version:3,id:s1,cwd:/project} {type:message,id:a1,parentId:null,message:{role:user,content:修 README}} {type:message,id:a2,parentId:a1,message:{role:assistant,content:[]}}优点对 AI Agent 的好处追加写简单每产生一个条目就 append 一行无需重写整个文件崩溃恢复友好写入中途崩溃已写入的行仍可解析适合长会话上万条消息也只需不断追加不必每次序列化大 JSON便于外部工具处理rg、脚本、日志工具都能直接扫描详见 docs/source/session-compaction.md。 会话树的核心id、parentId 与 leafId每个 entry 都带一个稳定id并用parentId指向父节点。整个文件因此组织成一棵树u1 用户问题 └─ a1 助手的初始方案 ├─ u2 继续方案 A │ └─ a2 方案 A 的结果 ← 分支 A └─ u3 改走方案 B └─ a3 方案 B 的结果 ← 分支 B教学版中这套数据结构定义在 protocol.ts每个message和compaction条目都有id/parentId两个关键字段。树中还有一个关键概念leafId叶子它代表当前会话视角的末端。文件里可以有很多分支但同一时刻只有一个 leaf 是「当前正在聊的位置」。 构建上下文从 leaf 一路回溯一个关键设计构建上下文时不是把文件里所有条目都发给模型而是从当前 leaf 沿parentId一路回溯到根再反转为正序。核心实现在 sessionStore.ts 的 pathToLeaf()while (current) { path.unshift(current); current current.parentId ? this.byId.get(current.parentId) : undefined; }如果当前 leaf 是a3模型看到的历史路径就是u1 → a1 → u3 → a3而u2 → a2这条分支虽然还在文件里却不属于当前上下文。 分支切换移动 leaf而不是删除历史分支切换是这套设计最精妙的地方——切分支不删除任何数据只是移动 leaf 指针教学版通过 switchLeaf() 校验目标节点存在后直接替换leafId服务层暴露POST /api/branch接口切换成功后向前端推送branch_switch事件见 server/index.ts前端收到事件后刷新会话视图旧分支随时可以再切回来。单元测试清晰地验证了这个行为切到分支 B 时上下文忽略分支 A再切回分支 A 时又能完整恢复见 sessionStore.test.ts。 Pi 的/tree还有一个很妙的交互选中一条用户消息时leaf 不会移到这条消息本身而是移到它的父节点同时把原消息文本回填到编辑器——你可以改写原问题后重新提交自然形成一条新分支。这正是「带着修正后的提问回到历史分叉点」。 3 分钟动手运行 Demo 3 感受会话树clone 仓库后执行npm install npm run demo:03Demo 会先建一条主线再从中间节点分出另一条分支最后分别打印两个 leaf 的上下文路径。输出大致如下leaf A context: user: 我想实现一个 Agent。 assistant: 可以从 Agent Loop 开始。 user: 选择方案 A assistant: A 的结果 leaf B context: user: 我想实现一个 Agent。 assistant: 可以从 Agent Loop 开始。 user: 选择方案 B assistant: B 的结果可以看到两条分支共享前半段历史却各自只看到自己那一路的对话。源码在 03-session-tree.ts配套的图文讲解见 docs/demos/03-session-tree.md。 会话条目不只是消息session 文件里记录的并不只有对话。不同 entry 负责恢复不同维度的运行状态entry 类型解决什么问题message构建后续 LLM 上下文model_change恢复时知道上一轮用的 provider/modelthinking_level_change恢复 reasoning 设置compaction长会话用摘要替代旧消息branch_summary分支跳转后携带离开分支的经验custom/custom_message扩展持久化自己的状态或注入上下文教学版只实现了message和最小化的compaction但类型上保留了扩展空间。特别值得一提的是压缩compaction不是删除历史而是追加一条摘要 entry旧消息原样保留随时可以重新构建分支设计思路见 docs/source/advanced-compaction.md 与 session-compaction.md。⚠️ 四个常见误区误区后果正确做法用数组下标表示历史位置删除、压缩、分支后引用会错用稳定id和parentId切分支时删除旧分支失去探索记录无法回滚保留旧 entry只移动 leaf压缩后把旧消息全删掉无法审计和重新构建分支追加 compaction entry不破坏原始历史只保存 assistant 最终文本工具结果和错误全部丢失用户、助手、工具结果都作为消息保存 延伸阅读会话树概念详解docs/concepts/sessions.md会话格式与压缩链路docs/source/session-compaction.mdAgentSession 运行层分层思想docs/source/agent-session.md教学版会话存储实现examples/teaching-agent/src/server/agent/sessionStore.ts前后端共享协议类型examples/teaching-agent/src/shared/protocol.ts写在最后回到最初的问题AI Agent 如何记住历史答案是——用 JSONL 追加写把每一步都变成不可变条目用id/parentId把条目组织成树再用一个轻量的leafId指针决定模型此刻能看到哪条路径。切分支只是移动指针压缩只是追加摘要历史永远完整可回滚。这套「JSONL 会话树 分支切换」的设计正是 how-pi-agent-works 教程中最值得你动手跑一遍npm run demo:03的核心机制。赞分享教程文档【免费下载链接】how-pi-agent-worksPi Agent 原理与实现项目地址https://gitcode.com/gh_mirrors/ho/how-pi-agent-works点击查看免费下载相关推荐Positron Agent Sessions 多会话导航 E2E 测试场景全解析会话切换与历史加载验证Positron Agent Sessions 多会话导航 E2E 测试场景全解析会话切换与历史加载验证 本篇文章围绕 Positron 仓库中 Agent代码编辑器桌面应用开发工具数据科学AI 应用如何管理 thClaws 会话恢复、切换与 JSONL 存档完全指南如何管理 thClaws 会话恢复、切换与 JSONL 存档完全指南 thClaws 会话管理完全指南thClaws 是一款开源 AI 智能体工具所有对话pi Coding Agent 会话文件格式Session Format详解JSONL 存储、树状分支结构与上下文重建机制pi Coding Agent 会话文件格式Session Format详解JSONL 存储、树状分支结构与上下文重建机制 pi 的 coding age人工智能大模型AI Agent代码智能体AI 应用工具调用上一篇Rufus 3步解决老旧电脑升级Windows 11难题TPM限制绕过全攻略下一篇签署流程分支逻辑DocuSeal条件路由实现创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
阅读完成 · 觉得有帮助?