大模型上下文工程实践- 上下文失控
本文节选自我正在整理的 「上下文工程实践」 项目,该项目已完整发布在 GitHub 上。
一、为什么要进行上下文管理
在设计和开发大模型应用时,当模型可以获取到足够的上下文时,设计的重点不再是“获取”,而是“整理”。此时需要关注的是如何对上下文进行有效的管理,通过修剪,压缩,删除等方式,使保留下来的上下文既足够相关,又能被高效利用
有的开发者会停留在获取的阶段,因为模型的上下文窗口一直在持续的扩大,只要上下文窗口足够大,那么获取的信息就不用在整理了,直接将全部的上下文输入给大模型
但是这种方式一定会达到你想要的效果吗?
实际上,更长的上下文并不会生成更好的响应,过度加载上下文会导致你的代理和应用以意识不到的方式失败。上下文可能会被污染,分散模型注意力,令模型困惑或者上下文内容是相互冲突的,这对于依赖上下文来收集信息、推理和协调行动的代理或应用来说是“致命的危险”
接下来我们一起来看看上下文失控的各种情况
1.1、上下文污染
🌟 定义:上下文污染是指幻觉或其他错误进入上下文,并被反复引用的情况
当上下文被污染的时候,代理会发展出无意义的策略,并重复行为,以追求一个无法实现的目标
在用户记忆的上下文中,我们会借助用户输入的历史记录,对这些记录使用大模型进行整理,归纳总结出来用户记忆数据,并且将这些数据存储到记忆模块中,但是如果在整理的时候出现“误解”,那么这个“错误的用户记忆”就一直存储在用户记忆模块中,持续污染相关的上下文查询
例如用户只是一次情绪化的表达:“这节课烦死了,根本没用”
那么系统整理出来的记忆变为:“用户认为《课程 C》没有价值。
后续检索相关用户记忆的时候,这条记忆就可能一直伴随《课程 C》进行回答,就会在长期的交互中误导大模型进行回答
- 有可能用户后面更换了态度,因为那次情绪表达不一定是因为课程的问题,也有可能因为在看这节课程之前,用户的心情已经很糟糕
- 可能用户表达的”这节课“可能是这个知识点或者这章而已,不是整个课程体系
在工具调用错误处理中,我们会向 LLM 输入工具调用错误并且会触发重试机制,但是有些开发者没有用心设计工具调用的错误显示和输出,导致**LLM 接收到的工具调用错误信息,并不一定能准确反映工具出错的真正原因。**所以模型反复在“错误”中重试
📝:关于上下文污染的解决方案,其实更多的会从大模型应用的架构设计开始考虑,例如:
- 在工具错误重试的机制中引入最大的重试次数,同时引入 LLM 反馈机制,当重试失败之后,模型可以将错误信息和原因反馈给用户,让用户输入新的内容来重新调整
- 在记忆模块导致的“过时问题”,那在设计记忆模块的时候,应该有记忆更新和精简的机制
1.2、上下文干扰
定义:上下文干扰是指当上下文变得过长时,模型过度关注上下文,忽视了在训练期间学到的内容。
在代理工作流程中,随着上下文增长,模型会收集更多的信息并累积,累积的上下文可能会变得让模型过度关注上下文信息中的过去动作,而较少利用其训练得到的策略
这个对于在创造性的代理和应用中是非常危险,会让模型的输出结果“固化”并且是较低质量的结果固化
在李继刚中提出的“场域共振”的理念中
我的理解关于场域共振:
- 场域:在你和大模型之间建立一个联系,这个联系就是一个场域,场域是一个交流通道,一个允许你和大模型进行交流的空间
- 共振:这个是结果,不是过程,能够触发这个结果的动作是“在这个场域中让大模型能理解我想做什么,并且它能够留出一定的发挥空间,它能够在这个空间中自由发挥”
场域共振的结果并不满足理解,而是超越理解,例如:我说了一句话,你说了一句话,你这话很懂我,这个本质上还是理解,场域共振最终是一种超越
所以过多的上下文会干扰这个场域中的信号,留给大模型的空间会越来越小,最后的结果无论如何调整也只是“还行,不是太烂”
那如何有效的在提示词或者上下文中输入更多的信息给大模型呢?
“极致压缩,并且在大模型内部发生连锁信息爆炸”
压缩这个词在哲学领域最明显,哲学家提出一个单词的概念,往往代表极深的含义,需要用一章甚至一本书来诠释那个单词的包含的意义,这个在逻辑类的书籍中也是同样存在的,例如:磁场,生产力和生产关系,几何中的对顶角等
整个过程有点像小时候玩的“深水炸弹”,当把“深水炸弹”放入水中的时候,它在水中像“炸开”一样了,整杯水都变得有味道了
我虽然只是传递了几个单词而已在提示词中,几个概念而已,但是在大模型的内部,其借助训练时学到的内容,这些概念和词汇或许已经炸开成为好几本书了,无意中我传递了更多的信息给大模型
📝关于上下文的干扰的解决方案:
- 上下文的修剪
- 上下文的总结
这两个方案都是实际可行的
1.3、上下文混淆
定义:上下文混淆是指模型使用上下文中多余的内容来生成低质量的响应
当你把某些信息放入上下文中,模型就会关注它。这可能是不相关的信息或无用的工具定义,模型都会把这些考虑在内
在工具调用的 LLM 中,传入工具定义给 LLM 是必须的的,但是过多的无关工具和工具定义会导致模型变得混乱,最终选择出来的工具不是正确的
所以在工具定义的上下文中,定义一定要清晰,有边界,同时当工具过多的时候,要适当使用 RAG 的方式去为用户输入检索相关的工具定义上下文给 LLM
📝 关于上下文混淆的解决方案:
- 使用 RAG 技术来检索相关的上下文
- 增强工具模块的定义
1.4、上下文冲突
定义:当你在上下文中加入新的信息或工具时,这些内容与上下文中已有的信息产生矛盾或冲突
这些新的信息不是无用的,而是有效的,只不过和之前的信息发生了冲突
这个在多智能体架构的设计中是最可能出现的,因为多智能的上下文是彼此分开进行的,但是在使用的时候智能体之间会互相使用彼此输出的结果,A 智能体有可能会使用 B 智能体的结果,或者 A 智能体会使用 B 和 C 智能体的结果
例如:现在有一个查询检索的请求,A 智能体并行调用 B 和 C 智能体,B 和 C 智能体可能由于信息来源的问题导致得到的结果是冲突的,那么这个时候冲突的上下文组装输入给了 A 智能体,那么 A 智能体输出的结果就会变得不乐观
📝 关于上下文冲突的解决方案:
- 可以使用上下文隔离的策略,将“大任务”拆分为不同方向的子任务,并且交给不同的 LLM
- 在设计 代理的架构时,可以仔细选择“单智能体架构”还是“多智能体架构”根据应用场景选择
最后
本文节选自我正在整理的 「上下文工程实践」 项目,该项目已完整发布在 GitHub 上。
如果你希望阅读更多相关的章节与案例,可以前往项目仓库查看:
👉 https://github.com/WakeUp-Jin/Practical-Guide-to-Context-Engineering
更多推荐
所有评论(0)