想象一下,你雇了一位智商超群但记忆只有七秒的顶级侦探来帮你查案。这位侦探脑子转得飞快,推理能力一流,可问题是,他每次开始工作前,都只看得见你亲手放在他面前的那些线索。线索给得精准,他能一击破案;线索给得又杂又乱,他就被无关细节带偏,甚至开始一本正经地胡说八道。这位侦探,就是大语言模型(LLM);而你把哪些线索、以什么顺序、用多大字号摆在他桌上的那套学问,就叫“上下文工程”(Context Engineering)。更棘手的还有一条:他的办公桌只有巴掌那么大——那就是上下文窗口。桌上放不下你所有的档案,放不下的要么永远堆在角落(被截断),要么需要临时去档案柜调取(检索),要么你学会把文件字写得密密麻麻(Token优化)。这篇文章,就是带你给这位“天才侦探”当一名合格的“情报管理员”。

岗位关联

上下文工程是AI应用开发者的核心基本功。学会它,你就能在不更换模型的前提下,把输出质量提升一个档次,让同样的模型在同样的场景下“显得”更聪明——这几乎是性价比最高的性能优化手段。

目录
  1. 可视化演示
  2. 上下文工程概述
  3. 上下文窗口管理
  4. 动态上下文选择
  5. RAG与上下文结合
  6. 多轮对话维护
  7. Token优化策略
  8. 系统化管理
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

展示上下文窗口Token预算分配、RAG检索注入与多轮对话上下文压缩的核心策略。

本节配有交互动效(进入视口后自动加载,约 3KB)。

上下文窗口Token预算分配 蓝色窗口内系统指令、对话历史、检索文档和用户输入竞争有限Token预算 System + History + RAG + Input ≤ Max 合理分配确保最相关信息进入窗口

上下文工程概述

假设你是一位刑侦队长,手下有一位智商爆表但记忆只有七秒的天才侦探。每次出案子,你都得亲手把线索摆到他桌上:目击者证词、现场照片、嫌疑人的不在场证明。他把这些线索扫一眼,就能推理出凶手。但你如果偷懒,把整箱杂物“哗啦”倒在他面前,他反而会被一张无关的购物小票带偏,得出“凶手是超市收银员”的荒唐结论。这位侦探对线索的依赖程度近乎苛刻——你摆什么,他就信什么。

这条线索的“摆法”,就是上下文工程。官方定义里,Context Engineering 指的是对输入大模型的全部信息进行系统性设计与管理,目的是在有限的信息通道内,最大化模型输出质量。它研究的是“喂什么、喂多少、怎么喂”这三个问题。模型本身的知识储备(预训练参数)像侦探的经验和直觉,而上下文则是他眼前的案件卷宗——两者缺一不可,后者的质量往往决定了最终推理的天花板。

为什么普遍认为上下文工程如此重要?因为大模型底层的 Transformer 架构对输入有一种“注意力均摊”特性:信息越多,每份信息分到的注意力权重可能越稀疏。换句话说,喂给模型的无关内容越多,模型越容易被“噪音”干扰。这就像给侦探桌上既放了关键指纹,又混进了三百张无关路人的照片,他反而不知道该看哪一张。核心指标就是信噪比——信号和噪音的比值。

所以,下一节我们就要解决一个更现实的问题:就算你精挑细选好了线索,办公桌就这么大,放不下怎么办?试着把十几份文件一股脑叠上去,侦探连看都看不过来——这就是上下文窗口的边界。

SNR=Token相关Token总\displaystyle SNR = \frac{Token_{相关}}{Token_{总}}
信噪比 = 真正有用的 Token 数 ÷ 你喂给模型的总 Token 数。这个数越接近 1,说明你在上下文里塞的每句话都在刀刃上。
  1. 分子 Token\_相关指真正影响模型输出质量的那部分内容,比如明确的指令、关键事实、目标用户的约束条件。
    Token相关=有效指令+必要事实+核心约束\displaystyle Token_{相关} = \text{有效指令} + \text{必要事实} + \text{核心约束}
  2. 分母 Token\_总指你输入给模型的全部字符拆分后的 Token 总量,包括废话、重复信息、冗余背景。
    Token总=Token相关+Token噪音\displaystyle Token_{总} = Token_{相关} + Token_{噪音}
  3. 比值含义信噪比大于 0.8 说明输入高度精炼;只有 0.3 说明超过一半的信息在“帮倒忙”。
    SNR∈(0,1],SNR 越接近 1 越好\displaystyle SNR \in (0, 1], \quad SNR \text{ 越接近 } 1 \text{ 越好}

上下文窗口管理

回到刑侦队的场景。你精心挑好了五份关键线索,兴冲冲地走向侦探的办公桌,却发现他的桌子只有一平方米——上面已经放着上一件案子的残留文件。你只能放下三份,另外两份要么扔掉,要么想办法压缩。这位侦探的办公桌面积,就是大模型的“上下文窗口”:模型一次推理能同时“看见”的 Token 数量上限。常见的有 8K(约 8000 个 Token,相当于 6000 个汉字)、32K、128K 甚至更大。窗口越大,桌上能摆的卷宗越多,但桌子的总面积终究有限。

技术上讲,上下文窗口管理包含三个层次。第一是容量感知:你要始终知道当前输入离满员还有多远,这比“凭感觉塞”重要得多。第二是溢出策略:当内容超出窗口时,常用三种处理方案——截断(直接丢掉最早的内容)、摘要(把旧内容压缩成几句话)、滑动窗口(只保留最近的 N 轮对话)。第三是窗口尺寸选择:不是越大越好,因为窗口越大,模型对每份信息的关注度越被稀释,且推理成本和时间随之上升。

办公桌就那么大,聪明的做法不是换更大的桌子(升级模型成本高昂),而是学会在现有桌面上做取舍。取舍的标准是什么?答案藏在下一节:不是所有文件都值得上桌,先看相关性,再决定放谁上去。

U=Token已用Token容量≤1\displaystyle U = \frac{Token_{已用}}{Token_{容量}} \leq 1
窗口利用率 = 已占用的 Token ÷ 窗口总容量。理想情况下,利用率应长期保持在 0.7 ~ 0.95 之间,低于 0.5 说明上下文太空、模型缺乏足够信息;达到 1.0 则面临溢出风险。
  1. Token\_已用当前对话中已经消耗的 Token 总量,包括系统提示、历史对话、检索文档和本轮提问。
    Token已用=Token指令+Token历史+Token检索+Token提问\displaystyle Token_{已用} = Token_{指令} + Token_{历史} + Token_{检索} + Token_{提问}
  2. Token\_容量模型的固定上下文窗口上限,由模型结构决定,开发者无法在运行时改变。
    Token容量=模型配置的窗口长度\displaystyle Token_{容量} = \text{模型配置的窗口长度}
  3. 约束 U ≤ 1一旦 U 超过 1,多余的 Token 会被“静默丢弃”——模型根本看不到它们,这会直接导致关键信息丢失。
    若 U>1⇒溢出丢弃⇒信息丢失\displaystyle \text{若 } U > 1 \Rightarrow \text{溢出丢弃} \Rightarrow \text{信息丢失}

动态上下文选择

侦探正在查一桩连环盗窃案,你却把保险柜里的所有资料——包括去年的宠物失踪案、上个月的噪音投诉记录——全搬到他桌上。他无奈地叹口气:“队长,我只想知道现场的指纹比对结果。”动态上下文选择,就是教你学会“按需取用”:每次只从档案池里挑出与当前任务最相关的那几份证据,而不是把整个档案室搬过来。

在 AI 应用开发中,候选信息的规模可能非常庞大——一个企业知识库里有上万篇文档,显然不可能全部塞进窗口。常见做法是引入一个相关度评分函数:对每个候选块计算它和当前问题的匹配程度,排序后只取 Top-K 注入上下文。这个评分通常由三部分加权组成:语义相似度(向量空间中问题与文档的余弦距离)、时效性(信息越新越有价值)、业务重要性(某些关键信息无论新旧都要保留)。

按照相关度打分,你终于学会了精选桌上文件。但新的问题又来了:侦探办公桌下的空间有限,可档案室有一整层楼的知识——他总不能每次要一份,你就跑一趟档案室吧?下一节,我们给侦探配一个“随叫随到的档案管理员”。

Score=α×sim(q,c)+β×recency(c)+γ×importance(c)\displaystyle Score = \alpha \times \mathrm{sim}(q, c) + \beta \times \mathrm{recency}(c) + \gamma \times \mathrm{importance}(c)
相关度得分 = 语义相似度权重 + 时效性权重 + 重要性权重。三个权重之和通常等于 1(即 α + β + γ = 1),具体比例由业务场景决定。
  1. sim(q, c)查询问题 $q$ 与候选块 $c$ 的向量余弦相似度,衡量“内容是否相关”。
    sim(q,c)=q⃗⋅c⃗∥q⃗∥×∥c⃗∥\displaystyle \mathrm{sim}(q, c) = \frac{\vec{q} \cdot \vec{c}}{\|\vec{q}\| \times \|\vec{c}\|}
  2. recency(c)候选块的时效因子,比如按时间衰减 $e^{-t / \tau}$,越新的信息得分越高。
    recency(c)=e−tc/τ\displaystyle \mathrm{recency}(c) = e^{-t_c / \tau}
  3. importance(c)业务重要性权重,比如用户 ID、订单号等关键实体,无论多旧都必须保留。
    importance(c)={1,c 含关键实体0.3,其他\displaystyle \mathrm{importance}(c) = \begin{cases} 1, & c \text{ 含关键实体} \\ 0.3, & \text{其他} \end{cases}
  4. 权重的平衡三个权重 $\alpha, \beta, \gamma$ 需人工调参,不同场景侧重不同——客服更重时效,法务更重语义。
    α+β+γ=1,α,β,γ≥0\displaystyle \alpha + \beta + \gamma = 1, \quad \alpha, \beta, \gamma \geq 0

RAG与上下文结合

为了让侦探的知识储备突破办公桌的物理限制,刑侦队给他配了一间“外置档案柜”——专门存放历年所有案件的卷宗。侦探办案时,你可以快速从档案柜里调出最相关的三份卷宗放到他桌上,其余的全部留在柜子里。档案柜不会占用桌面空间,却能随查随取。这就是 RAG(Retrieval-Augmented Generation,检索增强生成)的朴素原型。

RAG 在 AI 应用中的实现路径是:先把用户问题 $q$ 转换成向量,然后在向量数据库中检索最相似的 K 个文档块,最后把这些文档块作为“临时上下文”注入模型一起生成答案。这套流程完美解决了三个问题:一是让模型“知道”训练数据之外的知识(如企业内部文档);二是将知识获取成本从“每次重训模型”降为“一次录入资料库”;三是通过提供事实依据显著减少模型胡编乱造(幻觉)的概率。检索命中的核心计算就是向量相似度。

档案柜解决了“知识不够广”的问题,但别忘记侦探还在和人对话——聊到第五轮时,他可能已经忘了你第一轮说过“嫌疑人是个左撇子”。下一节,我们给他配一本“工作纪要”,让长对话不再“说了就忘”。

sim(q,d)=q⃗⋅d⃗∥q⃗∥×∥d⃗∥\displaystyle \mathrm{sim}(q, d) = \frac{\vec{q} \cdot \vec{d}}{\|\vec{q}\| \times \|\vec{d}\|}
查询向量与文档向量的余弦相似度,值域为 [-1, 1]。越接近 1,说明查询和文档在语义空间上越“对齐”,越值得被检索出来放进上下文。
  1. 向量 q 和 d把用户问题和候选文档分别通过嵌入模型映射成高维向量(如 768 维、1536 维),每个维度代表语义空间中的一个特征。
    q⃗∈R768,d⃗∈R768\displaystyle \vec{q} \in \mathbb{R}^{768}, \quad \vec{d} \in \mathbb{R}^{768}
  2. 点积 q·d逐维度相乘后累加,等价于“方向相同时值大”。
    q⃗⋅d⃗=∑i=1nqi×di\displaystyle \vec{q} \cdot \vec{d} = \sum_{i=1}^{n} q_i \times d_i
  3. 向量模长$|q|$ 和 $|d|$ 分别是两向量的长度,除以模长是为了消除“长向量天然分高”的偏差,只看方向。
    ∥q⃗∥=∑i=1nqi2\displaystyle \|\vec{q}\| = \sqrt{\sum_{i=1}^{n} q_i^2}
  4. 阈值与 Top-K设定最低相似度阈值(如 0.35),高于阈值的文档按得分排序,取前 K 条注入上下文。
    TopK={di∣sim(q,di)≥θ}\displaystyle \mathrm{TopK} = \{ d_i \mid \mathrm{sim}(q, d_i) \geq \theta \}

多轮对话维护

试想你和侦探连续讨论案情三小时,最后你问他:“那你觉得左撇子这个线索能锁定谁?”他一脸茫然:“哪来的左撇子?你第一轮时提过吗?”这就是大模型在多轮对话中的典型困境——每轮对话都是独立推理,模型不会自动记得上一轮的结论。上下文工程的核心挑战之一,就是维护一段持续有效的“工作纪要”。

多轮对话的上下文维护策略主要有三类。会话历史管理:保留最近 N 轮完整对话(滑动窗口),超出部分丢弃或降权。摘要记忆机制:定期把早期对话压缩成一句话摘要,比如“用户要求 3 天内发货,物流偏好顺丰”,摘要常驻上下文。关键信息保持:把必须记住的信息(用户名、订单号、偏好设置)抽取成结构化“槽位”,单独存储并每轮重新注入。这三者组合使用,可以做到“桌面上永远有最重要的信息,又不至于被历史淹没”。

有了“工作纪要”,侦探的长期记忆问题解决了。但会议室里还有一个细节让人头疼——你给他读了一整页案情报告,他听完只记住最后两行。下一节,我们教他用“电梯汇报”的方式讲重点。

Ct=Compress(Ct−1⊕Ut)\displaystyle C_t = \mathrm{Compress}\left( C_{t-1} \oplus U_t \right)
第 t 轮的上下文 = 对(上一轮上下文 + 本轮用户输入)做压缩。压缩操作可以是截断、摘要,也可以把旧信息替换为结构化槽位。
  1. C\_t第 $t$ 轮对话时的完整上下文集合,包含系统提示、对话历史、槽位信息。
    Ct={Prompt,History,Slots}\displaystyle C_t = \{ \text{Prompt}, \text{History}, \text{Slots} \}
  2. U\_t第 $t$ 轮的用户新输入。
    Ut=用户本轮发送的文本\displaystyle U_t = \text{用户本轮发送的文本}
  3. ⊕ 操作表示拼接,把新输入接到旧上下文的末尾,此时 Token 总量在增长。
    Ct−1⊕Ut=Ct−1+Ut\displaystyle C_{t-1} \oplus U_t = C_{t-1} + U_t
  4. Compress 函数对拼接后的内容执行压缩,具体可以是抽取摘要、丢弃过期信息、格式化槽位。
    Compress(X)=Summary(X)∪Slots(X)\displaystyle \mathrm{Compress}(X) = \mathrm{Summary}(X) \cup \mathrm{Slots}(X)

Token优化策略

侦探的办公桌上,放着一份打印得密密麻麻的五十页案情汇报。他翻了翻,无奈地揉了揉太阳穴:“队长,你能不能先说结论?”Token 优化策略,就是教你学会“电梯汇报”——在 30 秒内把最重要的信息讲清楚,而不是把整本文件甩给对方。每节省一个 Token,不仅省钱,更让模型把注意力集中在关键信息上。

结构化地看,Token 优化有三大方向。指令精简:砍掉“你好、请问、能否麻烦您”等寒暄词,把“请用中文回答以下问题,注意要详细”缩成“中文回答”,省出的 Token 留给真正的任务内容。结构化格式:用 JSON、Markdown 表格、代码块替代长句描述——一个 JSON 键值对表达的信息量远超一句自然语言。高密度表达:用“左撇子”代替“这个人习惯使用左手”,用“3d“代替”在三天之内”。积累下来,同样信息量的上下文可压缩 30% ~ 60%。

终于,你掌握了挑线索、管桌面、调档案、写纪要、说重点的全部技巧。但这些都是“某一次办案”的经验。如果队里来了一位新侦探(换个模型/新项目),你得把这些经验沉淀成制度——这就是最后一节:系统化管理。

CR=1−Token压缩后Token原始\displaystyle CR = 1 - \frac{Token_{压缩后}}{Token_{原始}}
压缩率 = 1 - 压缩后的 Token ÷ 压缩前的 Token。压缩率 0.5 表示省了一半空间,相当于上下文窗口“变大”了一倍。
  1. Token\_原始未经优化的原始文本的 Token 数,包括寒暄语、重复表达、完整阐述。
    Token原始=Token废话+Token信息\displaystyle Token_{原始} = Token_{废话} + Token_{信息}
  2. Token\_压缩后经过精简、结构化、高密度改写后的 Token 数。
    Token压缩后=Token信息(仅保留核心)\displaystyle Token_{压缩后} = Token_{信息} \text{(仅保留核心)}
  3. 压缩率的直观含义CR = 0.5 表示省了一半 Token,等价于在窗口容量不变的情况下,能容纳两倍的信息量。
    等效窗口容量=Token容量1−CR\displaystyle \text{等效窗口容量} = \frac{Token_{容量}}{1 - CR}

系统化管理

刑侦队来了新人,你不想把办案技巧再口述一遍,于是把过往案件中的优秀线索清单整理成了一本《情报管理手册》。从此,每一位新侦探入职后,照着手册就能快速进入状态。系统化管理上下文的思路与此完全一致:把零散的“经验”沉淀为可复用的“制度”。

系统化管理包含三个层面。上下文审计:定期记录并分析实际发送给模型的内容,检查是否存在冗余、遗漏或不一致;用日志和监控摸清 Token 花费的分布。模板化封装:把经过验证的高质量系统提示词、上下文拼装规则做成可复用模板,参数化(如插入用户姓名、日期、业务类型),避免每次手工拼写。质量评估:围绕生成效果建立量化指标,如答案准确率、相关性、用户满意度,通过 A/B 试验持续迭代上下文设计,让每一次改进都有数据支撑。

现在,你终于成了合格的“情报管理员”:你知道侦探的桌子有多大,知道该从档案柜里挑哪几份文件,知道怎么在长对话里保持纪要,也知道怎么把五十页报告压成一页。上下文工程不是某个单一技巧,而是一整套“用最少的信息,激发模型最大潜能”的方法论。

Q=∑i=1nwi×mi\displaystyle Q = \sum_{i=1}^{n} w_i \times m_i
上下文质量总分 = 各维度的加权得分之和。维度可包括相关性、完整性、时效性、简洁度,权重由业务优先级决定。
  1. m\_i第 $i$ 个评估维度的得分,每个维度按 0~1 打分,1 为满分。
    m1=相关性得分,  m2=完整性得分,  m3=简洁度得分\displaystyle m_1 = \text{相关性得分},\; m_2 = \text{完整性得分},\; m_3 = \text{简洁度得分}
  2. w\_i第 $i$ 个维度的权重,反映该维度对业务目标的贡献程度。
    w1+w2+w3=1,wi≥0\displaystyle w_1 + w_2 + w_3 = 1, \quad w_i \geq 0
  3. 加权求和把各维度得分乘以权重后累加,得到单一总分,便于横向对比不同上下文方案。
    Q=w1m1+w2m2+w3m3\displaystyle Q = w_1 m_1 + w_2 m_2 + w_3 m_3

AI 应用场景

智能客服机器人

阶段:多轮对话维护 + 动态上下文选择

解决的问题:传统客服机器人只做关键词匹配,用户说“我想退货”就被转到固定话术。接入上下文工程后,系统在每轮对话中动态维护客户订单号、购买时间、售后偏好等槽位,并将最近三轮对话摘要常驻窗口,使机器人能记住用户第一轮说过的商品型号,在第五轮回应时依然准确。

具体案例:某电商平台客服机器人,通过上下文工程将“用户问题重复率”降低 42%。当用户说“我之前说过要换货,现在怎么还没发货”,机器人能从上下文窗口中检索出隐含的“换货申请已提交”状态,直接回答物流进度,而非让用户重新描述。

企业知识库问答系统

阶段:RAG与上下文结合 + Token优化

解决的问题:企业内部文档动辄上千份,直接全部塞给模型既不现实成本也高。通过 RAG 架构,系统只检索与问题最相关的 5 个文档块(Top-5),注入上下文后让模型生成答案。结合 Token 优化,系统提示词被压缩成一段 200 Token 的“角色说明 + 回答规则”,整体调用成本下降 35%。

具体案例:某律师事务所使用 RAG 构建“法规助手”:律师提问“竞业限制的适用条件有哪些”,系统从法规库检索出《劳动合同法》相关条款与三份判例摘要,在上下文中标注来源,模型生成的回答不仅准确且附带出处,有效减少法律建议的幻觉风险。

AI写作助手

阶段:上下文窗口管理 + 系统化管理

解决的问题:长文写作时,用户希望模型“记住前面章节的风格”。传统做法是把全文重新粘贴一遍,Token 大量浪费。上下文工程方案:将写作风格抽取为 50 Token 的“风格描述”,把前文要点压缩为 200 Token 的“大纲记忆”,再加上当前章节的完整草稿,三者组合注入窗口。

具体案例:某新媒体团队用写作助手产出万字行业报告。系统每次续写时只注入“风格要求 + 已写章节的摘要 + 当前段落”,相比全文粘贴节省 70% Token,且文风一致性评分从 3.2 提升至 4.5(5 分制)。

Python 演示

python83 行
# -*- coding: utf-8 -*-"""简易上下文管理器: 模拟窗口容量控制 + 动态选择 + 多轮历史维护"""  class SimpleTokenizer:    """简易 token 估算器: 中文按 0.6 token/字, 英文按 0.25 token/字符"""     @staticmethod    def count(text):        cjk = sum(1 for ch in text if '\u4e00' <= ch <= '\u9fff')        other = len(text) - cjk        return int(cjk * 0.6 + other * 0.25) + 1  class ContextManager:    """上下文管理器: 容量控制 + 旧消息淘汰 + 关键信息槽位"""     def __init__(self, capacity=100):        self.capacity = capacity        self.messages = []        self.slots = {}        self.tokenizer = SimpleTokenizer()        self._total_count = 0     def _estimate(self, text):        return self.tokenizer.count(text)     def _trim(self):        """超限时淘汰最旧消息, 直到低于容量"""        while self._total_count > self.capacity and len(self.messages) > 1:            old = self.messages.pop(0)            self._total_count -= old["tokens"]     def add(self, role, content, slots=None):        """添加一条消息, 并提取关键槽位信息"""        if slots:            for key, value in slots.items():                self.slots[key] = value        cost = self._estimate(content)        self.messages.append({"role": role, "content": content, "tokens": cost})        self._total_count += cost        self._trim()        return len(self.messages)     def build_context(self):        """拼装最终上下文: 槽位优先 + 历史消息"""        parts = []        if self.slots:            slot_text = "关键信息: " + ", ".join(                "{}={}".format(k, v) for k, v in self.slots.items()            )            parts.append(slot_text)        for m in self.messages:            parts.append("{}: {}".format(m["role"], m["content"]))        return "\n".join(parts)     def stats(self):        return {            "messages": len(self.messages),            "tokens": self._total_count,            "capacity": self.capacity,            "slots": self.slots,        }  def demo():    cm = ContextManager(capacity=120)    print("=== 上下文管理器演示 ===")    cm.add("user", "我要买一双42码的黑色运动鞋", slots={"size": "42", "color": "black"})    cm.add("assistant", "好的, 已为您记录: 42码, 黑色, 预算有要求吗?")    cm.add("user", "预算500以内", slots={"budget": "500"})    cm.add("assistant", "好的, 500以内, 我为您找几款适合的")    cm.add("user", "顺便帮我看看有没有折扣", slots={"discount": "need"})    cm.add("assistant", "已加入折扣筛选条件")    st = cm.stats()    print("当前统计: tokens={tokens}/{capacity}, 消息数={messages}".format(**st))    print("槽位记录: {}".format(cm.slots))    print("\n最终上下文内容:")    print(cm.build_context())  if __name__ == "__main__":    demo()
目的:演示一个迷你上下文管理器如何在多轮对话中保持关键槽位(尺码、颜色、预算)并控制 Token 总量,超限时自动淘汰最旧消息——这正是生产环境客服机器人上下文模块的核心逻辑。
  1. class SimpleTokenizer用简易规则估算中英文 Token 数,生产级项目会改用 Hugging Face 的 tokenizer 离线工具。
  2. self._total_count = 0计数器加 _count 后缀,避免与实例方法同名造成调用冲突。
  3. def _trim(self)核心淘汰逻辑:只要总量超限就不停弹出最早消息,确保窗口永不溢出。
  4. cm.add("user", "...", slots={...})每次对话顺便抽出槽位(尺码/颜色/预算),槽位独立于历史消息长期保留。
  5. build_context()组装最终上下文:槽位信息永远排在最前,历史消息按时间顺序排列,这是动态上下文选择的一种简化实现。

常见误区

误区“既然模型记性差,那就把所有历史记录全部原封不动地塞给它,信息越多它回答越准确。”很多初学者在调试时第一反应就是把日志、文档、历史全拼进去。

正解上下文越长,噪音越多,关键信息反而容易被稀释。就像给侦探桌上堆了一千张照片,他翻到关键指纹时已经眼花。上下文窗口是“工作记忆”而不是“硬盘”,应只放入与当前任务直接相关的信息,通过摘要和槽位处理不常用的内容。

为何常见:人们容易用“人的直觉”理解模型——以为喂得多就记得多,忽略了 Transformer 的注意力稀释效应。

误区“窗口满了?把最早的消息删掉就行了,反正都是旧对话。”部分开发者以为 FIFO(先进先出)是唯一且合理的溢出策略。

正解早期消息中往往包含决定性的指令或用户偏好,直接丢弃会导致后续对话“失忆”。正确的做法是分级处理:关键槽位独立存储、早期对话压缩成摘要、最近 N 轮才用滑动窗口保留。就像办案时不是按时间丢线索,而是按重要性分类归档。

为何常见:因为 FIFO 实现最简单,写三行代码就能解决溢出,短期看不出副作用,等问题暴露时已经积重难返。

误区“RAG 不就是调个搜索引擎,把搜索结果拼到问题后面一起发给模型吗?随便接个文档库就能用。”

正解RAG 的核心在于“语义检索”和“上下文整合”两个环节。搜索按关键词匹配,语义检索按向量空间距离匹配,能召回“表述不同但意思相同”的文档;整合环节则需要决定文档顺序、截取长度、如何与系统提示词熔铸。检索到的垃圾文档甚至比不检索危害更大——相当于侦探拿到了错误的伪证。

为何常见:RAG 的对外接口看起来像“输入查询、输出文档”,「搜索」的心智模型让新手低估了内部细节的复杂度。

误区认为 Token 优化就是少写几个字,所以干脆把指令压缩到极端,结果模型完全听不懂要干什么。

正解Token 优化是“用同等 Token 传递更多有效信息”,而不是盲目缩短。删掉的是冗余寒暄和重复表述,保留的是必要的结构和约束。比如“请用 JSON 返回包含 name、price、stock 三个字段的数组”这句话虽然长,但每条信息都服务于输出的可用性——压缩后模型格式错乱反而更糟。

为何常见:受身边「越短越好」的直觉影响,忽略了上下文的核心目标不是“短”,而是“信息密度高”。

面试题

Q1. 上下文工程的本质目标是什么?

单选题 · easy

  • A.让模型记住更多历史数据
  • B.在有限窗口内最大化有效信息← 正确答案
  • C.提高模型训练数据量
  • D.减少模型推理的能耗

答案:B。上下文工程的核心是管理“喂给模型的信息”,目标是在有限的上下文窗口中放入最相关、最有价值的信息,从而提升输出质量。选项 B 准确。A 是常见误区——数据是记不住的,窗口有限;C 属于预训练阶段;D 是效果而非目标。

Q2. 上下文窗口中的 Token 已满时,最合理的处理方式是?

单选题 · easy

  • A.直接丢弃最早的消息
  • B.让模型自行选择遗忘内容
  • C.将早期消息压缩为摘要再保留← 正确答案
  • D.增大系统提示词

答案:C。溢出时应按“重要性分级”处理,摘要压缩(C)能保留早期关键信息。A 一刀切可能丢失用户最初设定的指令;B 模型没有自发遗忘机制;D 增加提示词只会让窗口更满。

Q3. 动态上下文选择中,相关度评分 Score 的三个加权项通常是?

单选题 · mid

  • A.语义相似度、文本长度、词汇频率
  • B.语义相似度、时效性、重要程度← 正确答案
  • C.词汇频率、情感倾向、语法正确性
  • D.文本长度、情感倾向、词汇频率

答案:B。Score = α×sim + β×recency + γ×importance,对应语义相似度、时效性和重要程度三个维度。B 与公式完全吻合。A 和 D 中的文本长度和词汇频率不是评分维度;C 中情感倾向与上下文选择无关。

Q4. RAG 系统中,余弦相似度公式的主要作用是?

单选题 · mid

  • A.计算两个文本的字面重合率
  • B.衡量两个文本在语义空间的匹配程度← 正确答案
  • C.评估生成答案的语法正确性
  • D.计算上下文窗口的占用率

答案:B。余弦相似度把问题和文档映射为向量,通过向量夹角衡量语义相似度,能匹配“表述不同但意思相近”的内容,这是 RAG 检索的核心。A 是字符级匹配模型;C 是语言模型质检;D 是窗口利用率衡量。

Q5. 多轮对话中,槽位(Slots)机制的主要作用是什么?

单选题 · mid

  • A.记录对话时间戳以排序
  • B.单独存储关键实体并每轮注入← 正确答案
  • C.压缩历史消息为一句摘要
  • D.统计每轮调用的 Token 数

答案:B。槽位机制把用户偏好、订单号等关键实体抽取出来独立存储,并在每轮对话重新注入上下文,防止关键信息被窗口淘汰。B 准确。A 是时间记录;C 是摘要记忆;D 是 Token 统计,都不涉及关键信息的保持。

Q6. Token 优化策略中,以下哪种做法属于“高密度表达”?

单选题 · mid

  • A.增加语义相似度评分权重
  • B.用“左撇子”替代“这个人习惯使用左手”← 正确答案
  • C.把历史消息全部拼接进窗口
  • D.使用更长的系统提示词列出规则

答案:B。高密度表达指用更少的 Token 传达同等信息量,B 正是用简洁词汇替换冗长描述。A 属于动态上下文选择的调参;C 是错误堆砌;D 是反向操作,增加 Token 消耗。

Q7. 上下文质量评估公式 Q = Σ(wᵢ × mᵢ) 中,wᵢ 的含义是?

单选题 · easy

  • A.第 i 个维度的得分
  • B.第 i 个维度的权重← 正确答案
  • C.上下文的总 Token 数
  • D.模型的推理速度

答案:B。公式中 wᵢ 是权重,mᵢ 是各维度得分。权重反映该维度对业务目标的贡献度,如相关性权重 0.5、简洁度权重 0.3。B 正确。A 把权重和得分搞混;C、D 与公式无关。

Q8. 上下文窗口满时,可采用的溢出处理策略有哪些?

多选题 · mid

  • A.截断最早的内容← 正确答案
  • B.将旧内容压缩成摘要← 正确答案
  • C.丢弃所有历史消息只留本轮输入
  • D.使用滑动窗口保留最近 N 轮← 正确答案

答案:ABD。正文讲到三种经典溢出策略:截断(A)、摘要压缩(B)、滑动窗口(D)。C 是错误的极端做法——完全丢历史会让模型“失忆”。另外还可配合槽位机制保留关键信息。

Q9. 关于 RAG 减少幻觉的原理,下列说法正确的是?

多选题 · hard

  • A.检索到的文档为生成提供事实依据← 正确答案
  • B.向量检索比关键词搜索更能召回语义相关文档← 正确答案
  • C.RAG 让模型在生成时完全复制文档原文
  • D.注入文档能引导模型基于引用内容作答← 正确答案

答案:ABD。RAG 通过检索注入事实依据(A),向量检索匹配语义而非字面(B),注入的引用内容约束了生成的依据范围(D)。C 错误——模型是“参考”文档生成而非“复制”文档,复制反而会引发版权和格式问题。

Q10. 系统化管理上下文包含哪些关键环节?

多选题 · hard

  • A.上下文审计← 正确答案
  • B.模板化封装← 正确答案
  • C.质量评估← 正确答案
  • D.模型微调

答案:ABC。系统化管理指把上下文经验沉淀为制度,包含审计、模板化封装、质量评估三个环节。D 模型微调属于模型层面的优化,不属于上下文工程范畴。审计用于发现问题,封装用于复用,评估用于量化改进。