Перейти к содержанию
Публикация AiManual

Журнал фактов: как заставить ИИ-агента не выдумывать цифры в отчётах

Разбираем, почему ИИ-агент выдумывает числа и ссылки в отчётах, чем не помогли постфактум-аудит и дословные цитаты и как схема «журнала фактов» с нумерацией ист

Коротко

Что будет в материале

  1. 01

    В чём проблема: убедительный отчёт с выдуманными числами

  2. 02

    Первая попытка: постфактум-аудит чисел и почему он утонул в правилах

  3. 03

    Вторая попытка: дословные цитаты и механическая проверка

  4. 04

    Как устроен журнал фактов: фиксация показателей на этапе планирования

В KW-7 AI есть режим целей: пользователь ставит задачу крупнее обычного запроса, а система сама составляет план, ищет в интернете, читает страницы, считает, строит графики и сохраняет отчёт. Прогон идёт от 15 минут до часа без участия человека, за это время агент делает 30-50 вызовов инструментов. Автор разбора этого кейса описал, как отчёты сначала выглядели триумфом автоматизации, а потом начали рассыпаться при сверке с источниками.

Числа выдумывались не потому, что модель «плохая». Она читала страницы, держала прочитанное в истории диалога и к моменту написания пересказывала его по памяти, когда часть контекста уже сжалась. Встроенная проверяющая модель ставила «высокое качество»: перед ней был развёрнутый ответ с таблицами, графиками и ссылками, а сверки каждого числа с реально открытыми страницами не происходило.

Дальше - три класса ошибок, две попытки закрыть их «снаружи» и итоговая схема «журнал фактов»: показатели фиксируются на этапе планирования, источники получают номера, факты извлекаются отдельными вызовами с дословной цитатой и проверяются кодом, отчёт пишется ссылками на номера фактов, а расчёты и графики строит система.

В чём проблема: убедительный отчёт с выдуманными числами

Отчёт на выходе выглядит как работа аналитика: структура, таблица с показателями, график динамики, список источников. Именно этот вид и усыпляет. Ошибку видно только при сверке: открываешь три сайта из сносок, и ни на одном из них нет чисел, которые на них «основаны».

Почему проверяющая модель говорила «высокое качество»

В KW-7 AI ответ оценивает вторая модель, встроенный проверяющий. Ей показывают готовый текст, и она судит о том, что видит: ответ развёрнутый, данные присутствуют, структура есть, ссылки проставлены. По этим признакам отчёт с выдуманными числами получал «высокое качество» ровно так же, как корректный.

Разрыв возникает из-за разницы вопросов. Проверяющий отвечает на вопрос «похоже ли это на полный ответ?», а от отчёта нужен ответ на вопрос «совпадает ли каждое число с тем, что написано на открытой странице?». Первое проверяется по тексту ответа, второе требует доступа к источникам и построчной сверки.

Три типа ошибок: выдуманные числа, перепутанные источники, несуществующие ссылки

Сбои полезно разделить, потому что ловятся они по-разному.

1. Чисел нет в источниках. Ряд продаж «2019: 1 118 ... 2022: 2 993» был подписан ссылками на три сайта, и ни на одном из трёх этих чисел не было. Модель нарисовала ряд на графике и сохранила его в файл отчёта.

2. Число есть, но смысл другой. Агент взял со страницы ряд цифр и выдал его за продажи, посчитав рост «+79% и +62%». Числа на странице действительно были. Только речь там шла о том, сколько машин ездит, а не о том, сколько продано за год. Сюда же относятся перепутанные атрибуции: цифры взяты с одного сайта, а ссылка стоит на другой.

3. Ссылки на несуществующие страницы. В отчёте появились адреса на autostat.ru вида /news/2024/12/31/..., таких страниц не существовало. Адрес выглядит правдоподобно, проверяется за секунды, но только если проверять.

Первый и третий классы ловятся механически: есть ли число в тексте страницы, открывается ли URL. Второй класс механическая сверка пропускает по определению, потому что число на месте и оно верное. Неверна интерпретация, а её код не видит.

Первая попытка: постфактум-аудит чисел и почему он утонул в правилах

Очевидное решение: после выполнения запроса сверять каждое число в готовом отчёте с текстом страниц, которые реально открывались. Не с интернетом вообще, а именно с теми страницами, что попали в историю вызовов.

Сначала это работало. Потом начались исключения, и каждое выглядело разумно само по себе: год «2024» - не данные, номер в рейтинге - не данные, строка «Прочие» в таблице - остаток, а не цифра из источника.

Дальше счёт пошёл на раунды. Десять раундов доводки аудита на одной и той же цели: каждый раунд закрывал найденную ошибку и добавлял новое правило, следующий прогон приносил новую ложную тревогу, а правила становились всё более специфичными для темы электромобилей. Ловушки и фильтры улучшали один конкретный отчёт и не переносились на другие.

Число на странице есть, оно верное. Неверен смысл.

Именно так аудит упёрся в потолок: подмену «парк вместо продаж» правила не ловили в принципе. Аудит проверяет наличие, а не значение. Плюс цена сопровождения: чем шире тематика, тем больше исключений, и каждое новое правило рискует сломать предыдущий отчёт.

Вторая попытка: дословные цитаты и механическая проверка

Следующий шаг сместил ответственность на модель: пусть каждая цифра сопровождается сноской с дословной цитатой и адресом страницы. Система механически проверяет, что фраза действительно есть на странице, а число входит внутрь этой фразы. Результат заметно лучше: часть выдуманных чисел отваливается сразу, потому что цитату неоткуда взять.

Дословность здесь принципиальна. Модели пересказывают страницы, а не копируют их, поэтому цитата в свободной форме почти всегда «почти правильная». Разбор отсылок Perplexity на 1355 примерах показывает ту же механику с другой стороны: цитируется пересказ, а не исходная строка. Отсюда практический вывод для агентов: сохранять HTML источников сразу, а не надеяться восстановить формулировку позже.

Почему сжатие истории ломает даже хорошие цитаты

Корень проблемы остался на месте. Модель читает страницы, держит прочитанное в истории диалога и потом пересказывает. Длинная работа - это 30-50 вызовов инструментов, контекст ограничен, история сжимается, и прочитанное в начале теряется. К моменту написания отчёта страница, открытая на десятом шаге, помнится уже как пересказ пересказа.

Это архитектурная причина, а не свойство конкретной модели. Пока знание живёт в истории вызовов, любое требование цитировать источник опирается на память о тексте. Значит, текст нужно вынести из истории в отдельное хранилище, к которому отчёт обращается по номерам.

Как устроен журнал фактов: фиксация показателей на этапе планирования

Журнал фактов - это хранилище записей, которое живёт вне диалога и не сжимается вместе с контекстом. Конвейер выглядит так:

  1. На этапе планирования явно фиксируется список показателей, которые нужны отчёту. До начала поиска, а не после.
  2. Каждому открытому источнику присваивается номер: S-1, S-2, S-3.
  3. Каждый факт извлекается отдельным вызовом с дословной цитатой и привязкой к номеру источника.
  4. Факт проверяется кодом: цитата найдена на странице, число входит в цитату.
  5. Отчёт пишется ссылками на номера фактов (F-01, F-02), а не на пересказ из памяти.
  6. Расчёты и графики строит система по зафиксированным числам.

Ключевой эффект: к моменту генерации текста модели не нужно вспоминать, что было в источнике. Ей достаточно сослаться на номер факта, а текст цитаты подставит код.

Нумерация источников и отдельный вызов на каждый факт

Один вызов на один факт сужает задачу до предела: конкретный показатель, конкретный номер источника, требование вернуть дословную фразу или статус «не найдено». Соблазн достроить ряд по соседним числам падает, потому что в контексте вызова нет соседних чисел. Проверка кода тоже становится однозначной: сравнение идёт с одной страницей, а не с десятком.

Цепочка выглядит так: показатель «продажи электромобилей в России за 2022 год» → источник S-4 → дословная цитата со страницы → проверка, что цитата есть в сохранённом HTML, а число входит в цитату → запись F-07 со статусом проверки. Дальше отчёт ссылается на F-07, и любая претензия к цифре разбирается по конкретной цитате.

Номер фактаПоказательЗначениеИсточникДословная цитатаСтатус проверки
F-07Продажи электромобилей в России за 2022 годберётся из цитатыS-4, autostat.ruфраза со страницы целикомцитата найдена, число внутри цитаты, смысл проверен вторым вызовом
F-08Средняя цена, 2023 год---не найдено: на открытых страницах только данные о парке

Почему расчёты и графики должен строить код, а не модель

Модель не считает проценты и не рисует ряды по памяти. Она передаёт номера фактов и правило расчёта, а арифметику и построение графика выполняет система по зафиксированным значениям. Так рост «+79% и +62%» не появится из ряда, который на самом деле описывал парк, потому что ряд для расчёта берётся из журнала, а не из пересказа.

Тот же принцип разделения работы между моделью и детерминированным кодом разобран в материале про библиотеку solvi: LLM извлекает факты из документа, код их проверяет и выносит решение, а хеш-след оставляет след для аудита. Журнал фактов устроен похоже, только вместо бизнес-решения на выходе отчёт.

Доработки, которые закрывают края: «не найдено», надёжность источника, смысловая проверка

Базовая схема убирает выдуманные числа, но оставляет три уязвимых места: чего делать при отсутствии данных, как показать качество источника и кто поймает подмену смысла.

Статус «не найдено» с причиной вместо правдоподобной цифры

Если данных нет, лучший ответ - зафиксировать это явно: «не найдено, на открытых страницах нет годового ряда продаж, есть только данные о парке». Такая запись информативнее выдуманного числа и не ломает отчёт: таблица остаётся полной, читатель видит пробел и его причину. Модели по умолчанию склонны заполнять пустую ячейку, поэтому статус должен быть обязательным полем записи, а не пожеланием в промпте.

Оценка надёжности источника по типу площадки

Не все источники равны, и это можно выразить без выдуманных рейтингов. Достаточно типа площадки: первоисточник (официальная статистика, регулятор, отчёт компании), отраслевое издание, агрегатор или перепечатка, форум и соцсети. Первоисточник даёт факту больший вес, перепечатка - меньший, потому что цифра могла измениться при пересказе. В отчёте тип источника показывается рядом с фактом, и читатель видит, на чём стоит вывод: на релизе ведомства или на посте в соцсети.

Независимая смысловая проверка вторым модельным вызовом. Проверяем, что число относится именно к зафиксированному показателю, а не к соседнему. Второй вызов получает определение показателя, цитату и число, но не весь отчёт: так проверяющий не подхватывает уверенный тон основного текста. Такая проверка отвечает на вопрос «парк это или продажи» и снижает риск смысловой подмены. Гарантии она не даёт: это вероятностная оценка другой модели, а не доказательство.

Что журнал фактов гарантирует, а что нет

Граница проходит ровно по смыслу. Журнал гарантирует, что цифра присутствует в источнике, привязана к дословной цитате и что цитата реально есть на странице. Проверка кодом здесь детерминированная: либо фраза найдена, либо нет.

Смысловую корректность журнал не гарантирует. Число может быть настоящим и при этом означать другой показатель, относиться к другому периоду или к другой методике подсчёта. Смысловая проверка вторым вызовом уменьшает этот риск, но не убирает его.

Есть и внешние ограничения. Качество отчёта зависит от того, что вообще открыто в интернете: если годового ряда не опубликовали, в журнале появится «не найдено», а не чудо. Ошибки планирования журнал не лечит: если на старте зафиксирован не тот показатель, дальше всё будет проверено и всё равно бесполезно. Обещать «ноль галлюцинаций» после такой схемы нельзя, корректная формулировка скромнее: выдуманные числа и битые ссылки почти исчезают, смысловые подмены становятся заметны и разбираемы.

Чек-лист внедрения для своего агента

Схема переносится на любой агент, который собирает отчёты по внешним источникам: корпоративный ассистент на LLM, RAG-пайплайн с проверкой источников, генератор аналитики. Порядок шагов и ошибка, которую закрывает каждый пункт:

  • Зафиксируйте метрики на планировании. Закрывает ошибку «в отчёте посчитали не тот показатель»: список нужных цифр появляется до поиска.
  • Пронумеруйте источники. Убирает путаницу атрибуции, когда число с одного сайта подписано ссылкой на другой.
  • Извлекайте факты отдельными вызовами с дословной цитатой. Снижает соблазн достроить ряд и даёт материалу для проверки.
  • Проверяйте цитату и число кодом. Отсекает выдуманные числа и ссылки на несуществующие страницы.
  • Храните журнал вне истории диалога. Снимает потерю прочитанного при 30-50 вызовах инструментов.
  • Пишите отчёт ссылками на номера фактов. Делает каждую цифру прослеживаемой до конкретной записи.
  • Считайте и рисуйте графики кодом. Убирает арифметические ошибки и «нарисованные» ряды.
  • Введите статус «не найдено» с причиной. Не даёт модели заполнить пробел правдоподобным числом.
  • Оценивайте тип площадки источника. Показывает, на чём основан вывод: первоисточник, издание или перепечатка.
  • Добавьте смысловую проверку вторым вызовом. Ловит подмену «парк вместо продаж», хотя и без гарантии.

Начинать стоит с первых пяти пунктов: они дают основной эффект и не требуют менять модель. Доработки из второй половины списка подключаются, когда базовая схема уже работает и видно, какие ошибки остались. Базовые правила проверки фактов и выбора инструментов, если нужно освежить контекст, собраны в отдельном разборе про галлюцинации и фактчекинг.

Главный сдвиг, который даёт журнал фактов, простой: агент перестаёт быть источником цифр и становится редактором, который ссылается на проверенные записи. Всё, что можно проверить кодом, проверяет код. Модели остаётся то, что кодом не проверить, - понимание, о каком показателе вообще идёт речь.

Подписаться на канал