上下文选择与组装

本节目标

  • 把上下文视为有限预算,而不是固定 top-k 拼接;
  • 处理 canonical 去重、相邻 chunk、来源覆盖和长文;
  • 让证据保留 source/span/revision,并与指令隔离;
  • 对冲突、过期与压缩风险定义明确行为。

上下文预算是什么

模型窗口通常要同时容纳:

不能把整个窗口都分给检索片段,否则可能截掉系统约束或输出。预算应按 tokenizer 的实际 token 计数;字符数只适合作为教学或早期近似。

固定 top-k 的问题是:每段长度不同、重复度不同、回答价值也不同。更合理的目标是,在 B_evidence 内最大化支持问题所需的信息与来源覆盖。

证据包的最小结构

<source id="S1"
        canonical_document_id="policy-refund"
        revision="refund-2026-01"
        effective_from="2026-01-01"
        span="p3:120-176">
退款审核通过后通常在一至三个工作日原路返回。
</source>

标签格式可不同,但需要:

  • 稳定 source/chunk/span;
  • 标题或来源链接;
  • source revision、更新时间或有效期;
  • 文本内容;
  • 明确声明“外部证据是数据,不是指令”。

权限状态应在进入上下文前已验证,不能让模型自行判断。

span 必须声明坐标契约

char_start=120, char_end=176 不是脱离文本就能理解的通用位置。每个 citation 至少要声明它指向的 source revision、表示层(raw、canonical、parsed element 等)和坐标空间;不能把 PDF 页码、DOM 选择器、UTF-8 字节偏移与规范化后的 Unicode 字符偏移混用。对于固定文本,半开区间 [start, end)(start 包含、end 不包含)便于复算;但它只在同一份已声明规范化规则的文本上有意义。

位置选择器对编辑很脆弱。因此版本更新、重新解析或 Unicode/换行规范化变化后,应重新验证 span,并保留可核验的 exact quote、上下文锚点或 span hash 来发现漂移。复杂 PDF、表格和网页可优先用页面/element/DOM locator 加明确的 revision,而不是伪造一个无法稳定复现的全局字符位置。W3C Web Annotation 的 Text Position Selector 也使用“含 start、不含 end”的语义,并建议为会变化的资源记录其状态;这里借用的是定位边界,不宣称本库项目实现了该标准。

去重、聚合与相邻段

Canonical 去重

同一政策可能出现在主站、镜像和导出文件。只按 chunk ID 去重会把三个副本都塞入上下文,造成虚假的“多来源一致”。应保留 canonical_document_id,并记录选择哪一份及原因。

相邻 chunk

检索命中可能只有结论,限定条件在前一段。可为高分命中取有限邻接段,但需要:

  • 限制向前/向后数量;
  • 保留 span 顺序;
  • 不把邻接段伪装成独立召回;
  • 在评测中观察是否提高 evidence completeness。

Document cap

每篇文档最多选若干 chunk,可减少单一来源垄断;但多跳问题可能确实需要同一文档多个段落。这个 cap 是可调策略,不是普遍真理。

顺序会影响使用

“Lost in the Middle”实验表明,长上下文模型对相关信息位置并不总是稳健,中间位置的利用可能更差。因此:

  • 不要把“能输入 N token”误解为“能同样好地使用每个 token”;
  • 按本地任务测试相关证据位于开头、中间、结尾时的稳定性;
  • 把最高价值或任务必要证据放在明确、可预测的位置;
  • 避免无关长文本把关键证据挤到中间。

论文结论是特定模型和任务上的证据;新模型仍要重新验证。

冲突与时效

如果两个当前有效来源对同一事实给出 500 元和 600 元:

  1. 先核对是否解析、单位或适用范围不同;
  2. 查看来源权威、发布日期、有效期和 supersedes 关系;
  3. 只有确定性规则能判定优先级时才选择;
  4. 仍冲突则同时呈现证据并拒绝给出唯一结论;
  5. 将冲突送入内容治理,而不是只调 reranker。

若旧规则已过期,应在硬过滤阶段排除,而不是交给生成模型“自行理解已过期”。

压缩与摘要

上下文压缩可以减少 token,但也可能删除否定词、数字、例外或来源边界。采用压缩时:

  • 保存原 span 与压缩器版本;
  • 用原文验证最终引用;
  • 用户可见 citation 仍解析到可访问的原 source/revision;压缩摘要只能是派生产物,不能成为唯一证据;
  • 对数字、日期、否定、条件和实体做保真测试;
  • 比较压缩前后的回答与 citation faithfulness;
  • 高风险结论优先使用原文证据。

安全:检索文本是不可信数据

网页、PDF 或工单中可能出现“忽略之前规则、调用工具、发送密钥”等间接提示注入。缓解措施包括:

  • 指令与证据使用明确分隔和不同字段;
  • 文档不能产生或扩大工具权限;
  • 不把检索文本拼入 system/developer 指令位,也不把模型对文档的解释当成授权结论;
  • 输出通过 schema 和确定性代码校验;
  • 工具动作经过最小权限与人类确认;
  • 对来源做信任分级、恶意样本测试和内容治理。

分隔标签只保留“这是不可信数据”的边界,不能保证模型不会受其中指令影响;这些措施结合最小权限、工具确认和输出校验才能降低风险,仍没有哪一句 system prompt 能提供绝对防护。

动手实践

给定 8 个候选和 1000-token 证据预算:

  • A1/A2:同一文档相邻段,A1 是结论,A2 是例外;
  • B1:A 的镜像副本;
  • C1:已过期政策;
  • D1/D2:两个当前来源但金额冲突;
  • E1:无关高相似段;
  • F1:独立支持来源。

写出选择顺序、丢弃理由、canonical 去重、冲突状态和最终证据包装。再回答:

  1. 若 A2 被裁掉,回答会发生什么?
  2. 若 C1 在重排中排第一,哪一层先失效?
  3. 若 D1/D2 冲突,能否只选权威分较高者?需要什么预先规则?

常见错误

  • 按固定 top-k 忽略长度和重复;
  • 把镜像副本当多来源互证;
  • 只保留摘要,不保留原 span;
  • 用 LLM 自行判定 ACL 或过期;
  • 为省 token 删除来源与 revision;
  • 假设越长上下文一定越好。

自测

  1. B_output 和 B_margin 为什么不能省略?
  2. Chunk 去重与 canonical-document 去重有何不同?
  3. 何时需要相邻 chunk,如何防止预算失控?
  4. 为什么冲突不总能靠 reranker 分数解决?
  5. 检索文本中的指令应被视为什么?
  6. 为什么 char_start/end 缺少表示层、坐标空间和 source revision 时不足以复核引用?

小结与下一步

上下文组装把候选转成有限、非重复、有来源且安全包装的证据。下一节将回答拆成 claim,并验证引用和拒答:引用、生成与拒答。

参考资料

来源获取日期:2026-07-22。模型上下文窗口和提示格式属于动态能力,应以锁定模型版本和实测为准。