摘要 :本文介绍 Agent Skills 中的 Progressive Disclosure(渐进式披露) 设计模式------将技能知识按需分层加载(L1 元数据 → L2 指令 → L3 资源),显著减少每次 LLM 调用的 token 消耗。本文严格遵循 agentskills.io / ADK SkillToolset 规范:L3 由 Agent 在 execute 阶段通过 load_skill_resource 工具按需调用 ,而非图节点提前批量加载。案例介绍 :配套 demo 实现一个基于 LangGraph 的多技能内容工作流智能体 ,具备 SEO 检查、博客写作、代码审查、研究摘要四类技能;智能体先通过 L1 元数据发现可用技能,再根据用户任务按需加载 L2 指令;在 execute 阶段将 load_skill_resource 暴露为 Agent 工具,由 LLM 根据 L2 指令按需加载 L3 参考文档。技术要点 :用 LangGraph 编排 discover → select → load_l2 → execute 流程;L1 仅解析 frontmatter;L2 按需读取 SKILL.md 正文;L3 在 execute 的 Agent 工具循环中按需调用加载;支持 tiktoken 统计各层 token 并与全量加载对比。
关键词:Progressive Disclosure;Agent Skills;L1/L2/L3;Token 优化;LangGraph;SKILL.md;按需加载
源代码链接:LangGraph 17. Progressive Disclosure 示例源代码
1. 为什么智能体需要「Progressive Disclosure」?
1.1 传统方式的痛点
想象一下,你经营一家拥有十位专家的咨询公司。客户每次来电,你都把所有专家的详细履历、工作手册、参考资料一口气塞进对话------即便客户只是问一个简单问题。这不仅浪费纸张和时间,还会让对话变得臃肿、难以聚焦。
智能体使用 Skills 时,若采用传统全量加载方式,也会遇到类似问题:
- 能力写死在 system prompt 中:研究、写作、SEO、代码审查等技能的全部指令一次性拼接到 system prompt;
- 每次调用都付费:无论用户问题是「请优化这段博客的 SEO」还是「帮我写一篇技术博客」,所有技能的完整说明都会进入 LLM 上下文,消耗大量 token;
- 扩展成本线性增长:每增加一个技能,system prompt 就增加几百到几千 token;10 个技能、每个平均 1000 token,则每次调用 baseline 就接近 10,000 token。
💡 理解要点 :把能力塞进 system prompt 的方式,在技能数量较少时尚可接受;一旦技能库扩展,每次请求都承担全部技能的 token 成本,既不经济,也容易触及 context 上限。
1.2 Progressive Disclosure 的核心思路
Progressive Disclosure(渐进式披露) 是 Agent Skills 规范 中定义的设计模式:将技能知识分为三个层次,按需加载,而不是一次性全部塞入上下文。
| 层级 | 内容 | 何时加载 | 典型规模 |
|---|---|---|---|
| L1 元数据 | name、description(frontmatter) | 每次调用 | ~100 tokens/技能 |
| L2 指令 | 完整 SKILL.md 正文 | 选定技能后 | <5000 tokens/技能 |
| L3 资源 | references/、assets/ 中的文件 | 技能明确引用时 | 按需 |
类比 :就像餐厅的菜单------顾客先看菜名和简短描述 (L1)决定要点什么,再向服务员询问做法和配料 (L2),若对某道菜的酱汁配方感兴趣,再要详细配方卡(L3)。不必一进门就拿到所有菜品的完整菜谱。
🔍 实际例子 :用户问「Review my blog post for SEO」。全量加载时,博客写作、SEO、研究、代码审查四个技能的完整指令(约 8000 token)全部在上下文中。采用 Progressive Disclosure 时:先加载 L1(4 个技能的 name + description,约 400 token)→ Agent 识别需要 SEO 技能 → 仅加载 seo-checklist 的 L2(约 300 token)→ 若技能内引用 references/seo-guidelines.md,再加载 L3。总消耗从 8000 降至约 700 token,节省约 90%。
1.3 小结:要解决什么?
Progressive Disclosure 要解决的核心问题:
- 降低 baseline token 消耗:每次调用只加载 L1「菜单」,让 Agent 知道有哪些技能可用;
- 按需加载 L2/L3:仅对与当前任务相关的技能加载完整指令和参考文档;
- 可扩展性:技能库增长时,baseline 仅随 L1 元数据线性增长,而非随全部技能内容爆炸式增长。
💡 理解要点 :Progressive Disclosure 不是「少用技能」,而是聪明地决定何时加载哪些知识。Agent 通过 L1 发现、选择,再通过 L2/L3 获得执行所需的具体指导。
2. 示例设定:一个「按需加载」的多技能内容工作流智能体
2.1 案例背景
我们构建一个多技能内容工作流智能体,具备四类能力:
- seo-checklist :SEO 优化检查清单,含 L3 参考文档
references/seo-guidelines.md; - blog-writer :博客写作技能,含 L3 风格指南
references/style-guide.md; - code-review:代码审查技能;
- research-summarizer:研究摘要技能。
用户可能提出单一任务(如「检查这段文字的 SEO」)或复合任务(如「写一篇博客并做 SEO 优化」)。我们希望智能体:
- 启动时仅加载 L1 元数据,了解可用技能;
- 根据用户任务,用 LLM 做语义匹配选出相关技能;
- 仅对选中的技能加载 L2 指令;
- 若技能指令中引用
references/中的文件,按需加载 L3; - 将加载的知识与用户输入一起交给 LLM 执行。
2.2 方案设计
配套 demo 实现基于 LangGraph 的 Progressive Disclosure 流程 ,严格遵循 agentskills.io / ADK SkillToolset 规范:
START
↓
discover (L1) → 扫描 skills_library,解析每个 SKILL.md 的 frontmatter
↓
select → 根据 user_task 从 L1 列表选出 1~N 个技能(LLM 语义匹配)
↓
load_l2 → 仅对选中技能读取完整 SKILL.md 正文
↓
execute → 将 L2 作为 system 上下文,将 load_skill_resource 暴露为 Agent 工具;
Agent 根据 L2 指令按需调用工具加载 references/ 中的文件(L3)
↓
END
同时,demo 内置 token 计量模块 :用 tiktoken 统计 L1、L2、L3 各层以及「全量加载」模式下的 token 数,并在 main.ipynb 中输出对比表,直观展示 Progressive Disclosure 的 token 节省效果。
2.3 典型流程示例
用户输入:「请检查下面这段博客的 SEO,并给出改进建议。」
- L1 :Agent 看到
seo-checklist: SEO优化检查清单...、blog-writer: 博客写作...等,识别需要seo-checklist; - L2 :加载
seo-checklist的完整 SKILL.md,得到 9 条检查项,其中指令写明「请先使用 load_skill_resource 工具读取references/seo-guidelines.md」; - Execute :LLM 收到 L2 指令后,主动调用
load_skill_resource工具获取 L3 文件内容,再按检查项逐项评估并输出建议。
💡 理解要点 :L3 由 Agent 按需调用 load_skill_resource 工具加载,而非图节点提前批量加载;blog-writer、code-review、research-summarizer 的 L2/L3 在此过程中从未被加载,从而避免了不必要的 token 消耗。
3. 状态与图结构:用 LangGraph 表达 Progressive Disclosure
3.1 状态定义
在 progressive_disclosure_graph.py 中,我们用 SkillsWorkflowState 描述图中流转的状态:
python
class SkillsWorkflowState(TypedDict):
user_task: str # 用户任务描述
l1_skills: list[dict] # discover 得到的 L1 元数据列表
selected_skill_names: list[str] # select 选中的技能名
l2_content: dict[str, str] # skill_name -> 完整 SKILL.md 正文
l3_content: dict[str, str] # execute 阶段由 load_skill_resource 工具调用结果填充
token_usage: dict # 各层 token 统计
final_response: str # execute 后的输出
3.2 图结构
text
START
↓
discover_node # 扫描 skills_library,解析 frontmatter → l1_skills
↓
select_node # 根据 user_task 从 l1_skills 选出技能 → selected_skill_names
↓
load_l2_node # 对 selected_skill_names 读取 SKILL.md 正文 → l2_content
↓
execute_node # 将 L2 作为 system,load_skill_resource 作为工具;
# Agent 按需调用工具加载 L3 → l3_content、final_response
↓
END
流程为线性;execute_node 内部为 Agent 工具循环(LLM → 若有 tool_calls 则执行工具 → 再次调用 LLM → 直至生成最终回复)。L3 的 l3_content 与 token 计量在 execute 阶段由工具调用结果动态填充。
3.3 核心节点逻辑与代码详解
下文逐一说明每个节点的职责、调用链路及关键代码实现。底层能力由 skill_loader.py 提供,图中节点负责编排与状态更新。
3.3.1 discover_node:将所有 skills L1 数据提取出来
职责 :扫描 skills_library/,仅解析每个 SKILL.md 的 YAML frontmatter (name、description),得到 L1 技能列表;同时用 count_tokens 统计 L1 文本的 token 数,写入 token_usage["l1"]。
调用链路 :discover_node → skill_loader.discover_skills() → 内部 _parse_frontmatter()。
skill_loader 的源代码如下:
py
def discover_node(state: SkillsWorkflowState) -> SkillsWorkflowState:
"""L1:扫描技能库,解析 frontmatter。"""
skills = discover_skills(DEFAULT_SKILLS_LIBRARY)
usage = state.get("token_usage") or {}
l1_text = "\n".join(
f"{s.get('name', '')}: {s.get('description', '')}"
for s in skills
)
usage["l1"] = count_tokens(l1_text)
return {
**state,
"l1_skills": skills,
"token_usage": usage,
}
skill_loader 中的 discover_skills(skill_loader.py):
python
def discover_skills(skills_root: Optional[Path] = None) -> List[Dict[str, str]]:
root = Path(skills_root) if skills_root else DEFAULT_SKILLS_LIBRARY
result = []
for path in sorted(root.iterdir()):
if not path.is_dir():
continue
skill_md = path / "SKILL.md"
if not skill_md.is_file():
continue
raw = skill_md.read_text(encoding="utf-8", errors="replace")
meta = _parse_frontmatter(raw) # 仅解析 --- ... --- 之间的 YAML
if meta.get("name"):
result.append(meta)
return result
_parse_frontmatter 用正则 ^---\s*\n(.*?)\n---\s*\n 匹配 frontmatter 块,解析其中 name、description 等字段。不读取正文,符合 L1 仅加载元数据的定义。
3.3.2 select_node:技能选择(LLM 语义匹配)
职责 :根据 user_task 从 l1_skills 中选出 1~2 个相关技能名。使用 LLM 做语义匹配:将 L1 列表与用户任务交给 LLM,由其根据 name 与 description 返回最相关的技能名。未配置 API 或任务为空时返回空列表。
流程 :将 L1 列表格式化为 - {name}: {description},与 user_task 填入 SELECT_SKILL_PROMPT,要求 LLM 仅返回技能名、多个用逗号分隔。解析响应后校验名称是否在 l1_skills 中,过滤无效项。
select_node 实现 (progressive_disclosure_graph.py):
python
def select_node(state: SkillsWorkflowState) -> SkillsWorkflowState:
skills = state.get("l1_skills") or []
user_task = state.get("user_task") or ""
if not skills:
return {**state, "selected_skill_names": []}
# 未配置 API 或任务为空时,无法进行 LLM 选择
if not _config.api_key or not user_task.strip():
return {**state, "selected_skill_names": []}
prompt = ChatPromptTemplate.from_template(SELECT_SKILL_PROMPT)
chain = prompt | _llm
response = chain.invoke({
"skills_list": _format_skills_list(skills),
"user_task": user_task,
})
content = (response.content or "").strip()
selected = []
for part in content.replace(",", ",").split(","):
name = part.strip().lower().replace(" ", "-")
if any(s.get("name") == name for s in skills):
selected.append(name)
return {**state, "selected_skill_names": selected}
相关 prompt:
py
SELECT_SKILL_PROMPT = """你是一个多技能内容工作流助手。你有以下技能可用(仅名称和简短描述):
{skills_list}
用户任务:
{user_task}
请从上述技能中选择与此任务最相关的 1~2 个技能。仅返回技能名称,多个用英文逗号分隔,不要解释。
例如:seo-checklist
或:blog-writer, seo-checklist
"""
3.3.3 load_l2_node:读取上阶段筛选后skills的l2信息
职责 :对 selected_skill_names 中每个技能,调用 skill_loader.load_skill() 读取完整 SKILL.md 正文 (去掉 frontmatter 后的部分),存入 l2_content[skill_name];并用 count_tokens 累计 L2 token,更新 token_usage["l2"]。
load_l2_node 实现:
python
def load_l2_node(state: SkillsWorkflowState) -> SkillsWorkflowState:
"""L2:对选中技能加载完整 SKILL.md 正文。"""
selected = state.get("selected_skill_names") or []
l2_content: dict[str, str] = {}
usage = dict(state.get("token_usage") or {})
total_l2 = 0
for name in selected:
full, body = load_skill(name, DEFAULT_SKILLS_LIBRARY)
if body:
l2_content[name] = body
total_l2 += count_tokens(body)
usage["l2"] = total_l2
return {
**state,
"l2_content": l2_content,
"token_usage": usage,
}
skill_loader 中的 load_skill (skill_loader.py):
python
def load_skill(skill_name: str, skills_root: Optional[Path] = None) -> Tuple[str, str]:
"""
L2:加载技能。读取指定技能的完整 SKILL.md 内容。
Args:
skill_name: 技能名称(子目录名)。
skills_root: 技能库根目录。
Returns:
(full_content, body_only)。body_only 为去掉 frontmatter 的正文。
"""
root = Path(skills_root) if skills_root else DEFAULT_SKILLS_LIBRARY
skill_dir = root / skill_name
skill_md = skill_dir / SKILL_FILENAME
if not skill_md.is_file():
return "", ""
try:
full = skill_md.read_text(encoding="utf-8", errors="replace")
except OSError:
return "", ""
body = full
m = FRONTMATTER_PATTERN.match(full)
if m:
body = full[m.end() :].strip()
return full, body
3.3.4 L3 按需加载:load_skill_resource 工具
职责 :遵循 agentskills.io / ADK SkillToolset 推荐做法,L3 不 由图节点提前加载,而是由 Agent 在 execute 阶段通过 load_skill_resource 工具按需调用。
实现方式:
-
skill_tools.py :将
load_skill_resource封装为 LangChain Tool(@tool),参数为skill_name和resource_path,内部调用skill_loader.load_skill_resource()读取文件。py@tool def load_skill_resource_tool(skill_name: str, resource_path: str) -> str: """加载技能参考资源(L3)。当技能指令(L2)要求阅读 references/ 中的某文件时调用此工具。 Args: skill_name: 技能名称,如 blog-writer、seo-checklist。 resource_path: 相对于技能目录的路径,如 references/style-guide.md 或 references/seo-guidelines.md。 Returns: 文件内容;若文件不存在则返回空字符串。 """ return load_skill_resource(skill_name, resource_path, DEFAULT_SKILLS_LIBRARY) -
SKILL.md 正文 :在 L2 指令中显式写明 「请使用 load_skill_resource 工具读取
references/xxx.md」,引导 LLM 在需要时调用该工具。py--- name: blog-writer description: 博客写作技能,含结构模板与风格指南。适用于技术博客、产品介绍、教程类内容。当用户需要撰写博客、文章或教程时使用。 --- # 博客写作指南 当用户请求撰写博客时,请先使用 load_skill_resource 工具读取 `references/style-guide.md` 获取写作风格与禁忌,然后按以下结构组织内容: ## 步骤 1:确定主题与受众 - 明确目标读者 - 确定核心信息(读者读完应带走什么) - 选择合适的语气(正式/轻松/技术向) -
execute_node :将 L2 作为 system 上下文,将
load_skill_resource_tool绑定到 LLM(bind_tools),运行 Agent 工具循环------LLM 根据 L2 指令决定是否调用工具,工具返回的 L3 内容进入对话上下文,LLM 据此完成任务。
何时加载 L3? 由 LLM 自主决定。当 L2 指令明确要求「使用 load_skill_resource 读取 references/xxx」时,LLM 会发起工具调用;若技能无 references 引用或 LLM 判断不需要,则不会加载,实现真正的按需加载。
3.3.5 execute_node:Agent 工具循环与 final_response
职责 :将 L2 作为 system 上下文,将 load_skill_resource 暴露为 Agent 工具;运行 Agent 工具循环,直至 LLM 生成最终回复;从工具调用结果中统计 L3 token 并填充 l3_content。
流程 :SystemMessage(L2 + 用户任务 + 工具使用说明) + HumanMessage(用户任务) → llm.bind_tools([load_skill_resource_tool]).invoke(messages) → 若返回 tool_calls,依次执行工具,将 ToolMessage 追加到 messages,再次调用 LLM → 重复直至无 tool_calls,此时 response.content 即为 final_response。
prompt 模板 (prompt.py):
python
EXECUTE_SYSTEM_INSTRUCTION = """你正在使用以下 Agent Skills 的指令执行用户任务。请严格按照技能说明完成用户请求。
--- 技能指令(L2)---
{skill_instructions}
---
重要:当技能指令中提到需要参考 `references/xxx.md` 或类似路径时,你必须先调用 load_skill_resource 工具读取该文件内容,再据此执行任务。不要假设或猜测参考文件内容。
用户任务:
{user_input}
"""
execute_node 实现
python
def execute_node(state: SkillsWorkflowState) -> SkillsWorkflowState:
"""
执行节点:将 L2 作为 system 上下文,将 load_skill_resource 暴露为 Agent 工具。
遵循 agentskills.io / ADK SkillToolset:Agent 根据 L2 指令按需调用 load_skill_resource,
加载 references/ 中的文件(L3)。L3 不提前加载,由 LLM 在对话中主动调用工具获取。
"""
l2 = state.get("l2_content") or {}
user_task = state.get("user_task") or ""
usage = dict(state.get("token_usage") or {})
parts = [f"## 技能: {name}\n\n{body}" for name, body in l2.items()]
skill_instructions = "\n\n---\n\n".join(parts) if parts else "(无技能指令)"
if not _config.api_key:
return {
**state,
"l3_content": {},
"token_usage": {**usage, "l3": 0, "total": usage.get("l1", 0) + usage.get("l2", 0)},
"final_response": "[请配置 OPENAI_API_KEY 或 DASHSCOPE_API_KEY]",
}
system_content = EXECUTE_SYSTEM_INSTRUCTION.format(
skill_instructions=skill_instructions,
user_input=user_task,
)
messages = [
SystemMessage(content=system_content),
HumanMessage(content=user_task),
]
llm_with_tools = _llm.bind_tools(_TOOLS)
l3_content: dict[str, str] = {}
total_l3 = 0
max_iterations = 10
iterations = 0
try:
while iterations < max_iterations:
iterations += 1
response = llm_with_tools.invoke(messages)
if not getattr(response, "tool_calls", None):
break
messages.append(response)
for tc in response.tool_calls:
tc_dict = tc if isinstance(tc, dict) else {"name": getattr(tc, "name", ""), "args": getattr(tc, "args", {}), "id": getattr(tc, "id", "")}
name = tc_dict.get("name", "")
args = tc_dict.get("args", {})
tool_call_id = tc_dict.get("id", "")
tool = _TOOLS_BY_NAME.get(name)
result = ""
if tool:
try:
result = tool.invoke(args)
if name == "load_skill_resource":
skill_name = args.get("skill_name", "")
resource_path = args.get("resource_path", "")
key = f"{skill_name}:{resource_path}"
l3_content[key] = result
total_l3 += count_tokens(result)
except Exception:
result = f"[工具 {name} 执行失败]"
messages.append(
ToolMessage(content=str(result), tool_call_id=tool_call_id)
)
final = (response.content if hasattr(response, "content") else str(response) or "").strip()
except Exception as e:
final = f"[LLM 调用失败: {type(e).__name__}] 请检查 API 配置。技能已按 Progressive Disclosure 加载完成。"
usage = dict(state.get("token_usage") or {})
usage["l3"] = total_l3
usage["total"] = usage.get("l1", 0) + usage.get("l2", 0) + total_l3
return {
**state,
"l3_content": l3_content,
"token_usage": usage,
"final_response": final,
}
💡 理解要点 :四个图节点(discover → select → load_l2 → execute);L3 在 execute_node 内部的工具循环中按需加载 ,由 LLM 根据 L2 指令主动调用 load_skill_resource,符合 agentskills.io 与 ADK SkillToolset 规范。
4. Token 计量与对比:tiktoken 驱动
4.1 计量模块
token_counter.py 提供 count_tokens(text, model),基于 tiktoken 对给定文本统计 token 数。支持 cl100k_base(GPT-4/3.5 等)编码。
4.2 对比模式
Demo 支持两种运行模式:
- Progressive 模式:按 L1 → select → L2 → L3 → execute 流程,仅加载选中技能的内容;
- Monolithic 模式:一次性加载所有技能的完整 SKILL.md + references,模拟「全量 system prompt」方式。
在 main.ipynb 中,对同一 user_task 分别跑两种模式,输出类似:
| 模式 | L1 | L2 | L3 | 总计 |
|---|---|---|---|---|
| Progressive | 420 | 380 | 0 | 800 |
| Monolithic | --- | --- | --- | 7200 |
从而直观看到:当用户只需 1 个技能时,Progressive 可节省约 90% 的 skill 相关 token。
5. 运行方式
5.1 环境与依赖
- Python 3.9+
- 依赖见
demo_codes/requirements.txt:langgraph、langchain-openai、tiktoken、python-dotenv等
5.2 配置
在 demo_codes/ 下创建 .env:
OPENAI_API_KEY=sk-... # 或 DASHSCOPE_API_KEY
BASE_URL= # 可选,如使用代理
MODEL=gpt-4o-mini # 可选
5.3 运行
命令行:
shell
cd demo_codes
python main.py
python main.py "请检查下面博客的 SEO:..."
Notebook :打开 main.ipynb,可逐步运行 discover → select → load_l2 → load_l3 → execute,以及 token 对比实验。
如下是 main.ipynb 中运行的测试代码的详细日志返回:
user_task = "请检查下面这段话的 SEO 并给出改进建议:LangGraph 是一个用于构建多步推理与智能体工作流的 Python 库,支持状态图与条件边。"
返回:
--- 运行日志 (verbose=1) ---
[discover] 开始扫描 skills_library...
[discover] 发现 4 个技能: ['blog-writer', 'code-review', 'research-summarizer', 'seo-checklist']
[discover] L1 token: 268
[select] 用户任务: 请检查下面这段话的 SEO 并给出改进建议:LangGraph 是一个用于构建多步推理与智能体工作流的 Python 库...
[select] 调用 LLM 进行技能语义匹配...
[select] 选中技能: ['seo-checklist']
[load_l2] 加载 L2: ['seo-checklist']
[load_l2] seo-checklist: 499 tokens
[load_l2] L2 总计: 499 tokens
[execute] 执行任务,技能: ['seo-checklist']
[execute] LLM 调用 (迭代 1)...
[execute] LLM 请求 1 次工具调用
[execute] [Tool] load_skill_resource_tool({'skill_name': 'seo-checklist', 'resource_path': 'references/seo-guidelines.md'})
[execute] -> L3 加载 seo-checklist:references/seo-guidelines.md, 280 tokens
[execute] LLM 调用 (迭代 2)...
[execute] LLM 返回最终回复(无工具调用)
[execute] L3 总计: 280 tokens, 最终回复: 3315 字符
=== Progressive 模式 Token 消耗 ===
L1: 268 | L2: 499 | L3: 280 | 总计: 1047
选中技能: ['seo-checklist']
=== Monolithic 模式 Token 消耗 ===
L2+L3 总计: 2174
Progressive 节省约 1127 tokens (52%)
5.4 技能库
Demo 自带 skills_library/,内含 seo-checklist、blog-writer、code-review、research-summarizer 四个技能。其中 seo-checklist 与 blog-writer 含 references/ 子目录,用于演示 L3 加载。若需扩展,可参考 skills_library/README.md 按 Agent Skills 规范添加新技能。
6. 小结与延伸
6.1 核心结论
- Progressive Disclosure 将技能知识分为 L1(元数据)、L2(指令)、L3(资源)三层,按需加载,显著降低 baseline token 消耗;
- LangGraph 可清晰编排 discover → select → load_l2 → (load_l3,这里通过Tools调用) → execute 流程,每步对应一个节点,状态在图中流转;
- Token 计量:用 tiktoken 统计各层消耗,并与全量加载对比,可量化 Progressive Disclosure 的收益。
6.2 延伸方向
- 技能选择 :可调整
SELECT_SKILL_PROMPT或引入 few-shot 示例,以提升复杂任务下的匹配准确度; - 多技能组合:支持同一任务加载多个技能(如 blog-writer + seo-checklist),L2 合并后一并交给 LLM,L3 由 Agent 按需调用;
- 与 LangGraph 7. 技能 Skills 集成 :本 demo 的
skill_loader与 LangGraph 7. 技能 Skills 的发现/加载逻辑兼容,可复用或替换为 LangGraph 7. 技能 Skills 的skill_loader.py; - 生产化:将 token 计量接入监控,设置阈值告警;对高频技能可做 L2 缓存,进一步减少重复读取。
参考资料:
- LangGraph 7. 技能 Skills --- 本系列前文,介绍 Skills 的动机、发现→选择→加载→使用流程及 Agent Skills 规范
- Agent Skills Specification (agentskills.io)
- ADK Agent Skills: Progressive Disclosure (Lavi Nigam, Part 1)
- ADK SkillToolset: File-Based & External Skills (Lavi Nigam, Part 2) --- load_skill_resource 工具按需调用的实现说明