При подтверждении агентного действия путь выглядел иначе, чем в API
Агент просит подтвердить запись файла. В карточке виден путь, похожий на reports/final.txt, и оператор нажимает «Разрешить». Инструмент получает строку с невидимыми управляющими символами Unicode; визуальный порядок части имени не совпадает с порядком кодовых точек. Если approval показывает только отрисованный текст, человек может согласовать не тот аргумент, который уйдёт в файловый API.
Отрисовка и значение строки расходятся
Алгоритм двунаправленного текста Unicode использует управляющие символы для порядка отображения. Например, U+202E — right-to-left override, а U+202C завершает такое форматирование. Есть и изоляты U+2066–U+2069. Эти символы могут быть допустимы в многоязычном тексте. Но для путей, URL, адресов получателя и имён ресурсов приложение должно показывать человеку фактическую строку, а не полагаться лишь на её визуальный вид.
Критичная граница — между отображением карточки и вызовом инструмента. Сохраните неизменённый объект аргументов после валидации; сформируйте из него approval и при согласии вызовите инструмент с тем же объектом. Не разрешайте модели пересчитать или заменить аргументы после одобрения. Если строка содержит bidi-controls, UI показывает предупреждение и вторую форму: escaped-представление с кодовыми точками, например \u202E. Оператор должен видеть и читаемый текст, и точное значение, которое будет отправлено.
Правило зависит от поля
Для машинных путей и доменов обычно проще запретить bidi-controls в аргументе и попросить агента построить новый безопасный путь. Для пользовательского описания заявки запрет может повредить законный арабский или иврит. Поэтому проверка привязывается к схеме инструмента: file_path и recipient проходят строгую нормализацию/allowlist, свободный comment отображается с безопасной изоляцией, но не становится командой. Unicode-нормализация вроде NFC сама по себе не удаляет управляющие символы направления.
Тестируйте на двух строках с одинаково выглядящей карточкой: обычный путь и путь с U+202E перед частью имени. В журнале проверки выведите список кодовых точек; в UI обе карточки должны быть различимы. После отказа инструмент не вызывается. После согласия журнал вызова должен содержать тот же хеш канонических аргументов, который был на карточке. Если клиент преобразует строку при сериализации, проверку выполняют на финальном значении непосредственно перед вызовом.
Хешируйте сериализованные аргументы с фиксированным порядком ключей и тем же кодированием, которое использует вызов инструмента. Иначе два эквивалентных JSON-объекта дадут разные хеши только из-за порядка полей. В карточке показывайте не только красивое имя файла, но и базовый каталог, действие (read, write, delete) и итоговый разрешённый путь после нормализации. Для URL дополнительно показывайте фактический host после разбора URL-парсером. Человек подтверждает ресурс и действие, а не загадочную строку вне контекста.
В платном курсе LLM Security PRO: Prompt Injection, утечки, tool-abuse вы проектируете ограничения полномочий, подтверждения действий и валидацию аргументов. Этот случай полезен для red-team suite: модель предлагает правдоподобное действие, а тест проверяет, совпадает ли согласованный аргумент с фактическим. Откройте программу курса, чтобы собрать такие проверки в агентном сервисе.
Продолжить на практике
- LLM Security PRO: Prompt Injection, утечки, tool-abuse ↗
Практический курс по LLM Security. Запустите локальный RAG/агента на реальном LLM (OpenAI API) и укрепите прод: защита от prompt/indirect injection, утечек и tool-abuse, строгий JSON-вывод (Schema/Pydantic), redaction и лимиты стоимости/циклов. Плюс профессиональные блоки: OWASP LLM Top-10, threat modeling, red-team suite и security-gates в CI/CD.
