为代理提供使用 Agent Skills 的工具:按需加载存储在 SKILL.md 文件夹中的说明、参考资料和脚本。模型会看到技能名称和说明的简短目录,仅在任务匹配时才加载相应技能。
技能可来自来源:Computer Workspace、R2 存储桶或代码。无论使用哪种来源,工具都相同。
将提供的适配器与 Think、Pi Durable 或 AI SDK 搭配使用。对于其他 harness,请使用 agents/skills 中的目录函数。
| 工具 | 作用 |
|---|---|
activate_skill |
返回技能说明、技能文件夹(如果有)以及随技能打包的文件列表。 |
read_skill_resource |
按 { name, path } 或 release-notes/references/guide.md 等限定路径返回一个打包文件。 |
run_skill_script |
运行打包的脚本。仅在设置实验性 script runner 时添加。 |
只有至少有一个可用技能时才会显示这些工具。name 仅限目录中的技能。二进制文件以 base64 形式返回。
除这些工具外,目录还会提供系统提示词文本,其中列出了每项技能:
Available skills. When a task matches a skill, use activate_skill with its name before proceeding.
- release-notes: Turn a list of changes into release notes.
- pirate-voice: Answer in a pirate voice.以下示例要求你已有 harness。要创建新代理,请从 Think 或 Pi harness 指南开始。
-
在 Worker 项目中更新 Agents SDK:
npm i agents@latestyarn add agents@latestpnpm add agents@latestbun add agents@latest -
为技能选择一个来源。
-
使用下方任一示例向 harness 注册工具。
Think 会为你添加工具和目录。从 getSkills() 返回来源:
import { Think, skills } from "@cloudflare/think";
export class MyAgent extends Think {
getSkills() {
return [skills.workspace(this.workspace)];
}
}import { Think, skills } from "@cloudflare/think";
export class MyAgent extends Think<Env> {
getSkills() {
return [skills.workspace(this.workspace)];
}
}Think 会在每轮对话开始前重新列出来源,因此新增或编辑的技能会在下一轮生效。
在你的 Pi harness 工厂中安装 skills() 扩展。它会添加 activate_skill、read_skill_resource 和 skills 系统提示词部分:
import { skills } from "agents/harness/pi";
import { r2 } from "agents/skills";
// Inside the harness factory, before Harness.open():
this.registry.install(
await skills([r2(this.env.SKILLS_BUCKET, { prefix: "skills/" })]),
);import { skills } from "agents/harness/pi";
import { r2 } from "agents/skills";
// Inside the harness factory, before Harness.open():
this.registry.install(
await skills([r2(this.env.SKILLS_BUCKET, { prefix: "skills/" })]),
);工厂构建扩展时会读取一次来源。这两个工具都标记为 replay: "safe"。
使用 loadSkillCatalog() 加载目录,然后将 createSkillTools() 传给 streamText() 或 generateText() 调用。将目录提示词添加到系统提示词中:
import { streamText } from "ai";
import { loadSkillCatalog, r2 } from "agents/skills";
import { createSkillTools } from "agents/skills/tools/ai-sdk";
const catalog = await loadSkillCatalog([
r2(env.SKILLS_BUCKET, { prefix: "skills/" }),
]);
const result = streamText({
model,
system: [instructions, catalog.prompt()].filter(Boolean).join("\n\n"),
tools: { ...tools, ...createSkillTools(catalog) },
messages,
});import { streamText } from "ai";
import { loadSkillCatalog, r2 } from "agents/skills";
import { createSkillTools } from "agents/skills/tools/ai-sdk";
const catalog = await loadSkillCatalog([
r2(env.SKILLS_BUCKET, { prefix: "skills/" }),
]);
const result = streamText({
model,
system: [instructions, catalog.prompt()].filter(Boolean).join("\n\n"),
tools: { ...tools, ...createSkillTools(catalog) },
messages,
});重新加载目录以获取已更改的技能,并根据新目录构建工具。每当目录提示词发生变化,catalog.fingerprint 都会改变;比较它即可判断是否需要重新构建缓存的系统提示词。
要添加 run_skill_script,请从 agents/skills/runner 传入运行器:createSkillTools(catalog, { scriptRunner: runner({ loader: env.LOADER }) })。请参阅执行。
在 harness 的工具处理程序中直接使用目录。activate() 和 readResource() 会返回结果而不是抛出异常,且渲染的文本与提供的适配器相同:
import {
formatSkillDiagnostic,
loadSkillCatalog,
renderSkillResource,
workspace,
} from "agents/skills";
// `computerWorkspace` is a Workspace from @cloudflare/computer.
const catalog = await loadSkillCatalog([workspace(computerWorkspace)]);
for (const diagnostic of catalog.diagnostics) {
console.warn(formatSkillDiagnostic(diagnostic));
}
// Register these handlers with your harness's tool interface.
function activateSkill(input) {
const activated = catalog.activate(input.name);
// Report failures as a tool error, for example an unknown skill.
if (!activated.ok) throw activated.error;
return activated.value;
}
async function readSkillResource(input) {
const read = await catalog.readResource(input);
if (!read.ok) throw read.error;
return renderSkillResource(read.value);
}import {
formatSkillDiagnostic,
loadSkillCatalog,
renderSkillResource,
workspace,
} from "agents/skills";
// `computerWorkspace` is a Workspace from @cloudflare/computer.
const catalog = await loadSkillCatalog([workspace(computerWorkspace)]);
for (const diagnostic of catalog.diagnostics) {
console.warn(formatSkillDiagnostic(diagnostic));
}
// Register these handlers with your harness's tool interface.
function activateSkill(input: { name: string }): string {
const activated = catalog.activate(input.name);
// Report failures as a tool error, for example an unknown skill.
if (!activated.ok) throw activated.error;
return activated.value;
}
async function readSkillResource(input: {
name?: string;
path: string;
}): Promise<string> {
const read = await catalog.readResource(input);
if (!read.ok) throw read.error;
return renderSkillResource(read.value);
}将 name 定义为 catalog.skills.map((entry) => entry.skill.name) 中的一个值。将 catalog.prompt() 添加到系统提示词中。没有技能时,它会返回 null。
技能损坏不会中断代理。loadSkillCatalog() 会在 catalog.diagnostics 中报告问题,同时保留其他技能:
| 诊断信息 | 原因 |
|---|---|
SkillWarning |
某项技能违反了规范规则,但仍被加载。 |
InvalidSkill |
无法加载某项技能,例如缺少 description。该技能不会显示给模型。 |
SourceFailed |
无法列出某个来源,例如存储桶不可用。 |
DuplicateSkill |
两个来源提供了同名技能。优先使用第一个来源。 |
工具错误(例如技能未知或文件缺失)会作为工具错误返回给模型,以便它重试。AI SDK 工具会抛出异常,而 Pi 工具会返回 isError: true。
- Agent Skills 概念:开放格式和渐进式披露
- Agent Skills:Agents SDK 中的来源和验证
- 执行:运行技能脚本
- 文件系统:为代理提供可存储技能的 Workspace