从提示工程到上下文工程:构建高效LLM应用的核心技术演进
1. 项目概述从“提示工程”到“上下文工程”的范式演进如果你在过去一两年里深度参与过大型语言模型的应用开发那么“提示工程”这个词对你来说一定不陌生。从最初的“请扮演一个专家”到复杂的思维链、少样本学习我们花了大量精力去雕琢输入给模型的“指令”试图用最精炼的语言撬动最精准的输出。然而随着模型能力的飞速提升特别是上下文窗口从几千token扩展到数十万甚至百万token一个更根本的问题浮现出来当模型能够“看到”并处理海量信息时我们工作的核心是否应该从“如何问”转向“如何喂”这正是“Meirtz/Awesome-Context-Engineering”这个项目所锚定的前沿领域——上下文工程。它不再仅仅关注单次交互的提示词技巧而是将整个与模型交互的过程视为一个动态的、结构化的信息环境构建过程。这个GitHub仓库本质上是一个精心整理的资源索引它系统地收集了关于如何设计、组织、管理和优化输入给LLM的上下文信息的论文、工具、框架和最佳实践。对于任何希望构建复杂、可靠、高性能LLM应用的开发者、研究者和产品经理而言这不再是一个“可选”的技能而是决定应用上限的“必修课”。我自己的体会是提示工程像是教模型“如何解答一道题”而上下文工程则是为模型“构建一个用于解题的完整知识库和思考框架”。当你的应用场景从简单的问答、摘要转向需要长期记忆、多轮复杂推理、处理超长文档的智能体、数据分析助手或代码生成平台时上下文的质量、结构和效率就直接决定了应用的成败。这个仓库的价值就在于它为我们提供了从理论到实践的全景地图。2. 核心概念拆解什么是上下文工程2.1 超越提示词上下文的广义定义在传统提示工程中“上下文”往往狭义地指代对话历史或当前提示词之前的少量文本。但在上下文工程的视角下上下文是一切输入到模型中的、用于影响其输出的信息总和。这包括系统提示与角色设定这是上下文的“元指令”定义了模型的角色、行为边界、输出格式和思考框架。一个设计良好的系统提示是高效上下文的基础。少样本示例经典的In-Context LearningICL核心通过提供输入-输出对让模型快速掌握任务模式。检索到的相关知识来自向量数据库、知识图谱或外部API的信息片段用于增强模型对特定领域事实的理解。长期记忆与对话历史在多轮对话中如何摘要、筛选和保留关键历史信息以维持对话连贯性。工具调用规范与结果当模型需要调用外部工具如计算器、搜索引擎、代码解释器时工具的描述、调用格式以及返回结果都是上下文的重要组成部分。中间思考过程在思维链CoT或思维树ToT等策略中模型自己生成的推理步骤也会被放回上下文以引导后续思考。上下文工程的核心任务就是对这些异构、动态、可能非常庞大的信息进行有效的编排、压缩、筛选和注入以确保模型在有限的注意力窗口内能访问到最相关、最有效的信息从而产生高质量、可靠且一致的输出。2.2 上下文工程面临的四大核心挑战为什么我们需要专门研究这个领域因为随着上下文变长、变复杂一系列棘手问题随之而来信息过载与注意力稀释模型并非能同等地关注上下文中的所有信息。无关或冗余信息会稀释模型对关键信息的注意力导致输出质量下降这种现象常被称为“中间丢失”或“长上下文性能衰减”。位置偏差许多模型对输入序列开头和结尾的信息更为敏感而中间部分的信息可能被相对忽略。如何将最关键的信息放置在模型更容易关注的位置是一个重要课题。上下文窗口的有限性与成本尽管窗口在扩大但终究是有限的。处理超长上下文如整本书、大量代码库的计算成本时间、显存、API费用也急剧上升。如何在不损失核心信息的前提下压缩上下文是工程化的关键。动态上下文的实时管理在智能体等场景中上下文随着行动和观察在不断扩展。如何实时地评估信息重要性、进行摘要、剔除过期信息维持一个高效且紧凑的工作记忆是构建持久化智能体的核心。“Awesome-Context-Engineering”仓库中收录的论文和工具正是围绕解决这些挑战而展开的。3. 核心技术栈与工具生态根据该仓库的归类上下文工程的技术栈可以大致分为几个层次从底层的理论研究到顶层的应用框架。3.1 基础方法与策略层这一层是上下文工程的“内功心法”主要研究如何通过提示词本身的结构设计来优化上下文利用。指令位置优化实验表明将最重要的指令如任务要求、输出格式放在系统提示的开头或结尾以及用户输入的末尾往往能获得更好的遵循度。避免关键指令被淹没在长篇大论的中间。少样本示例的选择与排序并非示例越多越好。示例的质量、多样性与当前查询的相关性远比数量重要。一种有效策略是“动态示例选择”即根据当前问题实时从示例库中检索最相关的几个示例而非固定提供。思维链的进阶用法除了简单的“让我们一步步思考”还包括自洽性让模型生成多个推理链然后选择最一致答案。先验知识提示在推理前先让模型陈述可能相关的知识或规则。步骤摘要对于极长的推理让模型阶段性地对自己的思考进行摘要再将摘要放入上下文避免原始冗长链条占用过多空间。实操心得在系统提示中我习惯使用“三重指令法”开头用一句话定义核心角色和目标中间详细阐述约束条件和格式规范结尾再次用强调句式如“记住最重要的是…”重申最关键的一两条规则。这能有效对抗模型在长上下文中的“遗忘”。3.2 检索增强与知识注入层当任务需要外部知识时如何高效检索并注入上下文是关键。这超越了简单的向量搜索。查询重写与扩展用户的原始查询可能信息不足。利用LLM对查询进行重写、扩展或生成假设性回答再用这个优化后的查询去检索能显著提升检索相关性。分层检索与混合检索不依赖单一检索器。结合向量检索语义相似、关键词检索精确匹配以及可能的元数据过滤时间、来源综合获取信息片段。检索结果的重排序与摘要检索到的文档可能很长且包含冗余。在注入上下文前可以用一个轻量级模型或规则对结果进行重排序按相关性排序甚至对每个文档生成一个简洁摘要只注入摘要和最关键的原句。知识图谱的利用将结构化知识实体、关系以文本或特殊格式如Markdown列表、JSON注入上下文能提供更精确、关联性更强的知识。3.3 上下文管理与压缩层这是处理长上下文的核心技术目标是在有限的窗口内保留信息精华。选择性上下文并非所有历史都需要保留。可以训练一个轻量级“重要性评分模型”或使用启发式规则如最近几轮、包含特定关键词的轮次动态选择哪些对话历史保留在上下文窗口中。摘要压缩增量摘要在对话过程中定期用模型将之前的对话历史摘要成一段紧凑的文字用摘要替代原始长历史。提取式摘要直接抽取历史中的关键句子、实体或事实断言组成新的上下文。对话记忆向量将历史对话编码成一个固定维度的向量记忆向量随每次交互更新。这个向量可以作为上下文的一部分输入模型提供“浓缩”的记忆。结构化表示将非结构化的长文本转化为结构化的表示再注入。例如将一篇长论文转换成由“标题、摘要、核心论点、论据、结论”构成的JSON大纲将代码库转换成文件树和关键函数签名列表。这极大降低了模型的认知负荷。外部记忆体完全将记忆移至模型外部如数据库。上下文只保留一个指向外部记忆的“指针”或“查询”。当模型需要时再通过检索机制将相关内容动态加载进上下文。这理论上支持无限长的记忆但引入了检索延迟和一致性问题。3.4 框架与系统层这一层提供了开箱即用的工具和框架将上述技术封装成开发者友好的接口。LangChain / LlamaIndex这两个流行的框架早已将上下文管理作为核心功能。它们提供了ContextChatEngine、记忆模块、各种检索器等高级抽象让开发者可以轻松组合不同的上下文策略。专门的长上下文优化框架一些研究项目或新产品开始涌现例如专注于超长代码库理解的框架它们内置了代码解析、分层检索和智能摘要的流水线。智能体框架中的上下文管理如AutoGPT、BabyAGI的衍生项目中上下文管理模块是核心组件负责维护智能体的目标、任务列表、执行历史和知识库并决定每一步将什么信息喂给模型。4. 实战构建一个基于上下文工程的文档问答系统让我们通过一个具体的场景——构建一个能处理百页级技术PDF文档的智能问答系统——来串联上述技术。假设我们使用GPT-4 Turbo128K上下文作为核心LLM。4.1 系统架构设计我们的目标不是简单地将整个PDF文本扔进上下文可能超长且低效而是构建一个动态的、多层次的上下文装配流水线。用户提问 ↓ 查询理解与重写模块 (LLM) ↓ 分层检索系统 ├── 章节标题/小标题检索 (关键词匹配) ├── 图表/表格说明检索 (关键词向量) └── 详细段落检索 (向量相似度) ↓ 检索结果重排序与去重 (规则 轻量模型) ↓ 上下文装配器 ├── 注入系统提示 (角色、格式、规则) ├── 注入文档元信息 (文件名、总页数、当前涉及章节) ├── 注入检索到的核心片段 (结构化排列) ├── 注入少量相关问答示例 (1-2个) └── 注入用户当前问题 (末尾) ↓ 调用LLM生成答案 ↓ 返回答案并可选地记录到对话历史/记忆4.2 关键环节实现细节4.2.1 文档预处理与索引首先我们不能直接处理原始PDF文本流。解析与结构化使用PyMuPDF或pdfplumber提取文本同时尽可能保留结构信息。我们将文档划分为元数据标题、作者、章节树。块按自然段落、列表或图表标题进行分割。为每个块赋予ID、所属章节、页码。特殊元素提取图表标题、表格数据转为Markdown格式、代码块。构建多粒度索引章节索引一个简单的字典章节标题 - [包含的块ID列表]。向量索引将所有文本块可能经过摘要如取前N句通过text-embedding-3-small模型编码存入Chroma或Weaviate等向量数据库。关键词索引对标题、图表标题、重要术语建立倒排索引用于快速精确匹配。4.2.2 查询重写与扩展用户可能问“第三章讲了啥”我们需要将其重写为更利于检索的查询。# 伪代码示例 def rewrite_query(original_query, conversation_history): prompt f 你是一个查询优化助手。请根据用户的原始问题和对话历史生成一个更全面、更利于从技术文档中检索信息的查询。 原始查询{original_query} 最近对话历史{conversation_history[-2:] if conversation_history else 无} 请输出优化后的查询 optimized_query llm.invoke(prompt, max_tokens100).strip() return optimized_query if optimized_query else original_query优化后的查询可能是“概述文档第三章‘系统架构’的主要组成部分、设计原理和核心流程图。”4.2.3 分层检索与结果融合这是核心步骤我们并行执行多种检索章节检索用优化后的查询匹配章节标题找到最相关的1-2个章节。向量检索用优化后的查询的向量在向量库中检索最相关的10-15个文本块。关键词检索在图表标题、表格标题、术语索引中查找精确匹配。然后进行融合与重排序来自“最相关章节”的块获得权重加成。向量检索结果中与关键词匹配的块获得权重加成。去除内容高度重复的块基于文本相似度。最终保留Top-8个最相关、最不冗余的文本块作为候选片段。4.2.4 上下文装配与提示词设计现在我们将所有信息组装成最终的上下文提示。# 系统提示 (角色与规则) 你是一个专业的技术文档分析助手。你的任务是根据提供的文档片段准确、简洁地回答用户问题。 **重要规则** 1. 答案必须严格基于提供的上下文。如果上下文没有相关信息请明确告知“根据提供的资料无法回答此问题”切勿杜撰。 2. 如果上下文涉及图表或表格请在答案中引用并描述其关键信息。 3. 答案结构清晰先给出直接结论再分点阐述细节。 # 文档元信息 当前分析文档《分布式系统设计指南.pdf》 共120页。当前问题主要涉及第3章“系统架构”。 # 检索到的核心上下文片段 (按相关性排序) [片段1 ID: sec3.2]: **3.2 核心组件** 系统主要由API网关、服务注册中心、配置中心...组成。图3-1展示了组件间的数据流。 [片段2 ID: fig3.1_desc]: **图3-1 系统组件数据流图** 该图说明了请求从网关路由到具体服务并经过认证、日志等中间件的流程... [片段3 ID: sec3.1]: **3.1 设计原则** 本章遵循微服务架构的松耦合、高内聚原则... ... (更多片段) # 参考示例 (1个) 用户第二章提到了哪些设计模式 上下文[关于第二章工厂模式、观察者模式的片段] 助手根据第二章内容主要提到了两种设计模式1. **工厂模式**用于...2. **观察者模式**用于...。具体可参考图2-3。 # 用户当前问题 用户请详细说明第三章中系统各个核心组件是如何协同工作的注意事项上下文装配时务必确保用户问题在最后。模型对提示词末尾的内容注意力最高。同时系统提示中的关键规则如“禁止杜撰”需要用加粗等格式强调并放在靠前位置。4.3 效果评估与迭代部署后需要持续评估系统表现。关键指标包括答案相关性答案是否紧扣提供的上下文事实准确性是否产生“幻觉”编造不存在的信息上下文利用率模型是否真的引用了我们提供的片段可以通过要求模型在答案中注明来源如[片段1]来辅助评估。根据bad case进行分析迭代优化环节如果模型常忽略某个重要片段可能是该片段在上下文中位置不佳尝试调整顺序。如果检索总找不到关键信息需要优化文档分块策略或查询重写模型。如果答案冗长可以在系统提示中更严格地限制输出长度和结构。5. 高级主题与前沿探索“Awesome-Context-Engineering”仓库也指向了一些更前沿的研究方向。5.1 上下文学习与模型微调的协同上下文工程ICL和模型微调Fine-tuning不是二选一而是互补的。对于高度专业化、固定模式的任务微调一个基础模型是高效的。但对于需要动态知识、零样本或少量样本快速适配的新任务上下文工程则更灵活。最佳实践是“微调模型的基础能力与风格用上下文工程提供任务特定知识和实时信息”。例如微调模型使其擅长遵循结构化指令和代码风格然后通过上下文注入具体的API文档和用户需求来生成代码。5.2 针对长上下文的模型优化模型本身也在进化。一些新技术旨在让模型更好地利用长上下文滑动窗口注意力如Longformer、LED将计算复杂度从序列长度的平方降低到线性。层次化注意力先对文本块进行摘要再在摘要层面进行注意力计算。检索增强的语言模型如RETRO、Atlas在模型架构内部集成了检索机制动态获取外部知识。作为应用开发者了解这些原理有助于我们选择更适合长上下文任务的模型例如Claude-3系列在长文档处理上口碑很好并理解其能力边界。5.3 上下文中的“推理痕迹”管理在复杂推理任务中模型产生的中间步骤思考链本身是宝贵的上下文。但如何管理这些可能很长的“推理痕迹”策略包括只保留最终结论或关键子结论丢弃中间推导细节。将复杂推理分解为子问题每个子问题在一个干净的上下文中解决上级问题只汇总子问题的结论。使用“暂存板”设计一个格式化的上下文区域让模型将其关键中间变量、假设和结论写在这里供后续步骤查阅避免与自然语言推理混在一起。6. 避坑指南与常见问题在实际操作中我踩过不少坑这里总结几个最常见的幻觉问题在长上下文中更隐蔽模型可能会综合多个片段中的信息推导出一个看似合理但上下文并未明确支持的观点。对策在系统提示中强力强调“严格基于上下文”并要求引用来源。对于关键事实可以设计一个“验证步骤”让模型先列出答案所依据的原文句子。检索到的信息相互矛盾当文档不同部分说法不一致时模型可能困惑。对策在上下文中明确指示模型如何处理矛盾例如“如果信息有冲突请以最新版本或第X章的描述为准”或“指出存在不一致”。上下文窗口浪费在格式和废话上原始文档的页眉、页脚、无关引用会占用宝贵token。对策预处理阶段必须严格清洗。在组装上下文时使用简洁的标记如[片段1]而非冗长的描述。性能与成本的权衡更复杂的检索和重写意味着更长的延迟和更多的LLM调用用于查询重写、摘要等。对策对延迟不敏感的后台任务可以使用复杂流水线对于实时交互可能需要简化流程例如使用更快的向量检索或缓存常见查询的结果。对话历史的无限制增长这是智能体应用的经典问题。对策实现一个简单的对话记忆管理策略。例如只保留最近5轮对话的原始内容将5轮之前的内容总结成一段“背景摘要”。每轮交互后都更新这个摘要。最后上下文工程没有银弹。最有效的方法永远是针对你的具体任务、你的文档类型和你的用户需求进行反复的实验、评估和迭代。从“Awesome-Context-Engineering”这个仓库出发深入阅读几篇标志性的论文动手搭建一个最简单的流水线然后不断优化它。你会发现当你真正掌控了上下文你就解锁了大型语言模型更深层、更强大的能力。这个过程本身就是构建下一代AI应用的核心竞争力。