上下文管理
上下文管理决定每轮模型调用放入哪些信息、怎样排列,以及哪些内容可以作为指令。本文从上下文的组成入手,依次说明预算分配、前缀缓存、按需读取和信任边界。遗漏关键事实、混入过期结果或加入大量无关内容,都会影响模型完成当前任务。
1. 面试核心
先记住这几条,再读正文- 上下文组成。 一次调用的上下文包含应用规则、工具定义、相关记忆、对话历史、工具结果、检索文档和当前请求。卡 · 综合题
- 前缀缓存。 稳定规则和工具定义放在前部、动态内容放在后部,有利于复用前缀缓存,降低输入费用与首 Token 延迟。卡 · 组装顺序与前缀缓存
- 渐进式披露。 渐进式披露先提供索引或摘要,再按任务读取细节,以更多调用轮次换取更小的单轮输入。卡 · 按需加载与渐进式披露
- 来源与授权。 执行权限由应用授权决定,检索文档和工具结果作为有来源的任务数据传入模型。卡 · 状态冲突与时效
2. 上下文的组成
组装上下文时,需要先分清每段内容来自哪里、用于什么目的。来源帮助应用核对事实,消息角色与内容边界则标明哪些是指令、哪些是待分析的数据。事实可靠性和指令权限是两个维度:工具成功返回,也可能带回过期网页或恶意文本。
| 内容 | 来源 | 处理方式 |
|---|---|---|
| 应用规则 | 开发者配置 | 放在对应的指令角色。 |
| 工具定义 | 本地配置或工具服务 | 审核用途与参数。 |
| 长期记忆 | 用户偏好或状态库 | 检查相关性、版本和权限。 |
| 检索到的内容 | 文档、网页、代码库 | 标注来源,作为数据引用。 |
| 历史消息 | 用户与模型 | 保留角色及工具调用关系。 |
| 当前请求 | 用户 | 在应用授权范围内解释。 |
这些内容的更新频率也不同。应用规则随版本发布而更新,工具定义随配置变化而更新。用户偏好变化较少,但也需要检查是否过期。检索文档与当前请求每轮变化,对话历史则随轮次增长。工具每执行一步,还会产生新的结果,需要保留调用 ID 和返回时间。
下面用一个示意说明规则、状态、历史与当前请求如何分层:
应用规则:任务范围、输出规范
相关状态:目标、约束、有效偏好
近期历史:用户消息、模型消息、完整工具交互
检索内容:来源、版本、摘录
当前请求:用户本轮输入
具体角色字段按所用 API 映射。在提供消息角色的接口中,用户消息对应 user,模型消息对应 assistant。工具结果使用接口规定的工具消息形式,并通过调用 ID 关联原请求。应用规则则放入该接口规定的指令位置。
用户偏好应作为有来源的状态传入,并按当前问题选择相关条目。比如,只把与本次任务有关的语言偏好或项目约束放入上下文。将外部记忆直接拼成系统规则,会让其中的文字获得更高指令权限,所以应保留它原有的来源和适用范围。
2.1 Token 预算与内容选择
预算分配要保证模型既能读完输入,也有空间继续生成。组装前先为输出和下一步工具结果留出空间,再把剩余预算分给固定指令、当前任务和相关证据。
组装后估算 Token 数。如果超出预算,按相关性、时效和必要性选择保留内容:
- 优先保留完成当前步骤所需的证据,移出离题文档和已经用过的旧工具结果。
- 同一事实有多个版本时,保留当前有效的版本,并记录来源与更新时间。
- 固定规则和当前请求中的必要条件要完整保留。必需文件本身超限时,可以分段处理。
摘录文档时,标题、版本和引用位置要一起保留。这样,模型给出结论后,程序或读者才能找到原文核对。
旧历史可用摘要缩短,具体方法见上下文压缩。
3. 组装顺序与前缀缓存
多个请求会重复使用相同的规则和工具定义。把这些稳定内容放在前部,服务就有机会复用相同前缀的计算,降低首 Token 延迟和输入费用。
前缀缓存的计算原理见大语言模型基础。这里重点说明应用怎样排列输入。
在保持消息角色和工具交互有效的前提下,可以按内容的变化频率组织:
- 工具定义和应用规则放在前部,在同一版本内保持稳定。
- 接着放较稳定的项目说明与相关用户偏好,并保留它们各自的来源。
- 再放对话历史,新消息追加到末尾,尽量保留已有内容。
- 最后放本轮检索文档和当前请求,时间戳、请求 ID 也放在这一变化区域。
缓存匹配的是序列化后的相同前缀,也就是接口把消息组织成模型输入后的开头部分。如果在开头插入每轮变化的时间戳,共同前缀就会变短。随机调整工具定义的顺序也有同样的问题。因此,工具顺序应固定,动态信息尽量靠后。
缓存能否命中还取决于提供方的最小长度、保存期限和请求路由等规则。OpenAI 提供缓存输入用量明细,Anthropic 提供自动缓存或显式缓存控制。启用方式与计费规则按所用接口核对,收益则通过实际用量(usage)验证。
压缩历史会改写前缀,变化位置之前的共同部分仍可复用。替换旧历史时,可以保留稳定规则,避免把整个输入一起重写。压缩会减少后续输入,却也会改变缓存命中量,所以要比较整次任务的费用与耗时。
4. 按需加载与渐进式披露
大文件和大量工具定义如果一次全部加载,会很快占满窗口。渐进式披露先给出索引或摘要,让模型知道有哪些内容,再按当前任务读取细节。
索引需要包含稳定的文件或段落位置,模型选定后,工具才能准确读取。常见的四类按需加载对象如下:
- 文件与文档:先返回目录、文件列表或章节摘要,并给出总长度。模型确定目标后,再按行号、页码或章节读取。
- 工具定义:工具较多时,先提供类别或工具搜索入口。检索到需要的工具后,再加载完整定义和参数说明。
- 工具结果:大结果写入文件,上下文中只放摘要、关键错误、总行数和路径。后续需要原文时,再分页或搜索。
- Skill:Skill 是包含任务说明和可选脚本的技能包。先展示名称和用途,匹配任务后再读取完整说明,按需加载脚本。
Skill 的加载机制见 Agent Skills。
渐进读取减少了单次输入,也让模型更容易找到当前步骤的重点,代价是增加工具调用轮次。是否采用,要看完整内容的大小与实际使用比例。如果文件很小,而且每轮几乎都要读全文,直接加载更简单。
5. 信任边界
上下文中的文档和网页会包含看起来像指令的文字。应用需要标明它们是待分析的数据,并由程序决定模型提出的操作能否执行。
组装时,要同时处理内容边界、数据范围和执行权限:
- 用明确标签包裹外部文档,比如
<document source="...">…</document>。在应用规则中说明其中内容只作参考,让模型更容易识别来源。 - 检索前按用户和租户过滤数据。凭证、无关内部规则和其他用户的数据应排除在本轮上下文之外。
- 工具结果引出高风险动作时,由程序校验权限与参数。模型负责解释文档,执行器负责判断操作是否获得授权。
标签只能帮助模型区分内容,无法独立阻止提示注入。具体防护机制见提示注入。
5.1 状态冲突与时效
旧记忆和当前输入冲突时,要先看它们描述的是偏好、业务事实还是授权。每条状态都应记录主体、来源、时间和适用范围,才能判断哪条仍然有效。
用户当前明确更正偏好时,应更新对应旧条目。订单状态等业务事实,则以授权系统中的当前记录为准。检索文档中的“忽略规则”仍属于文档内容。即使摘要或记忆转述了这句话,也要保留来源,避免它在压缩后被当作应用指令。
比如,旧摘要写着“允许发送报告”,本轮用户却撤回了授权。这时应把当前授权标记为已撤回,执行器据此停止发送。旧摘要只记录过去的决定,后续操作要依据当前授权。
6. 常见问题
6.1 窗口足够大时,还需要选择信息吗?
窗口足够大时,仍需要选择与任务相关的信息。更长的输入会增加费用和处理时间,冗余内容还会让关键证据更难被利用。在长文档问答中,位于中间的信息尤其容易被忽略。
因此,目标是提供完成当前步骤所需的充分信息,同时移出无关内容。选择效果应在目标模型与任务上评测,检查回答是否真正使用了必要证据。
6.2 多任务之间怎样隔离上下文?
每个任务或会话应维护独立的历史和状态,读取时同时核对用户、租户与会话 ID。这样可以避免把其他任务的结论或其他用户的数据混进当前输入。
授权范围一致时,可以共享稳定规则和工具定义。子任务也可以在独立 Agent 上下文中执行,只返回结论、证据和未决事项。主任务据此继续工作,无需加载子任务的全部探索过程。
跨会话记忆的保存与读取见Agent 记忆。
7 · 面试题卡片
本页题目与参考回答
7.1 用户消息、系统提示词、Memory 等信息如何组装并发送给模型?
题型:综合题
考察重点:说明不同来源的信息怎样分层、怎样保留工具调用关系,以及如何在预算内选择内容。
参考回答
应用应按消息角色与来源组装上下文,再按当前任务选择相关记忆、历史和证据。
规则与工具定义放在稳定的前部,之后加入有效偏好和项目状态。对话历史保留用户、模型和工具消息的角色,工具结果通过调用 ID 关联原请求。本轮检索文档与当前输入放在后部,文档标明来源与版本,并与指令分隔。
长期记忆只读取当前任务需要的条目。组装前预留输出与后续工具结果预算,组装后估算 Token 数。超限时优先移出无关检索结果和已用过的旧工具输出,再压缩旧历史。固定规则与当前请求的必要条件应完整保留,事实时效和当前授权则分别核对。
7.2 Prompt 中静态内容和动态内容应该怎样排列,才能更好地利用前缀缓存?
考察重点:解释哪些输入变化会缩短共同前缀,以及怎样用缓存用量验证排列效果。
相关内容:组装顺序与前缀缓存。
参考回答
把稳定规则和工具定义放在前部,把本轮文档与用户输入放在后部,有利于复用前缀缓存。
缓存复用与之前请求完全相同的前缀计算。历史只在末尾追加时,已有前缀得以保留;修改中间内容时,变化位置之前仍可复用。因此,时间戳与请求 ID 应靠后,工具列表也应保持固定顺序。
命中还受缓存期限、最小长度和请求路由等条件影响,需要读取提供方的缓存用量明细验证。压缩历史时保留稳定规则,并比较压缩后整次任务的费用与耗时,才能判断是否有收益。
7.3 文档读取结果如何使用渐进式披露,避免上下文快速膨胀?
考察重点:解释模型怎样从索引定位到原文,并比较减少输入与增加调用的代价。
相关内容:按需加载与渐进式披露。
参考回答
渐进式披露先返回文档索引,再根据当前任务读取选中的片段。
索引包含目录、章节摘要、总长度和稳定位置。模型据此选择章节,再通过工具的范围参数读取指定行或页。大型结果存入文件,上下文中保留路径、结论与关键错误,后续按引用搜索或分页读取。
这样能减少单轮输入,代价是增加调用次数。是否采用,要看完整内容大小和实际使用比例。文件很小且每次几乎都需要全文时,直接加载更简单。
7.4 旧记忆与当前输入冲突时,如何确定有效信息?
考察重点:区分偏好、业务事实和授权冲突,说明各自应以哪一类信息为准。
相关内容:状态冲突与时效。
参考回答
有效信息要按来源、时间和适用范围判断,并区分偏好、业务事实与授权。
用户明确更正偏好时,更新对应旧状态。业务事实则从授权系统读取当前记录。外部文档被写入摘要后仍是待分析的数据,保留来源有助于避免它被当作指令。
旧摘要中的授权如果已被撤回,执行器应按新状态停止对应操作。这样,过去的记录仍可追溯,当前动作也能遵守最新授权。