跳到正文
Elaine Blog
返回

需要时再加载:渐进式披露、工具发现与外部工作区

更新于:
Context Engineering

为了回答 A1042 的运费问题,系统可能有订单详情、物流记录、商品说明、所有政策和几十个操作工具。每轮都加载全部内容很浪费,但只告诉模型“需要什么自己找”又容易让它不知道从哪里开始。

渐进式披露的做法,是先提供足够判断下一步的信息,再读取完成当前任务所需的细节。它要求设计一条可发现、可读取、可停止的信息路径。

先给一个能用的目录

假设初始上下文包含三个已获准发现的入口:

资源简介当前可进行的动作
order:A1042当前用户的订单,包含签收时间与商品类别读取必要字段
policy:after-sales售后条款,需按订单适用日期和类别选择检索条款
logistics:A1042运输轨迹与签收记录运送事实有疑问时读取

“文件一”“知识二”这样的名字不够用,模型无法据此选择。简介应解释资源解决什么问题、有哪些关键字段,而不提前泄露整个正文。即使只展示标题,也要先检查发现权限;某个文件是否存在,本身就可能是受限信息。

用户问运费归属时,可以先读取订单的签收日期和商品类别,再查适用政策。如果订单时间明确,就不必立即加载几十条物流轨迹。后续用户说“显示签收但我还没收到”,新的问题才让物流记录成为必要信息。

这也可以由固定工作流完成,并不一定要模型自主决定。固定售后问题通常有稳定的数据需求,程序可以直接获取;开放式排查才可能从动态选择中受益。

发现、读取和执行要分开

工具目录中的一行简介用于发现。完整工具 Schema 说明参数、类型和返回结构,用于构造调用。实际执行则需要后端重新检查当前主体是否有权进行该操作。

例如初始只开放 lookup_ordersearch_policy。当用户明确进入申请流程时,应用才考虑加载生成申请草稿的工具。工具出现在哪个模型请求里,是上下文选择;这个调用能不能执行,是后端授权。二者不能互相替代。

“隐藏按钮”并没有撤销服务端权限。同样,暂时不把退款工具交给模型,也不能让公开的执行接口跳过校验。反过来,发现某个工具也不代表有权执行所有参数组合。

工具太多时,可以设计返回名称与用途的查找接口,再加载选中工具的完整说明。不要把所有 Schema 放进查找结果,重新制造同样的长度问题。工具简介应有清楚的区别,例如“查询退款状态”和“创建退款申请”,而不是两个都叫“处理退款”。

大结果怎样留在上下文之外

假设物流查询返回五千行轨迹,当前只需要最新签收事件。工具可以返回该事件、摘要和一个原文引用,而把完整结果保存在 Artifact 存储中。

{
  "artifact_id": "logistics-A1042-r8",
  "source_version": "r8",
  "summary": "存在签收记录;未发现质量核实记录",
  "available_sections": ["delivery", "transit", "exceptions"],
  "content_hash": "教学示意指纹",
  "expires_at": "2026-09-12T00:00:00+08:00"
}

引用只负责定位,不能因为字符串长得复杂就当成授权凭证。下一次读取仍需要带上可信身份,按资源权限检查。过期后应该返回引用失效,允许应用重新查询,而不是让模型猜测原文。

版本尤其重要。如果摘要来自 r8,读取引用却返回 r9,模型可能把两次不同时刻的结果当成同一事实。可以读取固定版本,或者明确报告版本已变化并重建摘要。哪种方案合适,取决于任务是需要历史重现还是最新状态。

摘要是导航,证据需要回到来源

目录说“适用质量问题退货”,不能推出商家一定承担运费。摘要可能省略“三十天内”“经核实”等条件。准备最终回答时,应读取足够完整的条款,并保留来源版本和定位信息。

这与 RAG 的证据组织 衔接:检索负责找到资料,本篇关心资料什么时候被加载,以及在后续调用中如何继续访问。按需加载不会自动纠正检索质量。

摘要也可能包含外部原文的恶意指令。把正文压成摘要不会提升其指令权限,来源和数据属性应一直保留。

一个受限读取接口怎样工作

progressive_loading.py下载 用标准库字典模拟资源存储。它支持目录发现、固定版本读取和分段加载,不调用模型。

from progressive_loading import Principal, discover, read_section

# 演示身份手工创建;生产由认证中间件生成,不能相信模型自报的身份。
principal = Principal("shop-a", "user-417")

# 先取已获准发现的资源简介,再读取某一固定版本的签收部分。
# 读取接口再次授权,不接受任意本地文件路径。
print(discover(principal))
delivery = read_section(principal, "order:A1042", "r12", "delivery")
print(delivery)

实现中对不存在和无权访问的资源采用相同的对外错误形状,内部仅记录受控原因。这样做可以减少接口直接暴露资源存在性的机会,但它不代表已消除所有时间侧信道。

如果底层使用文件系统,服务端需要将资源 ID 映射到受限根目录,并检查路径规范化、符号链接和文件权限。若使用对象存储,则要在服务端授权后读取或生成短期受限地址。资源 ID 和实际路径分离后,存储迁移也不会迫使模型记住新磁盘位置。

为什么按需加载有时更慢

假设一次目录决策调用需要 1 秒,读取需要 0.2 秒,随后回答再需要 1 秒,那么额外探索增加了时间。这些数字只是计算示意,不是服务实测。若资料本来只有一页,一开始直接提供可能更合适。

可以预先加载几乎每次都需要的订单关键字段和当前目标,将低频的大资料留给按需读取。对允许并行且互不依赖的只读来源,可以由应用并行获取;下一步查询依赖上一步结果时,仍然需要顺序执行。

还要有明确停止条件:例如本任务最多两次补充读取;相同资源同版本已加载则复用;连续读取没有新增证据则报告缺口。次数是业务策略,不存在适用于所有任务的固定最优值。

工作区文件怎样放进这个设计

工作区可以保存计划、资料和中间结果,入口文件提供导航;真正内容按任务读取。这是一种存储与发现安排,不意味着一个共享目录自动具备多租户隔离。

现有 Java 工程使用 AgentScope Workspace,官方说明见 Workspace。配套工程保留原入口,生产环境仍需自行安排工作区隔离、文件权限和生命周期。

当任务需要持续到下一轮,目录和引用只能解决“去哪里取”。应用还必须知道当前在处理哪张订单、哪些条件已确认。接下来要把会话历史与任务状态分开。

继续阅读

上一篇: 上下文不是越长越好:Token 预算、信息选择与排列

下一篇: 一次任务怎样继续:会话历史、工作状态与 Checkpoint

完整文件、依赖与运行边界见配套指南下载


分享这篇文章:

上一篇
上下文不是越长越好:Token 预算、信息选择与排列
下一篇
一次任务怎样继续:会话历史、工作状态与 Checkpoint