本页目录
SkillsNote 03

02 Skill 激活与渐进披露

学习目标

学习目标

理解一句话:DeepAgent 启动时只看到 skill 摘要,只有模型判断任务匹配时,才会用 read_file 读取完整 SKILL.md

它是什么

渐进披露就是分层加载上下文。第一层是 namedescription,用于让模型知道有哪些 skills;第二层是完整 SKILL.md,只在需要时读取;第三层是 scripts/references/assets/,只有 SKILL.md 指令要求时才继续读。它解决的是上下文膨胀,妈的,不然几十个 skill 一启动就把窗口塞爆。

三层加载

Agent 启动
  -> 读取每个 SKILL.md 的 frontmatter
  -> 系统提示词里出现 name、description、SKILL.md 路径

用户任务匹配某个 skill
  -> 模型调用 read_file 读取对应 SKILL.md
  -> 按正文 instructions 执行

instructions 指向支持资源
  -> 再读取 references/、assets/ 或执行 scripts/

最小可运行例子

代码见 ../02_progressive_disclosure.py

这个例子读取固定目录里的 deepagent_src/skills_teach/workspace/skills/langgraph-docs/SKILL.md,文件正文里有一个特殊标记 FULL_INSTRUCTIONS_ONLY_AFTER_READ,然后验证两件事:

  • discovery 文本里只有 skill 名称、描述和读取路径,不包含正文标记。
  • 手动读取 /skills/langgraph-docs/SKILL.md 后,才看得到正文标记。

这就是 DeepAgent 使用 skills 的关键:先发现,再按需读取。

运行

在项目根目录执行:

uv run python deepagent_src/skills_teach/02_progressive_disclosure.py

预期输出:

progressive disclosure ok

代码中的关键点

skills, error = _list_skills_with_errors(backend, "/skills/")
middleware = SkillsMiddleware(backend=backend, sources=["/skills/"])
discovery_text = middleware._format_skills_list(skills)

discovery_text 对应 Agent 启动时能看到的技能摘要,它会提示:

Read `/skills/langgraph-docs/SKILL.md` for full instructions

但它不会包含完整 SKILL.md 正文。

常见误区

最常见的误区是以为只要传了 skills=["/skills/"],Agent 就已经读完整个技能目录了。错,启动阶段只读 frontmatter;完整说明和支持资源都要等任务匹配后再按需读取。

边界

这个脚本验证的是框架加载机制,不模拟模型“是否应该激活某个 skill”的判断。模型判断属于 LLM 行为,稳定教学里别拿它做断言,不然一次过一次挂,烦死人。

下一章

下一章学“使用支持资源目录”:references/ 什么时候读,scripts/ 什么时候跑,assets/ 什么时候只是被复制或引用。

相关资源

  • 查看示例代码:deepagent_src/skills_teach/02_progressive_disclosure.py
    from __future__ import annotations
    
    from pathlib import Path
    
    from deepagents.backends import FilesystemBackend
    from deepagents.middleware.skills import SkillsMiddleware, _list_skills_with_errors
    
    
    ROOT_DIR = Path(__file__).resolve().parent / "workspace"
    SKILL_SOURCE = "/skills/"
    FULL_INSTRUCTION_MARKER = "FULL_INSTRUCTIONS_ONLY_AFTER_READ"
    
    
    def main() -> None:
        backend = FilesystemBackend(root_dir=ROOT_DIR, virtual_mode=True)
        skills, error = _list_skills_with_errors(backend, SKILL_SOURCE)
        middleware = SkillsMiddleware(backend=backend, sources=[SKILL_SOURCE])
        discovery_text = middleware._format_skills_list(skills)
    
        assert error is None
        assert "langgraph-docs" in discovery_text
        assert "Read `/skills/langgraph-docs/SKILL.md` for full instructions" in discovery_text
        assert FULL_INSTRUCTION_MARKER not in discovery_text
    
        read_result = backend.read(skills[0]["path"], limit=1000)
    
        assert read_result.error is None
        assert read_result.file_data is not None
        assert FULL_INSTRUCTION_MARKER in read_result.file_data["content"]
        print("progressive disclosure ok")
    
    
    if __name__ == "__main__":
        main()