在 Skills 中使用脚本
本页为脚本使用指南的非官方中文翻译。
在 Skills 中使用脚本
Section titled “在 Skills 中使用脚本”Skills 可以指示智能体运行 shell 命令,并将可复用脚本打包到 scripts/ 目录中。本指南介绍一次性命令、带有自身依赖项的自包含脚本,以及如何为智能体使用设计脚本接口。
当现有软件包已经满足你的需求时,可以直接在 SKILL.md 指令中引用它,而无需 scripts/ 目录。许多生态系统都提供了在运行时自动解析依赖项的工具。
uvx
uvx 在具有积极缓存的隔离环境中运行 Python 包。它随 uv 一起提供。
uvx ruff@0.8.0 check .uvx black@24.10.0 .- 不随 Python 一起提供 — 需要单独安装。
- 快速。缓存非常激进,因此重复运行几乎是即时的。
pipx
pipx 在隔离环境中运行 Python 包。可通过操作系统包管理器获得(apt install pipx、brew install pipx)。
pipx run 'black==24.10.0' .pipx run 'ruff==0.8.0' check .- 不随 Python 一起提供 — 需要单独安装。
- 一个成熟的
uvx替代品。虽然uvx已成为标准推荐,但pipx仍然是一个可靠的选项,具有更广泛的操作系统包管理器可用性。
npx
npx 运行 npm 包,按需下载。它随 npm(npm 又随 Node.js)一起提供。
npx eslint@9 --fix .npx create-vite@6 my-app- 随 Node.js 一起提供 — 无需额外安装。
- 下载软件包、运行它并为将来使用缓存它。
- 使用
npx package@version固定版本以获得可重现性。
bunx
bunx 是 Bun 等价于 npx 的命令。它随 Bun 一起提供。
bunx eslint@9 --fix .bunx create-vite@6 my-app- 在基于 Bun 的环境中作为
npx的即插即用替代品。 - 仅当用户的环境是 Bun 而非 Node.js 时才适用。
deno run
deno run 直接从 URL 或说明符运行脚本。它随 Deno 一起提供。
deno run npm:create-vite@6 my-appdeno run --allow-read npm:eslint@9 -- --fix .- 需要权限标志(
--allow-read等)才能访问文件系统/网络。 - 使用
--将 Deno 标志与工具自己的标志分隔开。
go run
go run 直接编译并运行 Go 包。它内置于 go 命令中。
go run golang.org/x/tools/cmd/goimports@v0.28.0 .go run github.com/golangci/golangci-lint/cmd/golangci-lint@v1.62.0 run- 内置于 Go — 无需额外工具。
- 固定版本或使用
@latest以使命令明确。
关于 Skill 中一次性命令的提示:
- 固定版本(例如
npx eslint@9.0.0)以使命令随时间表现一致。 - 在你的
SKILL.md中 说明前置条件(例如”需要 Node.js 18+”),而不是假设智能体的环境已具备这些条件。对于运行时级别的要求,请使用compatibilityfrontmatter 字段。 - 将复杂命令移入脚本。 当你使用一些标志调用工具时,一次性命令效果良好。当命令复杂到难以一次就写对时,
scripts/中经过测试的脚本会更可靠。
从 SKILL.md 引用脚本
Section titled “从 SKILL.md 引用脚本”使用 相对于 Skill 目录根的相对路径 来引用打包的文件。智能体会自动解析这些路径 — 无需使用绝对路径。
在你的 SKILL.md 中列出可用的脚本,以便智能体知道它们的存在:
## 可用脚本
- **`scripts/validate.sh`** — 验证配置文件- **`scripts/process.py`** — 处理输入数据然后指示智能体运行它们:
## 工作流
1. 运行验证脚本: ```bash bash scripts/validate.sh "$INPUT_FILE" ```
2. 处理结果: ```bash python3 scripts/process.py --input results.json ```译者注:相同的相对路径约定适用于支持文件,如
references/*.md— 代码块中的脚本执行路径相对于 Skill 目录根,因为智能体从该处运行命令。
当你需要可复用的逻辑时,请将脚本打包到 scripts/ 中,并在脚本中内联声明其依赖项。智能体可以通过单个命令运行该脚本 — 无需单独清单文件或安装步骤。
几种语言支持内联依赖声明:
Python
PEP 723 定义了内联脚本元数据的标准格式。在 # /// 标记内的 TOML 块中声明依赖项:
# /// 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.pyuv run 会创建一个隔离环境,安装声明的依赖项,然后运行脚本。pipx(pipx run scripts/extract.py)也支持 PEP 723。
- 使用 PEP 508 说明符固定版本:
"beautifulsoup4>=4.12,<5"。 - 使用
requires-python约束 Python 版本。 - 使用
uv lock --script创建锁定文件以获得完全可重现性。
Deno
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());deno run scripts/extract.ts- 使用
npm:表示 npm 包,使用jsr:表示 Deno 原生包。 - 版本说明符遵循 semver:
@1.0.0(精确),@^1.0.0(兼容)。 - 依赖项全局缓存。使用
--reload强制重新获取。 - 带有原生插件(node-gyp)的包可能无法工作 — 提供预构建二进制的包效果最佳。
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());bun run scripts/extract.ts- 无需
package.json或node_modules。TypeScript 原生支持。 - 包全局缓存。首次运行会下载;后续运行几乎是即时的。
- 如果目录树中任何位置存在
node_modules目录,则禁用自动安装,Bun 回退到标准 Node.js 解析。
Ruby
Bundler 自 Ruby 2.6 起随附。使用 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').textruby scripts/extract.rb- 显式固定版本(
gem 'nokogiri', '~> 1.16')— 没有锁定文件。 - 工作目录中的现有
Gemfile或BUNDLE_GEMFILE环境变量可能会干扰。
为智能体使用设计脚本
Section titled “为智能体使用设计脚本”当智能体运行你的脚本时,它会读取 stdout 和 stderr 以决定下一步该做什么。一些设计选择会让脚本对智能体来说变得显著更易于使用。
避免交互式提示
Section titled “避免交互式提示”这是智能体执行环境的硬性要求。智能体在非交互式 shell 中运行 — 它们无法响应 TTY 提示、密码对话框或确认菜单。在交互式输入上阻塞的脚本将无限期挂起。
请通过命令行标志、环境变量或 stdin 接受所有输入:
# 不好:等待输入而挂起$ python scripts/deploy.pyTarget environment: _
# 良好:清晰的错误及指导$ python scripts/deploy.pyError: --env is required. Options: development, staging, production.Usage: python scripts/deploy.py --env staging --tag v1.2.3使用 --help 记录用法
Section titled “使用 --help 记录用法”--help 输出是智能体了解脚本接口的主要方式。包括简要说明、可用标志和用法示例:
Usage: scripts/process.py [OPTIONS] INPUT_FILE
Process input data and produce a summary report.
Options: --format FORMAT Output format: json, csv, table (default: json) --output FILE Write output to FILE instead of stdout --verbose Print progress to stderr
Examples: scripts/process.py data.csv scripts/process.py --format csv --output report.csv data.csv请保持简洁 — 输出会与智能体正在处理的所有其他内容一起进入其上下文窗口。
编写有用的错误消息
Section titled “编写有用的错误消息”当智能体收到错误时,消息直接影响其下一次尝试。模糊的 “Error: invalid input” 会浪费一个回合。相反,请说明出了什么问题、预期是什么以及可以尝试什么:
Error: --format must be one of: json, csv, table. Received: "xml"使用结构化输出
Section titled “使用结构化输出”相对于自由文本,优先选择结构化格式 — JSON、CSV、TSV。结构化格式可被智能体和标准工具(jq、cut、awk)使用,使你的脚本在管道中可组合。
# 空白对齐 — 难以通过编程方式解析NAME STATUS CREATEDmy-service running 2025-01-15
# 分隔 — 明确的字段边界{"name": "my-service", "status": "running", "created": "2025-01-15"}将数据与诊断信息分离: 将结构化数据发送到 stdout,将进度消息、警告和其他诊断信息发送到 stderr。这让智能体可以捕获干净的、可解析的输出,同时在需要时仍能访问诊断信息。
进一步的考虑
Section titled “进一步的考虑”- 幂等性。 智能体可能会重试命令。“不存在则创建”比”创建并在重复时失败”更安全。
- 输入约束。 以清晰的错误拒绝模糊的输入,而不是猜测。尽可能使用 enum 和封闭集合。
- 支持 dry-run。 对于破坏性或有状态的操作,
--dry-run标志让智能体可以预览将要发生的事情。 - 有意义的退出码。 针对不同类型的失败(未找到、无效参数、认证失败)使用不同的退出码,并在
--help输出中记录它们,以便智能体了解每个代码的含义。 - 安全的默认值。 考虑破坏性操作是否应要求显式的确认标志(
--confirm、--force)或其他适合风险级别的保障措施。 - 可预测的输出大小。 许多智能体框架会自动截断超过阈值的工具输出(例如 10-30K 字符),可能会丢失关键信息。如果你的脚本可能产生大量输出,请默认为摘要或合理的限制,并支持像
--offset这样的标志,以便智能体在需要时可以请求更多信息。或者,如果输出量很大且不便于分页,请要求智能体传递一个--output标志,该标志指定输出文件或-以显式选择输出到 stdout。