Skip to content

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 вообще разрешены.

ToolCapabilityRiskGate
read_fileЧитать workspace fileslowразрешён в sandbox
write_fileИзменять workspace filesmediumpath policy
run_testsЗапускать local checksmediumcommand prefix policy
send_emailВнешний side effecthighhuman approval
deploySide effect в productionhighhuman 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.

Что сделать руками

  1. Откройте examples/yolo-runner-lite/policies/local-dev.json.
  2. Добавьте в task фальшивый blocked check, например ["curl", "https://example.com"].
  3. Запустите harness.
  4. Убедитесь, что result — blocked, а не failed.
  5. Найдите policy_check в JSONL log.

На что не соглашаться

  • Считать доступ к MCP server автоматически безопасным.
  • Кодировать policy только в natural-language prompt.
  • Логировать tool output, но не policy decision.
  • Блокировать dangerous tools, не давая агенту safe alternative.

Agentic Engineering: Context Engineering + Harness Engineering