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

Шаблоны контрактов генерации для RAG: как заменить строку на типизированный Pydantic-объект с проверкой

Семь шаблонов типизированных контрактов генерации для RAG на Pydantic. Устраните галлюцинации, получите проверяемые ответы с цитатами и флагами достоверности. П

Коротко

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

  1. 01

    Почему строковый вывод RAG - это источник хаоса

  2. 02

    Контракт генерации: от строки к Pydantic-схеме

  3. 03

    Семь шаблонов контрактов: от простого к сложному

  4. 04

    Правило декомпозиции: как подружить сложный контракт с маленькой LLM

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

Решение - перестать рассматривать генерацию как выдачу строки и начать работать с ней как с заполнением строгой типизированной схемы. Семь шаблонов на основе Pydantic-контрактов устраняют иллюзию «галлюцинации» модели и переводят внимание на реальные ошибки извлечения в цепочке парсинга, ретрива и самого контракта. Вы получаете детерминированный, проверяемый JSON с цитатами, флагами достоверности и мета-оценкой вместо текста, требующего ручной вычитки.

Почему строковый вывод RAG - это источник хаоса

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

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

Контракт генерации: от строки к Pydantic-схеме

Контракт генерации - это Pydantic-модель, которую модель обязана заполнить. Вместо промпта «Ответь на вопрос» вы даёте инструкцию «Заполни схему AnswerContract». Модель возвращает не строку, а типизированный объект с обязательными полями. Pydantic-валидация отсекает неполные ответы на уровне парсинга вывода: если поле quote не заполнено или confidence не соответствует enum, вы получите исключение, а не «почти правильный» текст.

Простейший контракт выглядит так:

from pydantic import BaseModel, Field

class FactoidAnswer(BaseModel):
    answer: str = Field(description="Итоговый ответ на вопрос")
    quote: str = Field(description="Точная цитата из документа, подтверждающая ответ")
    confidence: bool = Field(description="True, если цитата однозначно подтверждает ответ")
    relevance_score: int = Field(ge=1, le=5, description="Оценка релевантности найденного фрагмента")

Каждое поле заставляет модель явно указать источник. Вы сразу видите, опирается ли ответ на документ или на память модели. Этот объект можно логировать, сравнивать с эталоном и использовать в коде без дополнительного парсинга. Такой подход - основа для семи шаблонов, покрывающих 90% сценариев внедрения RAG в документооборот.

Анатомия типизированного контракта: поля, которые меняют всё

Четыре поля контракта переопределяют процесс проверки ответа. answer содержит итоговую формулировку - это то, что увидит пользователь. quote - точная цитата из ретрива, которая обосновывает ответ. Если модель не может найти цитату, она обязана оставить поле пустым, а не выдумывать текст. confidence - булев флаг или enum (HIGH, MEDIUM, LOW), который показывает, насколько однозначно цитата подтверждает ответ. relevance_score - оценка релевантности источника по шкале от 1 до 5.

Эти поля переводят внимание с «галлюцинаций» на реальные проблемы. Если confidence=False, а relevance_score=1, проблема в retrieval - нужно менять стратегию поиска или чанкование. Если quote заполнена, но answer противоречит цитате, проблема в генерации - контракт слишком сложен для модели или промпт сформулирован неоднозначно. Вы получаете конкретную точку отказа, а не размытое «модель ошиблась». Ошибки извлечения становятся инженерными задачами с измеримыми метриками.

Семь шаблонов контрактов: от простого к сложному

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

Шаблон 1: Фактоидный ответ с единственной цитатой

Базовый шаблон для вопросов, ответ на которые опирается на один фрагмент документа. Схема: один вопрос - один Pydantic-объект с полями answer и quote. Пример: «Какая версия модели используется в production?» Модель находит чанк с номером версии, заполняет answer значением «2.1.4», а quote - точной строкой из конфигурационного файла. Если ретрив не нашёл релевантный фрагмент, quote остаётся пустой, и Pydantic выбрасывает исключение. Этот шаблон подходит для FAQ по документации и мгновенно выявляет проблемы с retrieval.

Шаблон 2: Множественные цитаты для составного ответа

Расширение первого шаблона для случаев, когда ответ требует синтеза из нескольких частей документа. Поле quote заменяется на quotes - список строк. Модель собирает ответ из нескольких фрагментов и явно указывает каждый. Это критично для юридических и технических документов, где нельзя терять контекст. Например, вопрос «Какие условия расторжения договора?» может требовать цитат из разделов о сроках уведомления, штрафах и порядке возврата. Без списка цитат модель может упустить один из аспектов, и вы об этом не узнаете.

Шаблон 3: Бинарная проверка факта с флагом достоверности

Инструмент для задач верификации. Схема содержит поле is_true (bool) и обязательную цитату-доказательство. Сценарий: пользователь спрашивает «Правда ли, что модель поддерживает контекст 128K токенов?» Модель ищет в базе знаний подтверждение или опровержение, заполняет is_true и приводит цитату из спецификации. Флаг достоверности и цитата позволяют автоматически логировать результаты проверки без участия человека. Этот шаблон незаменим для систем, которые должны отслеживать изменения в быстро меняющейся AI-сфере.

Шаблон 4: Извлечение структурированных данных из документа

Контракт не просто отвечает на вопрос, а возвращает заполненную форму с вложенными Pydantic-моделями. Пример: извлечение параметров модели из статьи. Поля: model_name, parameters_count, release_date, architecture_type. Модель парсит документ и заполняет схему, которую можно сразу загрузить в базу данных. Это заменяет ручной парсинг и исключает ошибки копирования. Для каталога AI-моделей такой шаблон сокращает время актуализации данных с часов до секунд.

Шаблон 5: Сравнительный анализ с оценкой уверенности

Схема для сравнения двух или более сущностей по заданным критериям. Модель возвращает список сравнений, каждое с полями: критерий, сущность1, сущность2, вывод, confidence. Пример: сравнение двух LLM по скорости инференса, качеству кода и стоимости токена. Confidence позволяет фильтровать ненадёжные сравнения - если по какому-то критерию модель не нашла достаточно данных, вы увидите низкий confidence и сможете исключить этот пункт из отчёта. Шаблон полезен для автоматической генерации аналитических справок по новым моделям.

Шаблон 6: Цепочка рассуждений с верификацией каждого шага

Контракт заставляет модель показать ход мыслей и подтвердить каждый логический переход цитатой. Схема содержит поле steps - список объектов, где каждый шаг имеет thought и supporting_quote. Пример: анализ причин падения accuracy модели после обновления. Модель строит цепочку: «Изменился формат входных данных (цитата из лога изменений)» → «Новый токенизатор иначе обрабатывает специальные символы (цитата из документации)» → «Accuracy снизился на 3.2% (цитата из бенчмарка)». Этот шаблон даёт аудит рассуждения, который можно проверить по исходным документам.

Шаблон 7: Мета-оценка качества ответа самой моделью

Саморефлексия встроена в контракт. Дополнительное поле self_assessment содержит оценку по шкалам 1-5 (полнота, точность, релевантность) и текстовое обоснование. Модель не только генерирует ответ, но и оценивает его качество. Это позволяет построить автоматический фильтр: ответы с оценкой ниже 4 по любому критерию отправляются на ручную проверку или перегенерацию. Вы получаете двухуровневый контроль качества без дополнительных вызовов модели.

Правило декомпозиции: как подружить сложный контракт с маленькой LLM

Одна и та же Pydantic-схема работает на GPT-4 и на Mistral 7B, но маленькая модель может не справиться со сложным контрактом за один вызов. Она начнёт пропускать поля, путать цитаты или выдавать некорректный JSON. Решение - правило декомпозиции: разбить схему на несколько последовательных вызовов с прослойкой на Python. Сначала извлечь цитаты (простой контракт), затем на их основе сгенерировать ответ (второй контракт), потом выполнить мета-оценку (третий контракт).

Такой подход сохраняет все преимущества типизации, но адаптирует нагрузку под возможности модели. Каждый вызов получает узкую задачу и простую схему, с которой маленькая модель справляется уверенно. Вы теряете в latency из-за последовательных вызовов, но приобретаете детерминированность и проверяемость на каждом шаге. Для задач, где важнее точность, а не скорость ответа, это оптимальный компромисс. Принцип последовательной подачи контекста и досрочного выхода из цикла, снижающий затраты токенов на 65-80%, детально разобран в статье о детерминированных циклах подачи контекста в RAG.

Практический пример: декомпозиция контракта сравнения для Mistral 7B

Разберём декомпозицию шаблона 5 для сравнения двух моделей. Вместо одной сложной схемы создаём три простых:

class QuoteExtraction(BaseModel):
    quotes: list[str] = Field(description="Цитаты из документов, релевантные критериям сравнения")

class Comparison(BaseModel):
    criteria: str
    model_a_result: str
    model_b_result: str
    winner: str
    confidence: bool

class SelfAssessment(BaseModel):
    completeness: int = Field(ge=1, le=5)
    accuracy: int = Field(ge=1, le=5)
    notes: str

Пайплайн на Python: вызов 1 - модель получает все чанки и заполняет QuoteExtraction, собирая цитаты. Вызов 2 - модель получает только цитаты из первого шага и заполняет Comparison, не отвлекаясь на поиск. Вызов 3 - модель получает результат сравнения и заполняет SelfAssessment. Прослойка на Python управляет потоком данных между вызовами. Поведение маленькой модели становится детерминированным и проверяемым, а каждый шаг можно логировать и отлаживать независимо.

Внедрение в документооборот: от ответа к аудируемому решению

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

Для ML-инженера, внедряющего RAG в enterprise-среде, это означает снятие главного барьера - недоверия бизнеса к генеративным системам. Когда каждый ответ сопровождается цитатой и оценкой уверенности, юридический отдел может проверить источник за секунды, а не перечитывать весь документ. Структурированность и прозрачность, заложенные в ценности AI-MANUAL, здесь становятся инженерным требованием. Если вы проектируете AI-агента для работы с документами, стоит посмотреть на архитектурные решения в статье о построении AI-агента с нуля - контракты генерации естественно встраиваются в оркестрацию LLM и систему памяти агента.

Автоматический аудит: как Pydantic-валидация ловит ошибки извлечения

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

Конкретный пример: система обрабатывает договор и должна извлечь сумму штрафа. Ретрив возвращает чанк из раздела «Определения терминов», где сумма не упоминается. Модель пытается заполнить контракт, но поле quote остаётся пустым или содержит текст, не соответствующий answer. Pydantic-валидатор обнаруживает несоответствие и выбрасывает ValidationError с указанием проблемного поля. Пайплайн перехватывает исключение, запускает повторный ретрив с расширенным запросом и получает корректный чанк из раздела «Ответственность сторон». Автоматический аудит без участия человека.

Ограничения и когда контракты не нужны

Контракты увеличивают latency и стоимость - модель тратит токены на заполнение структуры, а не только на ответ. Для простых фактоидных запросов накладные расходы могут составлять 20-30% от общего бюджета токенов. Это плата за проверяемость. Контракты избыточны для творческих задач или чат-ботов, где важна беглость, а не строгость. Если пользователь спрашивает «Объясни концепцию attention простыми словами», цитата из статьи не добавит ценности, а только раздует ответ.

Очень сложные контракты с глубокой вложенностью могут снижать качество даже больших моделей. Модель начинает путаться в структуре и пропускать поля. Важна итеративная доработка схем: начать с трёх полей, проверить на сотне запросов, добавить четвёртое поле, снова проверить. Не пытайтесь спроектировать идеальный контракт с первого раза - это инженерный процесс, требующий тестирования на реальных данных. Честность в признании ограничений - один из принципов AI-MANUAL, и здесь он означает, что контракты не silver bullet, а инструмент с измеримым профилем затрат и выгод.

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