Перейти к основному содержанию
VOID

Void APIБаза знанийКак извлекать данные из текста в JSON с помощью нейросети

Как извлекать данные из текста в JSON с помощью нейросети

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

Когда LLM лучше регулярных выражений

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

Часто лучший вариант — комбинация: детерминированный код извлекает очевидное (email, ИНН, даты в известном формате), а модель — то, что требует понимания текста. Код же проверяет всё, что вернула модель.

Сначала схема, потом промпт

Опишите поля, типы и допустимые значения до того, как писать промпт. Каждое поле должно иметь ясный смысл: не «дата», а «дата выставления счёта». Для категорий задайте закрытый список значений. Разрешите null для полей, которых может не быть в тексте, — иначе модель начнёт их придумывать.

Если модель и клиент поддерживают структурированный вывод по JSON Schema, используйте его: так ответ гарантированно соответствует форме. Если нет — просите JSON в промпте и всё равно валидируйте ответ в коде. Схема гарантирует форму, но не правильность значений.

Схема заявки, Pydantic v2
from datetime import date
from typing import Literal
from pydantic import BaseModel, Field

class Lead(BaseModel):
    company: str | None = Field(description="Название компании клиента")
    contact_name: str | None
    email: str | None
    phone: str | None
    request_type: Literal["purchase", "support", "partnership", "other"]
    budget_rub: int | None = Field(description="Бюджет в рублях, если указан")
    deadline: date | None
    summary: str = Field(description="Суть запроса, до 200 символов")

Промпт для извлечения полей

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

Системный промпт
Ты извлекаешь данные из входящих заявок в JSON.
Правила:
- Используй только информацию из текста. Не угадывай.
- Если поля нет в тексте, верни null.
- request_type: purchase — хочет купить; support — проблема с продуктом;
  partnership — сотрудничество; other — всё остальное.
- budget_rub: целое число. Если указан диапазон — нижняя граница.
  Если валюта не рубли — null.
- deadline: формат YYYY-MM-DD. Относительные даты («через неделю») — null.
- Имена и названия компаний оставляй как в тексте.
- summary: одно предложение на русском.
Верни только JSON по схеме, без пояснений.

Код: запрос, разбор и валидация

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

extract.py
import json
from pydantic import ValidationError
from lead_schema import Lead  # схема из примера выше
from openai import OpenAI
import os

client = OpenAI(
    api_key=os.environ["VOID_API_KEY"],
    base_url="https://void-api.tech/v1",
)

SYSTEM = open("extract-prompt.txt", encoding="utf-8").read()

def extract_lead(text: str) -> Lead | None:
    messages = [
        {"role": "system", "content": SYSTEM},
        {"role": "user", "content": text},
    ]
    for _ in range(2):
        response = client.chat.completions.create(
            model="gpt-6-luna",
            messages=messages,
            temperature=0,
        )
        raw = response.choices[0].message.content
        try:
            return Lead.model_validate(json.loads(raw))
        except (json.JSONDecodeError, ValidationError) as error:
            messages += [
                {"role": "assistant", "content": raw},
                {"role": "user", "content": f"Ответ не прошёл проверку: {error}. Верни исправленный JSON."},
            ]
    return None  # отправить на ручную проверку

Документация API Void API

Как проверить точность извлечения

Соберите 50–100 реальных документов и вручную разметьте правильные значения. Сравнивайте ответ модели по каждому полю отдельно: общий процент «полностью правильных записей» скрывает, что, например, телефон извлекается всегда, а бюджет — в половине случаев.

Отдельно считайте галлюцинации — значения, которых нет в тексте. Для бизнес-процесса они опаснее пропусков: пустое поле человек заполнит, а выдуманный телефон уйдёт в CRM. Простая защита — проверять, что извлечённые email, телефоны и числа буквально встречаются во входном тексте.

Модель, стоимость и масштаб

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

Стоимость считается по токенам документа, промпта и ответа. JSON-ответ короткий, поэтому основная часть счёта — вход. Для длинных документов передавайте только релевантные страницы или разделы. Держите системный промпт неизменным, чтобы срабатывало кеширование.

Сравнить цены моделейКак считать стоимость токенов

Попробуйте GPT и Claude через Void API

Подключайте GPT и Claude к своим приложениям, ботам и ИИ-агентам через Void API — единый OpenAI-совместимый API. Доступ из России без VPN, пополнение по СБП и оплата по фактическому использованию. Выбирайте модель под задачу, сравнивайте цены и начинайте с одного API-ключа.

Перейти на void-api.techПосмотреть модели и цены

Вопросы и ответы

Как заставить нейросеть всегда отвечать валидным JSON?

Используйте структурированный вывод по JSON Schema, если модель и клиент его поддерживают, и в любом случае валидируйте ответ в коде с повторной попыткой при ошибке.

Можно ли извлекать данные из PDF и сканов?

Текстовые PDF сначала переводят в текст библиотекой. Для сканов нужно распознавание: OCR или модель с поддержкой изображений. Проверьте поддержку изображений конкретной моделью.

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

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