Как устроен AI-слой Al-ina: prod vs prototype, почему не fine-tune, hybrid scoring, validation pipeline. Ниже — полный pipeline от сырого аудио до visit_*.json.
Prod-путь batch-смены: микрофон на рабочем месте → OGG-смена → STT → SQLite → сегментация → DeepSeek → JSON → дашборд. Код: transcription_analyzer/.
auto_record.bat → auto_send.bat → POST /upload-audio). Live RTMP пишет в ту же streams.db, но без _audio metadata не попадает в visit pipeline.shift_*.ogg + metafinal_refinement + _audiotimeline_events| # | Этап | Модуль | Функция / триггер | Формат данных |
|---|---|---|---|---|
| L1 | Запись смены | auto_record.bat | FFmpeg mic → OGG | shift_YYYYMMDD.ogg, base_time_ms |
| L1 | Upload | main.py | upload_audio() → BackgroundTasks | multipart: file + stream_id |
| L2 | Batch STT | transcribe_wav.py | transcribe_whisper() / transcribe_yandex() | row: {text, _audio{recording_id, segment_*}} |
| L2 | Live STT | transcription/session.ts | emitTranscription() → gRPC | row без _audio (не в visit pipeline) |
| L3 | Timeline DB | loader.py | load_sqlite() | DataFrame: stream_id, timestamp_ms, clean_text |
| L4 | STT-сессии | pipeline.py | _split_into_stt_sessions() | группы фраз, пауза > 45 сек |
| L4 | Visit split | semantic_splitter.py | split_chunk() | candidate: raw_text, ts_start/end, pending |
| L5 | Summary | pipeline.py | _call_deepseek_visit() | JSON: summary, client_request, outcome… |
| L5 | KPI | scoring_engine.py | score_visit() | score_pct, score_level, t2 / ПС rubric |
| L5 | Sale | sale_detector.py | detect_sale() | sale_status, sale_evidence, confidence |
| L6 | Save | pipeline.py | process_stream() | visit_NNNN_hash.json |
| L6 | API | main.py | GET /visits, GET /stats | JSON list + агрегаты для UI |
Rule-based splitter без LLM на каждую границу — cost control. LLM вызывается только после формирования candidate-visit.
phrase_score (0–3) → density valleys (окно ±6) или greeting/goodbye markers. Статус до AI: analytics_status: pending_final_validation.Три вызова DeepSeek на визит (summary, KPI, sale) — только если perform_final_analytics=True. Sale detector: algo first, AI на хвосте 35% фраз если algo не уверен.
visit_*.json — idempotent по (stream_id, ts_start, ts_end). Опционально: _export_visit_audio_segment() → WAV/OGG клипа визита.Слева — схема обработки (код). Справа — скрин боевого дашборда с live API (без PII в расшифровках).
Primary pipeline не перезаписывает raw visits. Validation layer: pairwise check соседних candidate-visits → cluster merge → re-run DeepSeek на объединённом тексте. 173 pair labels в ML corpus. Документация: transcription_analyzer/docs/VISIT_VALIDATION_PIPELINE.md.
temperature 0.3, response_format: json_objecttemperature 0.1, анализ хвоста 35% фразМало gold-разметки на старте; rubric меняется под клиента (t2 → ПС). Быстрее iteration через промпт + rule layer. ML-merge — supervised roadmap, не замена LLM.
Разбивка STT-потока на визиты — чисто алгоритмически: phrase_score, rolling window, valley detection, greeting/goodbye anchors. LLM не вызывается на каждую границу — cost + latency.
STRONG_KEYWORDS в semantic_splitter (сим, тариф, MNP…)База тарифов t2 в промпте rubric, не в vector store. RAG по продуктовому каталогу — roadmap для KPI 1.2 (корректность фактов).
score_low_data при <15 фразsale_status = неясно (сейчас ~73%)mediamtx → RTMP / RTSP / HLS web (Node.js) → STT, timeline, API :5000 transcription-analyzer (FastAPI) → pipeline + dashboard :8001 nginx → al-ina.ru, /dashboard/ proxy
streams.db, visit_*.jsonSTT_BACKEND=whisper|yandex в .envОдин prod-файл 48,5 мин — реальный замер Whisper vs оценка Яндекс.
| Параметр | Whisper (faster-whisper small) | Yandex SpeechKit |
|---|---|---|
| Стоимость 48,5 мин | 0 ₽ | ~730 ₽ (15 ₽/мин) |
| Время обработки | 21 мин (real) | ~5 мин (estimate) |
| VAD / тишина | 46% убрано | Нет |
| Точные word timestamps | <0,1 с | ±25 с (chunks) |
| gRPC real-time stream | ❌ | ✅ |
| Решение | Whisper для batch-смен · Yandex для RTMP live | |
CatBoost на features: gap_sec, service_ratio, TF-IDF cosine. Labels из validated clusters + manual review.
Primary pipeline не перезаписывает raw visits. Validation layer → отдельный output → metrics только на validated subset.