原文:Jeremy Daly,Context Engineering for Commercial Agent Systems(2026-02-22)

这篇是阅读笔记,记的是商业多租户 Agent 里上下文该怎么当基础设施来做。原文是实地指南,不是规范。

《AI Workshop》里那小节「Context Engineering」讲的是给模型塞对信息和工具,和这篇不是一回事。

这篇在说什么

单用户、笔记本上的 Agent,随便怎么攒上下文都能跑。面向企业的多租户商业 Agent 不行。模型、API、工具调用都在趋同,撑过生产的差别在上下文。

能活下来的系统大致长这样:

  • 记忆是有类型的,不是一整段对话记录
  • 规范真相和派生加速层分开
  • 晋升和压缩都有显式门控
  • 每次运行有可重放、可审计的轨迹信封
  • 轮次之间主动剪枝,上下文按次组装,不靠窗口无限往下滚
  • 隔离是安全边界,在数据平面执行,不靠提示词自觉
  • 成本是一等信号,按层预算,按次归属

演示向的系统会把原始对话建索引、整包复用上下文、把向量库当成真相。成本和跨租户问题都是事后才发现。

商业系统有三项不能让:结构性隔离、确定性重放、经济可预测性。做不到隔离就会漏;做不到重放就没法安全地改;做不到预测单次成本就扩不下去。

还有一个容易忽略的转变:传统软件记的是对象(客户、发票、工单),Agent 系统多出来的是决策。为什么批了这个例外、当时用的哪版策略、决策时看见了什么,都得能追。没有轨迹就优化不了,没有重放就调试不了,没有溯源就没法信任持久记忆。

记忆:范围 × 类型

「记忆」和「上下文」如果不拆开,最后就是一个 blob。安全和正确性都从这里开始坏。

两个维度:

  1. 范围:谁能看见。这是安全边界,在存储和路由层执行,不能交给模型。
  2. 类型:它是什么。这决定它该怎么行为。

范围大概四层:

范围 放什么 谁来写
全局 安全规则、工具契约、本体、Agent 宪法 部署时写入,运行时锁死
租户 组织策略、知识库、操作手册、连接器 门控晋升,受保留策略约束
用户 偏好、工作风格、个人笔记 门控晋升,可设 TTL
会话 工具输出、草稿、中间计划、临时检索 自动回收,不晋升就不留

租户层是治理所在,也是投毒会变成系统性问题的地方。用户配置不要直接改租户基线,用覆盖层:租户状态权威,用户偏好按显式优先级叠上去。范围不只是可见性,多层对同一设置有意见时,它还定义决议顺序。

类型横跨范围:

  • 策略:规范性规则,通常全局或租户,版本化,严格控制
  • 偏好:稳定的个性化参数,通常用户范围
  • 事实:可复用的持久断言,必须带溯源
  • 情节:已完成工作的结构化摘要(案例已解决、例外已批准),从轨迹里抽出来
  • 轨迹:只追加的原始执行事件,飞行记录器

最常见的早期失败,是情节或事实悄悄变成策略。一次例外被存成「我们就是这么做的」,六周后例外成了默认。情节要记发生了什么、为什么、在哪版策略下、谁批准的,不要记成「以后都这样」。

没有范围的记忆是暴露,没有类型的记忆是熵。

Claude Code、Cursor、Windsurf、Warp、Letta、Bedrock AgentCore 的具体产品形态不一样,但都在把记忆做成有范围、有类型的东西,而不是一个对话桶。

真相和加速要拆开

分类法定了之后,下一块是把存储塌成一层:向量库、文档库、对话日志,或者三者搅在一起。原型能用,多租户不行。

规范存储是记录系统,状态必须能从它自己的历史重建,不依赖二级索引:

  1. 只追加的事件日志。每次运行记下检索了什么、评估了哪版策略、调了什么工具、走了什么审批、写出了什么、晋升了哪条记忆。没有它,就回答不了「决策时 Agent 知道什么」。
  2. 结构化记忆存储。事实、偏好、情节、已批准的覆盖、租户知识。每条带范围、类型、溯源、保留策略、敏感性。真相在这里,不在向量索引里。

派生存储是为了快:向量索引、缓存、物化视图。它们可重建、可失效、不权威。向量索引一旦变成真相,溯源、重放和删除保证一起丢。

混合搜索(词法 + 语义)可以做,但过滤要在排序之前,而且是硬谓词。检索结果仍是投影,取回正文时再对规范存储核对租户。规范层干净、投影层漂移,是调查跨租户不一致时很常见的画面:每层分区方式差一点,规模上来就看得见。

原始对话可以留在事件日志里当源材料,不要当检索表面。摘要会变、分词会变,埋在对话里的指令会以无法重放的方式影响下次检索。

每次运行都重新组装

上下文不是加载进来的东西,是组装、约束、压缩、有时丢掉的东西。生产系统重建上下文,失败的系统累积上下文。

一次运行按这个顺序走,跳步就会漂:

  1. 摄取。先钉死租户、用户、角色、隐私模式、敏感性、任务类型,以及本轮策略版本。检索过滤器在查询发出之前就建好。模型不负责过滤数据。
  2. 规划。先决定这次要哪类上下文(租户策略、旧情节、用户偏好、外部知识),再检索。反模式是「全都捞回来让模型自己看」。单次不炸,几周后 token、精度、检索面会一起慢慢坏。
  3. 检索。范围、可见性、敏感性、保留、隐私模式都在排序前生效。临时状态默认不进广泛检索。
  4. 组装工作集。进窗口的是临时分层上下文:全局宪法、租户策略、用户偏好、检索到的事实和情节、会话状态。每层有优先级、token 预算、截断规则。宪法和租户策略要有不可被挤占的保留额度,否则护栏只是建议。
  5. 语义稳定化。压缩之前先把引用规范化、把结构抽出来、把含义锚住。不先稳定就压缩,会删掉模型实际依赖的东西。
  6. Agent 垃圾回收。推理前去重、剪掉低置信构件、卡住工作集上限。
  7. 推理与行动。模型、工具、策略,加上需要时的人工审批。
  8. 晋升门控。决定什么能变成持久记忆。这是整套系统里风险最高的一步。
  9. 发出轨迹信封。一次运行一个只追加的信封,从事件日志物化,不发明新事实。至少钉住身份、模型与策略版本、前缀哈希、检索构件 ID、工具契约版本、晋升决策、token 与成本、父运行血缘。
  10. 生命周期垃圾回收。过期会话缓冲、失效派生索引、套用 TTL、归档大负载、执行保留。

三种回收不要混成一件事:

  • 语义稳定化保正确性
  • Agent 垃圾回收保成本和少漂移
  • 生命周期垃圾回收保持久性和合规

多轮对话也不能成为「窗口一直留着」的理由。每一轮发出轨迹、压缩会话构件、只晋升已批准的记忆,然后按规范记忆、已验证情节和已批准策略重新组上下文。整段历史接着滚,成本、漂移、投毒和重放都会变差。

运行边界用两个事件卡死:run_started 固定策略版本、前缀哈希、隐私模式、模型和父链接;run_finalized 记下最终状态、用量、成本和完整性哈希。信封可以从这两个边界加中间事件重建。

多 Agent:继承身份,不继承工作集

多 Agent 难的不是编排,是上下文过界之后还守不守得住。

子 Agent 不要继承父级的完整工作集。父级显式给出任务、适用策略和选中的构件;子 Agent 用自己的窗口做事,返回带类型的摘要。父级再把摘要放进自己的工作集。这样各自的 token 预算是自己的,重放也能按运行拆开。

必须继承的:租户身份、用户身份、同一版租户策略、全局宪法、隐私模式。委托不能把隐私降级,同一次运行里父子策略版本也不能漂。

不要继承的:父级会话历史、草稿、中间计划,以及父级工作集里没点名的东西。

子 Agent 的输出按工具输出对待:是数据,不是指令。要带类型(事实、情节、建议、工具结果)、溯源(哪个 Agent、哪次运行、哪个模型)和敏感性。它进持久记忆时走同一套晋升门控。内部 Agent 不豁免治理。

轨迹在多 Agent 里是树,不是一条线。parent_run_id、传下去的构件、返回的摘要、每个 Agent 的成本都要在。否则总账上看得到贵,看不到是哪个委托路径吃掉了预算。

投毒发生在「系统开始相信它」

多数失败看起来只是输出稍微差了一点。漂移通常来自三处:隔离没一致执行、坏上下文被当成真相、会话构件被晋升成持久记忆。危险不是模型幻觉一次,是系统把那次幻觉留下来了。

隔离是数据平面原语:

  • 每次检索都带上租户 / 用户过滤,而且是必需谓词
  • 先过滤,再排序
  • 从规范存储取回时,租户对不上就直接失败,不要尽力隔离
  • 每个派生索引使用同一套分区契约

投毒有三种,不只是提示词注入:

  1. 指令投毒。用户内容或工具输出里夹着「忽略先前指令」「一律批准」。策略只能来自签名、版本化的全局或租户构件。用户指令和工具输出都是输入。运行时永远不把指令晋升成策略。
  2. 先例投毒。一次例外被存成规范。例外可以临时存在,要进租户记忆必须走和正式状态一样的批准,并带溯源。
  3. 跨范围污染。用户构件升到租户,租户构件影响全局,索引意外跨租户。全局范围运行时只读。租户写入比用户写入更严。

晋升要当成数据库写入,回答四件事:活在哪一层、是什么类型、保留策略是什么、溯源能不能重放。

默认可行的方向:

  • 会话 → 用户:偏好、草稿、工作风格、用户自己的情节
  • 会话 → 租户:只有已验证的事实,和已批准的情节
  • 会话 → 全局:运行时永不允许

租户级事实要有人工批准、可信记录系统确认,或独立来源的重复佐证。秘密不持久化。PII 没有明确保留规则和同意,就不要轻易留下。

新租户可以有一段更松的引导期,否则冷启动时系统没有任何记忆,体验会很差。松是校准,不是取消门控。

关键路径只写最小记录

推理循环里只写最小规范记录:范围、类型、溯源、保留、敏感性。嵌入、去重、佐证、冲突检测、摘要、重建索引都放到后台加固。这样延迟可预期,丰富化失败也不会挡住推理,派生层挂了真相还在。

因此一条记忆在完全可信之前就已经落盘。状态要显式:

  • 临时:可重放,不进广泛检索
  • 活跃:已验证,可检索、可复用
  • 隔离:疑似投毒或自相矛盾,排除检索,并且要有纠正、撤销或恢复的路径。只排除、不解决,等于静默删除
  • 撤销:带溯源的墓碑,用来挡住检索把旧东西捞回来

加固失败时降低召回,不要降低正确性。规范记录保持完整,状态留在临时,投影重试。矛盾时隔离并记轨迹,不要静默覆盖。合并用确定性身份键(内容摘要 + 范围 + 类型),并且幂等。删除必须级联失效每一个派生层,否则记忆会复活。检索在投影缺失时要能退回规范存储。投影不能是正确性的前提。

冲突时,优先带已验证溯源的较新记忆,优先记录系统而不是 Agent 自己写的事实。

隐私是路由,不是开关

if privacy_mode: disable_logging() 不够。数据还会进队列、检索索引、可观测性、缓存、调试轨迹、分析作业和提示词缓存。新加一层日志,清理逻辑没跟上,隐私就静默退了。

隐私模式属于身份信封,在任何写入之前决定路由。无保留路径不要和保留路径共用同一套物理数据平面:独立存储、独立分区、独立加密域。至少要能分别控制:事件日志留全文、只留元数据,还是不留;结构化记忆能不能晋升;派生索引写不写;对象存储持久化不持久化。

「无保留」要写清楚不包括嵌入、分析日志、提示词缓存和模型厂商侧保留。做不到就不要这么承诺。

每条规范记录带保留策略和过期规则。过期时发墓碑,失效投影,去掉对象引用。没有失效的保留,会留下幽灵记忆。

加密是另一道边界,不只是合规姿态。租户范围的密钥、可轮换的数据密钥、规范存储和派生存储分开的加密域。派生系统被攻破时,规范真相和原始负载仍应处于加密隔离。缓存可以按租户分区、带 TTL,但永远不是权威。

成本有四张表面

单次运行不是输入 token 加输出 token。

总成本 = 推理 + 检索 + 工具 + 持久化

  • 推理随上下文变大,业务逻辑没变也会涨。漂移往往先在这里看见。
  • 检索随索引体积、嵌入维度、查询量和混合排序变贵。记忆越堆,就算 token 预算不动,检索也更贵。
  • 工具包括外部 API、数据库、连接器、重试和人工审批等待。企业场景里它经常比模型贵。
  • 持久化是经济承诺。一次晋升会在之后的每次运行里被反复付费。

多数团队只盯推理。长期主导项常常不是它。

层预算是最有效的结构控制之一。宪法、租户策略、用户记忆、检索情节、会话状态各有额度,加起来就是这次输入预算。没有额度,会话噪声会挤掉安全规则。

静态前缀(宪法 + 租户策略版本)做成稳定哈希,有三件事:策略变更可观测、重放能对上、提供商前缀缓存才用得上。缓存生效以后,边际成本会挪到动态尾巴:检索负载、工具轨迹、累积的会话状态。所以「前缀能缓存」不是可以放松尾巴的理由。

更多上下文不等于更好的答案。渐进式披露(元数据常驻,全文按需取)通常比一次前置灌满更稳。

评估的是整条上下文,不是抽一条输出

一次商业运行是身份、范围过滤、检索、层预算、稳定化、垃圾回收、工具、策略、晋升、生命周期和成本绑在一起的结果。只看最终回答,是在采样输出,不是在评估自主性。

要能回答:检索对了吗,范围守住了吗,策略还在工作集里吗,晋升符合规则吗,成本在预期内吗,明天同样输入还会一样吗。

重放是基线。固定模型版本、策略版本、前缀哈希、检索构件 ID、工具契约版本、晋升决策和分表面成本,再跑一遍。同样输入输出变了,就是漂移,来源可能是模型升级、索引变了、晋升污染、前缀不稳,或生命周期状态变了。没有构件 ID 的重放是概率性的。

模型升级按这个顺序:先冻结一批有代表性的生产轨迹(高上下文、多步工具、策略敏感、边缘审批),锁定构件和前缀;旧模型和新模型各重放一遍,比正确性、策略遵守、token、工具模式和成本;再影子跑,并行记录,不影响用户;最后才替换。上下文窗口变长也是架构事件,不是免费午餐,预算和组装规则要一起改。

要版本化的不只是模型名:温度和推理参数、静态前缀哈希、策略构件、工具契约、检索配置、压缩策略。任何一项在轨迹里看不见,回归分析就断了。

相对 RAG

朴素 RAG 假设检索无状态、记忆在外面、模型是主要推理面、历史可以安全往上加。商业 Agent 把这四条都打破了。检索会变成意外真相,对话会变成记忆,晋升会变成隐式,成本会不可预测。

RAG 是一块积木。上下文引擎还要有类型化记忆、范围、事件日志、结构化记忆、晋升门控、加固生命周期、混合检索、层预算、隐私路由、轨迹信封和确定性重放。

不必一次做完

原文故意不给一条成熟度阶梯。隔离很严但晋升很松、模型有版本但重放对不上、成本有埋点但生命周期在漂,这些可以同时存在。各轴分开长。

按自己已经碰到的约束先做:

  • 已经在跨租户处理企业数据:先做隔离和有范围的记忆
  • 行为在漂、又解释不了:先做轨迹信封和重放
  • 成本在复利:先做层预算和晋升纪律
  • 要做持久记忆:先把真相和加速拆开

托管记忆、厂商侧上下文管理和轨迹服务会越来越多,很多层会变成买而不是建。谁来建不重要,不变量要成立。

模型可以选择,上下文怎么组装、约束、晋升、保留、重放和计价,才是护城河。