技能将领域专业知识(如工作流、最佳实践、脚本、参考文档和模板)打包成可重用的目录。代理在启动时获取内容摘要,仅在相关时发现并读取包含的文件。
技能通过仅在启动时加载摘要并在任务需要时读取完整指令来帮助您避免上下文膨胀。您可以在代理和项目之间共享技能,并在单个代理中组合多个技能,使每个技能覆盖不同的能力。
用法
Create a top-level skills directory
创建一个目录来存放项目的所有技能,例如 skills/ 在您的后端根目录下。
Create a subdirectory inside your skills directory for your skill
每个技能是一个包含 SKILL.md 文件的目录:一个带有 YAML 前置元数据 (name 和 description)的 Markdown 文件,后面跟着代理激活技能时遵循的指令。技能目录还可以选择性地包含支持文件,如脚本、参考文档和模板。
深度代理技能遵循 代理技能规范.
Add a `SKILL.md` file with YAML frontmatter and instructions.
以 YAML SKILL.md 开头,以 YAML 前置元数据 开头,后跟 markdown 指令:
---
name: langgraph-docs
description: Use this skill for requests related to LangGraph in order to fetch relevant documentation to provide accurate, up-to-date guidance.
---
# langgraph-docs
## Overview
This skill explains how to access LangGraph documentation to help answer questions and guide implementation.
## Instructions
### 1. Fetch the documentation index
Use the fetch_url tool to read the following URL:
https://docs.langchain.com/llms.txt
This provides a structured list of all available documentation with descriptions.
### 2. Select relevant documentation
Based on the question, identify 2-4 most relevant documentation URLs from the index. Prioritize:
- Specific how-to guides for implementation questions
- Core concept pages for understanding questions
- Tutorials for end-to-end examples
- Reference docs for API details
### 3. Fetch and synthesize
Use the fetch_url tool to read the selected documentation URLs, then answer the user's question. Give a direct answer first, include the minimum necessary context, and link to the source pages rather than quoting long passages.
`
Pass the skills path when creating your agent
在创建代理时通过 skills 参数传入顶级技能目录的路径:
const backend = new FilesystemBackend({ rootDir: process.cwd() });
const agent = await createDeepAgent({
model: "anthropic:claude-sonnet-4-6",
backend,
skills: ["/skills/"],
});
此示例使用 FilesystemBackend 从磁盘加载技能。对于其他存储选项(包括从远程源加载技能),请参阅 后端和远程技能加载.
技能源路径列表。
路径必须使用正斜杠指定,相对于后端的根目录。
- - 如果省略,则不加载任何技能。
- - 使用
StateBackend(默认)时,提供包含invoke(files={...})的技能文件。使用create_file_data()中的deepagents.backends.utils来格式化文件内容;不支持原始字符串。 - - 使用
FilesystemBackend时,技能从磁盘加载,相对于后端的root_dir.
同名技能中,后面的源会覆盖前面的源(后者胜出)。
Invoke the agent
使用 invoke()向代理发送任务。在启动时,代理加载每个技能的 name 和 description 从 前置元数据 到系统提示词中。当您的任务与某个技能的描述相匹配时,代理会读取该技能的 SKILL.md 并遵循其说明。
const result = await agent.invoke(
{ messages: [{ role: "user", content: "What is LangGraph?" }] },
{ configurable: { thread_id: "1" } },
);
技能工作原理
随着代理承担更复杂的任务,它们所需的上下文也在不断增长。将所有说明加载到系统提示词中会浪费令牌在当前任务无关的信息上,而跨会话手动提供相同的指导也无法扩展。
技能分为三个层级加载。每个层级仅在任务需要时添加更多细节:
| 层级 | 加载内容 | 何时 |
|---|---|---|
| **1. 元数据** | name 和 description 从 SKILL.md 前置元数据 | 代理启动时,对每个已配置的技能 |
| **2. 说明** | 完整 SKILL.md 正文 | 技能被调用时 |
| **3. 资源** | 支持文件 位于 scripts/, references/下的 assets/ | 调用后按需加载,当说明引用它们时 |
下图展示了代理上下文中某一时刻显示的内容。启动时,每个技能的一级元数据都在系统提示词中。当技能被调用时,二级说明加入上下文。三级文件留在后端,直到代理在调用后读取它们。
当代理处理任务时,它分层加载技能信息:
在 Deep Agents 中,@SkillsMiddleware(属于 [默认中间件堆栈 当您传递 skills时)处理前两个层级,第三个层级由 LLM 处理:
- **发现** (一级):代理启动时,中间件扫描配置的技能路径,解析每个
SKILL.md前置元数据,并将name和description字段注入系统提示词。 - **读取** (二级):当代理调用技能时,它通过以下方式读取完整的
SKILL.md内容read_file. - **执行** (三级):调用后,代理遵循技能的说明并仅在说明需要时读取支持文件(脚本、参考资料、资产)。
何时使用技能
如果你发现自己经常给智能体类似的指令,特别是那些详细的包含多个步骤的指令,请考虑将这些指令编纂成规范。这样一来,以后当你想要完成类似任务时,智能体就已经知道该怎么做。
技能在编纂以下内容时特别有用:
- 分步骤工作流:跨越多个步骤的工作流,类似于配方。
- 领域特定知识:指导智能体如何使用工作流工具。例如,包含从哪里拉取信息的相关资料,包括技能可能需要访问的其他参考信息或脚本。
- 包含可执行代码的指令:将流程与智能体可以运行的脚本或模块打包在一起,这样它就能遵循经过测试的逻辑,而不必每次都从指令中重新生成。参见 使用技能执行代码.
- 指南:为智能体提供关于应遵循的防护措施的支持性指令。例如,遵循特定的格式或样式指南,或指定始终将测试作为工作流的一部分运行。
编写有效的技能
Agent 技能规范 包含了关于如何构建技能以实现可靠发现和激活的指导。以下建议在此基础上为深度智能体提供实用模式。
**保持 frontmatter 简洁** 且 SKILL.md 正文在 5,000 个 token 以内。每个技能的前置元数据都会在 发现阶段被添加到系统提示中,而完整正文仅在激活时读取。保持这两层精简意味着你可以加载许多技能而不会占用过多上下文窗口。
编写具体的描述。 在 发现阶段, description 字段是智能体看到的每个技能的唯一信息。好的描述会告诉智能体该技能的作用以及何时激活它,并包含智能体可以匹配的具体关键词:
# Good: specific about what and when
description: >-
Extract text and tables from PDF files, fill PDF forms, and merge
multiple PDFs. Use when working with PDF documents or when the user
mentions PDFs, forms, or document extraction.
# Poor: too vague for reliable matching
description: Helps with PDFs.
当你有多个相关领域的技能时,要清楚地区分它们的描述。重叠的描述会导致智能体激活错误的技能或在选项之间犹豫。如果两个技能服务于相似的目的,请将它们合并为一个。
保持指令专注。 Agent 技能规范建议将你的 SKILL.md 保持在 500 行以内。当指令变长时,将详细参考材料移至 支持资源文件 中并从主文件中引用它们 SKILL.md:
智能体仅在指令调用时加载参考文件,使每层渐进式披露都保持适当的大小。保持文件引用从 SKILL.md 开始只有一层深度,避免深层嵌套的引用链,因为那会迫使智能体多次读取才能获取所需信息。
为智能体构建指令。 将你的 SKILL.md 正文写成智能体可以遵循的清晰指令:
- 分步骤流程 适用于多步骤工作流
- 决策标准 用于在方法之间进行选择
- 预期输入和输出示例 以便智能体了解成功的样子
- 边缘情况 智能体应处理或向用户标记的情况
管理技能数量。 数量少但范围明确的技能优于数量多但功能重叠的技能。随着具有相似描述的技能数量增加,智能体选择正确技能的能力会下降。如果您发现自己拥有许多相关技能,请考虑:
- - 将相关功能整合到单个技能中,并为每个子任务设置专门部分
- - 使用参考文件来保持主文件
SKILL.md简洁,同时覆盖多个子任务
添加支持资源
除了 SKILL.md,技能目录还可以包含任何其他文件或目录。 智能体技能规范 为常见资源类型定义了三个可选目录。深度智能体不会在发现或激活时加载这些文件。智能体仅在您的 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 根目录的路径:
For API details, see the [reference guide](references/api-patterns.html).
To extract tables from a PDF, run:
scripts/extract.py
`
对于每个引用的文件,请说明其内容以及代理应在何时使用它。保持引用从以下位置起一级深 SKILL.md。避免使用深度嵌套的引用链,迫使代理多次读取才能获取所需信息。
后端和远程 skill 加载
Deep Agents 支持不同的后端,具体取决于您想要如何存储和管理 skill 文件:
- -
StateBackend:将文件存储在 LangGraph 代理状态中,供当前线程使用。 - -
StoreBackend:将文件存储在 LangGraph store 中,实现持久化的跨线程存储。 - -
FilesystemBackend:从可配置的磁盘路径下读取和写入 skill 文件root_dir.
运行时加载 skills
当您拥有大量 skills 但只有一小部分与特定运行相关时,可以根据运行时上下文(如用户角色、租户或请求类型)选择要加载的 skills。有两种主要方法:
动态 skill 列表
最简单的方法是在创建代理之前构建 skills 数组。根据您拥有的任何运行时上下文选择要包含的 skill 路径:
const SKILLS_BY_ROLE: Record<string, string[]> = {
engineering: ["/skills/code-review/", "/skills/testing/", "/skills/deployment/"],
data: ["/skills/sql-analysis/", "/skills/visualization/", "/skills/data-pipeline/"],
support: ["/skills/ticket-triage/", "/skills/runbook/"],
};
function createAgentForUser(userRole: string) {
return createDeepAgent({
model: "anthropic:claude-sonnet-4-6",
skills: SKILLS_BY_ROLE[userRole] ?? [],
});
}
这在 skills 位于磁盘或共享后端且您只需要控制代理可以看到哪些 skills 时效果很好。skills 本身不会被复制——您维护一份副本,并可调整传递给每次运行的路径。
命名空间 skills
对于每个用户的 skill 集独立管理的多租户应用程序,请将 /skills/ 路由到带有命名空间工厂的 StoreBackend。用仅该用户有权访问的 skills 填充每个命名空间,中间件在运行时解析到正确的集合:
createDeepAgent,
CompositeBackend,
StateBackend,
StoreBackend,
} from "deepagents";
const agent = await createDeepAgent({
model: "anthropic:claude-sonnet-4-6",
skills: ["/skills/"],
backend: new CompositeBackend({
default: new StateBackend(),
routes: {
"/skills/": new StoreBackend({
namespace: (ctx) => [
ctx.assistantId ?? "default",
ctx.config?.configurable?.user_id ?? "anonymous",
],
}),
},
}),
});
当不同用户或租户需要完全独立的 skill 库且可以单独更新时,此模式非常有用。关于开箱即用地处理 skill 访问、共享和工作区级别可见性的托管解决方案,请参阅 Fleet skills.
子代理的 skills
当您使用 子代理时,可以配置每种类型可以访问哪些 skills:
- 通用子代理:在您传递
skillstocreate_deep_agent时自动继承主代理的 skills。无需额外配置。 - 自定义子代理:不继承主代理的 skills。在每个子代理定义中添加
skills参数,指定该子代理的 skill 源路径。
技能状态完全隔离:主代理的技能对子代理不可见,子代理的技能对主代理也不可见。
const researchSubagent = {
name: "researcher",
description: "Research assistant with specialized skills",
systemPrompt: "You are a researcher.",
tools: [webSearch],
skills: ["/skills/research/", "/skills/web-search/"], // Subagent-specific skills
};
const agent = await createDeepAgent({
model: "google_genai:gemini-3.5-flash",
skills: ["/skills/main/"], // Main agent and GP subagent get these
subagents: [researchSubagent], // Researcher gets only its own skills
});
有关子代理配置和技能继承的更多信息,请参阅 子代理.
技能权限
生产环境部署通常需要控制三个方面:每个用户可以查看哪些技能、代理是否可以修改技能文件,以及写入是否需要人工审批。您可以通过以下方式控制可见性 skills 参数和 后端路由,访问权限通过 文件系统权限,审批通过 interrupt_on 或权限规则配合 mode="interrupt".
跨用户共享技能
要授予每个用户对同一策划库的访问权限,请将 /skills/ 路由到共享的 StoreBackend,并通过您的应用程序代码或管理工作流填充它。使用组织范围的命名空间,使该组织中的所有代理都解析到同一存储:
使用如下键填充存储 /company-policies/SKILL.md 以及包含以下内容的值 content 和 encoding 字段。 /skills/ 路由前缀在从存储读取记录之前会被剥离。
有关处理技能访问、共享和工作区级可见性的托管解决方案,请参阅 舰队技能.
您还可以组合共享库和个人库:路由 /skills/shared/ 到组织范围的 StoreBackend,路由 /skills/personal/ 到用户范围的后端,并在以下位置传递两条路径 skills。请参阅 允许代理编辑个人技能.
根据用户上下文限制技能
并非每个用户都应该看到所有技能。根据角色、租户或其他请求上下文控制在运行时加载哪些技能。有两种主要方法:
- - **动态技能列表** — 在创建代理之前构建
skills数组。根据不同的角色或请求类型传递不同的路径列表。当技能位于共享后端且按路径过滤时有效。 - - **命名空间技能** — 路由
/skills/to aStoreBackend并使用以用户或租户 ID 为键的命名空间工厂。用该身份应访问的技能填充每个命名空间。
这些模式可与以下读写控制配合使用。例如,您可以为管理员提供比工程师更大的技能集,同时保持两个库只读。
强制只读技能
要共享技能但不允许代理修改它们,请路由 /skills/ 到共享存储,并在以下情况下拒绝写操作 /skills/** 使用 文件系统权限。代理可以发现和读取技能;只有您的应用程序代码或管理员工作流才能更新存储。
将此用于企业知识库、经批准的工具说明或共享技能包,代理可从集中管理的上下文中受益,但不应重写真相来源。
要求技能写入需审批
如果代理可能写入技能文件,但您希望人工介入,请使用 interrupt_on 或带有 mode="interrupt"的权限规则。两者都在 write_file or edit_file 运行前暂停,并使用相同的恢复流程。
const agent = await createDeepAgent({
model: "anthropic:claude-sonnet-4-6",
skills: ["/skills/personal/"],
permissions: [
{
operations: ["write"],
paths: ["/skills/**"],
mode: "interrupt",
},
],
checkpointer: new MemorySaver(), // Required to pause and resume
});
或者,配置 interrupt_on={"write_file": True, "edit_file": True} 要求所有文件系统写入均需审批,而不仅是技能路径。请参阅 Human-in-the-loop 了解中断的处理和恢复。
允许代理编辑个人技能
默认情况下,如果后端允许且没有权限规则阻止该路径,代理可以写入技能文件。要让代理创建或完善技能而不触碰共享库:
- 将可写路径(如
/skills/personal/)路由到用户作用域的StoreBackend. - 在
skills. - 中传递该路径(以及任何共享路径)。不要为可写路径添加
deny规则。如果混合使用共享路径和个人路径,请将更具体的规则放在更广泛的拒绝规则之前(规则排序).
createDeepAgent,
CompositeBackend,
StateBackend,
StoreBackend,
} from "deepagents";
const agent = await createDeepAgent({
model: "anthropic:claude-sonnet-4-6",
backend: new CompositeBackend({
default: new StateBackend(),
routes: {
"/skills/shared/": new StoreBackend({
namespace: (rt) => ["curated-skills", rt.context.orgId],
}),
"/skills/personal/": new StoreBackend({
namespace: (ctx) => [
"user-skills",
ctx.config?.configurable?.user_id ?? "anonymous",
],
}),
},
}),
skills: ["/skills/shared/", "/skills/personal/"],
permissions: [
{
operations: ["write"],
paths: ["/skills/shared/**"],
mode: "deny",
},
],
});
代理使用 write_file 和 edit_file 在可写路径下创建或更新 SKILL.md 和支持文件。要在技能格式之外捕获一般学习内容,请将单独的路径(如 /memories/ )路由到另一个可写后端。请参阅 后端 了解路由和存储设置。
使用技能执行代码
没有代码执行,技能是被动的:代理读取指令并使用其可用工具遵循执行。代码执行将技能转变为主动能力。技能可以附带一个经过测试的脚本,用于调用 API、转换数据、验证输出或运行管道——代理会确定性地执行它,而不是每次都根据指令重新生成逻辑。这对于需要精确行为的工作流(数据转换、API 集成、合规检查)或依赖于代理无法仅通过工具调用使用的库的场景尤其有价值。
技能通过 沙盒脚本执行代码:代理在需要安装依赖、运行测试、调用 CLI 或与操作系统文件系统交互时运行捆绑脚本。
沙盒脚本
技能可以包含与 SKILL.md 文件一起的脚本。在您的 SKILL.md 中引用脚本,以便代理知道它们的存在以及何时运行它们:
---
name: arxiv-search
description: Search the arXiv preprint repository for research papers. Use when the user asks about academic papers, recent research, or scientific literature.
---
# arxiv-search
Search arXiv for papers matching the user's query.
## Instructions
1. Run `scripts/search.ts` with the user's query as an argument.
2. Parse the results and present them with title, authors, abstract summary, and link.
3. If the user asks for more detail on a specific paper, fetch the full abstract.
`
代理可以 _从任何后端读取_ 脚本,但要 _执行_ 它们,代理需要访问 shell,而只有 沙盒后端 provide.
沙盒后端 在隔离容器中运行。存储在沙箱外部的技能文件在沙箱内部不可用,这意味着代理无法执行技能脚本或访问技能资源,除非先将其传输进去。使用 自定义中间件 来处理此传输:
- - **
before_agent**:从后端读取技能文件并将其上传到沙箱中,以便代理从一开始就可以执行脚本。 - - **
after_agent**:从沙箱下载任何已更新或新创建的技能文件,并将其写回后端,以便更改在多次运行中保持。
有关在执行前同时初始化技能和记忆并在之后同步两者的完整示例,请参见 使用自定义中间件同步技能和记忆.
故障排除
使用 LangSmith 跟踪来调试技能发现, read_file 调用 SKILL.md以及支持资源访问。遵循 跟踪快速入门 进行设置。我们还建议您设置 LangSmith Engine,它会监控您的跟踪、检测问题并提出修复建议。
技能未激活
问题:代理处理任务时不读取技能的 SKILL.md.
解决方案:
- **使描述更加具体。** 代理仅根据
description字段在 发现阶段选择技能。包括技能的功能、使用时机以及代理可以匹配的关键词:
# Good
description: >-
Search the arXiv preprint repository for research papers. Use when the
user asks about academic papers, recent research, or scientific literature.
# Poor
description: Helps with research.
- **减少技能之间的重叠。** 如果多个技能有相似的描述,代理可能会跳过正确的技能或选错技能。请区分描述或 整合相关技能.
- **确认技能在
skillsarray.** 技能仅从您在代理创建时传递的路径或子代理特定的skillsparameters.
启动时缺少技能
问题:代理未在其系统提示中列出技能,或 read_file on SKILL.md fails.
解决方案:
- **检查技能路径。** 路径必须使用正斜杠并相对于后端根目录。使用
FilesystemBackend时,路径相对于root_dir。使用StateBackend时,通过invoke(files={...})传递技能文件create_file_data().
- **验证
SKILL.mdfrontmatter.** 中的name必须与父目录名称匹配并遵循 代理技能规范。使用skills-ref验证工具 检查格式。
- **检查文件大小。** Deep Agents 会跳过
SKILL.md发现过程中超过 10 MB 的文件。
- **检查分层来源。** 当同一技能名称出现在多个来源时 最后一个来源优先。来自较晚路径的旧技能或空技能可能会覆盖你期望的技能。
未找到支持文件
问题:代理读取了 SKILL.md 但无法访问脚本、引用或资产。
解决方案:
- **从以下位置引用文件
SKILL.md.** 代理不会自动发现支持文件。请说明每个文件包含什么内容以及何时使用。使用 相对路径 从技能根目录开始。
- **将路径保持在技能目录内。** 文件路径相对于后端解析。请确认支持文件存在于你的指令所引用的路径中。
- **将技能同步到沙箱中。** 如果你使用 沙箱后端,容器外部的技能文件在复制进去之前不可用。请参阅 沙箱脚本 和 使用自定义中间件同步技能和记忆.
脚本运行失败
问题:代理读取了脚本但无法运行。
解决方案:代理可以从任何后端读取脚本,但运行它们需要 沙箱后端。请参阅 使用技能执行代码.
子代理无法访问技能
问题:自定义子代理看不到主代理使用的技能。
解决方案:自定义子代理不会继承主代理的技能。请添加一个 skills 参数到每个 子代理定义 中,并指定该子代理的技能源路径。通用子代理从 create_deep_agent automatically.
参考
技能、记忆和工具
技能、 记忆 (AGENTS.md 文件)以及工具都为代理提供上下文或能力。下表总结何时使用每种方式:
| 技能 | 记忆 | 工具 | |
|---|---|---|---|
| **用途** | 按需能力,通过渐进式披露发现 | 启动时加载的持久上下文 | 代理可调用的程序化操作 |
| **加载方式** | 仅在代理确定相关性时读取 | 代理启动时加载 | 每轮可用 |
| **格式** | SKILL.md 在命名目录中 | AGENTS.md files | 绑定到智能体的函数 |
| **分层** | 用户,然后项目(后者覆盖前者) | 用户,然后项目(合并) | 在智能体创建时定义 |
| **使用场景** | 指令是任务特定的且可能很大 | 上下文始终相关(项目规范、偏好) | 智能体需要程序化操作,或者无法访问文件系统 |
这些是指导原则,不是硬性边界。在实践中,技能和记忆位于一个连续体内。智能体可以在工作时更新自己的技能,捕获新的流程并随着时间推移完善指令。这样,技能可以作为渐进式披露记忆的一种形式:智能体按需构建和检索上下文,而不是在每个提示时加载。
前置元数据字段
此 智能体技能规范 定义了以下前置元数据字段:
| 字段 | 必填 | 描述 |
|---|---|---|
name | 是 | 小写字母数字和连字符,1-64个字符。必须与父目录名称匹配。 |
description | 是 | 技能的用途及使用场景。最长1,024个字符。 |
license | 否 | 许可证名称或对捆绑许可证文件的引用。 |
compatibility | 否 | 环境要求(系统包、网络访问)。最长500个字符。 |
metadata | 否 | 用于附加属性的任意键值对。 |
allowed-tools | 否 | 技能可以使用的事先批准工具的空格分隔列表。实验性功能。 |
---
name: langgraph-docs
description: Use this skill for requests related to LangGraph in order to fetch relevant documentation to provide accurate, up-to-date guidance.
license: MIT
compatibility: Requires internet access for fetching documentation URLs
metadata:
author: langchain
version: "1.0"
allowed-tools: fetch_url
---
# langgraph-docs
Instructions for the agent go here. See [Usage](#usage) for a complete example of skill instructions.
`
更多示例技能,请参阅 深度智能体示例技能.