Оглавление

Структурированное формирование выходных данных

Structured Output Prompting (структурированное формирование выходных данных) – это техника, при которой мы «просим» ИИ выдавать результаты в заранее определенном формате, например, JSON, XML или YAML.

Вместо расплывчатых ответов мы получаем четкую структуру данных. Это достигается путем добавления в промпт (запрос к ИИ) инструкций о желаемом формате вывода. Например, вместо просьбы «извлеки информацию о книге» мы говорим: «извлеки название, автора и год издания книги и представь это в формате JSON».

Извлеки название, автора и год издания книги "Мастер и Маргарита" и представь это в формате JSON.

В результате мы получим:

{
  "title": "Мастер и Маргарита",
  "author": "Михаил Булгаков",
  "year": 1967
}

Основное преимущество – гарантированная валидность данных. Если мы указали схему JSON, то ИИ выдаст результат, соответствующий этой схеме. Это упрощает автоматическую обработку и анализ данных. Другое важное преимущество – легкость парсинга (разбора) данных. JSON, XML и YAML легко читаются машинами, что позволяет быстро интегрировать результаты работы ИИ в существующие системы.

Модель находит применение в самых разных областях — в электронной коммерции для автоматического извлечения характеристик товаров, в финансах для анализа новостей и отчетов, в медицине для обработки медицинских записей. Технологии активно используются в связке с retrieval-augmented generation (RAG) для создания сложных автоматизированных рабочих процессов.

Основные форматы: JSON, XML и YAML

JSON: Машинно-читаемая точность

JSON (JavaScript Object Notation) – это текстовый формат обмена данными, основанный на парах «ключ-значение». Его лаконичность и простота делают его идеальным для машинной обработки. JSON особенно хорошо подходит для автоматизации задач, где важна скорость и точность. Например, OpenAI function-calling использует JSON для определения структуры функций, которые может вызывать LLM. Интеграция с LangChain также упрощается благодаря JSON.

{
  "product_name": "Смартфон XYZ",
  "price": 499.99,
  "features": ["5G", "AMOLED display", "128GB storage"]
}

Пример выше показывает, как можно представить информацию о продукте в JSON.

XML: Человеко-читаемая структура

XML (eXtensible Markup Language) – это язык разметки, который использует теги для определения элементов данных. В отличие от JSON, XML более читаем для человека благодаря своей структуре, напоминающей HTML. XML часто используется для структурирования инструкций и конфигурационных файлов. Claude, например, может быть оптимизирован для работы с XML, где теги , и четко определяют роли различных частей данных.


  Смартфон XYZ
  499.99
  
    5G
    AMOLED display
    128GB storage
  

YAML: Простота и гибкость

YAML (YAML Ain’t Markup Language) – это формат сериализации данных, ориентированный на удобочитаемость. Он использует отступы для обозначения структуры, что делает его более компактным и понятным, чем XML. YAML поддерживает многострочные стили, что полезно для длинных текстовых блоков. Для валидации YAML-файлов может использоваться PyYAML.

product_name: Смартфон XYZ
price: 499.99
features:
  - 5G
  - AMOLED display
  - 128GB storage
description: |
  Этот смартфон обладает отличными характеристиками
  и идеально подходит для повседневного использования.

Руководство по сравнению и выбору форматов

Выбор формата зависит от конкретной задачи:

  • JSON идеально подходит для автоматизации и обмена данными между системами
  • XML хорош для структурирования инструкций и конфигурационных файлов, где важна читаемость
  • YAML – отличный выбор для конфигурационных файлов и данных, которые должны быть легко читаемы и редактируемы человеком

GPT-4o, современные модели Claude (например, Sonnet 4.5) и Gemini поддерживают различные структурированные форматы. Gemini нативно поддерживает JSON и перечисления для структурированного вывода, в то время как Claude активно использует XML-теги для структурирования промптов и вывода.

Выбор часто сводится к личным предпочтениям и требованиям проекта. Если нужна максимальная скорость обработки – выбирайте JSON. Если важна читаемость и возможность ручного редактирования – YAML или XML.

Методы структурированного промптинга

Промптинг на основе инструкций

Самый простой способ получить структурированный вывод — четко указать желаемый формат в инструкции. Важно не просто попросить ИИ извлечь информацию, а явно указать, как именно она должна быть представлена. Например, вместо «Опиши этот товар» лучше написать: «Извлеки название товара, цену и основные характеристики и представь это в формате JSON». Чем детальнее инструкция, тем выше вероятность получить желаемый результат.

Пример:

Извлеки информацию о фильме "Начало" и представь ее в формате JSON, включающем название, год выпуска, режиссера и список актеров.

Такой промпт даст более предсказуемый и структурированный результат, чем просто «Расскажи о фильме Начало». Важно помнить, что даже с четкими инструкциями ИИ может ошибаться, поэтому всегда полезно проверять результат на соответствие ожидаемой структуре. Лучше сразу предусмотреть обработку ошибок, чем потом вручную исправлять неверные данные.

Обучение на нескольких примерах

Few-shot learning (обучение на нескольких примерах) – это метод, при котором в промпт включаются примеры желаемого вывода. Это помогает ИИ лучше понять, какой именно формат требуется. Предоставление нескольких примеров с разными входными данными и соответствующими структурированными выводами значительно повышает точность.

Пример:

Вот несколько примеров извлечения информации о книгах в формате JSON:

Вход: "Книга '1984' написана Джорджем Оруэллом в 1949 году."
Вывод:
{
  "title": "1984",
  "author": "Джордж Оруэлл",
  "year": 1949
}

Вход: "Автором 'Мастера и Маргариты' является Михаил Булгаков, книга написана в 1967 году."
Вывод:
{
  "title": "Мастер и Маргарита",
  "author": "Михаил Булгаков",
  "year": 1967
}

Теперь извлеки информацию о книге "Гарри Поттер и философский камень", написанной Джоан Роулинг в 1997 году, и представь ее в формате JSON.

Чем больше примеров, тем лучше ИИ понимает закономерности и выдает более точные результаты. Однако, стоит помнить о лимите контекста – слишком большое количество примеров может привести к обрезанию промпта.

Рассуждение по цепочке

Chain-of-thought (цепочка рассуждений) – это метод, при котором ИИ сначала «думает» вслух, поэтапно рассуждая о задаче, а затем выдает структурированный результат. Это особенно полезно для сложных задач, требующих логического мышления.

Пример:

Сначала поэтапно рассуждай, а затем извлеки информацию о следующем предложении и представь ее в формате JSON: "Температура воздуха в Москве сегодня 25 градусов Цельсия, ветер северный, 5 м/с."

Рассуждение:
1. Нужно извлечь информацию о температуре, ветре и скорости ветра.
2. Температура указана в градусах Цельсия.
3. Направление ветра - северный.
4. Скорость ветра - 5 м/с.

Вывод:
{
  "temperature": "25 градусов Цельсия",
  "wind_direction": "северный",
  "wind_speed": "5 м/с"
}

Этот метод помогает ИИ лучше понять задачу и избежать ошибок.

Промптинг на основе ролей и вызова функций

Role-based prompting (назначение роли) – это метод, при котором ИИ «играет» определенную роль, например, «эксперта по анализу данных». Function-call prompting (вызов функций) – это метод, при котором ИИ вызывает заранее определенные функции для получения структурированных данных.

Пример (Role-Based):

Представь, что ты эксперт по анализу данных. Извлеки из следующего текста информацию о продажах и представь ее в формате JSON: "В первом квартале продажи выросли на 10%, во втором - на 15%, в третьем - на 5%."

Пример (Function-Call):

Предположим, у нас есть функция extract_sales_data(text), которая извлекает данные о продажах из текста и возвращает их в формате JSON.

Вызови функцию extract_sales_data для следующего текста: "В первом квартале продажи выросли на 10%, во втором - на 15%, в третьем - на 5%."

Промптинг на базе вызова функций требует предварительной настройки функций, но обеспечивает максимальный контроль над структурой вывода. OpenAI GPT-4 (и GPT-4o) и Claude активно используют этот подход.

Лучшие практики для надежных результатов

Четкость и конкретика

Четкость и конкретика – залог успеха. Избегайте двусмысленности в запросах. Укажите, какую именно информацию вы хотите получить и в каком формате.

Например, вместо «Извлеки информацию о пользователе» напишите: «Извлеки имя, email и дату регистрации пользователя и верни это как JSON объект». Используйте фразы, которые явно указывают на желаемый формат: «Return as JSON object», «Use YAML format». Чем точнее запрос, тем меньше вероятность ошибок.

Контекст и ограничения

Предоставление контекста помогает ИИ лучше понять задачу. Укажите, откуда берутся данные, какие ограничения существуют (например, лимит токенов). Ограничения помогают избежать «разрастания» ответа и фокусируют ИИ на главном.

Например, можно указать: «Ответ должен быть не более 200 токенов». Важно также указать схему данных, которой должен соответствовать вывод. Это можно сделать, например, с помощью JSON Schema.

Итеративное улучшение

Итеративное улучшение – важная часть процесса. Начните с простого запроса, оцените результат и постепенно усложняйте запрос, добавляя детали и уточнения. Используйте стратегии повторных попыток, если первая попытка не удалась. Например, в PocketFlow Node можно указать max_retries=3 при определении узла, чтобы автоматически повторить запрос три раза в случае ошибки. Не бойтесь экспериментировать с разными формулировками и подходами.

Распространенные ошибки и решения

Распространенные ошибки – ошибки форматирования и галлюцинации. Чтобы избежать ошибок форматирования, используйте валидацию с помощью Pydantic или Zod. Эти библиотеки позволяют проверить, соответствует ли вывод заданной схеме.

Для борьбы с галлюцинациями используйте разложение промпта на более мелкие части. Вместо одного сложного запроса разбейте задачу на несколько простых. «Explain step-by-step» – магическая фраза, которая помогает ИИ более осознанно подходить к задаче и уменьшает вероятность галлюцинаций.

Пример:

Для валидации JSON ответа можно использовать следующий код на Python с Pydantic v2+:

from pydantic import BaseModel, field_validator
import json

class User(BaseModel):
    name: str
    email: str
    registration_date: str

    @field_validator('email')
    @classmethod
    def email_must_contain_at_symbol(cls, email):
        if '@' not in email:
            raise ValueError('Invalid email format')
        return email

json_data = '{"name": "John Doe", "email": "john.doeexample.com", "registration_date": "2024-01-01"}'

try:
    user = User.model_validate_json(json_data)
    print("Valid JSON")
except Exception as e:
    print(f"Invalid JSON: {e}")

Этот код проверяет, соответствует ли JSON объект схеме User и содержит ли email символ @.

Практическое руководство по реализации

Примеры извлечения данных

Структурированное выходное подсказывание значительно упрощает извлечение данных. Рассмотрим пример извлечения информации о событии календаря с использованием Python и библиотеки openai в связке с Pydantic для валидации:

from openai import OpenAI
from pydantic import BaseModel, Field
from datetime import datetime

class CalendarEvent(BaseModel):
    title: str = Field(description="Название события")
    start_time: datetime = Field(description="Время начала события")
    end_time: datetime = Field(description="Время окончания события")
    location: str = Field(description="Место проведения события")

client = OpenAI()

def extract_event_info(text: str) -> CalendarEvent:
    response = client.responses.parse(
        model="gpt-4o-2024-08-06", # Или более поздняя версия gpt-4o, поддерживающая Structured Outputs
        input=[{"role": "user", "content": f"Извлеки информацию о событии из текста: {text} и представь в формате JSON, соответствующем схеме CalendarEvent."}],
        text_format=CalendarEvent
    )
    return response.output_parsed

event_text = "Встреча с командой завтра в 10:00 в офисе, заканчиваем в 12:00."
event = extract_event_info(event_text)
print(event)

Этот код использует новый метод client.responses.parse для автоматической валидации и приведения ответа к нужному типу с помощью Pydantic. Если LLM выдаст невалидный JSON, Pydantic выбросит исключение.

Суммирование и анализ

Структурированное выходное подсказывание также полезно для задач суммирования и анализа. Например, можно извлечь ключевые темы и тональность текста и представить их в JSON:

from openai import OpenAI
from pydantic import BaseModel, Field

class SentimentAnalysis(BaseModel):
    summary: str = Field(description="Краткое содержание текста")
    sentiment: str = Field(description="Тональность текста (положительная, отрицательная, нейтральная)")
    key_topics: list[str] = Field(description="Список ключевых тем")

client = OpenAI()

def analyze_sentiment(text: str) -> SentimentAnalysis:
    response = client.responses.parse(
        model="gpt-4o-2024-08-06", # Или более поздняя версия gpt-4o, поддерживающая Structured Outputs
        input=[{"role": "user", "content": f"Проанализируй текст: {text} и представь результат в формате JSON, соответствующем схеме SentimentAnalysis."}],
        text_format=SentimentAnalysis
    )
    return response.output_parsed

text = "Сегодня был отличный день! Погода прекрасная, и я успел сделать много дел."
analysis = analyze_sentiment(text)
print(analysis)

Этот код также использует client.responses.parse для получения структурированного вывода.

Интеграция с API и инструментами

Структурированное выходное подсказывание упрощает интеграцию с внешними API и инструментами. Например, можно использовать LangChain для создания цепочек, которые автоматически извлекают данные и передают их в другие сервисы.

Обработка ошибок и валидация

Валидация – критически важный шаг. Используйте Pydantic (Python) или Zod (JavaScript) для проверки соответствия структуры данных.

Пример (JavaScript с Zod):

import { z } from "zod";

const UserSchema = z.object({
  name: z.string(),
  email: z.string().email(),
  age: z.number().min(18),
});

const userData = { name: "John Doe", email: "invalid-email", age: 17 };

try {
  const validatedData = UserSchema.parse(userData);
  console.log("Valid data:", validatedData);
} catch (error) {
  console.error("Validation error:", error.errors);
}

Всегда предусматривайте обработку ошибок. Если LLM выдает невалидный JSON, повторите запрос с более четкими инструкциями или используйте резервный механизм.

Часто задаваемые вопросы (FAQ)

Какой формат выбрать: JSON, XML или YAML?

Выбор формата зависит от ваших задач.

  • JSON идеально подходит для машинной обработки и скорости, например, при работе с API.
  • XML подойдет, если важна читаемость человеком и структурирование данных, как в конфигурационных файлах, и особенно хорошо работает с моделями, такими как Claude, которые были обучены на данных с XML-структурой.
  • YAML – золотая середина, сочетающая удобочитаемость и гибкость, удобен для конфигураций и хранения данных.

Для простоты начните с YAML, а затем переходите к JSON для оптимизации.

Как избежать ошибок форматирования?

Используйте валидацию — в Python с Pydantic или в JavaScript с Zod. Эти библиотеки проверяют, соответствует ли вывод заданной схеме. Например, Pydantic поможет убедиться, что все обязательные поля в JSON присутствуют и имеют правильный тип. Лучше проверить сразу, чем потом искать ошибку в коде.

Какую модель LLM лучше использовать для структурированного вывода?

GPT-4o от OpenAI отлично справляется с JSON, обеспечивая высокую точность и скорость, особенно с функцией Structured Outputs. Claude от Anthropic хорошо работает с XML, особенно если нужно структурировать большие объемы данных, благодаря своей архитектуре обучения. Gemini от Google также поддерживает структурированный вывод в JSON и enum-значениях, включая JSON Schema. Попробуйте разные модели и сравните результаты на своих данных.

Как интегрировать структурированный вывод в существующие приложения?

Используйте библиотеки для парсинга (разбора) данных. В Python это json, xml.etree.ElementTree и PyYAML. В JavaScript – встроенный JSON.parse() и библиотеки вроде js-yaml и xml2js. Убедитесь, что ваш код корректно обрабатывает возможные ошибки парсинга.

Что делать, если модель отказывается выдавать структурированный вывод?

Уточните запрос! Добавьте примеры желаемого формата (few-shot learning). Используйте chain-of-thought reasoning, чтобы модель сначала «думала вслух», а затем выдавала результат. Если ничего не помогает, попробуйте другую модель или измените подход к формированию запроса.