一个实用定义
上下文工程是有意识地构造 Model 或 Agent 的输入状态,包括:
task + instructions + evidence + state + tool results + metadata
-> selection/order -> model call -> observable outcome
它与 Prompt Engineering 互补,而不是取代后者。短指令仍可能很关键,大型证据集也可能完全无关。目标不是最大化上下文长度,而是提供支持任务所需的最小可信上下文。
先定义 Context Contract
在选择 Vector Database 或 Memory Store 前定义契约:
| 字段 | 问题 |
|---|---|
| Task | 需要评估什么结果? |
| Audience | 面向哪个 Principal、Tenant 或 User? |
| Evidence | 哪些来源可以支持声明? |
| Freshness | 每个来源需要多新? |
| Provenance | 每项能否追踪到来源和 Revision? |
| Sensitivity | 哪些数据可进入 Model 或 Telemetry? |
| Budget | Token、延迟、存储和成本上限? |
| Deletion | State、Index、Cache 和 Export 如何删除? |
| Failure | 证据缺失或冲突时怎么办? |
这不是只靠 Prompt 实现的规则。Retrieval Layer 和 Tool Executor 必须强制 Tenant Scope、Access Policy 和结果上限。
上下文分层
按信任和生命周期分开:
| 层级 | 示例 | 通常处理 |
|---|---|---|
| Instructions | System Policy、Task Format | 短小、版本化、已审查 |
| Working State | 当前 Turn、Plan、待执行动作 | 有界、可过期 |
| Retrieved Evidence | 文档、代码、数据库记录 | Provenance、权限、时效 |
| Durable State | 偏好、决策、Memory | Purpose、有效期、删除 |
| Environment | Tool Result、时间、Feature Flag | 来源和时间戳 |
User Text、文档、注释、Memory 和 Tool Result 都是不可信内容,可能包含改变任务、外传数据或绕过 Policy 的指令。
选择与排序
选择应面向任务,信号包括:
- Lexical 和 Semantic Relevance;
- Authority 和 Source Trust;
- Recency 与有效时间;
- Tenant 和 Object Permission;
- Diversity 与冗余;
- 必需声明的 Evidence Coverage;
- 大小、延迟和成本。
排序同样重要。将任务约束和下一步决策所需证据放在模型更容易使用的位置。不要假设固定 Top K 能跨领域通用。记录选择原因和 Item Revision 以便评估。
Retrieval 不是授权
Retrieval 必须在 Ranking 前按 Access 过滤。高相似度不能授予文档访问权,Citation 也不能证明调用者拥有对象。
每项至少保留足够 Metadata 来回答:
source -> revision -> owner/tenant -> permission decision
-> retrieval reason -> context position -> model outcome
权限变化时,应将变更传播到 Index、Cache、Summary、Memory、Backup 和评估 Fixture。
带证据的压缩
压缩可以删除重复历史、日志、标记或无关字段,也可能删除否定、限定条件、例外或声明来源。
保存压缩记录:
{
"source_ids": ["doc-17@rev-4", "doc-22@rev-9"],
"summary_revision": "sum-3",
"claims": [
{
"id": "c1",
"text": "The rollout is paused for tenant B.",
"source_spans": ["doc-17#L88-L94"]
}
],
"omitted": ["raw debug logs"],
"expires_at": "recorded-by-policy"
}
保留来源链接和不确定性。评估压缩是否改变任务成功、无依据声明、拒答行为和延迟。不存在通用压缩比例或质量保证。
持久化与 Memory
只持久化有明确用途的信息:
- Validity Time 和 Observed Time;
- Source 与 Confidence;
- Subject 与 Tenant Scope;
- Sensitivity 与 Retention;
- Supersession 与 Deletion;
- 哪些主体或组件可以读取。
已提交的指令文件、对话摘要和 Semantic Memory 的所有权与失败模式不同。Memory 不能静默覆盖当前授权或更新来源。
Token、延迟与成本预算
Context Budget 不只包括 Model Window:
input tokens + output tokens
+ retrieval latency + reranking latency
+ storage/index cost + cache behavior
+ retries and downstream tool time
测量 p50/p95/p99 延迟和每个成功任务成本。Prompt Caching 可能在某些 Provider 和工作负载下有帮助,但必须核对 Cache Key、失效、隐私和计费语义。压缩可能减少输入,却增加一次 Model Call 并损失证据。
上下文安全
使用纵深防御:
- Retrieval 前分类和最小化数据;
- 在模型外强制身份和对象权限;
- 标记 Provenance 和不可信内容 Taint;
- 隔离 Tool 并限制 Egress;
- 限制 Retrieved Text、Tool Result 和 Memory Write;
- 破坏性或外部动作需要审批;
- 脱敏 Telemetry 并定义删除传播;
- 测试直接/间接 Prompt Injection、投毒、过时 State 和跨 Tenant 访问。
Context 是输入通道,不是 Policy 边界。不要把 Secret、Bearer Token 或无限制生产 Dump 放入 Context 文件。
评估上下文变化
改变 Retrieval、排序、压缩、Memory 或 System Instruction 都可能改变行为。维护版本化评估集:
| 评估 | 证据 |
|---|---|
| Contract | Schema、大小、权限、Provenance |
| Retrieval | Relevance、Evidence Recall、Tenant 隔离 |
| Answer | Correctness、Support、Completeness、Abstention |
| Agent | Tool、授权、重复副作用、恢复 |
| Operations | 延迟、成本、Cache 行为、故障处理 |
| Abuse | 注入、投毒、外传、删除、过时 State |
能用确定性 Oracle 的地方优先使用;开放式声明再使用经过校准的人或模型复核。模型分数不能证明 Context 安全或完整。
一个小型 Context Builder
Builder 应明确选择和限制:
from dataclasses import dataclass
from typing import Iterable
@dataclass(frozen=True)
class Evidence:
source_id: str
revision: str
text: str
tenant_id: str
allowed: bool
relevance: float
def build_context(
task: str,
evidence: Iterable[Evidence],
*,
tenant_id: str,
max_chars: int,
) -> list[Evidence]:
candidates = [
item for item in evidence
if item.allowed and item.tenant_id == tenant_id
]
ordered = sorted(candidates, key=lambda item: item.relevance, reverse=True)
selected: list[Evidence] = []
used = 0
for item in ordered:
if used + len(item.text) > max_chars:
break
selected.append(item)
used += len(item.text)
return selected
这是结构性片段,不是完整 Retriever。生产实现仍需要认证、对象级授权、可靠 Token 计算、过时数据处理、Provenance、分页和测试。
常见失败模式
- 把 Context Window 当成理解保证;
- 宣称 Prompt Engineering 已死亡;
- 未做访问控制就 Retrieval;
- 把相似度、Citation 或 Memory 当授权;
- 压缩掉例外和来源 Span;
- 没有 Purpose、Retention 和 Deletion 就持久化用户数据;
- 允许文档或 Tool Result 注入指令;
- 到处使用固定 Token 上限、Top K、Cache Policy 或节省比例;
- 只测回答流畅度,不测 Evidence Support;
- 将模型控制的身份、所有权、定价或角色放进 Context。
实践清单
- [ ] 定义 Task、Audience、Evidence、Freshness、Provenance、Sensitivity、Budget 和 Deletion。
- [ ] 分开 Instructions、Working State、Retrieved Evidence、Durable Memory 和 Environment。
- [ ] 在 Ranking 或注入前执行权限过滤。
- [ ] 记录 Source、Revision、选择原因和有效期。
- [ ] 压缩时保留 Source Span 和不确定性。
- [ ] 限制 Token、延迟、Tool Result、Memory Write 和 Telemetry。
- [ ] 默认 Context 排除 Secret 和无限制生产数据。
- [ ] 测试注入、投毒、过时 State、删除和跨 Tenant。
- [ ] 用任务、安全和运营证据评估 Context 变化。
- [ ] 模型分数必须服从确定性 Policy 与业务 Oracle。
总结
上下文工程是有纪律地管理 LLM 或 Agent 为任务可用的信息:选择相关证据、保存 Provenance、控制 State、遵守权限并测量结果。它不是填满最大 Window 的竞赛,也不是 Prompt 设计的替代品。先建立 Context Contract,在模型外执行安全控制,再由工作负载证据决定 Retrieval、压缩、缓存或持久化是否真正有用。