核心结论 :想让 Agent 更自动化,关键不是「给它更多知识」,而是「在对的时机只给它对的那一点知识 」。做法是动态挂载(dynamic loading) :把所有知识(Skill、领域文档、规则、经验)拆成「元数据常驻 + 正文按需注入 + 资源真需要才读 」三层,Agent 先用一句话描述「有哪些能力」做路由,命中后才把完整内容拉进上下文。这就是 Anthropic 推行的 SKILL.md 三层渐进加载(progressive loading) 模式,也是当前 Agent 平台收敛出的主流架构。它解决的核心矛盾是:知识越多,全塞进上下文的成本越高、噪音越大、越容易选错------动态挂载让「看起来懂一万件事」和「实际只加载一件事」同时成立。
目录
-
- 一句话结论
-
- 为什么不能把所有知识塞进上下文
-
- 核心思路:三层渐进加载(Progressive Loading)
-
- 第一层:元数据常驻(Metadata)
-
- 第二层:正文按需注入(Instructions)
-
- 第三层:资源真需要才读(Resources)
-
- 路由机制:search → inspect → select
-
- 运行时注入与记忆层:动态信息的两个入口
-
- 完整可运行代码:一个动态知识挂载器
-
- 对照表:症状 → 原因 → 解法
-
- 判断收尾
1. 一句话结论
先建立一个直觉 🎭:这就像「公司的知识管理」 ------你不需要把全公司所有部门的操作手册都印在员工桌上(那样桌面早爆了),而是先给一份「目录」(哪个部门管什么),需要时再调出对应那一本。动态挂载就是给 Agent 装一个「按需调阅」的知识库。
所以核心三句话:
- 元数据常驻:只放「知识目录」(名称 + 一句话描述),极省 token。
- 正文按需:命中后才把完整内容注入上下文。
- 资源懒读:脚本、参考文档真正要用才读。
一句话:动态挂载 = 把「知识」从「一次性塞满」改成「按索引调阅」------用一层薄薄的目录,撑起一个庞大的知识库。
2. 为什么不能把所有知识塞进上下文
先看「静态全塞」的三种死法:
- 上下文膨胀:几十个 Skill / 上百篇文档全塞进 system prompt,几万 token 起步,还没开始干活就烧掉大半窗口。
- 噪音干扰 :无关知识堆在一起,模型注意力被稀释,选错知识的概率反而上升。
- 维护地狱:加一个新 Skill 要改主提示词,改动风险高,且每次都要全量重测。
用类比 🎭:这就像「把整个图书馆塞进书包」 ------书越背越重,你反而找不到要的那本。聪明的做法是带一张索书号,到馆里按号取书。
💡 我在Agent规则管理:让 Memory 做索引、让 Skill 存规则------上下文上限实测与分工方案里实测过上下文上限的代价,动态挂载正是「不把所有规则塞进去」的工程答案。
3. 核心思路:三层渐进加载(Progressive Loading)
主流方案把一份知识拆成三层,逐层加载:
| 层级 | 内容 | 常驻还是按需 | 典型体积 |
|---|---|---|---|
| 第一层 | 元数据(名称 + 一句话描述) | 常驻 | 每条约 20--50 字 |
| 第二层 | 正文(完整指令 / 规则) | 命中时注入 | 每条几百到几千字 |
| 第三层 | 资源(脚本 / 参考文档 / 数据) | 真需要才读 | 可任意大 |
- Anthropic 的 SKILL.md 就是这套 :每个 Skill 是一个目录,
SKILL.md头部是元数据,正文是指令,旁边挂脚本与参考文件。 - 加载顺序:先看目录 → 命中就读正文 → 用到文件才读文件。
- 收益:Agent 「看起来」掌握了所有能力(因为目录全在),但实际上下文只加载了当前要用的那一点。
用类比 🎭:这就像「点菜」------菜单(元数据)全给你看,你点了哪道(命中),厨房才做哪道(加载正文),配菜用的特殊食材(资源)用到才现取。
4. 第一层:元数据常驻(Metadata)
第一层是「目录」,必须常驻,但必须极简。
- 内容 :每个知识只保留
name(名称)和description(一句话说明「什么时候用它」)。 - 关键 :description 要写「使用场景」,而不只是「它是什么」------因为路由是靠它匹配的。
- 体积控制:一条 20--50 字,50 条也就一两千 token,完全可接受。
反例 vs 正例:
| 写法 | 示例 | 问题 |
|---|---|---|
| ❌ 差 | name: pdf-tool, description: PDF 处理工具 |
太泛,路由不知道何时用 |
| ✅ 好 | name: pdf-extract, description: 需要从 PDF 里提取文字或表格时使用 |
带场景,路由能命中 |
💡 第一层是整个机制的「命门」:目录写得好不好,直接决定能不能挂载对。目录写得含糊,后面全白搭。
5. 第二层:正文按需注入(Instructions)
第二层是「完整内容」------命中后,才把它注入上下文。
- 触发条件:路由阶段判定「这个知识用得上」。
- 注入方式:把该知识的完整说明(步骤、规则、示例)拼到上下文里。
- 用完即弃:任务结束或切到别的知识,正文可以退出上下文(配合上下文压缩,见本专栏《Agent 上下文太长怎么办》)。
关键设计:
- 正文要自包含:一旦注入,模型不需要再回头找别的资料,就能照着执行。
- 正文别太长:如果一个知识正文就几千字,说明它该拆成多个子知识。
- 可审计:注入时记录「加载了哪个知识、为什么命中」,出问题能回放。
用类比 🎭:目录是「书名」,正文是「那本书」------你不会把整本书背上,但一旦决定读它,就要读到完整内容,不能只读一半。
6. 第三层:资源真需要才读(Resources)
第三层是「附件」------脚本、模板、参考文档、数据集,用到才读。
- 典型资源 :处理脚本(如
extract.py)、模板文件、长参考手册、示例数据。 - 加载时机:正文里提示「需要时执行这个脚本」,Agent 真执行时才读。
- 好处 :一个知识可以挂很大的资源,但不加载就不占上下文。
这三层的配合逻辑:
- 第一层:永远在(目录)。
- 第二层:命中才在(正文)。
- 第三层:用到才在(资源)。
💡 三层加起来,才能做到「知识库无限大、上下文占用极小」------这就是「看起来懂一切,实际只加载一件事」。
参考资料:
7. 路由机制:search → inspect → select
三层有了,那「怎么知道该加载哪个」?靠路由(routing)。业界收敛出的标准动作是三步:
- search(搜索):用任务描述去检索候选知识(按元数据匹配 / 向量检索)。
- inspect(查看):对候选逐个「看细节」,确认是不是真的对。
- select(选择):选定后加载正文,开始执行。
这套方法的精髓是:「证据不足就继续查或停止,不强行命中」。
- 高频知识常驻(经常用,放目录甚至正文常驻)。
- 长尾知识进 metadata 库,需要时再 search 回来。
- 命中率不靠「单次排序高分」,而靠「边界清楚 + 可审计 + 选择可回退」。
用类比 🎭:这就像「图书馆找书」------先查目录(search),翻两页确认是不是这本(inspect),确定后借走(select)。查不到就再查,而不是硬抓一本不相干的。
参考资料:
8. 运行时注入与记忆层:动态信息的两个入口
除了「知识库」,还有两类信息需要动态挂载:
① 运行时注入(runtime injection)
- 内容:当前时间、渠道 ID、用户偏好、会话状态等「每轮都可能变」的信息。
- 做法:每轮按需拼入,而不是写死在系统提示里。
- 好处:信息永远最新,且不浪费上下文。
② 记忆层(memory layer)
- 内容:跨会话积累的经验(上次怎么解决的、用户的长期偏好)。
- 做法:存到外部(如
MEMORY.md或向量库),不直接进系统提示,需要时才读取。 - 好处:Agent 能「记得」历史,但不让历史拖累当前上下文。
| 信息类型 | 存放位置 | 加载方式 |
|---|---|---|
| 静态知识 | Skill 目录 / 知识库 | 三层渐进加载 |
| 运行时信息 | 每轮计算 | 运行时注入 |
| 跨会话经验 | MEMORY / 向量库 | 按需读取 |
💡 这三类信息合起来,才是完整的「动态挂载」------知识按目录调、运行时按轮拼、经验按需读。
9. 完整可运行代码:一个动态知识挂载器
下面是一段复制粘贴就能跑的 Python 代码,实现完整的「三层动态挂载」:知识注册表存元数据、路由函数按任务匹配、命中后才加载正文、资源按需读取。运行无需第三方库。
python
# 动态知识挂载器:元数据常驻 + 正文按需 + 资源懒读
class KnowledgeRegistry:
def __init__(self):
self.metadata = [] # 第一层:元数据目录(常驻,极简)
self.bodies = {} # 第二层:正文(按需注入)
self.resources = {} # 第三层:资源(用到才读)
def register(self, name, description, body, resources=None):
"""注册一个知识:元数据进目录,正文和资源存起来先不加载"""
self.metadata.append({"name": name, "description": description})
self.bodies[name] = body # 正文存着,暂不注入
if resources:
self.resources[name] = resources # 资源存着,懒加载
def route(self, task):
"""路由:按任务关键词匹配元数据,返回候选知识名"""
hits = []
for meta in self.metadata:
# 简化路由:任务词命中 description 即算相关(真实场景用向量检索)
if any(word in meta["description"] for word in task.split()):
hits.append(meta["name"])
return hits
def load(self, names):
"""按需加载:只把命中知识的正文注入上下文"""
context = []
for name in names:
if name in self.bodies:
context.append(f"【{name}】{self.bodies[name]}") # 注入正文
return context
def read_resource(self, name, res_key):
"""资源懒读:真正需要时才读第三层资源"""
return self.resources.get(name, {}).get(res_key, "资源不存在")
if __name__ == "__main__":
kb = KnowledgeRegistry()
# 注册三个知识(元数据常驻,正文先不加载)
kb.register("pdf-extract", "需要从 PDF 提取文字或表格时使用",
"步骤:1. 加载 PDF 2. 调用解析 3. 输出结构化文本",
{"script": "extract.py"})
kb.register("image-crop", "需要裁剪或缩放图片时使用",
"步骤:1. 读图 2. 按坐标裁剪 3. 保存")
kb.register("email-send", "需要给用户发送邮件时使用",
"步骤:1. 校验地址 2. 组装内容 3. 发送并确认")
# 常驻的只有元数据目录(3 条,极省 token)
print("常驻目录:", [m["name"] for m in kb.metadata])
# 用户任务来了:先路由
task = "帮我从 PDF 提取表格"
hits = kb.route(task)
print("路由命中:", hits) # → ['pdf-extract']
# 只加载命中知识的正文
ctx = kb.load(hits)
print("注入上下文:", ctx)
# 需要脚本时才读第三层资源
print("资源读取:", kb.read_resource("pdf-extract", "script"))
怎么读这段代码 :metadata 是第 4 节的「元数据常驻」------只有 3 条名称+描述,占 token 极少;bodies 存正文但注册时不注入 ,只有 load() 命中后才拼进上下文,这是第 5 节「正文按需注入」;resources 里的脚本只有 read_resource() 真正调用时才读,是第 6 节「资源懒读」;route() 是第 7 节的「search」简化版(真实场景换成向量检索 + inspect + select)。跑一遍你会看到:常驻 3 条目录,实际只加载了 1 条正文------这就是「看起来懂三件事,实际只加载一件」。
10. 对照表:症状 → 原因 → 解法
| 症状 | 原因 | 解法 |
|---|---|---|
| system prompt 几万 token、上下文不够用 | 所有知识全塞进去 | 元数据常驻,正文按需注入 |
| 知识越多越容易选错 | 无关知识稀释注意力 | 路由先筛候选,只加载命中的 |
| 加一个新 Skill 要改主提示词 | 知识硬编码在 prompt 里 | 知识注册表 + 目录动态扩展 |
| 命中率低、经常挂载错 | 元数据 description 没写使用场景 | 描述改成「什么时候用它」 |
| 命中不到就硬套一个不相干的 | 路由强行命中 | search/inspect/select,证据不足就停 |
| 跨会话记不住经验 | 没有记忆层 | 经验存外部,按需读取 |
11. 判断收尾
什么时候该上动态挂载 :你的 Agent 拥有较多能力或知识 (十几个 Skill、上百篇文档)、或需要持续扩展 知识库、或已经遇到上下文吃紧/选错知识的问题------这时三层渐进加载 + 路由是刚需,否则迟早被知识量拖垮。什么时候可以不用 :你的 Agent 只有两三个固定能力、知识量很小------这时全塞进 prompt 反而更简单直接,动态挂载是过度设计。判断标准只有一条:知识量是否已经让「全塞」变得不划算------不划算,就上动态挂载;还很轻,就先别加复杂度。
本专栏《AI-Agent 工具》从 Agent 记忆、上下文、工具调用一路讲到知识挂载、架构与评测,每篇配可直接运行的代码,持续更新。想在做 Agent 产品时少踩坑,可在专栏页订阅。
参考资料(综合):
- Agent Skill Composition: Dynamic Capability Loading in Production -- Zylos Research ⭐值得阅读
- Agentic Skill Routing 实战:别再把所有 Skill 塞进 AI Agent 上下文 -- InfoQ ⭐值得阅读
- 你不知道的 Agent:原理、架构与工程实践 -- 腾讯新闻
- An Agent-Oriented Pluggable Experience-RAG Skill for Experience-Driven Retrieval Strategy Orchestration -- arXiv