上下文工程实战:从提示词焦虑到精准信息架构设计
发布时间:2026/10/14 8:10:15 锦皓数字建站

1. 从“提示词焦虑”到“上下文设计”一个被忽视的转折点如果你最近半年一直在折腾大模型应用大概率经历过这样一个阶段每天泡在各种提示词技巧里研究怎么加“你是世界级专家”、怎么用“让我们一步步思考”、怎么塞few-shot示例。折腾一圈下来效果时好时坏同一个提示词今天跑得通明天换个模型就翻车。我身边不少做AI应用的朋友都卡在这个瓶颈上直到大家慢慢意识到一个事实——提示词本身能解决的问题其实比想象中少得多。真正决定模型输出质量的往往不是那句指令写得多漂亮而是模型在生成之前它的“视野”里到底有什么。这就是“上下文工程”要解决的核心问题。说白了提示词工程关注的是“你怎么问”而上下文工程关注的是“模型看到了什么”。前者是话术后者是信息架构。一个模型再聪明如果你给它的上下文里塞了一堆无关噪音或者缺了关键事实它照样会一本正经地胡说八道。这篇内容我想聊的就是怎么系统性地设计模型看到的上下文——包括哪些信息该进、哪些该挡在外面、以什么顺序进、用什么格式进。适合已经跑通过基础对话Demo、但发现效果不稳定想进一步优化的开发者也适合做RAG、Agent、知识问答这类应用的产品和技术同学。我不会给你一套万能模板因为上下文工程本质上是个“因场景而异”的活儿但我会把背后的判断逻辑和实操方法讲透让你能自己推导出适合自己项目的方案。先给一个我自己的定义上下文工程是在模型推理之前对输入信息进行筛选、组织、压缩和排序的一整套工程实践。它比提示词工程更靠前也更底层。提示词是最后那层“包装”上下文才是“货”。货不对包装再精美也没用。2. 上下文窗口不是越大越好先搞清楚模型到底“看”到了什么2.1 上下文窗口的物理边界与注意力衰减很多人有个直觉既然现在模型支持几十万甚至上百万token的上下文那我干脆把所有相关资料全塞进去不就行了实测下来这个思路在简单任务上勉强能用一旦任务稍微复杂效果就会明显下滑。原因有两个层面。第一个是物理层面。上下文窗口确实变大了但模型对窗口内信息的“注意力”并不是均匀分布的。业界有个被反复验证的现象叫“中间遗忘”——模型对上下文开头和结尾的信息记得比较牢中间部分容易被忽略。你塞进去十万字真正被有效利用的可能只有头尾那几万字。这不是模型厂商没优化好而是注意力机制本身的特性决定的。第二个是信息干扰层面。假设你的上下文里有一段关键事实同时又混进了五段语义相近但结论不同的内容模型在生成时就会犹豫甚至把不同来源的信息缝合在一起产生看似合理实则错误的输出。我做过一个对比测试同样一个问题上下文里只放一段准确资料回答正确率大概在九成如果把这段资料和四段相似但过时的资料混在一起正确率直接掉到六成左右。信息不是越多越好冗余信息会稀释关键信息的权重。2.2 一个生活化类比上下文像给专家做简报你可以把模型想象成一位能力很强但完全不了解你项目的顾问。你跟他开一次会会议时间有限他只能听你讲这么多。上下文工程就是你准备这份简报的过程。如果你把公司三年的财报、所有会议纪要、竞品分析全堆给他他听完大概率抓不住重点。但如果你提前筛选出“这次要解决的具体问题”“相关的三个关键数据”“一条明确的约束条件”他就能给出高质量建议。简报的质量直接决定顾问的输出质量。模型也一样它不会抱怨你给的信息太多但它会用糟糕的输出“抗议”。2.3 判断“该给什么”的三个提问每次设计上下文之前我会问自己三个问题这三个问题基本能框定筛选方向模型要完成这个任务最少需要知道哪几件事把必要信息列出来这是底线。哪些信息是“看起来相关但其实会误导”的比如过时的版本、不同场景下的相似案例这些要主动排除。信息的呈现顺序会不会影响理解先给背景还是先给问题先给结论还是先给证据效果差别很大。这三个问题不需要复杂工具拿张纸就能列。但就是这三步能帮你砍掉一大半无效上下文。3. 上下文筛选的实操框架从“全量投喂”到“精准投喂”3.1 信息分层把上下文拆成四层来管理我在实际项目里习惯把上下文分成四层每层有不同的处理策略。这个分层方法不是标准答案但用下来比较顺手。第一层是系统指令层也就是角色设定、输出格式要求、硬性约束。这层内容相对固定通常放在上下文最前面。它的作用是给模型定调告诉它“你是谁、要遵守什么规则”。第二层是任务上下文层包括当前要解决的具体问题、用户的历史交互、相关的业务背景。这层是动态的每次请求都可能不同。它决定了模型这次要干什么。第三层是知识证据层也就是从知识库、文档、数据库里检索出来的事实性内容。这层是RAG应用的核心也是最容易出问题的地方——检索回来的东西质量参差不齐需要二次筛选。第四层是示例层给模型看的输入输出范例。这层可选但在格式要求严格的任务里非常有用。分层的好处是你可以针对每一层单独优化。比如知识证据层效果不好你就去调检索策略系统指令层不稳定你就去固化模板。混在一起调根本不知道问题出在哪。3.2 检索结果的二次过滤别让向量库“骗”了你做RAG的同学应该都有体会向量检索返回的Top-K结果经常有那么一两条是“语义相似但实际无关”的。比如你问“退款流程”检索回来一条“退货政策”字面很像但根本不是一回事。如果直接把Top-K全塞进上下文模型就可能把退货政策当成退款流程来回答。我的做法是在检索和组装上下文之间加一道过滤。具体操作上可以用一个轻量模型或者规则来判断每条检索结果和问题的实际相关性把明显跑偏的剔除掉。更简单的办法是给检索结果加上来源标签和时间戳让模型自己判断哪条更可信。实测下来哪怕只是把Top-K从10条砍到4条只要砍得准回答质量反而会提升。这里有个经验值可以参考对于事实型问答上下文里放3到5条高质量证据通常就够了对于需要综合多个来源的分析型任务可以放宽到8到10条但每条都要有明确的来源标注。3.3 上下文压缩用“摘要”换“空间”当单条资料本身就很长时直接塞进去会占用大量窗口。这时候需要做压缩。压缩不是简单截断而是提取和当前任务相关的部分。我常用的方法是“问题导向摘要”让一个便宜的小模型先读一遍长文档只提取和当前问题相关的段落和结论生成一段精简摘要再把摘要放进主上下文。这样既保留了关键信息又大幅节省了窗口空间。代价是多了一次模型调用但对于长文档场景这个代价很值。注意压缩会引入信息损失所以压缩后的摘要最好保留原文的引用位置方便在最终输出里做溯源。否则一旦模型基于摘要产生错误你连排查都无从下手。4. 顺序与格式的隐形力量同样的信息换个排法效果差一倍4.1 位置效应关键信息放头还是放尾前面提到模型对上下文中间部分注意力较弱这个特性直接影响信息排布。我的经验是最关键的约束和问题放在开头最重要的证据放在结尾附近中间放次要的补充材料。举个例子如果你要模型基于一份合同回答“违约金怎么算”那么开头应该明确“请严格依据以下合同条款回答不要自行推断”结尾附近放违约金相关的那几条条款原文中间可以放合同的基本信息。这样模型在生成时开头记住了约束结尾附近看到了关键条款中间部分即使被忽略也不影响核心任务。4.2 格式选择结构化标记比纯文本更“抗遗忘”同样一段信息用纯文本段落写和用带标签的结构化格式写模型的处理效果不一样。结构化格式相当于给信息加了“路标”模型更容易定位和引用。我常用的格式是给每段证据加上来源和类型标签比如[来源产品手册v2.3 | 类型官方定义] 退款指用户在购买后7天内发起的全额返还请求。 [来源客服FAQ | 类型操作说明] 退款需在订单页面点击“申请退款”按钮填写原因后提交。这种写法比直接堆两段文字清晰得多。模型在生成时能明确知道哪条是定义、哪条是操作步骤不容易混淆。而且一旦输出有问题你也能快速定位是哪条来源的锅。4.3 指令与证据的“距离”控制还有一个容易被忽略的点指令和它要约束的证据之间距离不能太远。如果你在开头说“只依据以下三条规则判断”然后隔了五千字才给出这三条规则模型很可能已经忘了开头的约束。我的做法是把强约束和它直接相关的证据放在相邻位置。比如判断类任务我会写成“依据以下规则判断[规则1][规则2][规则3]待判断内容[内容]”。规则和内容紧挨着模型不容易跑偏。5. 动态上下文让每一轮对话都“看到该看的”5.1 多轮对话里的上下文膨胀问题单轮任务的上下文好控制多轮对话就麻烦了。每多聊一轮历史消息就多一截几轮下来窗口就被占满了。更糟的是早期轮次里可能有一些已经过时的信息比如用户一开始说“我想买红色的”后面改口说“算了还是蓝色吧”如果两句话都在上下文里模型可能会纠结。处理多轮上下文核心思路是保留结论、压缩过程。用户明确表达过的偏好、确认过的事实、达成的共识这些要保留中间的试探、重复、无关闲聊可以压缩掉。具体实现上可以每几轮做一次历史摘要把之前的对话浓缩成一段“当前状态描述”替换掉原始消息。5.2 状态追踪把“对话历史”变成“结构化状态”比摘要更彻底的做法是维护一个结构化状态对象。比如一个订票助手它的状态可能是{ 出发地: 已确认, 目的地: 已确认, 日期: 待确认, 舱位偏好: 经济舱 }每一轮对话后更新这个状态然后把状态而不是完整历史放进上下文。这样无论聊多少轮上下文长度都是可控的而且信息高度聚焦。缺点是前期需要设计好状态字段对开放域对话不太适用。但对于任务型对话这个方法非常有效。5.3 触发式上下文注入该出现时才出现还有一种动态策略是“按需注入”。不是把所有可能用到的信息一开始就放进去而是等对话进行到某个节点判断需要某类信息了再动态检索并注入。比如一个技术支持助手用户描述问题时先只给基础排查步骤如果用户反馈“还是不行”再注入进阶排查方案如果用户提到具体错误码再注入该错误码的详细说明。这样上下文始终只包含当前最相关的信息噪音最小。实现上这需要一个简单的意图判断环节可以用规则也可以用模型。规则适合场景固定的应用模型适合开放一些的场景。我一般先用规则跑通主流程遇到规则覆盖不了的情况再补模型判断。6. 踩过的坑与验证方法上下文工程怎么调才不玄学6.1 三个我真实踩过的坑坑一把“相关”当成“有用”。早期做知识问答检索回来只要语义相似度高于阈值就全塞进去。结果模型经常把不同文档里的相似概念混在一起输出自相矛盾。后来加了来源区分和冲突检测才稳定下来。教训是语义相关不等于对当前问题有用必须结合任务判断。坑二上下文顺序随意排。有段时间我组装上下文时按检索分数从高到低排觉得高分在前更合理。结果发现模型经常忽略后面的低分但关键的证据。后来改成“关键约束在前、核心证据在后、补充材料居中”效果明显改善。顺序不是小事。坑三忽略格式的一致性。有一次上下文里混用了三种不同的标注格式模型在引用时张冠李戴。统一格式后问题消失。格式一致性对模型理解的影响比我想象的大。6.2 怎么验证上下文改动的效果上下文工程最怕“感觉变好了”这种主观判断。我的做法是建一个小型评测集固定20到50个典型问题每次改动上下文策略后跑一遍记录正确率、引用准确率、格式合规率这几个指标。正确率看最终答案对不对引用准确率看模型引用的证据是否真的支持它的结论格式合规率看输出是否符合要求的格式。三个指标一起看基本能判断改动是正向还是负向。如果条件允许最好做A/B对比同一批问题一半用旧上下文策略一半用新策略人工或自动评分对比。这样得出的结论比单看几个case靠谱得多。6.3 一个实用的调试技巧把上下文“打印”出来看模型看到的东西和你以为它看到的东西经常不是一回事。我养成了一个习惯每次调试时把最终组装好的完整上下文打印出来自己从头读一遍。读的时候问自己如果我是模型只看这段文字能不能得出正确结论有没有歧义有没有缺失这个笨办法帮我发现了无数问题。很多时候不是模型不行是上下文里藏着一句有歧义的话或者少了一个关键限定条件。自己读一遍比看一百个指标都直观。7. 不同场景下的上下文策略差异7.1 知识问答场景证据为王克制推断知识问答的核心是“有据可依”。上下文里应该以检索到的事实证据为主体系统指令里明确要求“只依据给定资料回答资料中没有的信息不要编造”。证据要标注来源方便溯源。对于证据之间可能存在的冲突要么提前解决要么在指令里说明“如遇冲突以最新来源为准”。这个场景下我倾向于把上下文做得“窄而深”——证据数量不求多但每条都要经过筛选和验证。宁可告诉用户“资料中没有相关信息”也不要让模型基于模糊证据硬答。7.2 创意生成场景给方向留空间创意类任务写文案、起名字、构思方案的上下文策略完全相反。这时候不需要塞大量事实而是要给足“调性参考”和“约束边界”。比如给几个风格示例、说明目标受众、列出必须包含的元素和必须避免的雷区。创意场景下上下文要“宽而浅”——提供氛围和方向但不限制具体表达。塞太多硬性事实反而会束缚模型的发挥。我通常会给2到3个风格示例加一段简短的调性描述剩下的交给模型。7.3 代码生成场景接口定义和约束优先代码生成对上下文的精确性要求极高。模型需要知道用什么语言、什么框架、输入输出是什么、有哪些必须遵守的接口约定。这些信息要放在最前面格式要严格。我习惯把接口定义、数据结构、关键约束用代码块的形式放进上下文而不是用自然语言描述。代码块对模型来说更“无歧义”。同时会明确说“不要引入未声明的依赖”“保持函数签名不变”这类硬约束。7.4 Agent任务场景状态和工具说明是核心Agent类应用的上下文里最重要的是当前状态和可用工具说明。模型需要知道“我现在在哪一步”“我有哪些工具可以用”“每个工具接受什么参数”。这些信息要结构化呈现并且随着任务推进动态更新。工具说明我一般写成简短的函数签名加一句用途描述不写长篇文档。状态则用键值对或简短列表。Agent的上下文要尽量精简因为每一步都要重新组装太长会拖慢响应也增加出错概率。8. 我个人的几条实操心得第一上下文工程没有一劳永逸的配置。模型在更新你的数据在变化用户的问题分布也在变。我一般每个月会重新跑一遍评测集看看之前的策略是否还成立。发现效果下滑就及时调整。第二先做减法再做加法。新手容易犯的错是不断往上下文里加东西觉得加得越多越保险。实际上应该反过来先确定最小必要信息集跑通之后再考虑要不要加。加的时候也要有明确理由不能凭感觉。第三把上下文当成产品来设计而不是当成字符串来拼接。它有自己的信息架构、有优先级、有格式规范。用做产品的思路去对待它效果会好很多。第四保留可追溯性。无论怎么压缩和筛选关键信息的来源要能追溯。这样出问题时你能快速定位而不是面对一个黑盒干瞪眼。最后分享一个我最近在用的检查清单每次上线新的上下文策略前过一遍必要信息是否齐全、冗余信息是否剔除、关键约束是否靠前、核心证据是否在有效注意力区、格式是否统一、来源是否可追溯、多轮场景下是否会膨胀。这七条过完基本不会出大问题。上下文工程这件事说到底就是让模型“看到该看的东西”剩下的交给模型自己的能力就好。
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。