技能将领域专业知识(如工作流程、最佳实践、脚本、参考文档和模板)打包到可重用的目录中。代理在启动时获取内容摘要,并仅在相关时发现和读取所包含的文件。 技能通过仅在启动时加载摘要和在任务需要时才读取完整说明来帮助你避免上下文臃肿。你可以在不同的代理和项目之间共享技能,并在单个代理中组合多个技能,使每个技能覆盖一项独立的能力。
要获取可立即使用、能提升你的代理在 LangChain 生态系统任务上性能的技能,请参阅 LangChain Skills 仓库。

用法

1

创建一个顶级技能目录

为你的项目创建一个目录来存放所有技能,例如在后端根目录下创建 skills/ 目录。
2

在你的技能目录内创建一个子目录用于你的技能

每个技能都是一个包含 SKILL.md 文件的目录:这是一个带有 YAML frontmatter(name 和 description)的 markdown 文件,后面是技能激活时代理遵循的说明。技能目录还可以选择性地包含支持文件,例如脚本、参考文档和模板。
skills
langgraph-docs
SKILL.md
深度代理技能遵循 Agent Skills 规范。
3

添加一个带有 YAML frontmatter 和说明的 `SKILL.md` 文件

SKILL.md 以 YAML frontmatter 开头,后面是 markdown 说明:
在你的 SKILL.md 中引用任何支持资源时,请说明每个文件包含什么内容以及何时使用它。代理通过技能说明中的引用来发现这些文件。
4

创建代理时传入技能路径

在创建代理时,在 skills 参数中传入你的顶级技能目录的路径:
此示例使用 FilesystemBackend 从磁盘加载技能。有关其他存储选项,包括从远程源加载技能,请参见后端和远程技能加载。
list[str]
技能源路径列表。路径必须使用正斜杠指定,并且相对于后端的根目录。
  • 如果省略,则不加载任何技能。
  • 使用 StateBackend(默认)时,请使用 invoke(files={...}) 提供技能文件。使用 deepagents.backends.utils 中的 create_file_data() 来格式化文件内容;不支持原始字符串。
  • 使用 FilesystemBackend 时,技能从相对于后端 root_dir 的磁盘加载。
对于具有相同名称的技能,后面的源会覆盖前面的源(后者胜出)。
当多个技能源包含同名技能时,skills 数组中后面列出的源中的技能优先(后者胜出)。这允许你从不同来源分层技能,例如,项目特定版本覆盖基础技能。
5

调用代理

使用 invoke() 向代理发送任务。在启动时,代理将每个技能的 name 和 description 从 frontmatter 加载到系统提示中。当你的任务匹配某个技能的描述时,代理会读取该技能的 SKILL.md 并遵循其说明。

技能如何工作

随着代理承担更复杂的任务,它们所需的上下文也随之增长。将所有指令加载到系统提示中会将令牌浪费在与当前任务无关的信息上,并且在不同会话之间手动提供相同的指导无法扩展。
技能使用渐进式披露:代理分层加载技能信息,而不是一次性全部加载。在启动时,它只看到每个技能的名称和描述。当技能被调用时,它会读取完整的 SKILL.md 说明。支持文件稍后加载,仅当说明中需要它们时。
技能在三个级别加载。每个级别仅在任务需要时添加更多细节: 下图显示了在给定时刻出现在代理上下文中的内容。在启动时,每个技能的级别 1 元数据都在系统提示中。当技能被调用时,级别 2 的说明会加入上下文。级别 3 的文件保存在后端,直到代理在调用后读取它们。
技能组件如何在启动和激活时映射到代理上下文
当代理处理任务时,它会分层加载技能信息:
技能如何从元数据到说明再到资源分层加载
在 Deep Agents 中,SkillsMiddleware(当你传入 skills 时成为默认中间件栈的一部分)处理前两个级别,第三个级别由 LLM 处理:
  1. 发现(级别 1):代理启动时,中间件扫描配置的技能源路径,解析每个 SKILL.md 的 frontmatter,并将 name 和 description 字段注入系统提示。
  2. 读取(级别 2):当代理调用一个技能时,它通过 read_file 读取完整的 SKILL.md 内容。
  3. 执行(级别 3):调用后,代理遵循技能的说明,并且仅在说明要求时才读取支持文件(脚本、参考、资产)。

何时使用技能

如果你发现自己反复给代理类似的指令,特别是当这些指令很详细且包含多个步骤时,可以考虑将指令整理给代理。这样,将来当你想完成类似的任务时,代理就已经知道该怎么做了。
你也可以要求你的代理为你与代理一起完成的任务编写一个技能。
技能对于整理以下内容特别有帮助:
  • 分步工作流程:跨越多个步骤的工作流程,类似于食谱。
  • 领域特定知识:指导代理如何将工具用于工作流程。例如,包含关于从哪里获取信息的信息,包括技能可能可以访问的其他参考信息或脚本。
  • 带有可执行代码的说明:将流程与代理可以运行的脚本或模块捆绑在一起,使其遵循经过测试的逻辑,而不是每次都从说明中重新生成逻辑。参见使用技能执行代码。
  • 准则:为代理提供关于应遵守的防护栏的补充说明。例如,遵循特定的格式或风格指南,或者指定始终将运行测试作为工作流程的一部分。

编写有效的技能

Agent Skills 规范包含关于构建技能以实现可靠发现和激活的指南。以下建议在此基础上,为 Deep Agents 提供了实用的模式。 保持 frontmatter 简洁,并将 SKILL.md 正文控制在 5,000 个令牌以内。每个技能的 frontmatter 都会在发现时添加到系统提示中,而完整的正文只有在激活时才会被读取。保持两个层都很小意味着你可以在不占用上下文窗口的情况下加载许多技能。 编写具体的描述。 在发现期间,description 字段是代理看到的关于每个技能的唯一信息。一个好的描述既要告诉代理技能做什么,也要告诉它何时激活,并且包含代理可以匹配的具体关键词:
当你拥有相关领域的多个技能时,请清晰地区分它们的描述。重叠的描述会导致代理激活错误的技能或在选项之间犹豫不决。如果两个技能服务于类似的目的,请将它们合并为一个。 保持说明集中。 Agent Skills 规范建议将你的 SKILL.md 控制在 500 行以内。当说明变长时,将详细的参考材料移入支持资源文件,并从主 SKILL.md 中引用它们:
skills
data-pipeline
SKILL.md
references
schema-reference.md
error-codes.md
代理仅在说明中需要时才加载参考文件,保持渐进式披露的每一层大小合适。保持文件引用距离 SKILL.md 一层深,避免深度嵌套的引用链,这会迫使代理进行多次读取才能获取所需信息。 为代理构建说明结构。 将你的 SKILL.md 正文编写为代理可以遵循的清晰说明:
  • 分步流程用于多步骤工作流程
  • 选择标准用于在方法之间做出选择
  • 预期输入和输出的示例,让代理知道成功是什么样子
  • 边缘情况,代理应该处理或标记给用户
管理技能数量。 范围明确的少量技能比大量重叠的技能表现更好。随着具有相似描述的技能数量增长,代理选择正确技能的能力会下降。如果你发现自己有许多相关的技能,请考虑:
  • 将相关能力整合到一个技能中,并为每个子任务设置章节
  • 使用参考文件来保持主 SKILL.md 简洁,同时涵盖多个子任务
使用 skills-ref 验证工具来检查你的 SKILL.md frontmatter 是否遵循 Agent Skills 规范的命名和格式约定。

添加支持资源

除了 SKILL.md 之外,技能目录还可以包含任何额外的文件或目录。Agent Skills 规范为常见的资源类型定义了三个可选目录。Deep Agents 不会在发现或激活时加载这些文件。代理仅在你的 SKILL.md 说明要求时才会读取或执行它们。

scripts/

scripts/ 目录存放代理可以运行的可执行代码,例如 API 客户端、数据转换或验证检查。脚本应该:
  • 是自包含的或清楚地记录依赖关系
  • 包含有帮助的错误信息
  • 优雅地处理边缘情况
支持的语言取决于你的代理设置。常见选项包括 Python、Bash 和 JavaScript 或 TypeScript。要执行脚本而不仅仅是读取它们,请参见使用技能执行代码。当代理需要 shell 时,请使用沙盒脚本。

references/

references/ 目录存放代理按需读取的补充文档。用于那些对于 SKILL.md 来说太详细但仍然特定于任务的材料,例如:
  • REFERENCE.md 用于详细的技术参考
  • FORMS.md 用于表单模板或结构化数据格式
  • 领域特定的指南(finance.md、legal.md 等)
保持单个参考文件的重点突出。代理仅在需要时加载它们,因此较小的文件使用的上下文更少。

assets/

assets/ 目录存放代理使用但不需要作为指令读取的静态资源,例如:
  • 文档或配置模板
  • 图像(图表、示例)
  • 数据文件(查找表、模式)
在 SKILL.md 中描述代理何时应该打开或复制每个资产。

从 SKILL.md 引用文件

当你引用支持文件时,请使用相对于技能根目录的路径:
对于你引用的每个文件,请说明它包含什么内容以及代理何时应该使用它。保持引用距离 SKILL.md 一层深。避免深度嵌套的引用链,这会迫使代理进行多次读取才能获取所需信息。

后端和远程技能加载

Deep Agents 支持不同的后端,具体取决于你希望如何存储和管理技能文件:
  • StateBackend:将文件存储在 LangGraph 代理状态中,用于当前线程。
  • StoreBackend:将文件存储在 LangGraph 存储中,用于持久的、跨线程的存储。
  • FilesystemBackend:从可配置的 root_dir 下的磁盘读取和写入技能文件。

在运行时加载技能

当你拥有大量技能集合但只有子集与特定运行相关时,可以根据运行时上下文(如用户角色、租户或请求类型)选择要加载的技能。有两种主要方法:

动态技能列表

最简单的方法是在创建代理之前构建 skills 数组。根据你拥有的任何运行时上下文选择要包含的技能源路径:
当技能位于磁盘或共享后端,并且你只需要控制代理看到哪些技能时,这种方法效果很好。技能本身不会被复制——你维护一份副本并改变传递给每次运行的路径。
SDK 只加载你在 skills 中传递的源。它不会自动扫描 CLI 目录,如 ~/.deepagents/... 或 ~/.agents/...。有关 CLI 存储约定,请参见应用数据。
如果你想在 SDK 代码中实现 CLI 风格的分层,请显式传递所有所需的源,按从低到高的优先级顺序:
然后在创建代理时将这个有序列表作为 skills 传递。

命名空间技能

对于多租户应用程序,其中每个用户的技能集是独立管理的,请使用命名空间工厂将 /skills/ 路由到 StoreBackend。用用户应该有权访问的技能填充每个命名空间,中间件在运行时解析到正确的集合:
当不同的用户或租户需要完全独立的技能库(可以单独更新)时,这种模式很有用。要获取处理技能访问、共享和工作区级别可见性的托管解决方案,请参见舰队技能。

子代理的技能

当你使用子代理时,你可以配置每种类型可以访问哪些技能:
  • 通用子代理:当你将 skills 传递给 create_deep_agent 时,会自动从主代理继承技能。不需要额外配置。
  • 自定义子代理:不继承主代理的技能。向每个子代理定义添加一个 skills 参数,其中包含该子代理的技能源路径。
技能状态是完全隔离的:主代理的技能对子代理不可见,子代理的技能对主代理也不可见。
有关子代理配置和技能继承的更多信息,请参见子代理。

技能权限

生产部署通常需要控制三件事:每个用户可以看到哪些技能,代理是否可以修改技能文件,以及写入是否需要人工批准。你可以通过 skills 参数和后端路由控制可见性,通过文件系统权限控制访问,通过 interrupt_on 或权限规则 mode="interrupt" 控制批准。

跨用户共享技能

为了让每个用户访问相同的策展库,请将 /skills/ 路由到共享的 StoreBackend,并从你的应用程序代码或管理工作流中进行初始化。使用组织范围的命名空间,使该组织中的所有代理都解析到相同的存储:
  • 按组织 ID 命名空间,用于工作区范围的技能(参见强制只读技能)。
  • 当每个用户需要独立的库时,按用户 ID 命名空间(命名空间技能)。
使用类似 /company-policies/SKILL.md 的键和包含 content 和 encoding 字段的值来初始化存储。在从存储读取记录之前,会去掉 /skills/ 路由前缀。 要获取处理技能访问、共享和工作区级别可见性的托管解决方案,请参见舰队技能。 你还可以组合共享库和个人库:将 /skills/shared/ 路由到组织范围的 StoreBackend,将 /skills/personal/ 路由到用户范围的后端,并在 skills 中传入这两个路径。参见允许代理编辑个人技能。

按用户上下文限制技能

并非每个用户都应该看到每个技能。根据角色、租户或其他请求上下文控制在运行时加载哪些技能。有两种主要方法:
  • 动态技能列表 — 在创建代理之前构建 skills 数组。为不同的角色或请求类型传递不同的路径列表。当技能位于共享后端且你按路径筛选时有效。
  • 命名空间技能 — 使用基于用户或租户 ID 的命名空间工厂将 /skills/ 路由到 StoreBackend。用该身份应该访问的技能填充每个命名空间。
这些模式与下面的读写控制协同工作。例如,你可以给管理员比工程师更大的技能集,同时保持两个库都是只读的。

强制只读技能

要在不让代理修改的情况下共享技能,请将 /skills/ 路由到共享存储,并使用文件系统权限拒绝 /skills/** 下的写操作。代理可以发现和读取技能;只有你的应用程序代码或管理工作流会更新存储。
将此用于企业知识库、批准的工具说明或共享技能包,代理应从集中管理的上下文中受益,但不应重写事实来源。

要求对技能写入进行批准

如果代理可能写入技能文件,但你希望首先有人工介入,请使用 interrupt_on 或权限规则 mode="interrupt"。两者都会在 write_file 或 edit_file 运行之前暂停,并使用相同的恢复流程。
或者,配置 interrupt_on={"write_file": True, "edit_file": True} 以要求对所有文件系统写入(不仅仅是技能路径)进行批准。有关处理和恢复中断,请参见人在环中。
文件系统权限中断需要 deepagents>=0.6.8。

允许代理编辑个人技能

默认情况下,如果后端允许且没有权限规则阻止该路径,代理可以写入技能文件。要让代理创建或完善技能而不影响共享库:
  1. 将一个可写路径(如 /skills/personal/)路由到用户范围的 StoreBackend。
  2. 在 skills 中传入该路径(以及任何共享路径)。
  3. 不要为可写路径添加 deny 规则。如果你混合了共享和个人路径,请将更具体的规则放在更广泛的拒绝规则之前(规则排序)。
代理使用 write_file 和 edit_file 在可写路径下创建或更新 SKILL.md 和支持文件。要在技能格式之外捕获一般性学习,请将单独的路径(如 /memories/)路由到另一个可写后端。有关路由和存储设置,请参见后端。

使用技能执行代码

没有代码执行,技能是被动的:代理读取说明并使用其可用的工具遵循它们。代码执行将技能转变为主动能力。技能可以附带一个经过测试的脚本来调用 API、转换数据、验证输出或运行管道——代理确定性地执行它,而不是每次都从说明中重新生成逻辑。这对于需要精确行为(数据转换、API 集成、合规性检查)或依赖于代理无法仅通过工具调用使用的库的工作流程尤其有价值。 技能通过沙盒脚本执行代码:当代理需要安装依赖项、运行测试、调用 CLI 或使用操作系统文件系统时,它会运行一个捆绑的脚本。

沙盒脚本

技能可以在 SKILL.md 文件旁边包含脚本。在你的 SKILL.md 中引用脚本,这样代理就知道它们存在以及何时运行它们:
skills
arxiv-search
SKILL.md
scripts
search.py
代理可以从任何后端_读取_脚本,但要_执行_它们,代理需要访问 shell,这只有沙盒后端提供。 沙盒后端在隔离的容器中运行。存储在沙盒之外的技能文件在沙盒内不可用,这意味着代理无法执行技能脚本或访问技能资源,除非先将它们传输进来。使用自定义中间件来处理此传输:
  • before_agent:从后端读取技能文件并上传到沙盒,以便代理可以从一开始就执行脚本。
  • after_agent:从沙盒下载任何更新或新创建的技能文件,并将它们写回后端,以便更改在多次运行中持续存在。
有关在执行前初始化技能和记忆,以及之后将两者同步回去的完整示例,请参见使用自定义中间件同步技能和记忆。

故障排除

使用 LangSmith 跟踪来调试技能发现、对 SKILL.md 的 read_file 调用以及支持资源的访问。请按照跟踪快速入门进行设置。我们建议你也设置 LangSmith Engine,它可以监控你的跟踪、检测问题并提出修复建议。

技能未激活

问题:代理处理任务时没有读取技能的 SKILL.md。 解决方案:
  1. 让描述更具体。 代理在发现时仅根据 description 字段选择技能。包括技能做什么、何时使用以及代理可以匹配的关键词:
  2. 减少技能之间的重叠。 如果多个技能有相似的描述,代理可能会跳过正确的技能或选择错误的技能。区分描述或合并相关技能。
  3. 确认技能在 skills 数组中。 技能仅从你在创建代理时传入的路径或子代理特定的 skills 参数加载。

启动时技能缺失

问题:代理在其系统提示中未列出某个技能,或者对 SKILL.md 的 read_file 失败。 解决方案:
  1. 检查技能源路径。 路径必须使用正斜杠,并且相对于后端根目录。使用 FilesystemBackend 时,路径相对于 root_dir。使用 StateBackend 时,在 invoke(files={...}) 中使用 create_file_data() 传递技能文件。
  2. 验证 SKILL.md frontmatter。 name 必须与父目录名称匹配,并遵循 Agent Skills 规范。使用 skills-ref 验证工具检查格式。
  3. 检查文件大小。 Deep Agents 在发现期间会跳过超过 10 MB 的 SKILL.md 文件。
  4. 检查分层源。 当同一技能名称出现在多个源中时,后者胜出。来自后面路径的旧技能或空技能可能会覆盖你期望的技能。

找不到支持文件

问题:代理读取了 SKILL.md 但无法访问脚本、参考或资产。 解决方案:
  1. 从 SKILL.md 引用文件。 代理不会自动发现支持文件。说明每个文件包含什么内容以及何时使用它。使用相对于技能根目录的相对路径。
  2. 将路径保持在技能目录内。 文件路径相对于后端解析。确认支持文件存在于你的说明引用的路径中。
  3. 将技能同步到沙盒中。 如果你使用沙盒后端,容器外的技能文件在复制进去之前不可用。参见沙盒脚本和使用自定义中间件同步技能和记忆。

脚本无法运行

问题:代理读取了脚本但无法运行它。 解决方案:代理可以从任何后端读取脚本,但运行它们需要一个沙盒后端。参见使用技能执行代码。

子代理无法访问技能

问题:自定义子代理看不到主代理使用的技能。 解决方案:自定义子代理不继承主代理的技能。向每个子代理定义添加一个 skills 参数,其中包含该子代理的技能源路径。通用子代理自动从 create_deep_agent 继承技能。

参考

技能、记忆和工具

技能、记忆(AGENTS.md 文件)和工具都为代理提供上下文或能力。下表总结了何时使用每种: 这些是指南,而不是硬性界限。在实践中,技能和记忆处于一个连续体上。代理可以在工作过程中更新自己的技能,随着时间的推移捕获新的流程并完善说明。这样,技能可以作为一种渐进式披露记忆的形式:代理按需构建和检索上下文,而不是在每次提示时都加载。

Frontmatter 字段

Agent Skills 规范定义了以下 frontmatter 字段:
请参考完整的 Agent Skills 规范 以了解详细的约束和验证规则。在 Deep Agents 中,SKILL.md 文件必须小于 10 MB。超过此限制的文件在技能加载期间会被跳过。
更多示例技能,请参见 Deep Agents 示例技能。