Практика работы с агентами

Как агент должен отличать факт от предположения

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

Уровень: средний Чтение: до 8 минут Результат: цитаты, происхождение данных и отказ от догадок

Почему уверенный ответ ещё не является фактом

Привязка к источникам — это правило, по которому утверждения агента должны опираться на доступные и проверяемые данные. Если подтверждения нет, агент обязан обозначить неопределённость или отказаться от ответа.

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

Практическая цель — разделить содержимое ответа на три категории:

  • Подтверждённый факт: утверждение непосредственно следует из предоставленного источника.
  • Вывод: утверждение получено из нескольких фактов логическим переходом, который явно показан пользователю.
  • Предположение: возможное объяснение без достаточного подтверждения; оно не должно выдаваться за факт.

Шаг 1. Задайте контракт ответа

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

Ты отвечаешь только на основании источников, переданных в текущем запросе.

Для каждого существенного утверждения:
1. Укажи идентификатор источника.
2. Приведи короткую точную цитату, подтверждающую утверждение.
3. Отметь тип: ФАКТ или ВЫВОД.

Если прямого подтверждения нет:
- не дополняй ответ сведениями из памяти;
- напиши: «В предоставленных источниках нет подтверждения»;
- перечисли, каких данных не хватает.

ВЫВОД допустим только тогда, когда:
- перечислены исходные факты;
- описан логический переход;
- вывод не представлен как цитата или установленный факт.

Не создавай названия документов, ссылки, даты, числа и цитаты.

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

Шаг 2. Передавайте происхождение данных вместе с текстом

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

{
  "sources": [
    {
      "source_id": "DOC-001",
      "title": "Пример внутренней инструкции",
      "location": "раздел 2",
      "retrieved_at": "2026-07-28T10:00:00Z",
      "content": "Пример текста источника: заявки рассматриваются в течение трёх рабочих дней."
    }
  ],
  "question": "Каков срок рассмотрения заявки?"
}

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

Полезные поля происхождения:

source_id
Стабильный идентификатор, который возвращается в ответе.
title
Понятное человеку название источника.
location
Страница, раздел, строка или другой способ найти цитату.
retrieved_at
Момент получения данных, если актуальность зависит от времени.
content
Точный фрагмент, доступный модели.

Не передавайте секреты, токены доступа и персональные данные только ради цитирования. До отправки модели применяйте действующие в вашей системе правила доступа и маскирования.

Шаг 3. Сделайте ответ машиночитаемым

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

{
  "answer": "Срок рассмотрения — три рабочих дня.",
  "claims": [
    {
      "text": "Срок рассмотрения — три рабочих дня.",
      "kind": "fact",
      "source_id": "DOC-001",
      "location": "раздел 2",
      "quote": "заявки рассматриваются в течение трёх рабочих дней"
    }
  ],
  "missing_information": []
}

Это также пример ожидаемого ответа на синтетические данные из предыдущего шага. В рабочей системе значение quote должно буквально встречаться в соответствующем content.

Для неподтверждённого вопроса ожидаемый результат должен быть другим:

{
  "answer": "В предоставленных источниках нет подтверждения.",
  "claims": [],
  "missing_information": [
    "Нужен источник, в котором указан запрошенный факт."
  ]
}

Шаг 4. Проверяйте ответ вне модели

Инструкция снижает риск, но не является контролем исполнения. Приложение должно отклонять ответ, если источник неизвестен или цитата отсутствует в переданном фрагменте.

function validateClaims(result, sources) {
  const byId = new Map(sources.map(source => [source.source_id, source]));

  for (const claim of result.claims) {
    const source = byId.get(claim.source_id);

    if (!source) {
      throw new Error("Ответ ссылается на неизвестный источник");
    }

    if (!claim.quote || !source.content.includes(claim.quote)) {
      throw new Error("Цитата не найдена в указанном источнике");
    }

    if (!["fact", "inference"].includes(claim.kind)) {
      throw new Error("Неизвестный тип утверждения");
    }
  }

  return true;
}

Этот безопасный пример выполняет только локальные проверки объектов в памяти. Он не обращается к сети, не изменяет файлы и не выводит содержимое источников в журнал.

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

Шаг 5. Проведите воспроизводимую проверку

Создайте небольшой набор синтетических случаев. Он не должен содержать реальные секреты, сведения о клиентах или неподтверждённые внешние данные.

  1. Передайте источник с явно указанным значением и задайте прямой вопрос о нём.
  2. Проверьте, что ответ содержит правильный source_id и дословную цитату.
  3. Задайте вопрос о факте, которого в источнике нет.
  4. Проверьте, что массив claims пуст, а ответ сообщает об отсутствии подтверждения.
  5. Передайте два противоречащих друг другу фрагмента.
  6. Проверьте, что агент показывает противоречие, а не выбирает удобную версию без объяснения.
  7. Измените одно число в источнике и повторите запрос.
  8. Проверьте, что ответ изменился вместе с источником и не сохранил прежнее значение.

Безопасная локальная команда для проверки синтаксиса JSON, если тестовый ответ сохранён в response.json:

python3 -m json.tool response.json > /dev/null

Успешное завершение подтверждает только корректность JSON. Оно не доказывает истинность ответа и не заменяет проверку цитат.

Как проверить результат

Система достигла минимально приемлемого поведения, если выполняются все условия:

  • каждый факт содержит идентификатор и местоположение источника;
  • каждая цитата действительно присутствует в переданном фрагменте;
  • выводы отделены от фактов и содержат объяснение перехода;
  • вопрос без подтверждения приводит к явному отказу от догадки;
  • противоречащие источники показываются пользователю;
  • ответ нельзя принять, если программная проверка происхождения не пройдена.

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

Типовые ошибки

Просьба «не галлюцинировать» без формата доказательства

Модель получает пожелание, но не получает проверяемого критерия. Требуйте идентификатор, цитату и тип утверждения.

Ссылка на документ без цитаты

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

Цитата из памяти модели

Разрешайте ссылки только на идентификаторы из текущего входа. Любой неизвестный идентификатор должен отклоняться приложением.

Скрытое превращение вывода в факт

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

Автоматический выбор одного из конфликтующих источников

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

Проверка только наличия цитаты

Цитата может быть вырвана из контекста, содержать отрицание или относиться к другому объекту. Для значимых решений нужна смысловая или ручная проверка.

Ограничения

Привязка ответа к источникам не гарантирует, что сами источники верны, актуальны и полны. Она показывает происхождение утверждения и делает ошибку наблюдаемой.

Короткие фрагменты могут потерять контекст, а длинные — добавить шум. Поиск способен не вернуть нужный документ. Оптическое распознавание может исказить число или отрицание. Метаданные тоже могут оказаться ошибочными.

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

Если система не может подтвердить утверждение, отказ — это корректный результат, а не сбой. Хороший отказ называет пробел и подсказывает, какой источник нужен для продолжения.

Короткий рабочий шаблон

  1. Размечайте источники стабильными идентификаторами.
  2. Передавайте текст вместе с происхождением и местоположением.
  3. Требуйте отдельный список утверждений.
  4. Для каждого факта требуйте дословную цитату.
  5. Отделяйте выводы от фактов.
  6. Проверяйте ссылки и цитаты программно.
  7. При отсутствии данных возвращайте явный отказ.
  8. При конфликте показывайте конфликт, а не скрывайте его.