Lyumi v4 — Structured retrieval (SQL lookup)
1 мая 2026, вечер. Архитектурный shift v3 → v4 — переход от prompt-patches к structured retrieval. Sprint завершён за один день (изначальная оценка была 5-7 дней; Камал поправил эстимат, оказался прав).
Suть сдвига
v3 (RAG-based): 164K чанков в ChromaDB → embedding retrieval → top-5 → LLM сшивает → промпт-патчи (anti-phantom 3 линии, fact-anchors, citation verifier, blacklist фантомных приказов) ограждают от галлюцинаций.
v4 (Hybrid structured + semantic): 14,216 records в SQLite + 164K чанков в ChromaDB. Для запросов с явными identifiers (ст. N кодекса, Приказ N, OSHA 1910.X) — детерминированный SQL lookup ПЕРЕД semantic. LLM получает structured data + опц. semantic дополнение.
Ключевое отличие: на запросах с явными identifiers phantom НПА-факта impossible by design. Не нужно надеяться что embedding найдёт правильный chunk — SQL exact match гарантирует точный текст.
Что в проде сейчас (1 мая 2026)
SQL база /opt/lyumi/lyumi_npa.db (118 MB, mounted в Docker как /app/lyumi_npa.db)
14,216 структурированных records:
| Категория | Количество | Источник |
|---|---|---|
| Articles (статьи кодексов) | 3,114 | 8 кодексов РК |
| Article parts (пункты внутри) | 10,709 | regex ^\s+(\d+(?:-\d+)?)\. |
| Orders (приказы/законы/ТР) | 176 | v/p/z/h PDF |
| International standards | 217 | OSHA, ISO, IOGP, NFPA, ANSI, ACGIH, AIHA, NIOSH, ILO, NEBOSH, OHSAS, IPIECA, SBTi |
8 кодексов РК (полная иерархия Раздел/Глава/Статья/Пункт)
| Code | Articles | Закон |
|---|---|---|
| КоАП | 1,071 | № 235-V от 2014 |
| УК | 503 | № 226-V от 2014 |
| ЭК | 418 | № 400-VI от 2021 |
| КЗ | 297 | № 360-VI от 2020 |
| КН | 284 | № 125-VI от 2017 |
| ТК | 221 | № 414-V от 2015 |
| ЗК | 186 | № 442 от 2003 |
| ВК | 134 | № 178-VIII от 2025 |
176 orders
- 139 приказы (МТСЗН 7+, МЧС 25, МЗ 15, МЭГПР 10, Минэнерго 10, МВД 7, прочие)
- 8 ТР ТС/ЕАЭС
- 5 постановлений Правительства
- 3 закона
- 21 не определилось (часть методичек с cyrillic именами, старые приказы)
217 international standards
OSHA 70, NFPA 7, AIHA 4, IOGP 3, ANSI 3, ACGIH 2, API 2, ILO 2, SBTi 2, NIOSH 1, org="?" 121 (parser detection не сработал — будет дочистка через Sonnet metadata extraction в monthly cycle).
Архитектура retrieval pipeline
User query
↓
[Synonym expansion + Multi-query async + Cohere Rerank] (как в v3)
↓
[Registry hint] из document_registry (если запрос про конкретный документ)
↓
[NEW v4] NPA SQL lookup — npa_lookup(query):
├── ст. N <кодекс> → article exact match
├── Приказ N (МТСЗН/МЧС/МЗ) → order exact match
└── OSHA 1910.X / ISO N / IOGP N → international standard lookup
↓
hits_to_context() injects [ТОЧНЫЕ ДАННЫЕ ИЗ БАЗЫ НПА] блок ПЕРЕД semantic chunks
↓
LLM (Sonnet 4) получает structured data + опц. semantic дополнение
↓
Streaming Telegram ответ
↓
Reflection layer (clean на структурированных запросах)
Smoke test 1 мая 19:51 (4/4 pass)
| Запрос | SQL hit | Время | Что пишет бот |
|---|---|---|---|
| ст. 156 УК РК | ✅ | 57s cold | Точные части 1-4: 160 МРП → 200 МРП → 5 лет → 7 лет + причинно-следственная связь |
| Приказ 344 МТСЗН наряд-допуск | ✅ | 10s | Реальные детали: 2 экземпляра, ЛЭП/газопроводы, хранение 1 год / при НС с расследованием |
| ст. 11 ТК РК | ✅ | 7s | "Акты работодателя" + ЭЦП + связка с СУОТ через ст. 182 |
| Приказ 340 МТСЗН СУОТ | ✅ | 10s | Структура: Планирование/Функционирование/Контроль/Совершенствование |
Reflection: clean после каждого — нет галлюцинаций, нет редактирования.
Тонкие места (что v4 НЕ решает)
1. Phantom examples / phantom statistics
SQL устраняет phantom НПА-факта (точный текст статьи). Но если юзер просит "приведи пример из практики казахстанского предприятия" — LLM может выдумать пример, потому что в SQL этого нет.
Что остаётся: Reflection layer + strict prompt rules для не-цитатной части ответа. Anti-phantom 3 линии частично нужны для examples / cases.
2. Тематические запросы
"Как ст. 156 УК применяется при коллективных переговорах в нефтегазе" — это не lookup-запрос, это semantic. ChromaDB остаётся primary source для тематических. Это норма — гибрид.
3. Иерархия правил/положений в orders
parse_orders.py извлёк metadata (number, issuer, date, title) + full_text для 176 файлов. Иерархия секций внутри (Глава I → 1. → 1.1) НЕ extracted — это в TODO для дочистки.
Это значит: "Приказ 344 МТСЗН пункт 5.3" найдёт приказ, но не пункт 5.3 точечно. Полный текст уйдёт в LLM, она найдёт.
4. International standards с org="?" (121 файл)
Parser detection не сработал на сложных filenames. OSHA 1910.146 ищется по filename pattern — но не все стандарты имеют чистое имя. Нужна Sonnet metadata extraction (~$0.50 на 121 файл).
Промпт-патчи: что МОЖНО снимать в next sprint
После v4 deploy эти compensations стали избыточны для structured queries. Не трогать прямо сейчас (бот в проде стабилен), но в отдельный prompt audit sprint удалить:
| Промпт-патч | Где | Что заменяет |
|---|---|---|
### ⛔ BLACKLIST фантомных приказов (ҚР ДСМ-16 и т.д.) |
llm.py | SQL не содержит несуществующих документов |
| Anti-фантом Линия 1 (Writer rule про темы приказов) | llm.py system prompt | SQL даёт реальную тему |
| Anti-фантом Линия 2 (Reflection #10 phantom attribution) | reflection.py | Может остаться для examples; для НПА упрощается |
| Anti-фантом Линия 3 (Pre-flight kb_api Haiku verify) | bot.py | Замещается детерминистическим lookup |
Fact-anchors 1.3м / 15 м/с / 7 лет / 188-V |
llm.py | Все эти факты теперь в SQL по lookup |
| Citation verifier (regex post-check ссылок на НПА) | bot.py verify_citations | SQL exact match до запроса к LLM |
| Synonym expansion для structured queries | llm.py expand_query | Не нужен (regex parsing query сам понимает "ст. N" / "Приказ N") |
Что ОСТАЁТСЯ в промптах (реально семантические правила): - Тон Люми (профессиональный, женский род о себе) - Юрисдикция РК (запрет на РФ-нормы — но это уже в данных через cleanup) - Формат документов (TBT/JSA/PTW pipelines имеют свою логику) - Anti-phantom для examples / statistics — там где SQL не помогает
Ожидаемое сокращение system prompt: −30-50% размера, без потери качества (часто с улучшением — модель не путается в собственных правилах).
Maintenance cycle (ежемесячный)
Кодексы и приказы РК обновляются. Каждый месяц:
- Скачать новые редакции с Әділет →
Карточки Core New/local standards/на маке - Запустить парсеры локально:
bash cd hse_copilot/npa_parser python3 parse_kodex.py --all --db /tmp/lyumi_npa.db python3 parse_orders.py --all --db /tmp/lyumi_npa.db python3 parse_international.py --db /tmp/lyumi_npa.db - cp /tmp/lyumi_npa.db в
Карточки Core New/hse_copilot/lyumi_npa.db(iCloud) - scp на AX41:
bash scp ~/Library/.../hse_copilot/lyumi_npa.db root@65.108.5.40:/opt/lyumi/ - Restart:
bash ssh root@65.108.5.40 "docker compose -f /opt/lyumi/docker-compose.yml restart bot" - Smoke test ключевых запросов (ст. 156 УК, Приказ 344, новых добавленных)
Полный цикл = ~10-15 минут активной работы. Re-parse быстрый (5 минут), scp быстрый, restart быстрый.
Файлы
На маке Карточки Core New/hse_copilot/
npa_parser/parse_kodex.py— парсер 8 кодексов (regex Раздел/Глава/Статья/Пункт)npa_parser/parse_orders.py— парсер приказов/законов/ТР (multi-pattern для header)npa_parser/parse_international.py— парсер 226 international standardslookup_npa.py— детерминистический SQL lookup с regex parsing querylyumi_npa.db(118 MB) — production copy SQLitebot.py— hook NPA SQL lookup перед registry_hint
На AX41 /opt/lyumi/
lyumi_npa.db(mounted в Docker как /app/lyumi_npa.db)lookup_npa.py(COPY *.py в Dockerfile)bot.pyс hook'ом.envдополненLYUMI_NPA_DB=/app/lyumi_npa.dbdocker-compose.ymlдополнен volume mount
Что в очереди (не блокирующе)
- Дочистить 121 international с org="?" через Sonnet metadata extraction (~$0.50, 30 минут)
- Иерархия секций в orders — extract Глава/Раздел/Пункт для приказов и правил (1-2 часа на edge cases)
- 21 "?" doc_type в orders — методички с cyrillic именами, старые приказы
- 67 orders с пустым issuer — расширить ISSUER_KEYWORDS
- Prompt audit — снять промпт-патчи перечисленные выше (отдельный sprint, 1-2 часа)
- Tool calling rewrite — явный choice LLM между lookup_tool / semantic_search / web_search (Q3 в strategy_2026)
Lessons (записаны в memory как feedback_*)
- AI-assisted dev радикально быстрее human-time эстиматов. "5-7 дней sprint" → 30 минут активного кода + ~2 часа integration. Камал поправил эстимат, был прав.
- Architecture > prompts. Один SQL lookup убирает 5+ промпт-компенсаций. OpenEvidence + GPT-5.5 "гоблины" — индустрия пришла к тому же.
- Production data парсится через regex на 90%+ на стандартных форматах Әділет. LLM нужен только для edge cases.
- iCloud + SQLite = "disk I/O error" — SQLite требует local filesystem. SQL DB положили в /tmp/ и потом cp в Карточки.
Связи
- [[lyumi/migration_ax41]] — миграция инфры (1 мая утро)
- [[lyumi/finetune_apr30]] — fine-tune эксперимент 30 апр (на полку, отдельная история)
- [[lyumi/strategy_2026]] — общая стратегия года
project_v4_sql_lookup_deployed.md— memory snapshot 1 маяproject_monthly_lora_loop.md— стратегия LoRA (отдельный трек)feedback_no_hybrid_architectures.md— single-path принцип Камала