分析 AI 遗忘历史对话的原理,并提供实用解决方案,提升 AI 交互效率。
The desk analogy and markdown state files(桌子类比和markdown状态文件)
我在我的hallucinations博客文章上收到了这样的评论。
就在昨天,Opus在每个提示词后都问我:"我们已经进行了很长时间,让我保存我的上下文,明天继续吧" 😂
:D 我真的每次都回答,你是计算机,继续吧。但情况变得更糟,所以我不得不开始新的会话 :)
模型基本上举手说"嘿,我们已经做了一段时间了。" 这实际上是最好的情况。
很多模型不会这样。它们只会悄悄变差。同样自信的语气,可靠性更差的答案。你不会知道这正在发生,直到出现明显的问题。
你粘贴一个很长的文档,问中间的某些内容,你会得到一个自信但错误的答案。或者你进行了二十条消息的对话,模型开始自相矛盾。
不是因为它在幻觉。是因为它快没地方了。
在前一篇文章中,我们讨论了模型大小。Tokens是成本单位。今天它们成为了内存的单位。
每个模型都有一个上下文窗口。这是它一次能在脑子里容纳的总tokens数。你的输入,加上它的输出,都必须放在这个窗口内。
把它想象成一张桌子。一张固定大小的桌子。模型需要思考的所有东西都必须同时在那张桌子上。你的问题。你粘贴的文档。对话历史。系统指令。所有一切。
如果你在桌子上放太多东西,东西就会开始被埋没。模型不会告诉你"嘿,我放不了所有这些。" 它只是处理它能专注的任何东西,悄悄地失去对其余部分的追踪。
桌子有多大?取决于模型。
一些较旧的模型有4,000个tokens的上下文窗口。那大约是3,000个单词。大约六页。
一些有128,000个tokens。那是一部短篇小说。
一些较新的模型有100万个或更多的tokens。那是多部小说。整个代码库。
但这里是大多数人忽视的一点。更大的上下文窗口并不总是意味着模型对其中的所有内容给予同等关注。这意味着更多的东西放得下。它并不意味着模型以同样的细心阅读每一页。
让我们以两种方式看待这个限制。
你粘贴二十页文本到一个模型。一份法律合同,一份保险政策,内部文档。你问第15节中第7节的某个问题。模型可能找到它,可能错过它,或者完全从错误的部分提取。
围绕你的目标信息的文本越多,模型的注意力被稀释得就越多。即使窗口还没满。
这是大多数人首先遇到的地方,就像上面的评论者一样。
默认情况下,模型没有你对话的单独"内存"。一些产品在上面附加了持久性(ChatGPT的memory,Claude的projects),但下面的模型仍然以同样的方式工作。每次你发送消息时,模型都会从头开始重新读取整个对话。你的第一条消息,它的第一个回复,你的第二条消息,它的第二个回复,一直到你刚才输入的内容。
整个记录每次都被重新输入。每次交换都会增加更多的tokens。
一个典型的问题可能是50个tokens。模型的回复可能是300个。所以一次交换是350个tokens。
十次交换?3,500个tokens。二十次交换?7,000个。
如果你在问详细问题并得到长答案,你可以在一个下午内用掉20,000或30,000个tokens。
这里是关键,你不仅仅在用完内存。你每次都在重新发送和重新支付整个对话历史。
Tokens是内存的单位,也是成本的单位。同样的资源,两个后果。
模型在处理长输入方面已经变得更好得多。你现在可以向它们抛出相当大的文档。但限制仍然存在。输入越长,就越可能遗漏某些内容。
研究人员给这个起了个名字。他们称之为"lost in the middle"。
当你给模型一个长输入时,无论那是文档还是对话历史,它往往会集中注意力在两个地方:最开始,和最结尾。中间的东西会获得更少的关注。
这就像读一个很长的电子邮件线程。你记得它是怎样开始的。你记得最新的消息。但那个埋在十四条消息深处的星期二下午2点的回复?祝你好运。
这就是为什么你在对话早期说的东西会随着记录的增长而漂移。你的早期消息最终在窗口的中间,而中间是注意力最弱的地方。
大多数模型不会警告你。无论它们是在清晰、聚焦的输入中工作,还是在淹没在上下文中,它们都会给你同样的自信语气。评论者用Opus的经历是罕见的例外,而不是规则。
如果你达到限制,使用有更大窗口的模型。更大的窗口就像一个更大的背包。你可以携带更多。但这并不意味着你可以立即找到你需要的东西。所以这些策略的其余部分仍然很重要。
如果你不需要所有内容,不要粘贴所有内容。
如果你的问题是关于第3节,给它第3节。不是整个文档。更少的噪音,更好的信号。
先总结,再提问。
如果你需要模型处理一个长文档,先要求它总结文档。然后根据总结提问你的真实问题。两次调用而不是一次,但第二次调用的上下文是聚焦的。只需确保总结没有遗漏重要的东西。
把重要的东西放在开头或末尾。
如果你写的提示包含参考材料,把你的实际问题放在最后。或者把最关键的上下文放在最开始。不要把重要的部分埋在中间。
重述重要的约束。 如果你在第一条消息中告诉模型某些关键内容,而现在你在第十五条消息,再说一遍。花费你几个tokens。节省你一个错误的答案。
使用系统提示词来处理持久规则。 大多数平台都有一个地方可以放置一致指导模型的指令。在ChatGPT或Claude.ai中,它被称为custom instructions。在Amazon Bedrock中,它是系统提示词字段。用清晰、明确的语言把你的稳定规则放在那里。但不要假设它们会完美地永远被遵循。在长对话中,在你当前的消息中重复关键指令仍然有帮助。
对话偏离时开始新会话。 如果你已经聊了20轮,话题已经转换了三次,开始一个新的对话。带上重要的东西。留下不重要的。
你可以把旧的回合总结成一个紧凑的概述,把它存储在某个地方(数据库、文件,甚至一个简单的变量),并在每次新调用的开始处注入该摘要。这本质上是一个对话上下文的DIY缓存。你可以构建一个版本,针对你的用例调整重要内容。
如果你是一个构建者,这应该很熟悉。我们曾经在Postgres前放Redis,这样不是每个请求都要打数据库。这里也是同样的模式。一些平台提供提示词缓存,其中系统提示词或重复的上下文被处理一次并在调用之间重复使用,而不是每次都被重新tokens化。你不会在每个请求上为相同的静态上下文重新支付。同样的直觉,不同的层:缓存昂贵的重复工作,只发送新的东西。
如果你想深入了解,请阅读Amazon Bedrock上的提示词缓存。
对于文档,检索是答案。与其把整个文档塞入上下文窗口,不如只检索相关的块并传入那些。这就是RAG(Retrieval-Augmented Generation)做的,我们将在下一篇文章中讨论。
两者的原则相同:给模型更少,但给它正确的更少。
如果你才刚开始:模型有一个叫上下文窗口的内存限制。它同时应用于文档和对话。更长的输入意味着更稀的注意力。如果你粘贴的东西很长,询问特定的部分。如果你在一个长对话中,重述重要的东西。如果事情开始感觉不对,开始新的会话。
如果你更多是构建者:上下文窗口大小是规格说明,不是保证。一百万token的窗口不意味着一百万tokens的完美回忆。把关键信息放在边缘,而不是中间。对于对话,实现旧回合的总结。开始思考检索,因为那是这个要去的地方。
所以当你给模型太多东西时,模型会忘记东西。如果有一种方法可以在正确的时间从你甚至从未自己粘贴过的文档中给它正确的东西呢?
下一篇文章,我们将深入研究检索。在正确的时间给模型正确的部分。
这篇文章是"Learning AI Out Loud"系列的一部分,一位云架构师从第一原理学习AI。
跟随系列
一些评论可能仅对已登录的访问者可见。登录以查看所有评论。
如需进一步操作,你可以考虑屏蔽此人和/或举报滥用。