你有没有遇到过这种情况明明Prompt写得清清楚楚资料也塞了一大堆模型还是答非所问甚至用你提供文档里一句无关的话生成了整个结论我最近接手一个跨平台系统项目文档库有几十万字一开始我贪心地把检索到的Top 10片段全塞进上下文结果模型被中后部某段讨论“异常边界情况”的内容带跑了主流程反而没有回答。后来我花了大量时间调整注入顺序、裁剪检索片段、压缩历史记录才意识到问题的根源不在Prompt写得不好而在上下文没管好。这就是我想聊的“上下文工程”要做的事让AI看到该看的东西而且以该看的顺序、该看的粒度去看到。你可以把它理解成给模型写“工作简报”——不是把所有原材料堆上去而是按照任务目标把关键信息放在它最容易注意到的位置。这篇文章不是科普概念是我在实际项目里做上下文设计、检索接入、对话记忆管理时的经验记录。适合正在做AI应用开发的工程师、Prompt设计者以及被“模型输出不稳定”折磨的产品经理参考。1. 上下文工程为什么提示工程不够用了1.1 提示工程解决“怎么说”上下文工程解决“看什么”提示工程的核心是优化指令文本让模型理解你希望它以什么角色、什么风格、什么格式来回答。但有一个问题提示工程默认“信息都在指令里”可现实中的AI应用大多是动态的用户的每句话、系统里的数据库记录、知识库检索结果、多轮对话历史这些都不是写Prompt时能预知的。我在实际调试中发现一组把系统提示、用户查询、检索片段全部加起来的内容里真正影响答案质量的往往不是那句“请你扮演一个资深分析师”而是模型“视野”里到底有哪些候选事实、冲突信息、噪音描述。提示工程解决的是“怎么把话说明白”上下文工程解决的是“给模型看什么材料”后者更像信息架构师干的活。举个生活化类比你让一个新同事帮你整理一份报告。只写清楚“请整理得专业一点”是不够的你还要决定给他哪些资料、哪些资料放前面、哪些资料只给摘要、哪些资料干脆不给。上下文工程就是做这件事的把模型的输入窗口当成一份有预算的简报逐字逐句地分配空间。1.2 定义与核心目标上下文工程是我目前最认可的工作定义它是指对待输入给大语言模型的全部内容——系统提示、用户输入、工具声明、检索结果、对话历史、输出约束——进行结构化设计、动态组织、持续优化的系统性工作。它的核心目标不是“让上下文更多”而是“让上下文更有效”。这里有个关键的认知转变上下文的单位是TokenToken就是钱也是注意力。模型处理上下文时不会像人一样均匀地阅读每一个字它对前置内容有较强记忆对结尾内容有较强的近期效应但中间段内容最容易被“忽略”这在领域里被称为“迷失在中间”现象。上下文工程要做的就是对抗这种注意力分布不均把高价值信息放到注意力高点。我在制定上下文规格书时会先用一句话写清楚本应用期望模型“优先依据什么、参考什么、忽略什么”。这句话听着简单但绝大多数项目没有认真想过。1.3 上下文工程与普通软件开发的三点差异第一它是一种“运行时资源管理”。普通后端开发管理的是CPU、内存、带宽而AI应用还要管理“上下文窗口”这个逻辑资源它既有大小限制又影响模型行为和费用。第二它的复杂度是动态的。同一个系统提示在不同轮次对话、不同用户、不同检索结果下效果可能完全不同必须动态组装。第三它的调试闭环很特别。代码报错有堆栈上下文出问题往往表现为“输出质量差”“答案偏了”,没有直接异常只能靠对比实验逐步收敛。从工程角度看这三点意味着我们不能把上下文构建写成一段硬编码字符串而应该把它设计成一条可组装、可观测、可回放的流水线。2. 上下文的黄金结构拆解每个注入片段2.1 系统提示定义模型的“世界观”系统提示是上下文里最稳定的部分它的作用是告诉模型“你是谁、任务是什么、边界在哪里、输出风格是什么”。很多人以为系统提示写一次就完了实际恰恰相反系统提示会与后续注入的检索内容、用户输入竞争注意力一旦后文出现了与系统提示矛盾的信息模型常常会跟随后文。我见过一份系统提示写了三百行从公司愿景写到语气偏好结果模型频繁“忘记”核心要求。后来我把系统提示重构为固定模块角色一句话、任务一句话、三条硬性规则、输出格式要求。删掉了所有形容词实测输出稳定性提升明显。这里有一条经验系统提示不是越详细越好它更像是给模型看的“宪法”只保留不可违背的原则性内容。关于业务细节、临时变量、检索结果应该放到下面的“工作记忆”部分。2.2 工作记忆任务相关的动态信息工作记忆是每一轮请求时才组装的信息包括用户当前问题、候选知识片段、数据库查询结果、表单状态等。这部分是上下文工程中最需要精细化运营的。我习惯把工作记忆按照“相关性-权威性-时效性”三个维度排序后注入。举例用户问“某跨平台系统的登录模块怎么设计”我检索到的前三段如果是“权限模型综述”“登录流程图”“历史遗留Bug说明”实习生的答案会明显偏向前者而不是流程图。另外一个重点不要把全部检索结果都塞进去。我做了个常见错误实验同一个问题检索Top 5时回答准确率62%塞Top 10时反而降到47%——因为多出来的片段引入了候选矛盾。这也印证了“上下文是预算不是仓库”的原则相关性不确定的宁可不要。2.3 工具与能力声明让AI知道自己手里有什么牌如果应用涉及工具调用工具的命名、描述、参数说明都应该被当作上下文的一部分来管理。模型的工具选择不是随机的它依赖工具描述与用户意图的语义匹配度。工具名如果起得不够直白描述写得模糊模型会选错工具或者干脆不调用。我踩过很实在的坑某次把“查询订单接口”描述成“获取交易快照信息”模型在用户问“我上周的订单”时反复调用另一个计算统计接口。把描述改回“根据订单号或时间范围查询订单明细列表”后选择率明显正常了。工具侧上下文优化的优先级不低于Prompt本身。3. 上下文减脂裁剪、压缩与顺序控制3.1 相关性裁剪只留下最有用的片段我用过一个很朴素但有效的分层裁剪策略第一步做语义去重连续几段讲同一个点的内容只保留一段第二步做冲突识别如果多段内容互相矛盾优先保留权威度高的来源并把冲突点在上下文中显式标注出来比如加一句“注意历史文档A与最新文档B对超时时间的描述不一致请以B为准”第三步做篇幅限制重要片段完整保留边缘片段只留摘要。有读者可能会问让模型看到矛盾信息有什么坏处坏处是模型会自己做“和事佬”把矛盾双方揉成一个含糊结论。我在项目里把“冲突提示”加进系统提示后模型开始主动说明“资料中存在两种说法”并给出取舍建议这个行为是很多团队想要的。3.2 信息压缩用摘要代替原文并不是所有信息都值得原样进入上下文比如很长的日志、冗长的合同条款、多页调研报告。这种场景建议做摘要压缩。但摘要压缩有个原则不能只总结主旨要保留关键实体、数字、结论性的陈述。我做了一个处理链路先把原始文本用模型抽取出“实体清单关键结论重要数字”再压缩成结构化格式。实测在同样的Token预算下压缩后的内容比原文提供了更多有效决策线索。注意压缩步骤也有成本可以选择用更小的模型来执行它在信息抽取任务上表现足够性价比高。3.3 顺序与位置效应把信息放在注意力高点模型注意力有“首位效应”和“最近效应”中间区域容易被弱化。所以重要的信息要么早出现要么出现在最后不要埋在上下文中部。这是我在实际项目中体会最深的一条。比如在构建长报告问答时我会把“结论先行”放在检索片段顶部把“过程推导”放在中间把“最后的约束条件”放在底部。效果是模型的输出结构明显更清晰。这里推荐写一个“上下文排序审计”小工具每次调试时打印注入上下文的顺序标注每条内容的来源与目的方便检查有没有把关键信息埋没。3.4 防干扰项减少无关指令与闲聊多轮对话里有大量“好的”“嗯嗯”“谢谢”之类的填充词以及历史中被模型纠正过的错误回答。这些如果不处理会持续干扰后续生成。我处理对话历史的策略保留每一轮“用户原始意图”而不是用户原话保留模型“最终有效回答”而不是模型的长篇推理。这样传给模型的历史就像会议纪要而不是录音带。另外还有一些隐藏干扰项日期时间、环境描述、上一轮输出里包含的“抱歉我无法回答”之类的话这些都要在注入前清洗。4. 从外部世界取上下文检索增强与知识注入4.1 检索增强的完整构建链路让AI“看到该看的东西”最依赖的就是检索环节。我实际使用的链路是文档切分 - 向量化 - 召回 - 重排序 - 信息注入。这条链路每个环节都有坑。先说文档切分。切分太小比如固定128个Token经常把一句话拆得七零八落切分太大比如2000个Token又会混杂多个主题。常用的办法是语义切分先按标题、段落、句子边界切再控制每段长度在300到800个Token之间。这里的核心是让每一段内容尽量主题单一。再说向量化。向量模型对文本的表达能力直接决定召回的精度。我通常维护两个索引一个基于语义的向量索引一个基于关键词的全文索引查完之后用RAG融合策略合并结果。单纯靠向量召回碰到专有名词、缩写、精确型号时会漏召单纯靠全文碰到同义表达、口语化问题时又召不全。4.2 重排序把最相关的内容捞回来初召回阶段要“宽进”一般拿回50到100个候选。但直接全塞进上下文既不经济也容易引入噪音。这时候就需要重排序模型介入把候选片段按与用户问题的真实相关性重新打分然后取Top 5到Top 8。这里要警惕一种情况重排序后的Top结果里有大量内容相互重复或者是同一来源的不同段落。要在重排序之后再做一次冗余去除。我在一次会话历史相关的调试中因为没做冗余去除上下文里塞了三段讲同一个权限校验过程的文档白白吃掉了好几百Token还让模型回答得啰嗦。重排序模型虽然精确度高但计算成本明显高于向量召回。常规做法是只在候选集上做比如50个里面重排而不是对全库做。线上如果预算紧也可以考虑用更轻量级的交叉编码器方案做两阶段重排。4.3 引用溯源让模型可以“自证”没用引用溯源之前模型给出的答案经常像“编的”。不是它想编而是上下文里没有明确告诉它“哪些句子来自哪个来源”。于是我改了注入格式每条信息前加一个ID标签如[来源1]并要求模型在回答时标注使用到的来源ID。就这么一个改动输出的“可信感”提升了一个档次。实际操作中引用溯源还能帮我排查问题。某次模型引用了一个错误来源的结论我查看输出后发现是重排序时把一条“历史废弃方案”排到了前面而系统提示里的时效性规则没有足够权重。定位到问题后我在重排序打分里加了对文档时间的惩罚因子问题就解决了。4.4 知识注入的格式设计知识注入最忌讳大段堆原文。我会把检索片段包装成统一的“信息卡片”格式标题、来源、时间、关键内容、与问题的相关性说明。这样模型不需要自己推断哪段是重点它直接按卡片来处理就行。这套格式看似简单带来的收益却很大。它让模型有条件在上下文中进行“比较”而不是“混合”。比如两张卡片分别描述方案A和方案B模型会针对问题给出选择倾向如果只是把两段话粘在一起模型很可能把A和B缝合出一个不存在的方案C。5. 动态上下文对话状态与记忆管理5.1 滑动窗口与“短期工作记忆”在做多轮对话时最简单的方式是把最近N轮对话原样拼接到上下文里。这个方案在小场景下能跑但很快会遇到两个问题Token消耗随对话轮数线性增长以及“远距离信息遗忘”。我现在的做法是给对话历史分区最近的2-3轮保留原始信息用于模型理解当前语境更早的历史做键值抽取用“用户关注点已确认事实未解决问题”的格式记录而不是留原文。这个方案在跨平台系统项目里实测效果稳定多轮后模型不会丢失用户在最初提出的核心需求。5.2 滚动摘要让历史“沉淀”下来对话超过一定轮数后上下文被历史占满新知识就没地方放了。我采用的滚动摘要策略是每当历史Token超过阈值就用模型对早先对话生成一份结构化摘要替换掉原始对话。摘要内容不是简单概括而是保留用户目标、关键实体、已给出的承诺、待办事项。这样等于给模型建了一份持续更新的“项目纪要”而不是把每句话都背下来。这里有个操作细节摘要生成本身会产生幻觉我建议在每次摘要时附带“对话原文片段”作为校验只抽取不生成新内容。生成式摘要适合提炼语气和隐含意图但涉及事实性内容时原话引用更保险。5.3 结构化记忆把知识存到“库”里除了文本摘要还可以把长期记忆结构化。比如用户偏好、项目约束、历史结论都可以写成实体-属性-值的形式存入一个小型状态层需要时再实时注入上下文。这种设计的优势是稳定无论过了多少轮都能精确还原关键事实不依赖模型对历史的二次推断。我在一个“某跨平台系统配置问答”的Demo中把数据库表结构、接口返回字段、权限规则抽成了结构化记忆问答准确率显著高于纯文本历史方案。模型需要什么我就把这部分结构以表格或者JSON格式注入输出精准很多。5.4 分层记忆场景化取舍完整的记忆架构可以做成分层场景设置层存放系统性常识会话记忆层存放本轮对话的目标与状态工作存储层存放当前正在处理的临时信息。这三层信息在每次请求时组装优先级从高到低。分层设计避免了“所有信息一锅烩”的混乱也让调试时更容易定位问题。我还养成了一个习惯任何上下文组件都必须标注它的生命周期。是“永久有效”“会话有效”还是“仅本次请求有效”没有生命周期的信息是最危险的它会在一个不该出现的时机被模型读到然后产生误导性输出。6. 常见问题与排查技巧实录6.1 问题速查表现象大概率原因排查方向模型输出啰嗦但没重点上下文里缺少结构化信息或者关键事实被大量修饰性内容淹没检查注入格式是否用信息卡片裁剪冗余段落加了很多资料后答案反而变差检索噪声过多模型被低相关片段带偏引入重排序限制注入片段数量加入冲突标注回答产生幻觉引用没有给模型来源标识或者模型被允许“猜测”使用来源ID标签并强制引用关闭开放式生成多轮对话后面越聊越蠢历史记录膨胀早期关键信息丢失启用滚动摘要与结构化记忆保留用户目标摘要模型不按系统提示执行提示顺序靠前注意力被后文削弱或提示内容重复冲突系统提示精简加固把“不可违背规则”复制到开头和结尾调用工具总是选错工具描述不直观名称有歧义或工具参数说明模糊重写工具描述用用户话术做工具名补充典型触发场景6.2 定位问题的“上下文回放”法遇到输出质量问题我第一步不是改Prompt而是把这次请求的完整上下文打印出来一步一步回放。看四件事一是模型“看到”了哪些片段二是这些片段的顺序是否符合注意力分布规律三是是否有多余的旧信息占据了有效窗口四是关键答案线索是否藏在上下文的中段。90%的问题在看完回放后就能定位。这个方法尤其适合和“错误输出对照实验”配合使用。我会把用户问题固定不变只调整上下文中一个变量比如同时做“只保留Top 3 vs Top 8”“带重排序 vs 不带”“原文注入 vs 摘要注入”观察输出变化。几个来回后哪个环节在拖后腿就非常清晰。6.3 成本与延迟的平衡口诀上下文工程做得好不好还会直接体现在账单和响应时间上。Token消耗就是钱重排序和摘要会引入额外延迟这些都是工程现实。我的平衡口诀是能在存储层解决的不放在上下文里解决能用小模型做的压缩不让大模型做能从结果受益的排序不依赖模型自己去推理信息优先级。比如高频问题可以预先缓存答案不需要每回都构造一堆上下文。再比如检索候选特别大时先用轻量级方案粗筛再对少量候选做昂贵重排序。这套思路放到任何规模的AI应用里都适用。7. 最后一件事写一份上下文规格书项目上线前我会要求团队把整个应用的所有上下文来源列成一张表包括每个内容块来自哪里、为什么存在、优先级多高、生命周期多长、最多占多少Token、位置放在前/中/后。这张表我称为上下文规格书。它带来的直接好处是出问题时不再靠“灵光一现”猜原因而是对着规格书逐行核对人员变动时新人看一遍规格书就能快速上手换模型或调参数时能批量评估影响面。很多团队花大量精力调Prompt却没有一份完整的上下文清单这是本末倒置的。最后分享一个小技巧无论用什么模型、什么框架每个上下文组件都要起一个“可追溯名称”。我在实际项目里看到太多人把系统提示、业务规则、临时数据全部拼在一段字符串里最后根本分不清每句话是谁、从哪里来的。给上下文加了名字以后调试效率提升非常明显你也可以在下一个项目里直接套用。上下文工程不是一个玄学技巧它就是把“让AI看到该看的东西”这件事变成一步步可检查、可验证、可优化的工程实践。