Prompt 模板之外:上下文什么时候需要一层独立的数据服务
2026 云栖大会技术主论坛上公布过一组来自数据库侧的数据:过去一年,阿里云 RDS PostgreSQL 新增实例数环比增长超过 400%,其中约 80% 的新增实例由 Agent 创建,输入输出流量中约 50% 由 Agent 交互驱动。
我们在规划 Agent Context 时,经常回到这组数据。它说明 Agent 已经在直接创建和使用数据系统,数据的主要读写方正在从人转向 Agent。不过我们对它的解读比较克制:这是一家云厂商在一个产品上的观察,能反映趋势,却推不出"每个企业都需要一层独立的上下文数据服务"。要不要分层,取决于各自系统里重复治理的成本有多高。
这篇文章讲我们怎么看"Prompt 内拼装"和"独立上下文数据层"的分工:什么情况下继续拼 Prompt 就够了,什么情况下该单独分出一层,分出来以后责任又怎么划。
原型阶段,我们也建议直接拼 Prompt
企业 Agent 的早期版本,通常把上下文处理写在应用内部:系统提示词里放一段固定规则,请求到来时查几份文档,再把用户资料、检索结果和工具说明拼成一个 Prompt。对于单一场景、少量数据和短周期验证,这是最快的路径。
我们并不主张在原型阶段就引入一套上下文服务,包括我们自己的产品。原型阶段要验证的是任务本身有没有价值,模型能不能把这件事做对。这时候把精力花在同步链路、权限模型和资产分类上,等于把验证成本转移到了基础设施上。如果业务方向在验证后调整,这些投入大多要重做。
所以我们的第一条建议是:只有一个封闭任务、数据稳定、没有跨用户共享、也不需要沉淀执行反馈的应用,直接拼装 Prompt 更经济。
不过,即使在原型阶段,也有一件成本很低的事可以先做:在 Prompt 模板里给每一段规则或资料注明来源和日期,比如出自哪份文档、哪个版本。这不需要任何额外的基础设施,却能让后面的迁移轻松很多。等到真的需要分层时,这些注释就是第一份副本清单,团队可以据此判断哪些内容来自同一个源头、哪些已经和源头脱节。
Prompt 拼装管不到的那部分问题
Prompt 内拼装发生在运行时。它根据当前任务决定角色说明、历史消息、检索片段和工具信息的排列方式,受模型窗口和 Token 预算约束。它擅长回答的是:这一次请求需要哪些内容,按什么顺序放进去,超出预算时压缩或舍弃哪一部分。
另一类问题它回答不了。某条规则来自哪个系统?原文删除之后,旧切片是否还留在索引里?两个 Agent 引用了同一规则的不同版本,以哪个为准?一位同事的私有偏好,会不会出现在另一位同事的回答里?这些问题发生在请求之前,也延续到请求结束之后。即使把每一次拼装的最终结果都保存下来,也只能重现当时给模型看了什么;原始来源、派生出来的知识单元、它们之间的权限关系,仍然需要另外管理。
系统扩张以后,这类问题会集中出现。多个 Agent 各自复制同一份规则,业务数据持续变化,权限要求收紧,执行经验需要跨任务复用。继续增加 Prompt 模板,模板数量会上去,来源、版本和生命周期的问题依然留在原地。
我们判断上下文是否已经变成一类需要单独管理的数据,通常只看一个问题:出错之后,能不能说清"当时 Agent 用的是哪一版依据,它从哪里来"。如果回答这个问题需要翻好几个 Agent 的代码和日志,上下文就已经需要一个独立的归属地了。
我们把哪些职责放进了数据层
独立上下文数据层的职责,是让可复用的上下文脱离某个 Agent 的模板和进程,成为持续维护的数据资产。在 Agent Context 里,我们把这些资产分成三类,并分别设计了治理方式。
Memory 来自对话与执行过程,属于用户或 Agent 私有,带有隐私属性和一定的概率性,默认只在单个 Agent 内召回。Knowledge 承载事实、规则和领域知识,可以来自企业已验证的文档,也可以由高价值记忆提炼而来,经审核后可以跨 Agent 共享。Skill 描述执行步骤、适用条件和工具配置,在执行中形成,先以候选版本出现,经评估后才发布。三类资产之间可以流转,但每一次跨类流转都要经过提炼或评审。
除了资产本身,还有几项工作在 Prompt 拼装里很难做好。数据层要连接数据库、业务系统、协作平台和多模态文件,用一次性同步完成存量初始化,再用增量同步处理新增、修改、删除和权限变化;同步时保留来源、作者、时间、权限和版本。检索走一个统一入口,屏蔽向量、全文和图检索之间的差异,权限过滤在内容交给模型之前完成。后台任务则持续做整理:记忆去重、冲突处理和衰减,知识的冲突审核与失效归档,旧版本保留追溯。
这些工作都要在请求之外长期运行,也都依赖一份所有 Agent 共同认可的状态,所以我们把它们从应用里拿了出来。
一条规则在数据层里的一生
用一条具体的规则来看,差别会更清楚。假设团队在钉钉文档里维护着一份发布审批规范,现在需要让几个 Agent 都遵守它。
在 Prompt 模板的做法里,有人把规范的要点复制进各个 Agent 的系统提示词,或者各自导入一份到自己的向量索引。规范修订时,需要有人记得逐个去改;规范废止时,更需要有人记得逐个去删。模板里不会记录这段文字是哪天、从哪一版复制过来的。
在数据层的做法里,这份文档通过同步进入知识库,同步时带上来源、作者、时间、权限和版本。入库时,内容被解析成知识单元,一部分是按 chunk 组织的图谱内容,一部分是保存在对象存储里的原始文档,两者通过来源关联;如果开启了入库评审,AI 会按逻辑性、噪音比、矛盾度打分,由人决定入库还是驳回。之后,几个 Agent 在授权范围内通过同一个入口检索到它,返回结果里带着文档标识,可以顺着找回原文。
规范修订后,增量同步把新版本带进来;如果新旧内容冲突,冲突不会自动覆盖,而要经过审核,旧版本保留追溯。规范长期没有被召回,后台会把它识别出来,判断是否过期或已被替代;确认失效后归档,同样保留追溯。整个过程中,"这条规则现在是哪一版、从哪里来、谁能看到"始终有一个确定的答案。
Agent 自己产生的上下文也需要归属
数据层管理的不只是企业文档。Agent 在工作中也持续产生上下文:用户的偏好、项目里做过的决定、某次排查得出的结论。这部分内容如果留在各个 Agent 的本地文件或会话历史里,会遇到另一组问题:换一个会话就找不回来,换一个 Agent 更是从零开始,而且无法统一审计和删除。
我们把这部分放进 Memory 统一管理。通过一键接入或 CLI 接入的 Agent 会自动召回和写入记忆。记忆每晚自动整理一次,合并重复、更新属性;遗忘管理可以按自定义条件和召回频率清理不再有用的内容。开发者可以用 memory list 审计记下了什么,用 memory update、memory delete 修改或删除。
"独立"指的是职责
我们说的独立,主要指职责独立,部署形态是次要的。小型系统完全可以先在现有架构里划出一个明确的模块,只要资产标识、权限、版本和生命周期不再散落在各个业务代码里;等来源、Agent 和团队增多以后,再迁到共享服务。
职责独立之后,访问隔离仍然要保留。多个 Agent 使用同一个入口,但要依据用户身份、任务范围、来源权限和资产类型读到不同的内容。共享的是治理和供给能力,各业务空间的边界依然存在。我们在产品里用工作空间和知识库级权限来表达这层边界,知识库可以按成员和用户组授予 Read、Write、Control 权限,底层同时提供物理与逻辑隔离。
同一个人在多个 Agent 之间切换时也是如此。ctxdb setup --all 可以一次检测并配置本机的所有 Agent,每个 Agent 在 ~/.ctxdb/ctxdb.json 里有自己的一段配置;知识库和 Skill 是几个 Agent 共用的部分,记忆默认私有,需要几个 Agent 共同遵守的偏好,应通过晋升变成知识。
常见的一个误区,是把临时搭起来的向量库改名为"上下文层"。向量检索只覆盖候选召回的一部分。如果删除无法传播到派生内容,权限只在应用末端过滤,Skill 和普通文档混在同一个索引里,那么这个服务即便独立部署,职责也没有分开。
自建与托管:差别在集成和一致性
自建同样能搭出类似的结构:向量库加全文检索负责召回,数据目录记录来源和血缘,权限服务做过滤,再配一组离线任务做清理和对账。我们不认为托管是唯一的选择。两条路线的主要差别在于集成成本,以及由谁来维护各个组件之间的一致性。比如源端删除一份文档之后,切片、图谱节点、缓存、引用过它的记忆和 Skill 都要跟着处理,自建方案需要自己保证这条链路在每个组件上都走通。
选择托管服务,也要清楚它目前的形态。以我们自己的产品为例,帮助文档中沿用 RDS ContextDB 的名称。接入前有两点可以先了解。接入方式之间的能力有差异:一键接入和 CLI 会安装 Hooks,自动在提交 prompt 时召回记忆、在每轮结束后提炼;MCP 接入只提供工具,何时调用由 Agent 自己决定。原生 API 分为 HTTP API 和 Agents API,HTTP API 已经可以用于知识库、文档和查询等操作,Agents API 的公开信息目前以定位为主;通过 API 开放控制台内置助手的 Agent 能力,还在规划中。
不管选哪条路线,应用层都仍然要按自己的模型、任务和预算组装最终的上下文包。数据层提供可追溯的材料,Prompt 工程负责本次调用怎样组织这些材料,两者的分工不会因为引入一个服务而消失。
分层之后,责任要写下来
我们推荐的一种分工是:
- 来源系统决定原始业务事实,以及这些事实的访问权限。
- 上下文数据层负责同步、组织、检索和治理,记录每条内容的来源和版本。
- Agent 编排层决定任务流程和工具调用。
- Prompt 组装层根据当前执行生成有限的上下文包。
- 模型在给定的上下文范围内推理和生成。
最容易模糊的是发布决定。数据层可以记录、组织、召回,也可以从执行结果中提炼候选,但候选是否成为共享资产,是组织的决定。我们在产品里刻意把这一步留给人:记忆晋升需要人工评审,质量分达到团队设定阈值的才可以自动入库;知识入库的冲突不会自动覆盖;Skill 只生成候选版本。如果让数据层自动完成发布,等于让一个检索系统去承担业务审批的责任。
分层之后,排查路径也要跟着变
上下文从 Prompt 模板里搬出去以后,出了问题就不能再只盯着最终 Prompt。排查需要回答两个问题:这次任务实际拿到了哪些上下文,这些上下文分别来自哪里。
第一个问题靠回放。执行 ctxdb debug enable 打开调试,之后可以用 ctxdb debug recall --session=<id> 回放某次会话中实际注入的 <recalled-memories> 和 <available-knowledge-bases>。第二个问题靠来源字段。kb search 加 --verbose 会返回 doc_name、kb_id、doc_id 和 tags,可以顺着找回原始文档和版本;记忆则可以用 memory list 查看当前记下的内容,用 memory get 查看单条。
有了这两条路径,"当时用的是哪一版依据"就从翻代码和日志,变成了查记录。分层之后,这个问题如果还要靠人工拼凑才答得上来,说明职责还没有归到数据层。
动手之前,可以先做一次废止演练
在决定是否分层之前,我们建议先做一次小范围的演练。在源系统里选一条正在被 Agent 使用的规则,假设它今天被废止,然后列出它在整个系统里的所有副本:Prompt 模板里的硬编码、各个 Agent 自建的向量索引、缓存、用户记忆中的引用、据此整理出来的操作步骤或 Skill。对每一处,估计多久能失效,由谁负责清理。
如果清单只有一两处,而且都能在一天内处理完,现有架构大概率还够用,不必急着引入新的一层。如果清单很长,或者有些位置根本说不清副本在哪里,分层的工程理由就比较充分了。
即便结论是需要分层,第一步也不必从平台选型开始。可以先把这一条规则的所有副本收拢到一个可追溯的位置,记录它的来源和版本,再看看要改动多少代码、要协调多少个团队。这次收拢的工作量,基本就是后续正式分层时每条规则要付出的成本,也能帮助团队判断哪些规则先迁、哪些可以暂时留在原处。
更多推荐

所有评论(0)