在技能中使用脚本#
如何在技能中运行命令并捆绑可执行脚本。
Skill 可以指示 Agent 运行 Shell 命令,并在 scripts/ 目录中包含可重用的脚本。本指南涵盖了一次性命令、带有自身依赖项的自包含脚本,以及如何为 Agent 设计脚本接口。
一次性命令#
当现有的软件包已经能满足你的需求时,你可以直接在 SKILL.md 指令中引用它,而无需 scripts/ 目录。许多生态系统都提供了在运行时自动解析依赖项的工具。
- uvx: 随 uv 一起发布。在隔离环境中运行 Python 包,具有强大的缓存功能。
uvx ruff@0.8.0 check . uvx black@24.10.0 . - pipx: 在隔离环境中运行 Python 包。可通过 OS 包管理器安装。
pipx run 'black==24.10.0' . pipx run 'ruff==0.8.0' check . - npx: 运行 npm 包,按需下载。随 npm(及 Node.js)一起发布。
npx eslint@9 --fix . npx create-vite@6 my-app - bunx: Bun 版本的
npx。 - deno run: 直接从 URL 或标识符运行脚本。需要权限标志(如
--allow-read)。 - go run: 直接编译并运行 Go 包。内置于
go命令中。
针对 Skill 中一次性命令的建议:
- 固定版本(例如
npx eslint@9.0.0),以确保命令的行为随时间推移保持一致。 - 在
SKILL.md中说明前提条件(例如“需要 Node.js 18+”),而不是假设 Agent 环境中已有这些条件。对于运行时级别的要求,请使用compatibilityFrontmatter 字段。 - 将复杂命令移至脚本中。当命令包含过多的标志且难以一次性写对时,在
scripts/中放一个经过测试的脚本会更可靠。
在 SKILL.md 中引用脚本#
使用相对于 Skill 目录根路径的相对路径来引用绑定的文件。Agent 会自动解析这些路径 —— 无需绝对路径。
在 SKILL.md 中列出可用脚本,以便 Agent 知道它们的存在:
## 可用脚本
- **`scripts/validate.sh`** — 验证配置文件
- **`scripts/process.py`** — 处理输入数据然后指示 Agent 运行它们:
## 工作流
1. 运行验证脚本:
```bash
bash scripts/validate.sh "$INPUT_FILE"
```- 处理结果:
python3 scripts/process.py --input results.json
> [!NOTE]
> 同样的相对路径约定也适用于 `references/*.md` 等支持文件 —— 脚本执行路径(在代码块中)是相对于 **Skill 目录根目录** 的,因为 Agent 是从那里运行命令的。
## 自包含脚本
当你需要可重用的逻辑时,在 `scripts/` 中绑定一个声明了自身依赖项的脚本。Agent 只需一条命令即可运行该脚本 —— 无需单独的清单文件或安装步骤。
几种语言支持内联依赖声明:
### Python (PEP 723)
[PEP 723](https://peps.python.org/pep-0723/) 定义了内联脚本元数据的标准格式。在 `# ///` 标记内的 TOML 块中声明依赖项:
```python
# /// script
# dependencies = [
# "beautifulsoup4",
# ]
# ///
from bs4 import BeautifulSoup
html = '<html><body><h1>Welcome</h1><p class="info">This is a test.</p></body></html>'
print(BeautifulSoup(html, "html.parser").select_one("p.info").get_text())使用 uv 运行(推荐):
uv run scripts/extract.pyDeno#
Deno 的 npm: 和 jsr: 导入说明符使每个脚本默认都是自包含的:
#!/usr/bin/env -S deno run
import * as cheerio from "npm:cheerio@1.0.0";
const html = `<html><body><h1>Welcome</h1><p class="info">This is a test.</p></body></html>`;
const $ = cheerio.load(html);
console.log($("p.info").text());Bun#
当没有发现 node_modules 目录时,Bun 会在运行时自动安装缺失的包。直接在导入路径中固定版本:
#!/usr/bin/env bun
import * as cheerio from "cheerio@1.0.0";
const html = `<html><body><h1>Welcome</h1><p class="info">This is a test.</p></body></html>`;
const $ = cheerio.load(html);
console.log($("p.info").text());Ruby#
Bundler 自 2.6 版本起随 Ruby 一起发布。使用 bundler/inline 直接在脚本中声明 gem:
require 'bundler/inline'
gemfile do
source 'https://rubygems.org'
gem 'nokogiri'
end
html = '<html><body><h1>Welcome</h1><p class="info">This is a test.</p></body></html>'
doc = Nokogiri::HTML(html)
puts doc.at_css('p.info').text为 Agent 环境设计脚本#
当 Agent 运行你的脚本时,它会读取 stdout 和 stderr 来决定下一步该做什么。一些设计选择可以使脚本更易于 Agent 使用。
避免交互式提示#
这是 Agent 执行环境的一个强制要求。Agent 在非交互式 Shell 中操作 —— 它们无法响应 TTY 提示、密码对话框或确认菜单。一个阻塞在交互式输入上的脚本将无限期挂起。
请通过命令行标志、环境变量或 stdin 接受所有输入。