feat(bot): LLM-шлюз — GigaChat + mock, extract / risk / phrase / summarize #32

Merged
Eleboba merged 1 commits from feat/7-llm-gateway into dev 2026-10-03 15:01:53 +03:00
Owner

Что меняется

LLM-шлюз (SPEC §7): единая точка входа app/llm/gateway.py, провайдеры GigaChat и офлайн-mock, системные промпты с запретами, фильтр ответов и шаблоны-fallback в config/texts/phrases.yaml.

Closes #7

Зона

bot

Как проверить

  • make lint test: tests/test_llm.py — 52 теста, live-тест пропускается без ключа
  • python -m app.llm.cli extract "сплю плохо, кошмары почти каждую ночь" — после #2 (scrub); сейчас корректно отказывается без scrub

Публичный API

from app.llm.gateway import get_gateway, ITEM_CONFIDENCE_THRESHOLD
gw = get_gateway()
await gw.extract_item(scale_item_id, item_text, max_score, answer: ScrubbedText) -> ItemScore | None
await gw.extract_checkin(text: ScrubbedText) -> CheckinFacts | None
await gw.risk_classify(text: ScrubbedText) -> RiskLevel   # ошибка -> NONE
await gw.phrase(intent: str, context: dict | None = None) -> str   # всегда строка
await gw.summarize_for_doctor(structured: dict) -> str

Те же функции доступны на уровне модуля (gateway.extract_item(...) и т.д.).

Чек-лист

  • rebase на origin/dev
  • make lint + make test зелёные
  • лог в issue (### 2026-10-03)
  • нет ПДн в логах, нет реальных данных, нет секретов
  • общие файлы не тронуты
## Что меняется LLM-шлюз (SPEC §7): единая точка входа `app/llm/gateway.py`, провайдеры GigaChat и офлайн-mock, системные промпты с запретами, фильтр ответов и шаблоны-fallback в `config/texts/phrases.yaml`. Closes #7 ## Зона bot ## Как проверить - `make lint test`: `tests/test_llm.py` — 52 теста, live-тест пропускается без ключа - `python -m app.llm.cli extract "сплю плохо, кошмары почти каждую ночь"` — после #2 (`scrub`); сейчас корректно отказывается без scrub ## Публичный API ```python from app.llm.gateway import get_gateway, ITEM_CONFIDENCE_THRESHOLD gw = get_gateway() await gw.extract_item(scale_item_id, item_text, max_score, answer: ScrubbedText) -> ItemScore | None await gw.extract_checkin(text: ScrubbedText) -> CheckinFacts | None await gw.risk_classify(text: ScrubbedText) -> RiskLevel # ошибка -> NONE await gw.phrase(intent: str, context: dict | None = None) -> str # всегда строка await gw.summarize_for_doctor(structured: dict) -> str ``` Те же функции доступны на уровне модуля (`gateway.extract_item(...)` и т.д.). ## Чек-лист - [x] rebase на origin/dev - [x] make lint + make test зелёные - [x] лог в issue (### 2026-10-03) - [x] нет ПДн в логах, нет реальных данных, нет секретов - [x] общие файлы не тронуты
Eleboba added 1 commit 2026-10-03 15:01:12 +03:00
feat(bot): LLM gateway with GigaChat and offline mock providers
CI / ruff · pytest (pull_request) Successful in 23s
924a51c483
Single entry point app/llm/gateway.py: extract_item, extract_checkin,
risk_classify, phrase, summarize_for_doctor. Two-level design:
LLMProvider (transport, GigaChat) and LLMTasks (PromptedTasks over a
provider, or rule-based MockTasks). Shared policy in the gateway:
assert_scrubbed backstop, confidence threshold 0.5, risk failure -> NONE,
forbidden-output filter with config/texts/phrases.yaml fallbacks.

Refs #7

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Eleboba merged commit ef2f92816e into dev 2026-10-03 15:01:53 +03:00
Eleboba deleted branch feat/7-llm-gateway 2026-10-03 15:01:53 +03:00
Sign in to join this conversation.