Void APIБаза знанийКак извлекать данные из текста в JSON с помощью нейросети
Как извлекать данные из текста в JSON с помощью нейросети
Заявки из почты, реквизиты из счетов, контакты из резюме — нейросеть хорошо превращает неструктурированный текст в поля. Но чтобы результат можно было сохранить в базу без ручной проверки каждой записи, нужны схема, валидация и понятное поведение при сомнениях. Разберём, как построить такой конвейер.
Когда LLM лучше регулярных выражений
Если документы приходят в одном шаблоне, регулярные выражения и парсеры быстрее, дешевле и предсказуемее. LLM выигрывает там, где формулировки свободные: письма клиентов, заявки из форм с полем «комментарий», счета разных поставщиков, резюме.
Часто лучший вариант — комбинация: детерминированный код извлекает очевидное (email, ИНН, даты в известном формате), а модель — то, что требует понимания текста. Код же проверяет всё, что вернула модель.
Сначала схема, потом промпт
Опишите поля, типы и допустимые значения до того, как писать промпт. Каждое поле должно иметь ясный смысл: не «дата», а «дата выставления счёта». Для категорий задайте закрытый список значений. Разрешите null для полей, которых может не быть в тексте, — иначе модель начнёт их придумывать.
Если модель и клиент поддерживают структурированный вывод по JSON Schema, используйте его: так ответ гарантированно соответствует форме. Если нет — просите JSON в промпте и всё равно валидируйте ответ в коде. Схема гарантирует форму, но не правильность значений.
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. При ошибке валидации делается одна повторная попытка с текстом ошибки — модель обычно исправляет формат. Если и вторая попытка неудачна, запись уходит на ручную проверку, а не в базу.
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 # отправить на ручную проверкуКак проверить точность извлечения
Соберите 50–100 реальных документов и вручную разметьте правильные значения. Сравнивайте ответ модели по каждому полю отдельно: общий процент «полностью правильных записей» скрывает, что, например, телефон извлекается всегда, а бюджет — в половине случаев.
Отдельно считайте галлюцинации — значения, которых нет в тексте. Для бизнес-процесса они опаснее пропусков: пустое поле человек заполнит, а выдуманный телефон уйдёт в CRM. Простая защита — проверять, что извлечённые email, телефоны и числа буквально встречаются во входном тексте.
Модель, стоимость и масштаб
Извлечение полей — задача, с которой часто справляются недорогие модели. Начните с быстрой модели, измерьте точность на размеченной выборке и переходите на более сильную только для тех типов документов, где качество недостаточно.
Стоимость считается по токенам документа, промпта и ответа. JSON-ответ короткий, поэтому основная часть счёта — вход. Для длинных документов передавайте только релевантные страницы или разделы. Держите системный промпт неизменным, чтобы срабатывало кеширование.
Попробуйте GPT и Claude через Void API
Подключайте GPT и Claude к своим приложениям, ботам и ИИ-агентам через Void API — единый OpenAI-совместимый API. Доступ из России без VPN, пополнение по СБП и оплата по фактическому использованию. Выбирайте модель под задачу, сравнивайте цены и начинайте с одного API-ключа.
Вопросы и ответы
Как заставить нейросеть всегда отвечать валидным JSON?
Используйте структурированный вывод по JSON Schema, если модель и клиент его поддерживают, и в любом случае валидируйте ответ в коде с повторной попыткой при ошибке.
Можно ли извлекать данные из PDF и сканов?
Текстовые PDF сначала переводят в текст библиотекой. Для сканов нужно распознавание: OCR или модель с поддержкой изображений. Проверьте поддержку изображений конкретной моделью.
Что делать, если модель придумывает значения?
Разрешите null в схеме, явно запретите угадывать в промпте и проверяйте в коде, что ключевые значения встречаются во входном тексте.