1. 项目概述从“上下文工程”到“提示工程”的范式演进最近在GitHub上看到一个挺有意思的项目叫“Awesome-Context-Engineering”。乍一看标题你可能会有点懵——“上下文工程”是什么听起来像是某种软件架构或者系统设计的新名词。但如果你点进去结合项目描述和里面的资源列表就会发现它其实和我们熟悉的“提示工程”有着千丝万缕的联系甚至可以说是对后者的一种深化和系统化。简单来说这个项目收集和整理了关于如何为大型语言模型设计和构建有效“上下文”的资源、工具、论文和最佳实践。这里的“上下文”指的就是你提供给AI模型的那段输入文本它包含了你的指令、背景信息、示例、约束条件等等。为什么这值得专门用一个“工程”来命名因为在实际应用中尤其是在构建复杂的AI应用时如何组织、管理和优化这段上下文已经从一个简单的“写提示词”技巧演变成了一个需要系统性思考和设计的工程问题。想象一下你正在开发一个基于大模型的客服机器人。早期你可能只是写一句“请用友好的语气回答用户关于产品退货的问题”。但随着需求复杂化你需要告诉机器人公司的退货政策是什么、哪些商品可以退、用户的历史订单信息、当前对话的情绪状态、甚至需要引用知识库里的某篇具体文章。所有这些信息都需要被精心编排塞进一个有限的“上下文窗口”里并且要确保模型能准确理解每部分信息的角色和优先级。这个过程就是“上下文工程”要解决的问题。它面向的是开发者、AI应用架构师、产品经理以及任何希望将大模型能力稳定、可靠地集成到实际业务场景中的人。这个项目就像一个导航图它不直接教你写某个具体的提示词而是告诉你在构建一个健壮的AI系统时关于“上下文”这个核心组件业界有哪些前沿的研究、实用的框架、高效的工具和值得借鉴的模式。接下来我就结合这个项目的内容和我自己的一些实践经验来深入拆解一下“上下文工程”到底在做什么以及我们该如何上手。2. 核心概念拆解为什么“上下文”本身成了工程问题要理解“上下文工程”的必要性我们得先看看传统的“提示工程”遇到了哪些天花板。2.1 从单轮对话到复杂工作流的挑战最初的提示工程很大程度上聚焦于如何通过精巧的措辞在单次交互中让模型输出更好的结果。比如使用“思维链”提示、提供少样本示例、指定输出格式等。这些技巧在探索模型能力和完成简单任务时非常有效。然而当我们要构建一个真正的应用时交互很少是单轮的。它可能是一个多轮对话系统需要维护整个对话历史作为上下文也可能是一个自动化工作流需要将前一个步骤的输出作为下一个步骤的输入还可能是一个需要实时查询外部数据库或API的智能体。这时上下文就不再是一段静态的文本而是一个动态的、不断增长和演化的数据结构。问题随之而来大模型的上下文长度是有限的。虽然现在128K、甚至更长上下文的模型越来越多但成本无论是API调用费用还是计算延迟和效果并非线性增长。更长的上下文可能导致模型忽略中间的重要信息即“中间丢失”问题或者增加无关信息的干扰。因此如何从海量的潜在信息中动态地筛选、组织、压缩出最相关、最精炼的上下文就变成了一个必须解决的工程问题。2.2 上下文内容的模块化与结构化在复杂场景下上下文的内容也高度异构。它可能包含系统指令模型的角色、行为准则、输出格式要求。对话历史用户和AI之前的多轮交流。检索到的知识从向量数据库或知识图谱中查询到的相关文档片段。工具调用结果执行某个函数如查询天气、计算数据后返回的结果。私有数据用户的个人资料、偏好设置、会话状态。示例少样本学习的范例。如果把这些信息全部用自然语言平铺直叙地拼接在一起会变得极其冗长且难以维护。上下文工程倡导的是像编写软件一样对待上下文模块化、结构化、可复用。例如使用特定的XML标签或Markdown分隔符来划分不同的上下文区块并为每个区块定义清晰的角色。这不仅能提升模型的理解准确度也使得上下文的生成和管理过程更易于调试和迭代。2.3 性能、成本与可靠性的权衡最后上下文直接关系到应用的性能、成本和可靠性。发送过长的上下文意味着更高的API费用和更慢的响应速度。而不恰当的上下文则可能导致模型产生幻觉编造信息、偏离主题或执行错误操作。因此上下文工程的目标之一就是在有限的令牌预算内最大化信息的“信噪比”确保模型获得完成任务所需的最优信息集同时控制成本并保障输出的稳定性和准确性。3. 上下文工程的核心技术栈与工具选型“Awesome-Context-Engineering”项目里列举了大量的工具和框架我们可以将其归纳为几个关键的技术方向。了解这些工具能帮你快速搭建自己的上下文处理流水线。3.1 上下文管理与编排框架这类工具帮助你以编程的方式定义、组装和管理上下文。它们通常提供了高级抽象让你摆脱手动拼接字符串的繁琐。LangChain / LlamaIndex这两个是生态中最知名的框架。虽然它们功能广泛但其核心能力之一就是上下文的构建与编排。例如LlamaIndex 提供了强大的“检索器”和“查询引擎”能自动从你的数据源中检索相关文档并将其格式化成模型可接受的上下文。LangChain 则通过“链”和“代理”的概念允许你将多个步骤检索、加工、生成串联起来每个步骤都会对上下文进行增删改查。提示模板引擎几乎所有框架都支持提示模板。这不仅仅是简单的字符串替换而是支持条件逻辑、循环和包含其他模板。你可以像写HTML模板一样定义你的系统提示、用户消息占位符、示例插入点等。成熟的模板引擎能极大提升提示词的可维护性和复用性。实操心得不要过早陷入框架选择困难症。对于新手我建议从LangChain开始它的社区最活跃教程和示例也最丰富。先用它实现一个最简单的RAG流程理解“文档加载-文本分割-向量化存储-检索-上下文组装-调用模型”这个完整链路之后再根据具体需求考虑是否切换到更轻量或更专注的工具。3.2 检索增强与知识注入这是上下文工程目前最火热的方向即Retrieval-Augmented Generation。核心思想是不让模型仅依赖其内部参数化的知识而是动态地从外部知识库中检索相关信息并将其作为上下文提供给模型。向量数据库如 Pinecone、Weaviate、Qdrant、Chroma。它们负责存储你的文档经过文本分割后的向量嵌入并能根据查询的向量进行相似性搜索返回最相关的文本片段。检索器检索的逻辑可以很复杂。不仅仅是简单的向量相似度搜索还可以结合关键词搜索如BM25、元数据过滤如按日期、作者筛选、甚至多路检索结果重排序。LlamaIndex在这方面提供了丰富的“检索器”组件。查询转换与扩展用户的原始查询可能不够好。工具可以帮助你重写查询、生成假设性问题、或进行多语言扩展以提高检索的召回率。3.3 上下文优化与压缩技术当检索到的文档太多或者对话历史太长时我们需要压缩上下文。提取式摘要直接选取原文中最关键的句子或段落。可以通过基于嵌入的聚类、基于图算法如TextRank的关键句提取或者直接训练一个小型模型来打分。抽象式摘要调用另一个大模型通常是更小、更快的模型对长文本进行总结再将总结放入上下文。这能大幅减少令牌数但存在信息损失的风险。选择性上下文并非所有历史对话都同等重要。可以设计策略只保留最近N轮对话或者只保留包含特定实体、关键词的对话轮次。对于工具调用结果也可以只提取其中的关键数据字段而不是返回完整的JSON。3.4 上下文评估与调试工具如何知道你的上下文设计得好不好这需要评估和调试。可视化与追踪像LangSmith、Weights Biases 这类平台可以记录每次AI调用的完整上下文、模型输出、延迟和成本。你可以直观地看到上下文是如何组装的并对比不同上下文下模型输出的差异。评估框架使用RAGAS、TruLens、DeepEval等框架从“上下文相关性”、“答案忠实度”、“信息完整性”等多个维度自动化地评估你的RAG系统或上下文策略的效果。它们可以帮助你量化改进而不是靠感觉。4. 构建一个生产级上下文处理流水线实战指南理论说再多不如动手搭一个。下面我以一个“智能技术文档问答助手”为例拆解一个相对完整的上下文工程实践。目标是用户用自然语言提问系统能从公司内部的技术文档库中找到答案并用易于理解的方式回复。4.1 阶段一知识库准备与索引构建这是所有工作的基础。垃圾输入必然导致垃圾输出。文档加载与解析工具使用 LangChain 的DocumentLoader支持 PDF、Markdown、HTML、Confluence、Notion 等。对于技术文档Markdown 和 HTML 是主流。关键点解析时要尽可能保留文档结构信息如标题层级、代码块、表格。这些结构信息对于后续的文本分割和模型理解至关重要。可以为每个文档块添加元数据如来源URL、最后修改日期、所属产品模块等。文本分割策略为什么不能简单按字数切分技术文档中一个完整的函数说明可能被切到两个块里导致信息不完整。推荐方法采用递归分割法。优先按文档的天然结构分割如按标题##分割如果分割后的块仍然太大再按句子或固定长度进行二次分割。LangChain 的RecursiveCharacterTextSplitter结合MarkdownHeaderTextSplitter是个不错的选择。分割参数块大小和重叠区需要调优。对于技术文档块大小在512-1024字符可能比较合适重叠区在100-200字符以确保上下文连贯。# 示例使用LangChain进行文本分割 from langchain.text_splitter import RecursiveCharacterTextSplitter, MarkdownHeaderTextSplitter from langchain.document_loaders import DirectoryLoader # 首先按Markdown标题分割 headers_to_split_on [(#, Header 1), (##, Header 2), (###, Header 3)] markdown_splitter MarkdownHeaderTextSplitter(headers_to_split_onheaders_to_split_on) md_header_splits markdown_splitter.split_text(markdown_content) # 然后对每个块进行递归字符分割防止单个块过长 text_splitter RecursiveCharacterTextSplitter( chunk_size1000, chunk_overlap200, length_functionlen, separators[\n\n, \n, 。, , , , , , ] ) final_docs text_splitter.split_documents(md_header_splits)向量化与存储嵌入模型选择对于技术文档需要能理解代码和专业术语的模型。text-embedding-ada-002是通用且稳定的选择。开源模型如BGE-M3、Snowflake Arctic Embed也表现不俗且可以本地部署。向量数据库选型对于起步阶段轻量级的Chroma内存或持久化模式足够使用易于集成。如果数据量极大数百万条以上或对性能要求极高可以考虑Pinecone或Weaviate这类托管服务。存储元数据务必把每个文本块的元数据来源、标题等和向量一起存储。这在后续检索时进行过滤非常有用。4.2 阶段二查询时上下文的动态组装这是上下文工程的核心环节。当用户提问时系统需要实时构建最有效的上下文。查询理解与转换用户提问可能是模糊的。例如“这个API报错怎么解决” 系统需要将其与具体的产品、版本、错误信息关联。做法可以先用一个小模型或大模型的一次快速调用对用户查询进行意图识别和查询重写。例如将其扩展为“[产品A] [v2.0] API 调用时返回‘404 Not Found’错误的解决方案”。混合检索与重排序第一步召回。使用向量检索找到语义相似的文档块。同时可以并行一个关键词检索如BM25以覆盖那些表述不同但主题相同的文档。第二步重排序。将召回的前K个结果比如20个送入一个专门的“重排序模型”。这个模型比嵌入模型更精细能判断文档块与查询的相关性并重新排序。Cohere的 rerank 模型或开源的BGE-Reranker是常用选择。第三步过滤与去重。根据元数据过滤掉不相关版本或产品的文档并对内容高度重叠的文档块进行去重。上下文模板设计这是将检索结果、系统指令、对话历史等“组装”成最终提示词的地方。一个好的模板是成功的一半。# 系统指令 你是一个专业、耐心且准确的技术文档助手。你的知识来源于以下提供的上下文文档。请严格基于上下文信息回答问题。如果上下文中的信息不足以回答问题请明确告知用户“根据现有文档我无法找到相关信息”并建议其查阅其他官方渠道。不要编造信息。 # 上下文文档 {context} # 对话历史最近3轮 {history} # 当前用户问题 {question} # 输出要求 请用清晰、有条理的方式回答。如果涉及步骤请分点说明。如果上下文中有代码示例请直接引用。关键技巧角色定义清晰告诉模型“你是谁”。知识边界明确强调“严格基于上下文”这是减少幻觉的关键。结构化分隔使用#、|im_start|、等清晰的分隔符区分不同部分。提供示例对于复杂任务在系统指令后直接提供1-2个输入输出的例子效果显著。4.3 阶段三上下文缓存与对话状态管理对于多轮对话高效管理对话历史上下文至关重要。对话历史窗口不可能无限制地将所有历史对话都塞进上下文。常见的策略是“滑动窗口”只保留最近N轮对话。更智能的策略是进行摘要增量式摘要每轮对话后用一个小模型将本轮对话的核心信息摘要出来更新到一个“对话摘要”字段中。下次生成上下文时不放入完整历史而是放入这个“对话摘要”加上最近1-2轮原始对话。这能极大地节省令牌并保留长期记忆。上下文缓存对于相同的或相似的查询其检索结果可能是一样的。可以缓存“查询-相关文档块ID”的映射避免重复进行昂贵的向量检索和重排序。注意设置合理的缓存过期策略尤其是当知识库更新时。5. 高级模式与前沿探索当你掌握了基础流水线后可以探索一些更高级的上下文工程模式这些在Awesome项目的论文和实验性工具中常有提及。5.1 智能体中的上下文管理在AI智能体场景中上下文更加动态。智能体需要记忆自己的目标、已执行的动作、观察到的结果以及外部环境的状态。思维框架如ReAct、Chain-of-Thought其本质是将“思考过程”也作为上下文的一部分输出并引导模型下一步行动。这需要精心设计提示模板让模型在“思考”、“行动”、“观察”之间循环。长期记忆智能体可能需要记住跨会话的信息。这通常需要借助外部数据库向量库或传统数据库来存储和检索“记忆”。每次交互时根据当前状态去检索相关的长期记忆并将其作为上下文注入。工具使用上下文当模型决定调用一个工具函数时需要将函数描述、参数作为上下文的一部分。调用返回后需要将结果清晰地整合进对话历史供后续步骤参考。这里的挑战是如何格式化工具调用和结果让模型最容易理解。5.2 上下文压缩与精炼技术面对超长文档或复杂任务直接塞入全部上下文可能低效且昂贵。Map-Reduce将长文档拆分成多个小块分别对每个块提问Map最后将所有答案综合成一个最终答案Reduce。这避免了上下文长度限制但可能丢失全局信息。Refine迭代式处理。先基于第一部分上下文生成一个初始答案然后依次阅读后续部分不断修正和补充这个答案。这种方式生成的答案连贯性更好。使用更小的“法官”模型训练或微调一个参数量较小的模型专门用于阅读长文档并提取出与当前问题最相关的几个句子再由主模型基于这些精炼后的句子生成答案。这实现了上下文内容的“预过滤”。5.3 上下文中的元数据与结构化指令除了自然语言文本我们可以在上下文中嵌入结构化的指令引导模型进行更精确的推理或输出。JSON模式约束在系统指令中直接要求模型以特定JSON格式输出并给出详细的Schema描述。这比用自然语言描述“请输出一个包含A、B、C字段的对象”要可靠得多。逐步推理指令对于数学或逻辑问题在上下文中明确写出推理步骤的占位符如“让我们一步步思考1. ... 2. ...”引导模型遵循这个结构。负面示例除了提供正确的示例也可以提供一些常见的错误回答示例并说明为什么错。这能帮助模型更好地理解边界和禁忌。6. 避坑指南与常见问题排查在实际操作中你会遇到各种各样的问题。下面是一些我踩过的坑和对应的解决方案。问题现象可能原因排查与解决思路答案不准确出现幻觉1. 检索到的文档不相关。2. 上下文模板未强调“基于上下文”。3. 模型能力不足或温度参数过高。1.检查检索质量打印出检索到的文档人工判断是否相关。优化检索策略调整嵌入模型、尝试混合检索、引入重排序。2.强化系统指令在模板中用加粗、重复等方式强调“必须严格基于提供的上下文”。3.调整生成参数降低temperature如设为0.1增加top_p或设置seed以获得更确定性的输出。模型忽略了部分上下文1. 上下文过长模型出现“中间丢失”。2. 上下文结构混乱模型无法区分重点。1.压缩上下文对检索结果进行摘要或提取关键句。优先将最相关的信息放在上下文开头和结尾模型对这两部分更敏感。2.结构化上下文使用清晰的标记如## 文档1,## 文档2分隔不同来源的信息。对于关键信息可以用“重要...”的格式突出。多轮对话中模型遗忘之前内容对话历史管理策略不当丢失了关键信息。1.增加历史轮数适当扩大滑动窗口的大小。2.引入摘要实现增量式对话摘要将长历史压缩成精炼的要点。3.关键信息显式重复对于对话中确定的重要信息如用户偏好、任务目标可以在后续轮次的系统指令中显式重申。响应速度慢1. 检索步骤耗时尤其是向量检索大规模数据。2. 上下文过长导致模型生成慢。3. 网络或API延迟。1.优化检索为向量数据库建立索引使用更快的嵌入模型对常见查询进行缓存。2.精简上下文应用上下文压缩技术减少输入的令牌数。3.异步与流式对于非实时场景采用异步调用。对于实时对话如果可以使用模型的流式响应让用户先看到部分结果。处理复杂逻辑或代码时效果差上下文中的代码或逻辑描述不够清晰、完整。1.改进文本分割确保代码块及其解释文字不被切分到不同的文档块中。2.提供更多示例在系统指令或上下文中提供几个类似复杂问题的处理示例Few-shot。3.分步引导将复杂问题拆解成多个子问题通过多轮交互或让模型分步思考来解决。一个非常重要的心得建立评估基线。在开始任何优化之前先手动构造一个测试集比如50-100个典型问题记录下当前系统在“答案准确性”、“相关性”、“完整性”上的表现。之后任何架构或策略的改动都基于这个测试集来评估效果是提升还是下降。没有度量优化就是盲目的。上下文工程不是一个一蹴而就的静态配置而是一个需要持续观察、度量和迭代的动态过程。它结合了软件工程、信息检索和认知科学的理念目标是在人与大模型之间搭建一座高效、可靠的信息桥梁。随着模型能力的演进和应用场景的深化如何更好地设计、传递和利用上下文必将成为AI应用开发者的一项核心技能。这个Awesome项目合集是一个绝佳的起点但真正的知识还是在解决一个个具体问题的实践中积累起来的。