1 мая 2026 — большой сдвиг архитектуры
За один день закрыли работу которая планировалась на 5-7 дней. Ключевое изменение — переход от promt-базированной phantom-защиты к SQL-deterministic retrieval. Фантомы на конкретные НПА теперь невозможны по архитектуре, а не по промпту.
Что сделано
1. Миграция Lyumi на AX41
- Новый сервер Hetzner AX41-NVMe (16 vCPU, 64 GB RAM, NVMe SSD), Helsinki, IP
65.108.5.40 - CPX52 (16 vCPU/32GB) остаётся warm fallback до 5 мая, потом отключим
- Manual-embed режим в retriever.py: SentenceTransformer + vanilla BAAI/bge-m3, single-path
- bge-m3-hse-v2 fine-tuned НЕ взяли в прод (trade-off 79% golden(14) / 39% natural)
- Pushkin (digest bot) также переехал на AX41
2. SQL lookup deployed (главное)
Новый слой retrieval до векторного поиска. lookup_npa.py + lyumi_npa.db в bot.py перед retriever.
База SQL (122 MB): | Таблица | Записей | |---|---| | codes | 8 (ТК, УК, КоАП, ЭК, ЗК, ВК, КЗ, КН) | | articles | 3,114 | | article_parts | 10,709 | | orders | 176 | | international_standards | 217 | | npa_values | 7,643 | | Итого SQL records | ~14,200 |
3. ACGIH TLV-2022 OCR хак
Документ защищён custom CID-шрифтом без ToUnicode mapping. Решение: render через pymupdf 200dpi → rotate -90° → tesseract --psm 4 → split blob по pattern [CAS-num].
Результат: - 616 веществ из 55 страниц «Adopted Values» - 96% с TLV-TWA, 100% с CAS - ~10 минут на OCR всех страниц
lookup_pdk cross-language: - RU↔EN маппинг: бензол↔benzene, сероводород↔hydrogensulfide, аммиак↔ammonia, etc. - Запрос «TLV бензол» → КР ПДК + ACGIH (Benzene 0.05/2.5 ppm A1) в одном LookupHit
Инсайты
Cluj insight: архитектура выше промпта
«Мы делали ошибку, мы промптами пытались архитектурные дыры заткнуть» — Камал
Bonus insights
- bge-m3 ST/FE dense идентичны (cosine 1.000000 на 5 запросах) — sparse можно подключать без переиндексации
- Whisper Groq бесплатно — voice INPUT в проде
- Cohere rerank вредит B_code_article -11pp — BM25 находит точный результат сразу, реранкер перетасовывает и теряет. Идея: adaptive rerank для запросов по регексу кодекса. Но в проде SQL уже забирает эту категорию.
Бенчмарки
Retrieval baseline (vanilla bge-m3 + BM25 + Cohere rerank, golden_v1 90q, semantic match)
Final numbers (с полным rerank): | Метрика | Значение | |---|---| | Avg keyword match @top-10 | 56.5% | | Hit@10 (≥50% kw) | 61.1% | | Strong Hit@10 (≥80% kw) | 32.2% | | Zero-hit | 0% | | Speed | 7.6s/query (с sleep 7s для Cohere Trial 10 RPM) |
По категориям (Hit@10): | Категория | n | Hit@10 | kw@10 | Комментарий | |---|---|---|---|---| | A_direct_number | 26 | 88.5% | 78.1% | НПА с номером — потолок | | B_code_article | 18 | 27.8% | 30.7% | Статьи кодекса — SQL решает в проде | | C_topic | 13 | 53.8% | 52.6% | Тематические | | D_mixed | 13 | 76.9% | 68.7% | Смешанные | | E_edge | 15 | 53.3% | 44.9% | Edge cases | | F_date_ministry | 5 | 40.0% | 49.3% | Дата/министерство |
SQL coverage (smoke test после деплоя)
- ст.156 ТК РК, Приказ ҚР ДСМ-70, ПДК сероводорода/аммиака/бензола/свинца/ртути, TLV benzene/ammonia/formaldehyde/H₂S — все ✅
- Боевой скрин от юзера: Раздел 4 ТК РК → Люми точно назвала ст.179-190 + «документ у меня в базе целиком»
ACGIH OCR
- 616 веществ, 96% с TLV-TWA, 100% с CAS
Decisions и deferrals
| Решение | Статус |
|---|---|
| Sparse retrieval (bge-m3) | Дефер на 9 мая — после недели логов, сравнение с baseline 61.1% Hit@10 |
| Multi-vector (ColBERT) | НЕ делаем — 334 GB storage, не влезет в RAM AX41 |
| ONNX-квантизация | беквыход в testing не дал speedup — deferred |
| Compliance Calendar | НЕ делаем — много возни |
| Investigation Module | Спека в lyumi/modules/investigation, sprint позже |
| Document Intelligence | Спека в lyumi/modules/document_intelligence, sprint позже |
| Voice Output | НЕ делаем, Voice INPUT уже в проде |
| Adaptive rerank (skip Cohere на B_code) | Отложено — SQL уже решает |
План на следующую неделю
2-8 мая: - Наблюдаем прод с SQL — выявляем где lookup_npa ломается, false negatives - 5 мая: выключаем CPX52 - По фидбэку юзеров: фиксы SQL detection regex'ов
9 мая (суббота): - Решение по sparse retrieval по числам log_analysis.py + eval +sparse vs baseline - Критерий: +3pp Hit@10 на golden_v1 → деплой, меньше → остаёмся на baseline
Цифры дня
- 14,200 SQL records в проде
- 616 веществ ACGIH (96% с TWA)
- 167,332 чанков ChromaDB
- Hit@10 baseline = 61.1%, Strong = 32.2%, kw = 56.5%
- 5-7 дней планировали → 1 день сделали
- 0 downtime