技能是可重用的代理能力,提供专门的工作流程和领域知识。
您可以使用 Agent Skills 为您的深度代理提供新的能力和专业知识。要获取可立即使用的技能,以提升您的代理在 LangChain 生态系统任务上的表现,请参阅 LangChain Skills 仓库。
深度代理技能遵循 Agent Skills 规范。
什么是技能
技能是一个目录结构,其中每个文件夹包含一个或多个文件,这些文件包含代理可以使用的上下文:
- 一个
SKILL.md 文件,包含关于技能的指令和元数据
- 附加脚本(可选)
- 附加参考信息,例如文档(可选)
- 附加资源,例如模板和其他资源(可选)
任何附加资源(脚本、文档、模板或其他资源)必须在 SKILL.md 文件中引用,并提供文件内容和使用方法的信息,以便代理决定何时使用它们。
技能如何工作
当您创建深度代理时,可以传入包含技能的目录列表。代理启动时,会读取每个 SKILL.md 文件的 frontmatter。
当代理收到提示时,它会检查在完成提示时是否可以使用任何技能。如果找到匹配的提示,它会审查技能文件的其余部分。这种仅在需要时审查技能信息的模式称为渐进式披露。
您可能有一个技能文件夹,其中包含一个以特定方式使用文档站点的技能,以及另一个用于搜索 arXiv 预印本研究论文库的技能:
skills/
├── langgraph-docs
│ └── SKILL.md
└── arxiv_search
├── SKILL.md
└── arxiv_search.ts # 用于搜索 arXiv 的代码
SKILL.md 文件始终遵循相同的模式,以 frontmatter 中的元数据开头,后跟技能的指令。
以下示例展示了一个技能,该技能提供了在提示时如何提供相关 langgraph 文档的指令:
---
name: langgraph-docs
description: 此技能用于与 LangGraph 相关的请求,以获取相关文档,提供准确、最新的指导。
---
# langgraph-docs
## 概述
本技能解释如何访问 LangGraph Python 文档,以帮助回答问题和指导实现。
## 指令
### 1. 获取文档索引
使用 fetch_url 工具读取以下 URL:
https://docs.langchain.com/llms.txt
这将提供所有可用文档的结构化列表及其描述。
### 2. 选择相关文档
根据问题,从索引中识别 2-4 个最相关的文档 URL。优先考虑:
- 针对实现问题的具体操作指南
- 用于理解问题的核心概念页面
- 端到端示例的教程
- API 详细信息的参考文档
### 3. 获取选定的文档
使用 fetch_url 工具读取选定的文档 URL。
### 4. 提供准确指导
阅读文档后,完成用户的请求。
有关更多技能示例,请参阅 深度代理示例技能。
重要提示有关编写技能文件时的约束和最佳实践,请参阅完整的 Agent Skills 规范。值得注意的是:
- 如果
description 字段超过 1024 个字符,将被截断。
- 在深度代理中,
SKILL.md 文件必须小于 10 MB。超过此限制的文件将在技能加载期间被跳过。
完整示例
以下示例展示了使用所有可用 frontmatter 字段的 SKILL.md 文件:
---
name: langgraph-docs
description: 此技能用于与 LangGraph 相关的请求,以获取相关文档,提供准确、最新的指导。
license: MIT
compatibility: 需要互联网访问以获取文档 URL
metadata:
author: langchain
version: "1.0"
allowed-tools: fetch_url
---
# langgraph-docs
## 概述
本技能解释如何访问 LangGraph Python 文档,以帮助回答问题和指导实现。
## 指令
### 1. 获取文档索引
使用 fetch_url 工具读取以下 URL:
https://docs.langchain.com/llms.txt
这将提供所有可用文档的结构化列表及其描述。
### 2. 选择相关文档
根据问题,从索引中识别 2-4 个最相关的文档 URL。优先考虑:
- 针对实现问题的具体操作指南
- 用于理解问题的核心概念页面
- 端到端示例的教程
- API 详细信息的参考文档
### 3. 获取选定的文档
使用 fetch_url 工具读取选定的文档 URL。
### 4. 提供准确指导
阅读文档后,完成用户的请求。
在创建深度代理时传递技能目录:
StateBackend
StoreBackend
FilesystemBackend
import { createDeepAgent, type FileData } from "deepagents";
import { MemorySaver } from "@langchain/langgraph";
const checkpointer = new MemorySaver();
function createFileData(content: string): FileData {
const now = new Date().toISOString();
return {
content: content.split("\n"),
created_at: now,
modified_at: now,
};
}
const skillsFiles: Record<string, FileData> = {};
const skillUrl =
"https://raw.githubusercontent.com/langchain-ai/deepagentsjs/refs/heads/main/examples/skills/langgraph-docs/SKILL.md";
const response = await fetch(skillUrl);
const skillContent = await response.text();
skillsFiles["/skills/langgraph-docs/SKILL.md"] = createFileData(skillContent);
const agent = await createDeepAgent({
checkpointer,
// IMPORTANT: deepagents skill source paths are virtual (POSIX) paths relative to the backend root.
skills: ["/skills/"],
});
const config = {
configurable: {
thread_id: `thread-${Date.now()}`,
},
};
const result = await agent.invoke(
{
messages: [
{
role: "user",
content: "what is langraph? Use the langgraph-docs skill if available.",
},
],
files: skillsFiles,
},
config,
);
import { createDeepAgent, StoreBackend, type FileData } from "deepagents";
import {
InMemoryStore,
MemorySaver,
} from "@langchain/langgraph";
const checkpointer = new MemorySaver();
const store = new InMemoryStore();
function createFileData(content: string): FileData {
const now = new Date().toISOString();
return {
content: content.split("\n"),
created_at: now,
modified_at: now,
};
}
const skillUrl =
"https://raw.githubusercontent.com/langchain-ai/deepagentsjs/refs/heads/main/examples/skills/langgraph-docs/SKILL.md";
const response = await fetch(skillUrl);
const skillContent = await response.text();
const fileData = createFileData(skillContent);
await store.put(["filesystem"], "/skills/langgraph-docs/SKILL.md", fileData);
const agent = await createDeepAgent({
backend: new StoreBackend(),
store: store,
checkpointer,
// IMPORTANT: deepagents skill source paths are virtual (POSIX) paths relative to the backend root.
skills: ["/skills/"],
});
const config = {
recursionLimit: 50,
configurable: {
thread_id: `thread-${Date.now()}`,
},
};
const result = await agent.invoke(
{
messages: [
{
role: "user",
content: "what is langraph? Use the langgraph-docs skill if available.",
},
],
},
config,
);
import { createDeepAgent, FilesystemBackend } from "deepagents";
import { MemorySaver } from "@langchain/langgraph";
const checkpointer = new MemorySaver();
const backend = new FilesystemBackend({ rootDir: process.cwd() });
const agent = await createDeepAgent({
backend,
skills: ["./examples/skills/"],
interruptOn: {
read_file: true,
write_file: true,
delete_file: true,
},
checkpointer, // Required!
});
const config = {
configurable: {
thread_id: `thread-${Date.now()}`,
},
};
const result = await agent.invoke(
{
messages: [
{
role: "user",
content: "what is langraph? Use the langgraph-docs skill if available.",
},
],
},
config,
);
技能源路径列表。路径必须使用正斜杠指定,并且相对于后端的根目录。
- 如果省略,则不加载任何技能。
- 使用
StateBackend(默认)时,通过 invoke(files={...}) 提供技能文件。
- 使用
FilesystemBackend 时,从磁盘相对于后端的 root_dir 加载技能。
对于同名技能,后面的源会覆盖前面的源(最后一个生效)。
SDK 仅加载您在 skills 中传入的源。它不会自动扫描 CLI 目录,例如 ~/.deepagents/... 或 ~/.agents/...。有关 CLI 存储约定,请参阅 应用数据。
如果您希望在 SDK 代码中实现类似 CLI 的分层,请按从低到高的优先级顺序显式传入所有所需源:[
"<user-home>/.deepagents/{agent}/skills/",
"<user-home>/.agents/skills/",
"<project-root>/.deepagents/skills/",
"<project-root>/.agents/skills/",
]
然后在创建代理时将该有序列表作为 skills 传递。
源优先级
当多个技能源包含同名技能时,skills 数组中后面列出的源中的技能优先(最后一个生效)。这允许您对来自不同来源的技能进行分层。
// 如果两个源都包含名为 "web-search" 的技能,
// 则来自 "/skills/project/" 的技能获胜(最后加载)。
const agent = await createDeepAgent({
skills: ["/skills/user/", "/skills/project/"],
...
});
子代理的技能
当您使用子代理时,可以配置每种类型可以访问哪些技能:
- 通用子代理:当您将
skills 传递给 create_deep_agent 时,会自动继承主代理的技能。无需额外配置。
- 自定义子代理:不继承主代理的技能。向每个子代理定义添加一个
skills 参数,其中包含该子代理的技能源路径。
技能状态完全隔离:主代理的技能对子代理不可见,子代理的技能对主代理也不可见。
const researchSubagent = {
name: "researcher",
description: "具有专门技能的研究助理",
systemPrompt: "You are a researcher.",
tools: [webSearch],
skills: ["/skills/research/", "/skills/web-search/"], // 子代理特定技能
};
const agent = await createDeepAgent({
model: "google_genai:gemini-3.1-pro-preview",
skills: ["/skills/main/"], // 主代理和通用子代理获取这些
subagents: [researchSubagent], // 研究员仅获取其自己的技能
});
有关子代理配置和技能继承的更多信息,请参阅子代理。
代理看到的内容
配置技能后,“技能系统”部分会注入到代理的系统提示中。代理使用此信息遵循三步过程:
- 匹配—当用户提示到达时,代理检查是否有任何技能的描述与任务匹配。
- 读取—如果技能适用,代理使用其技能列表中显示的路径读取完整的
SKILL.md 文件。
- 执行—代理遵循技能的指令,并根据需要访问任何支持文件(脚本、模板、参考文档)。
在您的 SKILL.md frontmatter 中编写清晰、具体的描述。代理仅根据描述决定是否使用技能——详细的描述会带来更好的技能匹配。
技能与记忆
技能和记忆(AGENTS.md 文件)服务于不同的目的:
| 技能 | 记忆 |
|---|
| 目的 | 通过渐进式披露发现的按需能力 | 在启动时始终加载的持久上下文 |
| 加载 | 仅在代理确定相关性时读取 | 始终注入系统提示 |
| 格式 | 命名目录中的 SKILL.md | AGENTS.md 文件 |
| 分层 | 用户 → 项目(最后一个生效) | 用户 → 项目(组合) |
| 使用时机 | 指令特定于任务且可能很大 | 上下文始终相关(项目约定、偏好) |
何时使用技能和工具
以下是使用工具和技能的一些通用指南:
- 当有大量上下文时使用技能,以减少系统提示中的令牌数量。
- 使用技能将能力捆绑到更大的操作中,并提供超出单个工具描述的额外上下文。
- 如果代理无法访问文件系统,请使用工具。