dbe36d3323746672914a07923b3275f69527a08c
Прежний guard снимал эмбеддинг-матч, если услуга собрала в клинике больше 8 разных названий. Это наказывало легитимные частотные услуги — одна «МРТ головного мозга» реально встречается под десятками протоколов (с контрастом, 3Тл, предоперационная), и все они верно нормализуются к ней. Процент падал до 69%. Теперь снимаем только НЕуверенные матчи (<0,72) внутри концентрированных групп: так отсекается сиблинг-захват (напр. «Магний Mg (моча)» подтягивал Никель/Свинец/Ртуть в моче на пороге 0,70), а верные вариации остаются сопоставленными. Признак ошибки — низкая уверенность, а не число названий. Итог на тестовом архиве: 16 140 позиций извлечено, 73,7% нормализовано автоматически (цель ТЗ ≥70%), 273 неуверенных матча — в очередь верификации. Цифры выровнены в README, ARCHITECTURE, питч-деках, PPTX, quality_report. Плюс полировка: извлечение города клиники, регистронезависимый поиск. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
MedArchive — обработка архива прайсов клиник-партнёров
Terricon Valley · Medtech Hackathon (26–28.06.2026).
Живой демо: https://med.secondbrain.tools
🎬 Демо-трейлер
▶️ Смотреть трейлер (40 сек) · вживую: med.secondbrain.tools/pitch
Система автоматически разбирает архив разнородных прайс-листов клиник (PDF, сканы, DOCX, XLSX/XLS), извлекает услуги и цены, нормализует их к справочнику из 1287 услуг и даёт поиск и сравнение «кто оказывает услугу и по какой цене».
Результат на тестовом архиве (8 клиник, 10 файлов)
- 16 140 позиций извлечено: нативными парсерами + трудные PDF (битый текстовый слой, нестандартная вёрстка) — через Gemini Vision; обработаны все 8 клиник.
- 73,7% позиций нормализованы автоматически (цель ТЗ — не ниже 70%).
- Остальное уходит в очередь ручной разметки, как и предполагает ТЗ.
Полный отчёт о качестве — docs/quality_report.json.
Стек и решения
| Слой | Решение |
|---|---|
| Извлечение | Python: pdfplumber + PyMuPDF, openpyxl/xlrd, python-docx. Таблицы из PDF без линий восстанавливаются по координатам слов |
| Vision-добор | Gemini (gemini-2.5-flash) — для сканов и битого текстового слоя |
| Нормализация | Каскад: код тарификатора → точное совпадение → эмбеддинги Gemini → нечёткое сравнение → очередь unmatched |
| Валидация | Правила ТЗ §4.4: положительность цены, резидент ≥ нерезидент, аномалии, версионирование |
| Хранилище | SQLite (MVP, разворачивается без Docker). Боевая схема PostgreSQL + pgvector — в db/migrations |
| API | FastAPI: эндпоинты ТЗ + /stats, загрузка архива, авто-загрузка из папки, алерты об изменении цен, экспорт в Excel; OpenAPI на /docs |
| Фронт | Одностраничный (Tailwind): поиск и сравнение цен, экран верификации оператора, дашборд обработки |
| Деплой | Контейнер API за Caddy на Selectel KZ |
Подробно об устройстве системы — docs/ARCHITECTURE.md (поток данных, карта модулей, модель данных, обоснование решений).
Запуск локально
python -m venv .venv && .venv/bin/pip install -e .
# архив прайсов → data/raw/, справочник → data/reference/dictionary.xlsx
GEMINI_API_KEY=... python scripts/run_pipeline.py # → data/medarchive.db + отчёт
uvicorn api.main:app # → http://localhost:8000/docs
# открыть web/index.html?api=http://localhost:8000
Эмбеддинги и Vision вызываются через Gemini API, поэтому локальная модель не нужна и контейнер остаётся лёгким. Поиск и сравнение в готовой базе работают без обращений к API.
Структура
contracts/ — общие модели данных (контракт между модулями)
db/ — схема PostgreSQL + pgvector
etl/ — извлечение, нормализация, валидация, конвейер
api/ — REST API поиска и сравнения
web/ — одностраничный фронт
infra/ — деплой (compose, Caddyfile)
docs/ — отчёт о качестве, план
pitch/ — презентация и демо-сценарий
scripts/ — запуск конвейера и проверки
Description
Languages
Python
60.5%
HTML
37.5%
CSS
0.7%
Dockerfile
0.5%
TypeScript
0.5%
Other
0.3%
