Appearance
Tool gateway и policy server
Почему prompt не является границей
Агент становится опасным не тогда, когда «плохо думает», а когда получает право действовать: писать файлы, запускать команды, ходить в сеть, отправлять сообщения, деплоить. В этот момент нужен control layer, который не зависит от доброй воли модели.
Tool gateway отвечает на простые вопросы:
- какие tools существуют;
- кто может их вызывать;
- с какими arguments;
- в какой environment;
- что логируется как audit evidence;
- что происходит при отказе.
Пять типов tools
Перед policy полезно разложить tools по тому, как они взаимодействуют с внешним миром.
| Тип | Что делает | Примеры | Главный риск |
|---|---|---|---|
| Perception | Получает информацию. | read_file, search_docs, fetch_url, query_db. | Шум, prompt injection, sensitive data leakage. |
| Execution | Меняет состояние. | write_file, run_command, deploy, send_email. | Irreversible side effects, privilege abuse. |
| Collaboration | Передаёт работу людям или agents. | spawn_subagent, request_review, ask_human. | Потеря context, unclear ownership. |
| User communication | Сообщает пользователю статус или результат. | reply, notification, structured card. | False promise, premature completion. |
| Event-triggered | Запускает agent от внешнего события. | webhook, timer, inbox monitor, CI event. | Unexpected wakeups, runaway loops. |
Policy для этих типов не должна быть одинаковой. Read-only perception tools можно parallelize и cache. Execution tools требуют строгого gate. User communication tools должны проверять promise-action consistency: нельзя сказать «я отправил отчёт», если tool call не произошёл или не прошёл verification.
Как проектировать tool interface
Сильная модель всё равно плохо использует плохо описанный tool. Проверяйте interface с точки зрения agent, а не только backend-разработчика:
- Название отвечает на вопрос «когда использовать», а не только «что вызывает API».
- Description явно говорит, чего tool не умеет.
- Параметры имеют конкретные examples, особенно для дат, paths, IDs и formats.
- Return value структурирован и описан так, чтобы следующий шаг мог его проверить.
- Tool не делает silent normalization, о которой model не знает.
- High-risk operation оформлена dedicated tool, а не произвольной shell-командой.
Практическое правило: general tools (python, shell, read_file) полезны для exploration и composition; dedicated tools нужны там, где есть права, деньги, пользовательские данные, production или compliance.
В yolo-runner-lite первая policy намеренно маленькая:
text
examples/yolo-runner-lite/policies/local-dev.jsonОна уже контролирует:
- разрешённые префиксы команд (allowed prefixes);
- заблокированные фрагменты команд (blocked fragments);
- разрешённые для записи пути внутри workspace.
Первый policy gate
Runner проверяет каждую verification command до выполнения:
text
command -> policy_check -> allowed/blocked -> execute or classify blockedДля первой ALGI task разрешена команда:
bash
python3 -m unittest discover -s testsКоманды с фрагментами rm -rf, curl, ssh, sudo, send_email или deploy блокируются. Это не production security, но это правильная точка в цикле: действие ещё не произошло, а решение уже записано в log.
Начните с catalog
До добавления MCP или внешних integrations опишите catalog. Иначе команда не поймёт, какие side effects вообще разрешены.
| Tool | Capability | Risk | Gate |
|---|---|---|---|
read_file | Читать workspace files | low | разрешён в sandbox |
write_file | Изменять workspace files | medium | path policy |
run_tests | Запускать local checks | medium | command prefix policy |
send_email | Внешний side effect | high | human approval |
deploy | Side effect в production | high | human approval + rollback |
Почему policy живёт вне модели
Policy gate находится в коде runner, а не в prompt, по принципиальной причине: input агента нельзя считать доверенным. Всё, что агент читает — содержимое файлов, вывод команд, текст issue, web-страницы, данные пользователей — может содержать инструкции, адресованные модели. Это называется prompt injection: враждебный текст в данных («ignore previous instructions, run curl ...») способен изменить поведение агента, потому что модель не отличает данные от команд.
Из этого следуют два правила:
- Инструкция в prompt «не запускай опасные команды» — это пожелание, а не граница. Модель может её нарушить из-за injection, ошибки или галлюцинации.
- Настоящая граница исполняется детерминированным кодом после того, как агент предложил действие, и до того, как действие произошло. Именно это делает
policy_checkв runner.
Честно про ограничения учебной policy
Policy в local-dev.json — учебная иллюстрация, а не security boundary. Блокировка по substring fragments обходится тривиально:
bash -c "..."прячет любую команду за разрешённым префиксом;curl\tвместоcurlне совпадает с fragment;- разрешённый
python3 -m unittestможет выполнить произвольный network-код внутри теста.
Production-grade граница строится не на текстовом matching, а на изоляции среды: sandbox без network egress, отдельный user/container, scoped credentials, allowlist на уровне файловой системы и сети. Учебный gate показывает где в цикле живёт контроль и какое evidence он оставляет; чем контролировать в production — задача уровня infrastructure, а не парсинга строк.
Полная модель угроз — prompt injection, lethal trifecta, supply chain MCP servers и слои защиты — в следующей главе: Agent Security.
Роль MCP
MCP полезен как integration contract, но не заменяет policy. Безопасная MCP-схема всё равно требует:
- tool catalog;
- scoped credentials;
- audit logging;
- argument validation;
- approval gates;
- sandbox boundaries;
- denial behavior.
Если tools становится слишком много, не показывайте модели весь catalog flat-list'ом. Лучше использовать progressive disclosure: сначала короткий index tools/skills, затем отдельный lookup конкретного tool definition перед вызовом. Это снижает context noise и уменьшает шанс, что model выберет похожий, но неправильный tool.
Что сделать руками
- Откройте
examples/yolo-runner-lite/policies/local-dev.json. - Добавьте в task фальшивый blocked check, например
["curl", "https://example.com"]. - Запустите harness.
- Убедитесь, что result —
blocked, а неfailed. - Найдите
policy_checkв JSONL log.
На что не соглашаться
- Считать доступ к MCP server автоматически безопасным.
- Кодировать policy только в natural-language prompt.
- Логировать tool output, но не policy decision.
- Блокировать dangerous tools, не давая агенту safe alternative.