Звонящий не выдаёт данные сам: автомат держит раскрытые факты явно и отдаёт звонящему только их. Тест прогоняет длинную серию реплик и проверяет, что ни один нераскрытый факт не прозвучал. Главная находка — матчинг по порогу близости не работает. На multilingual-e5-small настоящие вопросы дают 0.79–0.95, а «Оставайтесь на линии» — до 0.89: диапазоны перекрываются, и любой порог либо выдаёт адрес на «успокойтесь», либо не слышит «где вы находитесь?». Решение — сравнение с ближайшим соседом: у пункта чек-листа несколько формулировок (examples), рядом общий список не-вопросов (checklists/common.yaml), и реплика засчитывается пункту, только если она ближе к нему, чем к любому не-вопросу. На отложенных фразах: 19 из 20 вопросов, 0 из 8 ложных срабатываний. Реплика режется только по границам предложений, со знаком: «?» для e5 — сильный признак вопроса, без него «Куда ехать» уходит к не-вопросам. Подсказка берёт неотработанный пункт из автомата. В живой сессии автомат начнёт слышать оператора, когда голосовой контур передаст ему stt.final. Ждёт ключа LLM: условие approach у скрытых фактов, звонящий своими словами, dialog/llm.py с кэшем.
28 lines
1.1 KiB
Python
28 lines
1.1 KiB
Python
"""Модели диалога, общие для всех сессий процесса.
|
||
|
||
Эмбеддер грузится один раз при старте приложения: 2–3 секунды на загрузке
|
||
занятия недопустимы, а на старте стенда их никто не заметит.
|
||
Если модели нет — занятие всё равно идёт, но подсказки теряют точность
|
||
(идут по порядку чек-листа), и это видно в /api/health.
|
||
"""
|
||
|
||
import logging
|
||
from functools import lru_cache
|
||
from pathlib import Path
|
||
|
||
from app.config import get_settings
|
||
from app.dialog.embeddings import E5Embedder, Embedder
|
||
|
||
log = logging.getLogger(__name__)
|
||
|
||
ROOT = Path(__file__).resolve().parents[2]
|
||
|
||
|
||
@lru_cache(maxsize=1)
|
||
def get_embedder() -> Embedder | None:
|
||
model_dir = ROOT / get_settings().models_dir / "e5-small"
|
||
try:
|
||
return E5Embedder(model_dir)
|
||
except FileNotFoundError:
|
||
log.warning("модели эмбеддингов нет в %s — слот-автомат выключен, make models", model_dir)
|
||
return None
|