Извлечение данных (extraction) — это превращение неструктурированного текста в поля: название компании, ИНН, сумма, дата, список товаров. Здесь строгий формат ответа и подготовка входных данных важнее, чем самая большая модель. Все модели ниже доступны по одному ключу sk-heli- из вкладки «Ключи» после регистрации на getheli.ru.
С каких моделей начать
Выбирайте по замеру, а не по названию: разметьте вручную 30–50 документов и сравните долю полностью правильных полей у 2–3 моделей. Часто быстрая модель с хорошей схемой справляется не хуже сильной, а сильную стоит оставить для документов, на которых быстрая ошибается.
- openai/gpt-5.4-mini — универсальный старт для извлечения по схеме.
- google/gemini-3.5-flash и google/gemini-3.5-flash-lite — для больших объёмов и длинных документов.
- deepseek/deepseek-v4-flash — недорогой вариант для простых схем на большом потоке.
- anthropic/claude-sonnet-5 или openai/gpt-5.5 — когда нужно рассуждение: сложные таблицы, договоры, неоднозначные формулировки.
Строгий формат: JSON Schema
Вариант null для отсутствующих полей важен: без него модель склонна придумывать значение. После json.loads проверяйте данные кодом, например Pydantic-моделью: длина ИНН, сумма больше нуля, дата не в будущем. Поддержка json_schema зависит от модели; если её нет, используйте режим json_object и опишите поля в промпте.
import json, os
from openai import OpenAI
client = OpenAI(base_url="https://getheli.ru/v1", api_key=os.environ["HELI_API_KEY"])
document_text = open("invoice.txt", encoding="utf-8").read()
schema = {
"type": "object",
"properties": {
"company": {"type": ["string", "null"]},
"inn": {"type": ["string", "null"]},
"total": {"type": ["number", "null"]},
"date": {"type": ["string", "null"], "description": "YYYY-MM-DD"},
},
"required": ["company", "inn", "total", "date"],
"additionalProperties": False,
}
resp = client.chat.completions.create(
model="openai/gpt-5.4-mini",
messages=[
{"role": "system", "content": "Извлеки поля из документа. Если поля нет, верни null."},
{"role": "user", "content": document_text},
],
response_format={"type": "json_schema",
"json_schema": {"name": "invoice", "strict": True, "schema": schema}},
max_tokens=1000,
)
data = json.loads(resp.choices[0].message.content)Подготовьте вход
- HTML: удалите скрипты, стили, меню и футер, оставьте основной текст (BeautifulSoup, trafilatura). Это сокращает токены и шум.
- PDF с текстовым слоем: извлеките текст библиотекой pypdf или pdfplumber; pdfplumber умеет отдавать таблицы строками и ячейками.
- Сканы и фото: в Heli есть POST /v1/ocr, совместимый с Mistral OCR. Он принимает document_url, image_url или base64 и возвращает страницы в Markdown, которые затем можно передать модели для извлечения.
- Длинные документы: делите на части по разделам и объединяйте результаты кодом.
Типичные ошибки
Если ответ обрезан лимитом (finish_reason равен length), JSON окажется неполным и json.loads упадёт — увеличьте max_tokens. Не просите модель посчитать итоговую сумму по строкам: надёжнее извлечь строки и сложить их кодом. Ошибки Heli приходят в формате OpenAI с полем error.message, по нему удобно разбирать сбои в логах.
Попробуйте Heli
Ключ sk-heli- появляется после подтверждения почты. Через Google и Яндекс — сразу в кабинете.