Что реально даёт выигрыш, а что является декорацией. Проверено на полном томе ИОС1.1 (78 стр., 11,8 МБ, текстовый слой есть).
| Этап | Чем делать | Что даёт |
|---|---|---|
| 1. Извлечение | pypdf постранично в JSON ({page, chars, text}) |
полный корпус; проверить, что нет страниц с chars < 50 (скан без слоя) |
| 2. Сверка кодом | Decimal + re, на своей машине |
вся арифметика, балансы, нумерация, обозначения НТД, повторы |
| 3. Независимый аудитор | модель ДРУГОГО семейства по первоисточнику | находки, которые пропустил из-за невнимательности к тому же тексту |
Том объёмнее ~20 страниц, или когда отчёт будет разбираться с подрядчиком, или когда одну и ту же методику надо применить без пропусков и с проверяемым следом. Для быстрой прикидки по одному листу достаточно этапов 1 и 2.
√(P²+Q²), tgφ, годовой расход — только кодом.СОВПАДАЕТ / НЕ СОВПАДАЕТ / НЕ ПРОВЕРИТЬ.max_tokens с большим запасом.content. Ответ приходит completion_tokens == max_tokens, reasoning_tokens == max_tokens, а content пустой. Признак: нулевая длина ответа при списанной стоимости. Лечение — поднять max_tokens до 16000 и требовать «отвечай сразу, без длинных рассуждений».anthropic/claude-sonnet-5.5: при промпте ~87 тыс. символов модель ушла в reasoning, вернула finish_reason=length и пустой content. Рабочая схема: max_tokens ≥ 24000 (лучше 32000) и дробление ПЗ на части по ~25 тыс. символов (том 78 стр. → 4 части, 45–97 с на часть). Обязательно проверять оба поля — content И finish_reason; пустой content записывать как ошибку прогона, а не как «нового не найдено». Эндпоинт: POST https://api.polza.ai/v1/chat/completions, заголовок Authorization: Bearer <HERMES_CUSTOM_POLZA_AI_API_KEY>.Не складывать списки, а разделить находки по источнику:
Отдельно фиксировать в отчёте, что дал третий этап — это честная оценка метода и единственный способ понять, когда его стоит повторять.
Текстовый слой таблицы — плоский текст, колонки разделены пробелами, поэтому разбор идёт регулярками по префиксу номера строки, а не по позициям колонок:
m = re.match(rf"^(\d{{1,2}})\s+(\S.*)$", line) # номер строки + остаток
rest = re.sub(r"\d+\s*кВт", "", rest) # убрать «22кВт» из названия
# строки-продолжения (перенос номера с прошлой страницы) отбрасывать по «Изм. Кол.уч.»
Признак правильного разбора: сумма Ру по строкам сходится с «Итого ВРУ с КРМ» с точностью до округления. Если не сходится на десятки кВт — разбор врёт, а не документ.