可迁移心智模型Context 是 Projection,不是 Storage:存储回答“系统拥有什么”,Context Builder 回答“此刻允许模型看什么、为什么看、按什么顺序看”。

Context 是运行时视图,不是数据仓库

模型一次推理能看到的全部 Token——系统指令、Tool 描述、消息、状态、检索片段、Memory 和环境观察——共同构成 Context。Anthropic 在 2025 年的工程文章中把 Context Engineering 定义为:从不断演化的候选信息中,为有限 Context Window 策划最有用的 Token 集合。这比“写好一段 Prompt”更接近生产 Agent 的真实问题。

信息已经存在,不代表它应该进入当前请求。把完整会话、所有工具和全部企业文档都塞入模型,会同时扩大延迟、成本、注意力竞争、Prompt Injection 面和数据泄露面。反过来,过度裁剪会让模型缺少完成条件、事实或失败历史。目标不是 Token 最少,而是在目标质量和风险约束下,边际效用最高。

运行时投影:同一信息宇宙会为不同决策生成不同 Context
信息宇宙政策、状态、消息、知识、Memory、Tool 观察。
策略过滤身份、租户、用途、阶段和风险先决定可见性。
效用排序相关性、权威性、时效和互补性共同决定优先级。
预算序列化按模型协议组装,并保留来源与裁剪记录。
不能由模型独自决定可见性LLM 可以参与相关性判断,但租户隔离、授权、数据地域和敏感级别必须在检索或组装层以确定性规则执行。

建立上下文来源清单

架构师首先需要一张来源登记表,而不是一个巨大的字符串模板。每个来源至少记录 Owner、作用域、权威等级、时效、敏感级别、估算成本、注入风险和失效策略。这样才能在故障时回答:“答案引用的规则来自哪里,当时版本是什么?”

稳定指令

系统政策、Agent 身份、输出契约和 Tool Contract 通常跨步骤稳定,但“稳定”不等于永久复制。它们应被版本化,并区分必须每次显式出现的安全不变量与可以按需发现的工具说明。工具太多时,先按能力元数据检索候选,再向模型暴露最小集合。

会话与运行状态

消息历史回答“用户和系统说过什么”,Run 状态回答“系统已经做了什么、下一步等待什么”。二者不能互相替代:把模型曾说“订单已取消”的消息当成业务状态,会制造假完成;只保留结构化状态而删除用户纠正,又会丢失决策原因。

检索和记忆

企业知识是带来源版本的组织事实候选;Memory 是从历史交互提炼的偏好或经验候选。它们进入 Context 前都需要当前身份过滤与新鲜度判断。Memory 不应凌驾于实时业务数据,RAG 片段也不能仅凭向量相似度获得“可信”身份。

外部观察

Tool 返回、网页、文件和其他 Agent 输出是环境数据,不自动具有指令权。最安全的处理是使用结构化信封携带 source、observedAt、trust、content,并在系统指令中明确外部内容不得改变权限或目标。

来源清单的最小决策字段
来源权威性典型作用域主要失败默认处置
安全/业务政策高,版本化组织、租户、任务版本冲突、遗漏硬保留;冲突时阻断
业务状态权威系统拥有对象、用户、租户读取过期、读错对象按需实时读取并带版本
对话/Run 记录事实记录,不是业务真值会话、Run膨胀、顺序错误窗口 + 状态化摘要
检索/Memory候选证据用户、团队、知识域越权、过期、误召回过滤、排序、引用
Tool/外部内容依来源而定单步或 Artifact间接注入、截断数据化、Schema 校验

组装是一条有策略的流水线

把 Context Builder 设计成可测试的纯函数边界:输入是任务、身份、Run 快照和候选来源;输出是模型消息、来源清单、预算报告和丢弃原因。模型 Provider 的消息格式只应出现在最后的 Adapter 中。

// 简化但可执行的 TypeScript:先做授权,再做效用选择
type Candidate = {
  id: string; text: string; tokens: number
  scope: { tenantId: string; userId?: string }
  authority: 0 | 1 | 2 | 3; freshness: number; relevance: number
  mandatory?: boolean
}

export function selectContext(
  candidates: Candidate[],
  request: { tenantId: string; userId: string; budget: number }
) {
  const visible = candidates.filter(item =>
    item.scope.tenantId === request.tenantId &&
    (!item.scope.userId || item.scope.userId === request.userId)
  )
  const ranked = visible.sort((a, b) =>
    Number(b.mandatory) - Number(a.mandatory) ||
    (b.authority * .4 + b.freshness * .25 + b.relevance * .35) -
    (a.authority * .4 + a.freshness * .25 + a.relevance * .35)
  )
  const selected: Candidate[] = []
  let used = 0
  for (const item of ranked) {
    if (used + item.tokens > request.budget && !item.mandatory) continue
    if (used + item.tokens > request.budget) throw new Error('mandatory context exceeds budget')
    selected.push(item); used += item.tokens
  }
  return { selected, used, dropped: visible.length - selected.length }
}

生产实现还需要语义去重、冲突分组、引用映射和序列化,但顺序不能颠倒:先鉴权、后召回;先去重、后压缩;最后才序列化。否则不可见内容即使最终没返回,也可能进入 Reranker、摘要模型或 Trace。

预算不只看总 Token

总窗口应拆成输入、推理、输出和 Tool 往返的预算。输入内部再按不可丢失的约束、当前任务状态、证据和补充上下文分配软硬额度。硬额度用于安全政策、输出 Schema、当前对象 ID 等不变量;软额度允许检索证据根据边际收益竞争。

位置同样是架构变量。Lost in the Middle 的研究表明,相关信息位于长输入中间时性能可能下降。工程上不能把它简化成“重要信息永远放开头”:消息角色、模型家族和任务不同。更可靠的做法是把关键约束靠近决策点、删除重复噪声,并对同一内容做位置扰动实验。

预留是硬约束如果 Context Builder 把窗口全部消耗在输入上,模型可能无空间生成 JSON 或下一次 Tool 参数。预留输出和 Tool 反馈不是性能优化,而是可完成性条件。

压缩必须显式管理信息损失

裁剪、抽取、摘要、结构化归并和 Artifact 引用具有不同损失函数。日志可以抽取异常窗口,重复 Tool 输出可以归并,长文档可以保留标题路径并引用原文;但金额、日期、身份、否定条件、未完成动作和批准记录不能让模型自由改写。

建立压缩账本。每个派生摘要保存原始对象 ID、源版本、压缩策略、生成模型/规则版本、创建时间和受保护字段校验值。摘要多次滚动会累积漂移,因此到达轮次、时间或冲突阈值后,必须回到原始记录重建,而不是继续摘要摘要。

优先引用 Artifact,而不是复制大对象。代码、报表、图片和完整 Tool 结果保存在受控 Artifact Store 中,Context 只放摘要、定位符和按需读取工具。这减少 Token,并让原始证据保持可审计。前提是模型能可靠发现和读取 Artifact;否则“指针化”会变成隐形信息缺失。

Context 污染与冲突处理

污染不是只有恶意 Prompt Injection。陈旧状态、错误 Memory、跨任务残留、重复证据和互相矛盾的政策都会改变模型行为;外部检索内容还可能携带 间接 Prompt Injection。冲突处理应在组装层显式完成:先按权限淘汰不可见来源,再按业务权威、版本和时间排序;无法决定时把冲突本身交给用户或人工,而不是让模型挑一个“更像真的”。

冲突优先级不是统一的“最新覆盖”
冲突错误做法决策规则
用户偏好 vs 安全政策按最近消息政策优先,记录被拒绝的偏好
Memory 地址 vs 订单实时地址语义分数高者胜当前业务对象的权威状态优先
两版产品文档全文同时塞入按目标产品版本过滤;无法判定则澄清
Tool 内容要求提权作为下一条指令执行按不可信数据处理,权限仍由服务端策略决定

用消融和扰动验证上下文价值

只观察最终正确率无法判断 Context 是否有效。记录每个候选的入选原因、Token、来源版本和模型引用情况,然后对固定任务集执行四类实验:移除某个来源看质量是否下降;替换为陈旧版本看系统能否识别;改变位置看性能方差;加入高相似干扰项看模型是否被污染。

评测至少同时看任务成功、事实/引用正确、延迟、输入 Token、失败方差和越权率。某类 Context 平均提升很小但显著降低严重错误,仍可能值得保留;相反,平均质量提升却引入跨租户泄露,不可接受。

主动提取:为什么“相关性最高”不能直接作为 Context 入选规则?
相关性不包含权限、权威性、时效、互补性和成本。一个高度相关但越权或过期的片段比无关内容更危险;多个相似高分片段还可能挤掉关键约束。
迁移判断:把模型窗口扩大四倍,哪些设计仍不能删除?
身份过滤、来源与版本、冲突处理、注入隔离、输出预留和消融评测都不能删除。更大窗口降低容量压力,却扩大成本、干扰和泄露面。
实践证据:怎样证明摘要没有悄悄改掉关键状态?
保留原文指针和摘要版本;为受保护字段做结构化抽取与确定性对比;构造否定、金额、时间和未完成事项的回归样本;达到漂移阈值后从原始记录重建。

资料与事实边界

以下以官方文档、标准、论文和原始工程资料为主。厂商 API、价格、限额与模型能力会变化,落地时仍需按目标版本做能力探测和回归。

  1. Anthropic:Effective context engineering for AI agents — Context 的有限性、策划原则与 Agent 长时运行策略(2025-09)
  2. Liu et al.:Lost in the Middle — 长 Context 中相关信息位置影响性能的实验依据
  3. OpenAI:Conversations API — 会话状态持久化与输入项的数据模型;具体保留策略需按当前账户配置核验
  4. OWASP:LLM Prompt Injection Prevention Cheat Sheet — 外部内容、间接注入和信任边界的安全依据