上一篇我们给 omp 立了个坐标:终端里的 AI 编程助手,跟 Cursor/Windsurf 同类。但当时只字未提它最反直觉的能力——一个会话跑几个小时、改几十个文件、跨多轮工具调用,上下文为什么不爆、不丢、能回溯?
答案藏在一个叫 Session Tree 的数据结构里。本篇拆开它。
问题:为什么传统 chat 容易崩
先说清楚要解决什么。普通的 LLM 对话是线性的:每条消息追加到列表末尾,整段历史塞进下一次请求的 prompt。一旦对话变长:
- token 爆炸:上下文窗口塞满,老消息被截断或报错
- 走错路没法回头:agent 做了一步操作你立刻后悔,但没有”撤销这一轮”的语义
- 分支探索不可能:想试两种方案对比?只能开两个会话从头来
omp 把 session 当成版本控制问题而不是聊天记录问题——这才是关键差异。
数据模型:日志 + 树
底层存储很简单:追加写入的 JSONL 文件,每行一个条目(用户消息、agent 回复、工具调用、工具结果……)。追加写入意味着永不修改历史,跟 git 一样安全。
但运行时它把这串日志重建成一棵树。每个条目有 id 和 parentId,当前位置由 leafId 标记:
interface SessionTreeNode { entry: SessionEntry; children: SessionTreeNode[]; label?: string;}你看到的”当前对话”其实是从根到 leafId 的一条路径。任何时刻你都能把 leafId 跳到树的另一个节点——这就是”时间旅行”。
三个核心操作
1. /tree — 打开树选择器
输入 /tree,或双击 Escape(空编辑器状态下),弹出交互式树形选择器,支持模糊搜索和键盘导航。选中任意节点,leafId 跳过去,对话从那条路径重建。等于 git checkout 任意 commit。
实战中最常用场景:agent 改着改着走偏了,你 /tree 跳回三步之前那个分支点,重新引导——不用开新 session 重打一遍背景。
2. /btw + branch — 旁路提问
写到一半想问个小问题(“这个 API 的参数顺序是啥?”),又不想污染主对话。用 /btw 提问,回答显示在浮层面板,主对话不动。
如果觉得这个回答值得并进主线:在面板里按 b(Branch),omp 会在会话树里创建新分支,把 /btw 的问答合并进去。按 c(Copy)则只复制到剪贴板,不入主线。
这是”低成本探索”的入口——不破坏主任务节奏,又能临时查证。
3. Branch Summary — 跨分支带记忆
这是整个 session 机制里最精彩的部分。
想象你尝试方案 A 走了 20 步发现死路,/tree 跳回去试方案 B。问题来了:**走 A 的那 20 步上下文怎么办?**直接丢弃的话,agent 不知道”之前试过 A 不行”,可能又往那个方向走。
omp 的做法:跳到 B 时,自动把”从 A 的当前点到 A/B 公共祖先”这段路径用 LLM 生成摘要,插入到 B 的起点。算法在 packages/agent/src/compaction/branch-summarization.ts:
collectEntriesForBranchSummary() 1. 找 old leaf 与 new leaf 的最近公共祖先 2. 收集 old leaf → 公共祖先 的所有条目 3. 按时间排序,LLM 生成摘要 4. 摘要插入 new leaf 位置效果:切到 B 后,agent 的上下文里有一段”之前试过 X 方案,遇到 Y 问题,放弃”的摘要——既不浪费 token 跑完整 A 历史,又不丢失关键教训。
跟 Compaction 的分工
容易混淆的两个机制,列清楚:
| 机制 | 作用对象 | 目的 |
|---|---|---|
| Compaction | 当前分支的历史 | 压缩上下文长度,把老对话重写成摘要 |
| Branch Summary | 被离开的分支 | 跨分支带记忆,让新分支知道”试过什么” |
两者都持久化为 session 条目,在重建 LLM 上下文时作为 user-context 消息注入。简单说:Compaction 是同一条路的压缩,Branch Summary 是换路时带便签。
Agent Hub — 多 agent 的 session 视图
会话树之外,omp 还有一个 Agent Hub(Alt+A 或 Ctrl+S):子代理管理中心。表格视图列出所有子代理(task、explore、reviewer……)的状态(running/idle/parked)、未读 IRC 消息、当前任务;选中后切到对话视图,可以直接发消息 steer 子代理。
这跟 session tree 的关系:每个子代理有自己的 session 树,Agent Hub 是跨 session 的总览。多 agent 协作时,这里是观察调度情况的指挥台。专栏后面讲多 agent 时会展开。
实战建议
跑了几个月后我总结了三条:
- 走偏立刻
/tree——别犹豫。等到 agent 改了 5 个文件再回头,比立刻 fork 代价大得多 - 复杂探索用
/btw+ branch——比开新 session 便宜,比直接问污染主对话干净 - 别怕 Branch Summary——它自动跑,你只需要知道”换分支不会失忆”,剩下交给系统
session 是 omp 的对话载体,但光有载体还不够——你还需要在载体上注入约束,让 agent 按你的项目规范走。下一篇我们就讲这个:omp 的 Rules 系统,以及它的”实时中断”高级形态 TTSR。