Результаты инструментов AI: что значит пусто
Результаты инструментов AI должны отличать пустые данные от ошибки чтения. Тест Norman показывает, почему все страницы ещё не доказывают единый снимок данных.
- Категория
- Общее
- Обновлено
- Автор
- Stan Kharlap
Агент проверяет набор записей и сообщает: «Ничего не отсутствует». Звучит скромно. На деле это сильное утверждение: нужные записи прочитаны, проверка охватила заданную область, а собранные данные подтверждают отсутствие проблемы.
Я хочу, чтобы это утверждение было обосновано ещё до того, как модель сформулирует ответ. Пустой список, прерванное чтение и недоступный источник не могут означать одно и то же. Даже чтение всех страниц даёт более слабую гарантию, чем чтение единого согласованного снимка данных.
Это важно сейчас, когда агенты берут на себя проверки. В анонсе FloQast от 16 сентября есть проверка бухгалтерских записей с помощью AI и поиск аномальных транзакций. Workiva представила Agent Studio и автоматизацию аудиторских тестов 15 сентября. Это описания возможностей от поставщиков, а не независимые измерения качества. Они делают практическим вопрос: какие доказательства позволяют агенту сказать, что проверка ничего не нашла?
Почему пустому результату инструмента нужны доказательства?
«Проблем не найдено» и «проверить наличие проблем не удалось» в небрежной интеграции могут превратиться в одинаковый пустой массив. Обработчик таймаута возвращает значение по умолчанию, функция подсчитывает элементы, ассистент пишет уверенный ответ. Арифметика в конце может быть правильной, хотя оснований для вывода нет.
Ошибка возникает до генерации текста. Когда недоступный источник уже превращён в обычную пустую коллекцию, у модели больше нет информации, позволяющей отличить неудачное чтение от отсутствия записей. Инструкция отвечать осторожнее не восстановит различие, которое отбросил адаптер. Система сама лишила следующий компонент необходимого контекста.
Поэтому отрицательному результату нужен контракт чтения. Укажи, какая область запрошена, удалось ли прочитать соответствующую коллекцию и какую согласованность обеспечивает источник. Затем сформулируй находку в этих границах. «Среди полученных записей нет отсутствующих связей» уже, чем «Все документы на месте». Ни одна из этих фраз не доказывает, что источник вообще содержит каждый документ из реального мира.
Чем отличаются полный, частичный и недоступный результаты?
Отделяй состояние чтения от обнаруженных проблем. Полное чтение может вернуть находки или не найти ничего. Частичное чтение уже может дать полезные наблюдения, но не устанавливает итог для всей коллекции. Недоступное чтение не даёт проверенного количества. Эти состояния должны оставаться различимыми и после обработки ответа.
| Наблюдение | Допустимый вывод | Необоснованный вывод |
|---|---|---|
| Принятая коллекция с находками | Эти полученные записи соответствуют условию проверки | Найдены все возможные проблемы |
| Принятая коллекция без находок | Ни одна полученная запись не соответствует условию | Исходный бизнес-процесс полностью завершён |
| Часть страниц прочитана, следующая недоступна | Есть частичные наблюдения | Во всей коллекции нет проблем |
| Источник недоступен | Проверка не смогла установить результат | Количество проблем равно нулю |
| Страницы согласуются по количеству и идентификаторам | Эти проверки согласованности пройдены | Все страницы относятся к одному снимку |
Инструмент может вообще не выдавать частичные наблюдения. Проверенный читатель Norman возвращает недоступный результат вместо частичной сводки. Это намеренная граница ответа: последующий код не получает итоговое количество из неполностью прочитанной коллекции. Другой вариант реализации мог бы возвращать частичные находки, если неполнота охвата остаётся явной и не теряется при дальнейшей обработке.
Что показал тест результатов инструмента Norman?
Мы локально запустили код чтения для проверки документов и функцию сводки Norman, подставив синтетические ответы с пагинацией. Настоящие функции приложения выполняли проверку структуры и агрегацию. Транспорт API заменили имитацией, конфигурацию и контекст изолировали. Ни клиентская база данных, ни модель, ни работающий внешний сервис в эксперименте не участвовали.
Принятая пустая коллекция дала нулевой счётчик. Когда чтение следующей страницы завершалось таймаутом, функция возвращала статус недоступности без итоговых чисел. Страницы неверной структуры, повторяющиеся идентификаторы записей и изменение заявленного размера коллекции также отклонялись. Это доказывает конкретное поведение на проверенных входах, а не универсальную корректность данных или всех возможных ответов.
Затем в изолированной копии мы добавили намеренно ошибочный контрольный вариант: прямо перед агрегацией заменили недоступный результат пустым списком. Те же сценарии ошибок стали возвращать обычные пустые сводки, и соответствующие проверки тестов перестали проходить. Это специально внесённое изменение для эксперимента. Мы не утверждаем, что какая-либо прежняя версия в эксплуатации работала именно так.
Вывод касается сохранения информации. Правильной обработки в читателе недостаточно, если следующий адаптер подставляет значение по умолчанию. Наша статья о повторных попытках разбирает, какую операцию безопасно повторить. Здесь вопрос другой: какой вывод потребитель вправе сделать из уже завершившегося вызова инструмента и какие основания у него для этого есть.
Почему полная пагинация не доказывает единый снимок?
Есть и вторая граница, которую одной обработкой ошибок не исправить. Представим искусственную коллекцию из записей A и B. До изменения у A есть связь с документом, а у B нет. После изменения у A связь отсутствует, зато у B появляется. В каждом из двух состояний источника есть одна отсутствующая связь.
Теперь прочитаем A из раннего состояния, а B из позднего. В собранном ответе есть оба идентификатора, заявленный размер не изменился, у обеих полученных записей есть связь. Сводка сообщает ноль. Она описывает собранные ответы, но не описывает ни одно из двух исходных состояний. Проблема не в подсчёте элементов, а в том, какие наблюдения были объединены.
Мы сконструировали именно такие ответы страниц и пропустили их через те же функции Norman. Читатель принял их. Это показывает предел проверок количества и идентификаторов. Перед нами синтетический контрпример, а не обнаруженный инцидент в рабочей системе и не измерение того, как часто происходят одновременные изменения данных.
Стабильная сортировка помогает обойти коллекцию, но не замораживает изменяющиеся значения. Для более сильной гарантии нужен механизм на стороне источника: например, курсор, привязанный к снимку, или версионированный экспорт. Если такой гарантии нет, описывай наблюдение как чтение в течение интервала. Не превращай его незаметно в утверждение о едином моменте времени.
Как инструмент агента должен сообщать о недоступном результате?
Используй структуру результата, в которой отсутствие и неопределённость являются разными состояниями. Ниже приведён пример контракта приложения, а не хранимая схема Norman и не сообщение протокола MCP:
{
"status": "unavailable",
"coverage": "incomplete",
"finding_count": null,
"consistency": "not_established",
"next_action": "repeat_the_read"
}
Важны не названия полей. Отсутствующее измерение не должно случайно стать обычным нулём. Определи, в каких состояниях допустимы количества, потребуй обработку остальных состояний и проверь правило вплоть до отображения. Если схема допускает противоречивые сочетания значений, ей всё ещё нужна семантическая проверка. Само по себе соответствие форме JSON этого не обеспечивает.
Спецификация инструментов MCP различает ошибки протокола и ошибки исполнения, передаваемые через isError. Это различие и контракт охвата приложения отвечают на разные вопросы. Ошибку исполнения нужно передать как ошибку; успешному вызову всё равно нужен контекст для интерпретации данных. Наш локальный эксперимент проверял результат приложения, а не сериализацию MCP или обработку этого флага клиентом.
Что агенту говорить при незавершённой проверке?
Формулировка должна следовать доказательствам. После неудачного чтения: «Я не смог завершить проверку». После частичного чтения нужно назвать наблюдения частичными и оставить общий вывод открытым. После принятого чтения следует указать, что проверено, в какой области и был ли установлен согласованный снимок. Эти оговорки сообщают пользователю полезную информацию о границах результата.
Это особенно важно, когда один ответ строится по нескольким источникам. Работающий источник не должен скрывать недоступность другого. Сохрани отдельный исход каждого обращения, прежде чем решать, возможен ли общий вывод. Хорошо написанный абзац не должен превращать неоднородное состояние доказательств в единый успокаивающий статус. Иначе различие потеряется уже в последнем шаге системы.
Похожее различие мы проводили для памяти агента: записанная активность не доказывает полезный исход автоматически. Здесь полученные записи не доказывают полноту автоматически. В задачу агента входит объяснение границы, а не просто выбор самой гладкой интерпретации числа. Пользователю нужно понимать, на какой именно вопрос это число действительно отвечает.
Как тестировать контракты результатов инструментов?
Начни с успешного чтения пустой коллекции как положительного случая. Затем прерви следующую страницу, повтори страницу, измени заявленный размер и убери поля, необходимые для интерпретации записи. Проверяй одновременно состояние результата и отсутствие итоговых чисел при неполном охвате. Тест, который проверяет только сообщение об ошибке, может не заметить случайный ноль в другом месте ответа.
Добавь контрольный вариант, отбрасывающий ошибку, и убедись, что тесты контракта это замечают. Сохрани также пример смешанных состояний: прохождение всех проверок пагинации нельзя выдавать за доказательство изоляции снимка. Наша статья об обвязке агента объясняет общий контекст исполнения, но каждой границе доказательств нужна собственная проверка с конкретным ожидаемым результатом.
Этот эксперимент не устанавливает сквозное поведение модели, согласованность рабочей базы или состояние развёртывания. Он показывает, как конкретные функции приложения интерпретируют контролируемые входные данные. Следующая проверка должна выяснить, сохраняют ли эти различия транспорт, потребитель и окончательный ответ. Фраза «Ничего не найдено» становится полезной, только когда система способна объяснить, что именно ей удалось успешно проверить.
Частые вопросы
- Означает ли пустой результат инструмента, что ничего не отсутствует?
- Только в пределах области и гарантий успешно выполненной проверки. Пустая коллекция отличается от недоступного источника и частичного чтения. Даже принятая пагинация не обязательно даёт согласованный снимок. Результат должен объяснять, что прочитано и что подтверждает источник, а не создавать впечатление полной проверки всего реального процесса.
- Может ли полная пагинация вернуть несогласованный результат?
- Да. Страницы могут отражать разные состояния источника, хотя общее количество и идентификаторы остаются правильными. Синтетический тест Norman объединил наблюдения до и после изменения и получил результат, не описывающий ни одно состояние. Чтение с привязкой к снимку или версионированный экспорт могут дать более сильные гарантии, если источник их поддерживает.
- Как AI-агенту обрабатывать недоступные данные инструмента?
- Сохраняй состояние недоступности в инструменте, агрегации и окончательном ответе. Не подставляй пустой список или нулевой счётчик вместо отсутствующего измерения. Если сохраняются частичные наблюдения, явно укажи их охват. Следующий шаг, включая повторное чтение, должен оставаться отдельным действием, а не подтверждением того, что исходная проверка успешно завершилась.
Norman берет операционную финансовую работу на себя
От invoicing до bookkeeping: Norman организует повторяющиеся финансовые процессы так, чтобы вы успевали к дедлайнам с меньшим объемом ручной работы.