Tool Parameter Fidelity

Модель должна знать, над какими данными инструмент действительно выполнил действие. Если adapter молча нормализует, обрезает, декодирует или дописывает аргументы, агент действует в мире, отличающемся от наблюдаемого, и не может диагностировать повторяемый отказ.

Инвариант

Полезно различать три объекта:

proposed_args   — что выдала модель
effective_args  — что после валидации реально получил обработчик
observed_result — что вернулось модели и в audit log

Идеальный путь сохраняет proposed_args == effective_args. Если это невозможно, преобразование становится частью явного контракта: runtime сообщает, что изменил, почему и какое значение исполнил. Молчаливое расхождение запрещено.

Это относится не только ко входу. Результат тоже нельзя незаметно урезать, переформатировать или подменять успешной заглушкой: агент должен отличать полный вывод, bounded preview, сохранённый внешний артефакт и отказ (Bounded Tool Output, Unknown Not A Value).

Где теряется точность

Слой Типичный сдвиг
сериализация escaping, Unicode normalization, перевод реальных newline в литералы или обратно
schema adapter неявное coercion строки в число, удаление неизвестных полей, подстановка default
policy gateway переписывание пути, команды или target; добавление scope/tenant/флага
SDK / shell wrapper дополнительное quoting, environment expansion, скрытые CLI-аргументы
tool implementation нормализация регистра, пробелов, кавычек или кодировки
result adapter truncation, redaction или «починка» ошибки без маркировки

Особенно разрушителен exact-match интерфейс. Модель читает строку с типографскими кавычками, передаёт её как old_string, adapter меняет кавычки, а инструмент закономерно отвечает no match. Повторное чтение снова показывает исходную строку, поэтому модель не может увидеть слой, где возникло расхождение, и зацикливается.

Не всякое преобразование запрещено

Нормализация и добавленные runtime-поля иногда необходимы. Запрещена не трансформация, а её невидимость и смешение владельцев.

  • Проверка типов и отказ предпочтительнее «догадливого» coercion.
  • actor_id, tenant_id, permission scope и idempotency key задаёт доверенный runtime, а не модель. Они хранятся отдельным policy_context, не маскируются под предложенные ею аргументы (Tool Gateway).
  • Канонизация пути или Unicode допустима, если schema обещает её, ответ показывает effective value, а destructive operation требует проверки результата.
  • Redaction секрета показывается как redaction, а не как исходное значение; в аудите можно хранить хэш или ссылку на защищённый payload.
  • Автоматический retry не вправе менять смысл аргументов. Если стратегия изменилась, это новый вызов с отдельной записью.

Пример ответа адаптера:

{
  "status": "executed_with_transformations",
  "proposed_args_hash": "sha256:…",
  "effective_args": {"path": "/workspace/a.txt", "encoding": "utf-8"},
  "transformations": [
    {"field": "path", "kind": "workspace_resolution", "from": "a.txt", "to": "/workspace/a.txt"}
  ],
  "result": {"bytes_written": 418}
}

Для опасного изменения безопаснее вернуть needs_confirmation с preview effective arguments и исполнить только после подтверждения, чем сначала переписать запрос, а потом объяснять результат.

Как тестировать adapter

  1. Round-trip corpus: пробелы, реальные newline, обратные слеши, кавычки, combining Unicode, emoji, null, нулевой байт и длинные значения проходят весь путь model-shaped JSON → handler.
  2. Differential test: прямой вызов обработчика и вызов через каждый adapter получают одинаковые effective arguments либо ожидаемый, описанный diff.
  3. Unknown-field test: лишнее поле отклоняется явно, а не исчезает.
  4. Default test: каждый подставленный default присутствует в effective arguments и tool result.
  5. Mutation test: намеренное скрытое преобразование должно ломать контрактный тест.
  6. Read-after-write: для записи проверяется фактическое состояние внешней системы, а не только success от wrapper.
  7. Trace localization: сохраняются хэши или безопасные представления на границах model output → parser → gateway → handler, чтобы найти первый diverging layer (Trajectory Prefix Evals).

Ведущая метрика — не доля валидного JSON, а semantic argument fidelity: совпало ли исполненное намерение с тем, которое видел и подтвердил агент. Для exact-copy инструментов добавляются byte/code-point exact match и позиция первого расхождения.

Наблюдаемость без утечки

Полный raw payload нельзя безусловно писать в обычный лог: там могут быть токены, PII и содержимое файлов. Audit record хранит:

  • версию schema и adapter;
  • хэш исходных аргументов;
  • redacted effective arguments;
  • список преобразований и их причины;
  • policy context отдельно от model-proposed fields;
  • идентификатор защищённого полного payload при необходимости расследования;
  • фактический результат или явный отказ.

Так сохраняется возможность найти слой порчи, но observability не превращается в канал утечки.

Границы

  • Fidelity не означает «исполнять всё буквально»: политика безопасности может и должна отклонить запрос.
  • Прозрачность преобразования не делает его правильным — schema и policy всё равно требуют ревью.
  • Read-after-write обнаруживает расхождение после действия, но не предотвращает необратимый вред; для него нужен preview и confirmation.
  • Книжные примеры про конкретные IDE не подтверждены независимым issue или changelog; переносится класс отказа, а не обвинение продукта.

Связано с

  • Tool Calling — общий цикл от JSON-запроса до результата
  • Tool Gateway — проверка и policy context до побочного эффекта
  • Agent Failure Modes — повторяемый отказ без видимой для модели причины
  • Agent Audit Log — границы, на которых сохраняется provenance вызова
  • Trajectory Prefix Evals — локализация первого слоя, где значение разошлось