5. Инструменты — вычисления и действия
🔵 Движки, которые что-то исполняют: скрипты, shell-команды, субагенты, воркфлоу, а также доставка результата (email, файлы). Сводную таблицу всех движков см. в «Справочник инструментов».
5.10 script_tool
Скрипт Rhai или JavaScript.
kind: script_tool
name: currency
description: Конвертация валют.
script: currency.rhai # .rhai → Rhai, .js → JavaScript (QuickJS)
parameters: { ... }
max_operations: 10000000
Скрипт определяет fn run(args) (Rhai) или function run(args) (JS). Полный
справочник — 07-scripts.
5.14 subagent_tool
Делегировать задачу субагенту. Спавнит дочерний агент-процесс, отдаёт задачу, ждёт завершения и возвращает его итоговый ответ. Траты дочернего списываются на сессию родителя (наследует группу бюджета), после — очистка.
kind: subagent_tool
name: delegate_research
description: Делегировать исследование субагенту.
template: trace-agent # или inline instructions + tools:
# instructions: "You are a research assistant."
# tools: [http_fetch, fs_read]
# budget: { max_per_turn: 2000, max_per_minute: 20000, max_total: 20000 }
| Поле | Описание |
|---|---|
template |
шаблон для делегирования (приоритетнее instructions) |
instructions |
inline-инструкции без шаблона |
tools |
имена инструментов субагента (перекрывает шаблон) |
budget |
лимит токенов { max_per_turn, max_per_minute, max_total } |
output_schema |
JSON Schema структурированного результата (субагент завершается job_done; проверенный payload — в data) |
Рантайм-аргументы: task (обязателен), опциональные template/instructions.
5.16 email_tool
Отправить письмо (SMTP).
kind: email_tool
name: send_report
description: Отправить отчёт оператору.
smtp:
host: smtp.example.com
username: agent@example.com
password_env: SMTP_PASSWORD # или password: "..."
from: agent@example.com
tls: starttls # starttls (по умолч., 587) | ssl (465) | none (25)
port: 587
to: ops@example.com
subject: "Agent report"
| Поле | Описание |
|---|---|
smtp.host / username / from |
сервер, логин, From (обязательны) |
smtp.password / password_env |
пароль inline или имя env |
smtp.tls |
starttls (по умолч.) | ssl | none |
to / subject |
дефолты, перекрываемые аргументами |
Аргументы: body (обязателен), опциональные to / subject.
5.17 vk_tool
Вызов VK API от имени сообщества (group access token) — универсальный шлюз плюс удобные действия для типовых бизнес-задач.
kind: vk_tool
name: vk_api
description: Вызвать VK API от имени сообщества.
token_env: VK_GROUP_TOKEN # env с group access token (по умолч. VK_GROUP_TOKEN)
service_token_env: VK_SERVICE_TOKEN # env с сервисным ключом (по умолч. VK_SERVICE_TOKEN)
api_version: "5.199" # версия API (по умолч. "5.199")
owner_id: -123456789 # дефолтный владелец (для wall_post)
| Поле | Описание |
|---|---|
token_env |
имя env с токеном сообщества (групповые действия: send_message, wall_post, generic-шлюз) |
service_token_env |
имя env с сервисным ключом — для поисковых/читающих методов (search), недоступных групповым токенам |
api_version |
версия VK API (по умолч. 5.199) |
owner_id |
дефолтный владелец для wall_post (отрицательный = группа) |
Два режима вызова. Generic-шлюз — любой метод VK API:
{ "method": "wall.get", "params": { "owner_id": -123456789, "count": 5 } }
Удобные действия (внутри движок сам подставляет обязательный random_id
и параметры по умолчанию):
{ "action": "wall_post", "message": "Новый пост от агента" }
{ "action": "send_message", "peer_id": 123, "message": "Привет" }
{ "action": "search", "q": "бренд", "count": 10 }
| Действие | VK-метод | Токен | Что делает |
|---|---|---|---|
send_message |
messages.send |
групповой | сообщение в диалог (peer_id, message, опц. attachment) |
wall_post |
wall.post |
групповой | пост на стену (owner_id, message, опц. attachments) |
search |
newsfeed.search |
сервисный | поиск записей/упоминаний (q, count) |
Результат: content — pretty-JSON ответа, data — распарсенный response
(для композиции с visualize_tool). Групповой токен нужен с правами messages,
wall, photos, docs, market, groups. Читающие/поисковые методы
(newsfeed.search, wall.get, groups.search) недоступны групповым
токенам — для них нужен сервисный ключ (service_token_env).
5.18 shell_tool
Запустить команду CLI. Универсальный запуск внешней программы: команда, флаги,
рабочая папка и окружение фиксируются в YAML автором агента; LLM лишь
подставляет значения в input. В отличие от произвольного fs_read, LLM не
выбирает команду — он выбирает только аргументы по заданной JSON Schema.
kind: shell_tool
name: git_log
description: Показать последние коммиты репозитория.
command: git
args: ["log", "--oneline", "-n", "{{ input.limit | default(10) }}"]
cwd: /srv/agent-os # рабочая папка (по умолч. — папка сервера)
env:
GIT_PAGER: "cat" # доп. переменные окружения
stdin: "{{ input.text }}" # текст в stdin (опционально)
timeout_secs: 30 # жёсткий таймаут (по умолч. 30)
capture: both # stdout | stderr | both (по умолч.)
parse_json: false # распарсить stdout как JSON в data.parsed
parameters: { ... } # JSON Schema входа агента
| Поле | Обязат. | Описание |
|---|---|---|
kind |
да | shell_tool |
name |
да | имя для LLM |
description |
нет | описание для LLM |
command |
да | программа (шаблон MiniJinja над input) |
args |
нет | список аргументов (каждый — шаблон) |
cwd |
нет | рабочая папка (шаблон) |
env |
нет | доп. переменные окружения (значения — шаблоны) |
stdin |
нет | текст, подаваемый в stdin (шаблон) |
timeout_secs |
нет | таймаут (по умолч. 30) |
capture |
нет | какие потоки вернуть: stdout | stderr | both |
parse_json |
нет | распарсить stdout как JSON в data.parsed |
Команда наследует окружение сервера + env, выполняется с лимитом по времени.
Результат: content — захваченный вывод, success — нулевой код выхода,
data — { exit_code, stdout, stderr, parsed? }.
Все строковые поля — шаблоны MiniJinja над input. Если на сервере задан
logging.temp_dir, в шаблонах доступна переменная {{ temp_dir }} — scratch-
каталог текущей сессии, куда можно нагенерировать файл (см.
file_tool с источником temp).
5.19 workflow_tool
Запустить воркфлоу.
kind: workflow_tool
name: run_triage
description: Запустить воркфлоу триажа.
workflow: triage # имя воркфлоу по умолчанию
Запускает воркфлоу и возвращает его run id. Имя воркфлоу можно перекрыть
аргументом workflow; input — входной payload. Требует, чтобы в ядре был
подключён WorkflowService (делается при старте сервера). См.
12-workflows.
5.20 file_tool
Отправить файл пользователю. Отправляет пользователю файл (отчёт, документ,
экспорт данных) в виде скачиваемого блока file. Агент обычно не имеет
доступа к файловой системе, поэтому содержимое берётся из одного из источников:
kind: file_tool
name: send_file
description: Отправить файл пользователю.
max_bytes: 10485760 # макс. размер файла в байтах (по умолч. 10 МиБ)
| Аргумент | Описание |
|---|---|
name |
имя файла для скачивания (обязательно), напр. report.html |
mime |
MIME-тип (необязательно; выводится из расширения name) |
content |
содержимое строкой (markdown / HTML / CSV / JSON…) |
data |
любой JSON — сериализуется в файл (pretty JSON) |
path |
прочитать байты из локального файла (если агент может писать файлы) |
temp |
{ name } — прочитать файл, который другой инструмент записал в scratch-каталог сессии |
state |
{ key, scope?, path? } — значение из state store (БД). scope: session/user/agent (по умолч. резолв user → session → agent); path — точечный путь внутрь значения |
source |
{ tool, index, field, path } — результат другого инструмента в этой сессии. field: content (по умолч.)/data/visual; index: 0 = последний |
Источник выбирается по приоритету content → data → path → temp →
state → source. Пример отчёта, собранного из результата предыдущего
инструмента:
# вызвать: send_file { "name": "report.csv", "source": { "tool": "build_report" } }
LLM видит только компактную сводку в content; сами байты (base64) едут в
visual и доходят до веб-виджета (ссылка скачивания), Android и Telegram
(документ).
Временное хранилище (scratch) сессии
Если в конфигурации задан logging.temp_dir, ядро выделяет каждой сессии
scratch-каталог <temp_dir>/<session_id>/. Инструмент-генератор (например,
shell_tool, запускающий офисный CLI) пишет файл туда через
{{ temp_dir }}, а file_tool забирает его по имени:
# shell_tool: нагенерить .xlsx в scratch сессии
kind: shell_tool
name: export_xlsx
description: Сгенерировать отчёт в Excel.
command: libreoffice
args: ["--headless", "--convert-to", "xlsx", "--outdir", "{{ temp_dir }}", "{{ input.docx }}"]
# вызвать: send_file { "name": "report.xlsx", "temp": { "name": "report.xlsx" } }
Каталог удаляется при закрытии/истечении сессии.
5.21 office_tool
Движок-обёртка над OfficeCLI (один
самодостаточный бинарь, MS Office не нужен). При первом использовании бинарь
скачивается автоматически в data/officecli/ и проверяется по SHA-256;
далее он кешируется. Готовый файл пишется в scratch сессии и возвращается
блоком file (как у file_tool) — внешние shell_tool-обёртки не нужны.
kind: office_tool
name: make_docx
description: Собрать Word-документ из Markdown.
operation: create # create | fill | extract | convert | edit | merge
format: docx # docx | xlsx | pptx (для create/merge)
# template: templates/contract.docx # для fill: путь к шаблону (отн. YAML)
# binary: /path/to/officecli # опц. явный путь к бинарю
# download_url: "https://..." # опц. переопределение
# sha256: "..." # опц. (пусто = не проверять)
# auto_download: true # по умолч. true
# pdf_bin: soffice # fallback для PDF (если нет плагина)
# pdf_exporter: /path/to/officecli_pdf_exporter # опц. явный путь к плагину
# timeout_secs: 120 # таймаут одной команды
Операции
operation |
Что делает | Аргументы |
|---|---|---|
create |
собрать документ с нуля | name + content (docx, Markdown) / rows+columns или csv (xlsx) / slides (pptx) |
fill |
заполнить шаблон с плейсхолдерами {{key}} |
name + data (объект) или rows (массив → mail merge, результат — zip) |
extract |
прочитать документ текстом/CSV для LLM | temp/path + опц. mode (text/outline/annotated/issues/csv) |
convert |
экспорт в HTML/SVG/PDF | name (.html/.svg/.pdf) + temp/path |
edit |
применить правки set/add/remove/replace |
name + temp/path + ops: [{ action, path, type?, props?, find?, replace? }] |
merge |
объединить несколько документов в один | name + `files: [{ temp |
Плейсхолдеры шаблонов (fill)
В шаблоне используются двойные фигурные скобки {{key}} — в абзацах, таблицах,
колонтитулах и заголовках графиков. Заполнение — это officecli merge:
# вызвать: fill_contract { "name": "dogovor.docx", "data": { "client": "ООО Ромашка", "sum": "150000" } }
# вызвать (mail merge): fill_contract { "name": "dogovor.docx", "rows": [ {...}, {...} ] }
# → вернёт dogovor.zip с N заполненными файлами
Шаблон .docx с плейсхолдерами можно получить самому из Markdown:
make_docx → contract.md с текстом вида {{client}}.
Редактирование (edit)
edit копирует входной документ в выходной и применяет список правок (исходник
не меняется). Каждая правка — { action, path, ... }:
# вызвать: edit_doc { "name": "edited.docx", "temp": { "name": "in.docx" },
# "ops": [
# { "action": "replace", "path": "/body", "find": "ООО Старое", "replace": "ООО Новое" },
# { "action": "set", "path": "/body/p[1]/r[1]", "props": { "bold": true } },
# { "action": "add", "path": "/body", "type": "paragraph", "props": { "text": "Новый абзац" } },
# { "action": "remove", "path": "/body/p[3]" }
# ] }
Действия: set (свойства по --prop), add (элемент --type), remove,
replace (поиск/замена текста через --find/--replace). path — адрес
элемента OfficeCLI (/body/p[1], /Sheet1/A1, /slide[1]/shape[1], …).
Примеры (полный набор)
Готовый агент-«секретарь» лежит в config/agents/office/ — там же все эти
инструменты и шаблон договора templates/contract.docx. Ниже — выдержки.
1. create — документ с нуля
# tools/make_docx.yaml
kind: office_tool
name: make_docx
description: Собрать Word из Markdown.
operation: create
format: docx
// вызов: { "name": "report.docx", "content": "# Отчёт\n\nТекст..." }
# tools/make_xlsx.yaml
kind: office_tool
name: make_xlsx
description: Собрать Excel из таблицы.
operation: create
format: xlsx
// вызов: { "name": "price.xlsx", "columns": ["Name","Price"], "rows": [["Apple",3],["Banana",5]] }
2. fill — шаблон с {{key}} + mail merge
# tools/fill_contract.yaml
kind: office_tool
name: fill_contract
description: Заполнить договор данными.
operation: fill
format: docx
template: ../templates/contract.docx # путь отн. этого YAML
// один документ: { "name": "dogovor.docx", "data": { "client": "ООО Ромашка", "sum": "150000" } }
// mail merge: { "name": "dogovor.docx", "rows": [ { "client": "A" }, { "client": "B" } ] }
// → вернёт dogovor.zip с N заполненными файлами
3. extract — чтение (текст или CSV)
kind: office_tool
name: extract_text
description: Прочитать документ текстом.
operation: extract
// { "temp": { "name": "dogovor.docx" } } → текст
// { "temp": { "name": "price.xlsx" }, "mode": "csv" } → CSV
4. convert — HTML / SVG / PDF
kind: office_tool
name: convert_pdf
description: Экспорт в PDF.
operation: convert
// { "name": "out.html", "temp": { "name": "in.docx" } }
// { "name": "out.pdf", "temp": { "name": "in.docx" } } // плагин + headless Chromium
5. edit — точечные правки
kind: office_tool
name: edit_doc
description: Внести правки в документ.
operation: edit
// { "name": "out.docx", "temp": { "name": "in.docx" }, "ops": [
// { "action": "replace", "path": "/body", "find": "старое", "replace": "новое" } ] }
6. merge — объединить документы
kind: office_tool
name: merge_docs
description: Объединить документы в один.
operation: merge
format: docx # docx — склейка текста; xlsx — конкатенация строк
// { "name": "all.docx", "files": [ { "temp": { "name": "a.docx" } }, { "temp": { "name": "b.docx" } } ] }
Форматы и ограничения
createподдерживаетdocx(из Markdown),xlsx(из строк/CSV) иpptx(изslides: [{ title, bullets[] }]).convertдаётhtml,svgиpdf. Дляpdfдвижок использует экспортер-плагин (officecli_pdf_exporter) — отдельный бинарь, который OfficeCLI находит черезOFFICECLI_PLUGIN_EXPORTER_PDF. Плагин рендерит документ в HTML движком OfficeCLI, а затем печатает его в PDF headless Chromium-браузером. Если браузера нет, он скачивается автоматически (chrome-headless-shellиз Chrome for Testing) в~/.cache/agent-os/browser(Linux) /%LOCALAPPDATA%\agent-os\browser(Windows). Работает headless на Linux-сервере.- Если плагина нет,
convert pdfоткатывается наsoffice(LibreOffice) — путь к бинарю задаётся полемpdf_bin. - Сам OfficeCLI скачивается при первом вызове: нужен доступ к GitHub Releases
(или задайте
download_url/binary).