对话历史
一段长时间的对话会撞上一堵硬墙:模型的上下文窗口。本页的一切内容都因这堵墙而存在,而真正有意思的部分在于:哪些东西会被丢弃、哪些会被保留,以及哪些还能再找回来。
回收上下文的四种方式
标题为“回收上下文的四种方式”的部分与其说它们是几个备选项,不如说它们是一架梯子,从代价最低的开始。
| 机制 | 代价 | 保留 | 丢失 |
|---|---|---|---|
| 省略 | 无 | 叙述中的每一个字 | 平淡无奇的旧工具结果 |
| 图像剥离 | 无 | 它们周围的文本 | 旧截图 |
| 快照 | 无 | 以像素形式保留的每一个字 | 无视觉模型的可读性 |
| 摘要 | 一次模型调用 | 一段叙述 | 它没有挑选的细节 |
省略和剥离先执行,因为它们是免费的,而且在真正重要的意义上无损:它们丢掉的都是没人会再读的冗余内容。
为什么摘要是最后手段
标题为“为什么摘要是最后手段”的部分摘要是这四种方式中唯一要花一次模型调用的,也是唯一会替你决定什么才算重要的。两者都是实实在在的代价。而更有意思的是那次调用,因为它出现的时机。
压缩通常在撞墙之前按阈值触发。但它也会被动触发:在提供方自己以请求过大为由拒绝之后——启发式估算低估了提供方实际测到的数量。在这种情况下,采用摘要的压缩器必须再发一次请求来缩减上下文,而它发出的这次请求,恰恰就是刚刚溢出的那一次。
快照压缩把被丢弃的历史渲染成布满像素字形的密集页面,再以图像的形式交还。
其前提源于一个计费上的怪癖:视觉模型对图像按固定费率或按面积计费,与图像里有多少字符毫无关系。一万二千个字符被丢弃的对话,要花掉相当于一万二千个字符的文本 token。同样的字符渲染到一页上,只花一张图像的钱。
它之所以值得拥有,而不只是显得聪明,是因为它不需要模型调用、不需要密钥,也不需要网络。它是溢出恢复期间唯一始终可用的策略。
重建后的形态是:原文照录的头部、转为图像的中间部分、原文照录的尾部。头部是任务以及下游一切都要回指的那些约束;尾部是当前工作所在的位置。中间部分被重读得最少,代价却最高。
快照在每一轮都从保留的源文本重新渲染,绝不基于上一轮的像素。对图像再成像,字形每压缩一次就损失一代,直到没有任何东西能读懂它们。
一次运行到底从哪里恢复
标题为“一次运行到底从哪里恢复”的部分过去,每次运行框架运行都从空历史开始,靠提示词里的 <context> 块重建连续性——那是对话的摘要,而不是对话本身。由此带来三个后果:
- 恢复等于重新讲述。 模型从未看到自己先前的推理,也没看到工具实际返回的字节,只看到对它们的描述。
- 回退随进程一同消亡。
checkpoint是指向实时消息列表的一个索引,因此重启会丢失模型设过的每一个标签。 - 重试无法区分“没有可重试的内容”和“什么都没加载”。 无论哪种情况,重启后失败的那一轮都已从实时状态中消失。
这三个问题都通过持久化对话记录得到解决。它在每个回合边界保存,绝不在回合中途保存:在工具调用与其结果之间捕获的历史,没有任何提供方会接受,因此在这一瞬间崩溃,恢复的是上一个完整回合,而不是一个无法重放的半截回合。
恢复后的运行会裁剪到最新的消息,剪切点是不留下孤立工具结果的那种边界——一次结果如果它的调用被裁掉,这种请求会被提供方直接拒绝,而一份发不出去的对话记录比一份更短的记录更糟。
会话树
标题为“会话树”的部分每条消息都记录自己所承接的上一条消息,每个对话都指明自己当前的分支末端。这一个决定就是整个特性的全部。
建立分支不写入任何内容。 它只是移动指针。你离开的那条路径仍然在那里,所以切回去只是再移动一次指针,而不是做一次恢复——而且为了重跑而修改提示词,也不再会让你失去那个正在用来对比的答案。
没有它,任何形式的后退都必须隐藏或删除消息,而隐藏是一个后来的读者看不穿的谎言。
分支与分叉
标题为“分支与分叉”的部分| 分支 | 分叉 | |
|---|---|---|
| 发生的事 | 指针移动 | 路径被复制 |
| 结果去向 | 同一个对话 | 一个新对话 |
| 代价 | 无 | 分支的一份副本 |
分叉会用全新的 id 复制,而不是共享数据行。两个共享数据行的对话会互相看到对方后来的消息,而这恰恰是分叉绝不该做的事。
回退沿用同一个指针
标题为“回退沿用同一个指针”的部分运行期间的 checkpoint / rewind 组合会标记一个干净的回合边界,并在一次探索之后回到那里,同时保留一份摘要。由于检查点与对话记录一起持久化,模型在重启前设下的标签仍然会落在它当初被设置的位置。目标没有在裁剪中存活的检查点会被丢弃,而不是被就近钳制——“回到该标签”却落在别处,恰恰是标签存在的意义所在:防止这种失败。
- 分支对话 — 树形导航器、分叉与导出
- 工具上下文与提示缓存 — 填满上下文窗口的另一半
- 斜杠命令 —
/compact、/shake、/context、/tree