一、Agent技能渐进式披露的多种实现方案
Agent技能渐进式披露(Progressive Disclosure) 的多种实现方案。
核心思想:不要一次性把所有技能完整内容塞进上下文,先给摘要,按需加载详情 ,用来控制 token 开销,适配不同大小的技能文档。
原文把方案分成4大维度:
- 存储后端(Storage backends):技能数据存在哪里
- 技能发现机制(Skill discovery):Agent怎么知道有哪些技能
- 技能内容加载策略(Progressive disclosure strategies):拿到技能时怎么读取内容
- 技能尺寸选型参考(Size considerations):按token大小选择方案
你前面那段 LangChain AgentMiddleware 代码,就是:内存字典存储 + 系统prompt列表发现技能 + 单次完整加载 这套组合。
二、分维度详细解析
1. Storage backends|技能存储后端
| 类型 | 说明 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|---|
| In-memory 内存(教程方案) | 技能用Python字典(TypedDict)定义,程序启动加载到内存 | 访问极快,无IO,延迟最低 | 修改技能需要改代码+重新部署;重启丢失 | 技能数量少、稳定不常变更;追求低延迟 |
| File system 文件系统(Claude Code) | 技能 = 目录+文本文件;通过read_file等文件工具读取 |
改技能只改文件,不用发布代码;天然分层 | 文件IO有延迟;需要目录扫描、权限管理 | 本地项目、大量技能,需要频繁更新技能文档 |
| Remote storage 远端存储 | S3 / 数据库 / Notion / 外部API,工具按需拉取 | 技能集中管理,多实例共享;权限控制;版本管理 | 网络IO,延迟高;依赖外部服务,要处理异常 | 多Agent集群、技能需要平台化管理 |
2. Skill discovery|技能发现机制(Agent如何感知存在哪些技能)
| 类型 | 说明 | 优点 | 缺点 |
|---|---|---|---|
| System prompt listing 系统Prompt列表(教程方案) | 启动时把所有技能简短描述拼进system prompt,Agent一开始就知道技能清单 | 实现最简单,不需要额外工具调用;稳定 | 技能太多时,摘要本身也会占用token |
| File-based 基于文件扫描 | Agent调用工具扫描目录,自动发现技能文件 | 新增技能只要新增文件,不用改代码 | 目录扫描消耗token;需要处理文件遍历 |
| Registry-based 注册中心 | 调用API/服务查询可用技能列表 | 集中管控,权限、动态上下线;适合大规模集群 | 依赖外部服务;多一轮工具调用 |
| Dynamic lookup 工具动态查询 | 通过工具调用list_skills()获取技能清单 |
清单不会常驻system prompt;技能数量可无限扩展 | 每轮任务可能需要多一次工具调用,增加轮次 |
3. Progressive disclosure strategies|渐进加载策略(拿到技能后怎么加载内容)
| 策略 | 说明 | 优点 | 缺点 |
|---|---|---|---|
| Single load 单次加载(教程方案) | 调用一次load_skill,一次性返回该技能全部内容 |
实现最简单;Agent拿到完整指令,逻辑简单 | 技能很大时,单次加载会瞬间占满上下文 |
| Paginated 分页加载 | 大技能拆成多页,多次工具调用分批读取 | 控制单次进入上下文的token;防止上下文爆掉 | 多轮工具调用,增加延迟;Agent需要管理页码状态 |
| Search-based 检索式加载 | 在技能内部检索,只返回匹配片段(类似grep) | 只拉取相关片段,token利用率最高 | Agent需要会写检索查询;实现复杂,可能丢失上下文 |
| Hierarchical 分层加载 | 先加载技能概览,再按需深入子章节 | 天然渐进;结构清晰,贴合人类阅读习惯 | 需要维护文档层级结构;Agent需要理解目录结构 |
4. Size considerations|技能尺寸选型参考
这是经验参考,不是硬性标准,要结合模型上下文窗口大小调整
技能大小 Token范围 推荐方案 理由 Small 小型技能 <1K token 直接放入system prompt + Prompt Cache 体积小,缓存后成本低、响应更快;不需要按需加载 Medium 中型技能 1K ~ 10K token 按需加载(教程方案:摘要在system prompt,load_skill单次拉完整内容) 全部塞进prompt太贵;按需加载平衡成本与易用性 Large 大型技能 >10K token,或超过上下文窗口5~10% 分页 / 检索式 / 分层加载 完整加载会耗尽上下文,必须局部读取,不能一次性全量载入
三、组合方案对比(你当前方案 vs 其他典型方案)
✅ 你的教程方案组合
In-memory存储 + System prompt列表发现技能 + Single load单次加载
- 优点:代码简单、延迟低、容易调试
- 短板:技能更新要重新部署;不适合超大技能;技能数量不能无限膨胀
📁 Claude Code方案组合
File system存储 + File-based目录扫描发现技能 + Search-based/ReadFile读取
- 优点:技能纯文件管理,免部署;天然支持大文档检索
- 短板:文件IO;目录扫描会消耗token;本地环境才有文件能力
☁️ 企业平台方案组合
Remote存储(DB/S3) + Registry注册中心发现技能 + Paginated/检索加载
- 优点:多实例共享、权限管控、动态上下线,支持海量技能
- 短板:架构复杂,依赖外部服务,网络延迟
四、核心取舍总表(决策矩阵)
| 评估维度 | In-memory | File System | Remote Storage |
|---|---|---|---|
| 技能更新是否需要重新部署 | ✅ 需要 | ❌ 不需要(改文件) | ❌ 不需要(远端更新) |
| 访问延迟 | 最低 | 中等 | 较高(网络) |
| 最大支持技能体积 | 中小 | 中大 | 超大 |
| 实现复杂度 | 最低 | 中等 | 高 |
| 多实例共享技能 | ❌ 不支持 | 有限支持 | ✅ 原生支持 |
| 适合Agent规模 | 单机、原型 | 单机本地Agent | 集群、平台化 |
五、一句话总结选型逻辑
- 原型/小体量、追求速度:内存存储 + system prompt列出技能 + 单次加载(你现在这套)
- 本地项目,技能经常修改:文件系统 + 目录扫描 + 文件读取
- 企业平台,海量/超大技能,多Agent共用:远端存储 + 注册中心 + 分页/检索加载
- 技能很小(<1k token):干脆直接塞system prompt,不需要渐进披露;技能很大,不能一次性全量加载,必须分页/检索。
六、Mermaid 架构简图(可选,方便放到文档)
#mermaid-svg-vgQmPAPTOmdl3fuw{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-vgQmPAPTOmdl3fuw .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-vgQmPAPTOmdl3fuw .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-vgQmPAPTOmdl3fuw .error-icon{fill:#552222;}#mermaid-svg-vgQmPAPTOmdl3fuw .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-vgQmPAPTOmdl3fuw .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-vgQmPAPTOmdl3fuw .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-vgQmPAPTOmdl3fuw .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-vgQmPAPTOmdl3fuw .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-vgQmPAPTOmdl3fuw .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-vgQmPAPTOmdl3fuw .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-vgQmPAPTOmdl3fuw .marker{fill:#333333;stroke:#333333;}#mermaid-svg-vgQmPAPTOmdl3fuw .marker.cross{stroke:#333333;}#mermaid-svg-vgQmPAPTOmdl3fuw svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-vgQmPAPTOmdl3fuw p{margin:0;}#mermaid-svg-vgQmPAPTOmdl3fuw .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-vgQmPAPTOmdl3fuw .cluster-label text{fill:#333;}#mermaid-svg-vgQmPAPTOmdl3fuw .cluster-label span{color:#333;}#mermaid-svg-vgQmPAPTOmdl3fuw .cluster-label span p{background-color:transparent;}#mermaid-svg-vgQmPAPTOmdl3fuw .label text,#mermaid-svg-vgQmPAPTOmdl3fuw span{fill:#333;color:#333;}#mermaid-svg-vgQmPAPTOmdl3fuw .node rect,#mermaid-svg-vgQmPAPTOmdl3fuw .node circle,#mermaid-svg-vgQmPAPTOmdl3fuw .node ellipse,#mermaid-svg-vgQmPAPTOmdl3fuw .node polygon,#mermaid-svg-vgQmPAPTOmdl3fuw .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-vgQmPAPTOmdl3fuw .rough-node .label text,#mermaid-svg-vgQmPAPTOmdl3fuw .node .label text,#mermaid-svg-vgQmPAPTOmdl3fuw .image-shape .label,#mermaid-svg-vgQmPAPTOmdl3fuw .icon-shape .label{text-anchor:middle;}#mermaid-svg-vgQmPAPTOmdl3fuw .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-vgQmPAPTOmdl3fuw .rough-node .label,#mermaid-svg-vgQmPAPTOmdl3fuw .node .label,#mermaid-svg-vgQmPAPTOmdl3fuw .image-shape .label,#mermaid-svg-vgQmPAPTOmdl3fuw .icon-shape .label{text-align:center;}#mermaid-svg-vgQmPAPTOmdl3fuw .node.clickable{cursor:pointer;}#mermaid-svg-vgQmPAPTOmdl3fuw .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-vgQmPAPTOmdl3fuw .arrowheadPath{fill:#333333;}#mermaid-svg-vgQmPAPTOmdl3fuw .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-vgQmPAPTOmdl3fuw .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-vgQmPAPTOmdl3fuw .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-vgQmPAPTOmdl3fuw .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-vgQmPAPTOmdl3fuw .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-vgQmPAPTOmdl3fuw .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-vgQmPAPTOmdl3fuw .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-vgQmPAPTOmdl3fuw .cluster text{fill:#333;}#mermaid-svg-vgQmPAPTOmdl3fuw .cluster span{color:#333;}#mermaid-svg-vgQmPAPTOmdl3fuw div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-vgQmPAPTOmdl3fuw .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-vgQmPAPTOmdl3fuw rect.text{fill:none;stroke-width:0;}#mermaid-svg-vgQmPAPTOmdl3fuw .icon-shape,#mermaid-svg-vgQmPAPTOmdl3fuw .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-vgQmPAPTOmdl3fuw .icon-shape p,#mermaid-svg-vgQmPAPTOmdl3fuw .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-vgQmPAPTOmdl3fuw .icon-shape .label rect,#mermaid-svg-vgQmPAPTOmdl3fuw .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-vgQmPAPTOmdl3fuw .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-vgQmPAPTOmdl3fuw .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-vgQmPAPTOmdl3fuw :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 1.看技能摘要(system prompt)
2.需要详情时调用工具
3.读取技能内容
4.返回技能内容
Agent
技能发现
渐进加载策略
存储后端
内存 / 文件 / S3/DB