Расширение скриптов навыков
Помимо написания инструкций в SKILL.md, вы также можете добавить исполняемый код в навык через каталог scripts.
В этом разделе вы узнаете, как использовать скрипты для расширения функциональности навыка.
Зачем использовать скрипты
Использование скриптов позволяет:
- Инкапсулировать сложную логику и избежать написания большого объёма кода в SKILL.md
- Предоставлять проверенные, надёжные реализации
- Позволять агентам повторно использовать одни и те же инструменты и функции
- Обрабатывать более сложные операции ввода/вывода
Совет: когда вы замечаете, что агент многократно реализует одну и ту же логику при разных выполнениях, это часто хороший момент, чтобы создать скрипт.
Структура каталога скриптов
Скрипты следует размещать в подкаталоге scripts/ каталога навыка:
Структура каталогов
├── SKILL.md
└── scripts/
├── script1.py
├── script2.sh
└── helper.js
Руководство по написанию скриптов
1. Самодостаточность
Скрипты должны быть настолько самодостаточными, насколько это возможно, или чётко документировать свои зависимости.
Пример самодостаточного скрипта
"""
Скрипт извлечения текста из PDF
Зависимость: pip install pdfplumber
Запуск: python scripts/extract_pdf.py input.pdf
"""
import sys
import pdfplumber
def extract_text_from_pdf(pdf_path):
"""Извлечь текст из PDF-файла"""
with pdfplumber.open(pdf_path) as pdf:
text = ""
for page in pdf.pages:
text += page.extract_text() or ""
return text
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Использование: python extract_pdf.py <pdf-файл>")
sys.exit(1)
pdf_path = sys.argv[1]
text = extract_text_from_pdf(pdf_path)
print(text)
2. Понятная обработка ошибок
Скрипты должны предоставлять полезные сообщения об ошибках, помогающие агентам понять, что пошло не так.
Пример обработки ошибок
def main():
if len(sys.argv) < 2:
print("Ошибка: отсутствует обязательный аргумент", file=sys.stderr)
print("Использование: python script.py <входной файл> [выходной файл]", file=sys.stderr)
sys.exit(1)
input_file = sys.argv[1]
try:
# Выполнить основную логику
process_file(input_file)
except FileNotFoundError:
print(f"Ошибка: файл {input_file} не найден", file=sys.stderr)
sys.exit(1)
except PermissionError:
print(f"Ошибка: нет прав на чтение файла {input_file}", file=sys.stderr)
sys.exit(1)
except Exception as e:
print(f"Ошибка: при обработке файла произошла неизвестная ошибка: {e}", file=sys.stderr)
sys.exit(1)
if __name__ == "__main__":
main()
3. Обработка граничных случаев
Скрипты должны корректно обрабатывать различные граничные случаи, а не аварийно завершаться.
Пример обработки граничных случаев
"""Проверить, допустимы ли входные данные"""
if not text:
return False, "Ввод не может быть пустым"
if len(text) > 10000:
return False, "Длина входных данных превышает предел (макс. 10000 символов)"
return True, ""
# Использование проверки
is_valid, error_msg = validate_input(user_input)
if not is_valid:
print(f"Проверка не удалась: {error_msg}")
sys.exit(1)
Ссылки на скрипты в SKILL.md
Когда навыку нужно выполнить скрипт, опишите в SKILL.md, как его вызывать.
Ссылки на скрипты:
## PDF 文本提取 使用脚本提取 PDF 中的文本: ```bash python scripts/extract_pdf.py input.pdf ``` 脚本会从 input.pdf 提取所有文本并输出到标准输出。 如果需要将结果保存到文件: ```bash python scripts/extract_pdf.py input.pdf > output.txt ```
Примечание: при ссылке на скрипты используйте пути относительно корневого каталога навыка.
Поддерживаемые языки скриптов
Поддерживаемые языки сценариев зависят от используемой вами реализации агента. Распространённые варианты включают:
| Язык | Описание |
|---|---|
| Python | Самый часто используемый вариант, мощный и простой для написания |
| Bash | Подходит для системных операций и инструментов командной строки |
| JavaScript | Подходит для задач, связанных с Web |
Совет: при выборе языка сценариев учитывайте среду выполнения целевого пользователя. Если сомневаетесь, Python — самый безопасный выбор.
Полный пример: навык обработки PDF
Давайте рассмотрим полный пример, показывающий, как объединить SKILL.md и сценарии:
Структура навыка
├── SKILL.md
└── scripts/
├── extract.py
├── fill_form.py
└── merge.py
Содержимое SKILL.md:
---
name: pdf-tool
description: 处理 PDF 文件,包括提取文本、填写表单、合并文件。使用场景:处理 PDF、提取文本、填写表单、合并 PDF.
---
## 提取 PDF 文本
从 PDF 文件中提取文本内容:
```bash
python scripts/extract.py input.pdf
```
输出是提取的纯文本内容。
## 填写 PDF 表单
使用 JSON 数据填写 PDF 表单:
```bash
python scripts/fill_form.py input.pdf data.json output.pdf
```
data.json 格式:
```json
{
"field_name": "字段值",
"another_field": "另一个值"
}
```
## 合并 PDF
将多个 PDF 文件合并为一个:
```bash
python scripts/merge.py output.pdf input1.pdf input2.pdf input3.pdf
```
## 依赖安装
需要安装 pdfplumber 和 PyPDF2:
```bash
pip install pdfplumber PyPDF2
```
Два режима использования
Существует два способа использования кода в Skill:
| Метод | Применимый сценарий | Нужен ли каталог scripts/ |
|---|---|---|
| Одноразовая команда | Нужно только вызвать существующие инструменты, пользовательская логика не требуется | Не требуется |
| Самодостаточный скрипт | Сложная логика, которую нужно переиспользовать | Необходимы |
Одноразовые команды
Когда существующие инструменты менеджера пакетов уже удовлетворяют требованиям, вы можете напрямую ссылаться на них в инструкциях SKILL.md, не создавая каталог scripts/.
Ниже приведены распространённые способы выполнения в каждой языковой экосистеме:
uvx(Python)
uvx — это команда для запуска инструментов, входящая в состав uv. Она запускает пакеты Python в изолированной среде, а благодаря агрессивному кэшированию повторные запуски происходят почти мгновенно.
Пример
uvx ruff@0.8.0 check .
# Запустить указанную версию black для форматирования кода
uvx black@24.10.0 .
pipx(Python)
pipx — зрелая альтернатива uvx, которую можно установить через системные менеджеры пакетов (например,brew install pipx)。
Пример
pipx run 'black==24.10.0' .
# Запустить указанную версию ruff
pipx run '[email protected]' check .
npx(Node.js)
npx поставляется с npm и скачивает и запускает npm-пакеты по требованию.
Пример
npx eslint@9 --fix .
# Создать проект с Vite
npx create-vite@6 my-app
go run(Go)
Встроенная в Go команда запуска инструментов компилирует и запускает удалённые пакеты напрямую.
Пример
go run golang.org/x/tools/cmd/goimports@v0.28.0 .
# Запустить проверку golangci-lint
go run github.com/golangci/golangci-lint/cmd/golangci-lint@v1.62.0 run
Рекомендации по написанию одноразовых команд: фиксируйте номера версий (например,
npx [email protected]) чтобы обеспечить единообразное поведение; объявляйте предварительные требования в SKILL.md (например, "Требуется Node.js 18+"); когда команды становятся сложными, выносите их в каталог scripts/.
Ссылки на скрипты в SKILL.md
Используйте пути, начинающиеся от корня каталога Skill,относительные пути, для ссылок на упакованные файлы.
Агент автоматически разрешит эти пути; нет необходимости использовать абсолютные пути.
Сначала перечислите доступные скрипты в SKILL.md:
Пример
- **`scripts/validate.sh`** — Проверка файлов конфигурации
- **`scripts/process.py`** — Обработка входных данных
- **`scripts/report.py`** — Генерация отчётов об анализе
Затем ссылайтесь на них в шагах операции:
Пример
1. Запустите скрипт проверки:
```bash
bash scripts/validate.sh "$INPUT_FILE"
```
2. Обработка данных:
```bash
python3 scripts/process.py --input results.json
```
Пути выполнения скриптов указываются относительно корневого каталога Skill, поскольку Агент запускает команды из каталога Skill. Это также относится к вспомогательным файлам, таким как references/*.md.
Самодостаточные скрипты
Когда вам нужна логика для повторного использования, вы можете упаковать скрипты вscripts/каталог и объявить зависимости внутри скрипта.
Агент может запустить его одной командой, без дополнительных шагов установки.
Самодостаточный скрипт Python (PEP 723)
PEP 723 определяет стандартный формат объявления зависимостей внутри скриптов Python.
Используйте# ///маркеры для оборачивания объявления зависимостей в формате TOML:
Пример: самодостаточный скрипт Python
# dependencies = [
# "beautifulsoup4",
# ]
# ///
from bs4 import BeautifulSoup
# Пример HTML-контента
html = '<html><body><h1>Welcome</h1><p class="info">EXAMPLE Test</p></body></html>'
# Разбор HTML с помощью BeautifulSoup
soup = BeautifulSoup(html, "html.parser")
# Извлечение текста абзаца с class="info"
info_text = soup.select_one("p.info").get_text()
print(info_text)
Как запустить:
Пример
uv run scripts/extract.py
# Запуск с pipx
pipx run scripts/extract.py
EXAMPLE 测试
Самодостаточный скрипт Deno
Deno используетnpm:иjsr:спецификаторы import для достижения самодостаточности:
Пример: Самодостаточный скрипт Deno
import * as cheerio from "npm:[email protected]";
const html = `<html><body><h1>Добро пожаловать</h1><p class="info">ПРИМЕР Тест</p></body></html>`;
const $ = cheerio.load(html);
console.log($("p.info").text());
Пример
Самодостаточный скрипт Bun
Когда у Bun нетnode_modulesкаталога, он автоматически устанавливает отсутствующие пакеты:
Пример: Самодостаточный скрипт Bun
import * as cheerio from "[email protected]";
const html = `<html><body><h1>Добро пожаловать</h1><p class="info">ПРИМЕР Тест</p></body></html>`;
const $ = cheerio.load(html);
console.log($("p.info").text());
Пример
Самодостаточный скрипт Ruby
Ruby используетbundler/inlineчтобы объявить зависимости gem в скрипте:
Пример: Самодостаточный скрипт Ruby
gemfile do
source 'https://rubygems.org'
gem 'nokogiri'
end
html = '<html><body><h1>Welcome</h1><p class="info">EXAMPLE Test</p></body></html>'
doc = Nokogiri::HTML(html)
puts doc.at_css('p.info').text
Пример
Ключевые моменты проектирования скриптов для агентов
Агент определяет свои следующие действия, читая stdout и stderr, поэтому при проектировании скрипта следует учитывать особенности использования агентом.
Избегайте интерактивных запросов
Это жёсткое требование. Агент работает в неинтерактивной оболочке и не может отвечать на TTY-приглашения, диалоги ввода пароля или меню подтверждения.
Все входные данные должны передаваться через аргументы командной строки, переменные окружения или stdin.
Пример: неправильный подход в сравнении с правильным подходом
$ python scripts/deploy.py
Целевая среда: _
# Правильно: понятное сообщение об ошибке и указания
$ python scripts/deploy.py
Ошибка: --env обязателен. Варианты: development, staging, production.
Использование: python scripts/deploy.py --env staging --tag v1.2.3
Предоставьте документацию --help
--helpВывод — основной способ для Агента понять интерфейс скрипта.
Включите краткое описание, доступные параметры и примеры использования:
Пример: хороший вывод --help
Обработать входные данные и сформировать сводный отчёт.
Параметры:
--formatFORMAT Формат вывода: json, csv, table(По умолчанию: json)
--outputFILE Записывать вывод в файл вместо stdout
--verboseВыводить информацию о ходе выполнения в stderr
Примеры:
scripts/process.py data.csv
scripts/process.py --format csv --output report.csv data.csv
Пишите полезные сообщения об ошибках
Когда Агент видит сообщение об ошибке, он соответствующим образом корректирует свою стратегию; чем конкретнее сообщение, тем легче Агенту самостоятельно исправиться.
Пример
Ошибка: неверный ввод
# Хорошее сообщение об ошибке
Ошибка: --format должен быть одним из: json, csv, table.
Получено: "xml"
Используйте структурированный вывод
Предпочитайте структурированные форматы, такие как JSON, CSV и TSV, для вывода, а не произвольный текст.
Структурированные форматы могут обрабатываться как Агентом, так и стандартными инструментами (jq, cut, awk), что упрощает их комбинирование.
Пример
ИМЯ СТАТУС СОЗДАНО
my-service работает 2025-01-15
# Рекомендуется: формат JSON с чёткими границами полей
{"name": "my-service", "status": "running", "created": "2025-01-15"}
Выводите структурированные данные в stdout, а сообщения о ходе выполнения и диагностическую информацию — в stderr. Так Агент получает чистый, легко разбираемый вывод и при необходимости может просматривать диагностическую информацию.
Дополнительные рекомендации по проектированию скриптов
| Рекомендация | Описание |
|---|---|
| Идемпотентность | Агент может повторять команды. "Создавать, если не существует" безопаснее, чем "создавать и выдавать ошибку при дубликатах" |
| Ограничения входных данных | Отклоняйте неоднозначный ввод с понятной ошибкой, а не пытайтесь угадать намерение пользователя |
| Поддержка пробного запуска | Для деструктивных или изменяющих состояние операций предусмотрите--dry-runфлаг, позволяющий Агенту предварительно просмотреть операцию |
| Осмысленные коды выхода | Используйте разные коды выхода для разных типов сбоев (не найдено, неверный аргумент, ошибка аутентификации и т. д.) |
| Предсказуемый размер вывода | По умолчанию выводите сводку и предоставьте--offsetдругие параметры, чтобы Агент мог при необходимости получить больше информации. |
| Безопасные значения по умолчанию | Деструктивные операции должны требовать явный флаг подтверждения (--confirm、--force) |
Полный пример скрипта навыка
Ниже приведена полная структура каталога навыка со скриптами:
Пример
├── SKILL.md # Основной файл инструкций
├── scripts/
│ ├── overview.py # Скрипт обзора данных
│ ├── summary.py # Скрипт статистической сводки
│ └── validate.py # Скрипт проверки данных
├── references/
│ └── api-errors.md # Справочник по ошибкам API
└── assets/
└── report-template.md # Шаблон отчёта
Соответствующее содержимое SKILL.md:
Пример
name: csv-analyzer
description: >
Анализируйте файлы CSV и табличные данные. Когда у пользователя есть файлы CSV, TSV или Excel
и он хочет исследовать, преобразовывать или визуализировать данные, используйте это.
---
# Анализ данных CSV
## Доступные скрипты
- **`scripts/overview.py`** — Отображает обзор данных (количество строк, имена столбцов, типы)
- **`scripts/summary.py`** — Генерирует статистическую сводку
- **`scripts/validate.py`** — Проверяет качество данных
## Рабочий процесс
1. Сначала запустите скрипт overview, чтобы понять структуру данных:
```bash
uv run scripts/overview.py input.csv
```
2. Сгенерируйте статистическую сводку:
```bash
uv run scripts/summary.py input.csv --output summary.json
```
3. Проверьте качество данных:
```bash
uv run scripts/validate.py input.csv
```
## Примечания
- Для больших файлов используйте параметр `--chunk-size` для обработки по частям
- Для китайских CSV-файлов попробуйте параметр `--encoding gbk`
Распространение скриптов и зависимости
Если вашим скриптам нужны внешние зависимости, у вас есть несколько вариантов:
1. Документируйте зависимости в SKILL.md
Самый простой способ — записать необходимые зависимости в SKILL.md.
2. Используйте виртуальные окружения
Для сложных проектов можно создать виртуальное окружение.
3. Используйте Docker
Если требуется полноценная среда выполнения, можно использовать контейнер Docker.
Примечание: убедитесь, что скрипты могут запускаться в целевой среде. Прежде чем писать скрипты, разберитесь в среде выполнения целевого пользователя.
Итог
В этом разделе мы узнали, как использовать скрипты для расширения функциональности Skill:
- Поместите скрипты в каталог scripts/
- Скрипты должны быть самодостаточными и иметь чёткую обработку ошибок
- Используйте относительные пути при ссылке на скрипты в SKILL.md
- Убедитесь, что скрипты могут запускаться в целевой среде