引言
大型语言模型无疑能实现惊人功能。但除了内部知识库外,它们高度依赖输入的信息(即上下文)。上下文工程的核心在于精心设计这些信息以使模型成功运作。当工程师发现仅靠编写巧妙提示不足以应对复杂应用时,这一理念逐渐流行。如果模型不知道所需事实,它无法猜测。因此,需要整合所有相关信息,使模型真正理解当前任务。
术语"上下文工程"受到关注的部分原因源于安德烈·卡帕西广为传播的推文:
支持用’上下文工程’替代’提示工程’。人们将提示视为日常使用中给LLM的简短任务描述,而在每个工业级LLM应用中,上下文工程是一门精妙的艺术与科学,旨在用恰到好处的信息填充上下文窗口以支持下一步操作…
本文将保持一定理论性,并尽量简化内容。
什么是上下文工程?
如果收到请求:“嘿,能写篇关于LLM工作原理的文章吗?"——这是一个指令。我会撰写认为合适的内容,并瞄准中等专业水平的受众。如果受众是初学者,他们可能难以理解内容;如果是专家,可能认为过于基础或脱离上下文。还需要一系列指令,如受众专业水平、文章长度、理论或实践重点以及写作风格,才能写出引起共鸣的文章。
类似地,上下文工程意味着向LLM提供从用户偏好和示例提示到检索事实和工具输出的一切信息,使其完全理解目标。 以下是我创建的视觉图,展示可能输入LLM上下文的元素:
每个元素可视为模型上下文窗口的一部分。上下文工程是决定包含哪些元素、以何种形式及顺序排列的实践。
上下文工程与提示工程的区别
我不会 unnecessarily 拉长内容。希望您已理解核心概念。但对于未理解的读者,简要说明:提示工程传统上专注于编写单一自包含提示(即时问题或指令)以获得良好回答。相反,上下文工程关注LLM周围的整个输入环境。如果提示工程是"我问模型什么?",那么上下文工程就是"我给模型展示什么,以及如何管理这些内容以完成任务?”
上下文工程的工作原理
上下文工程通过三个紧密连接的组件管道运作,每个组件旨在通过让模型在正确时间看到正确信息来做出更好决策。以下是各组件的作用:
1. 上下文检索与生成
此步骤拉取或生成所有相关信息以帮助模型更好理解任务。可包括历史消息、用户指令、外部文档、API结果甚至结构化数据。例如,为回答HR查询检索公司政策文档,或使用CLEAR框架(简洁、逻辑、明确、适应、反思)生成结构良好的提示以进行更有效推理。
2. 上下文处理
此步骤优化所有原始信息以供模型使用。包括长上下文技术如位置插值或内存高效注意力机制(例如分组查询注意力和Mamba等模型),帮助模型处理超长输入。还包括自 refinement,即提示模型迭代反思并改进自身输出。一些最新框架甚至允许模型生成自身反馈、判断性能,并通过自我创建和筛选示例自主进化。
3. 上下文管理
此组件处理信息的存储、更新和跨交互使用。在客户支持或随时间运作的代理等应用中尤为重要。长期记忆模块、内存压缩、滚动缓冲缓存和模块化检索系统等技术使得在多个会话中保持上下文而不压垮模型成为可能。这不仅关乎放入什么上下文,还关乎如何保持其高效、相关和最新。
上下文工程的挑战与缓解策略
设计完美上下文不仅是添加更多数据,还关乎平衡、结构和约束。以下是一些可能遇到的关键挑战及其潜在解决方案:
- 无关或嘈杂上下文(上下文分散):输入过多无关信息可能混淆模型。使用基于优先级的上下文组装、相关性评分和检索过滤器仅拉取最有用的信息块。
- 延迟和资源成本:长而复杂的上下文增加计算时间和内存使用。截断无关历史或将计算卸载到检索系统或轻量模块。
- 工具与知识集成(上下文冲突):合并工具输出或外部数据时可能发生冲突。添加模式指令或元标签(如@tool_output)避免格式问题。对于来源冲突,尝试归属或让模型表达不确定性。
- 保持多轮对话连贯性:在多轮对话中,模型可能幻觉或丢失事实跟踪。跟踪关键信息并在需要时有选择地重新引入。
其他两个重要问题:上下文毒化和上下文混淆已被德鲁·布罗尼格详细解释,建议进一步查阅。
总结
上下文工程不再是可选技能。它是让语言模型不仅响应而且理解的支柱。在许多方面,它对最终用户不可见,但定义了输出感受的有用性和智能程度。本文旨在温和介绍其概念和工作原理。
如果您有兴趣进一步探索,以下是两个深入学习的可靠资源:
- 《大型语言模型上下文工程综述》
- davidkimai/上下文工程 代码库