Полный отказ от LLM: детерминированный rules-анализ

Решение Виктора: ИИ убран из проекта — карточки детей (ПД) не должны
покиать контур. Анализ полностью локальный и детерминированный.

- services/rules_analysis.py: правила вместо Claude (бывший
  analyze_with_fallback + rule_based_urgency из closed_cases):
  urgency по возрасту/профилям, зоны через geo+scoring,
  behavioral_prediction/immediate_actions/key_locations — справочники.
- search_engine: анализатор инъекцией (CaseAnalyzer, Protocol),
  импорт claude_service удалён; рантайм — rules_analyze.
- УДАЛЕНЫ: services/claude_service.py, backend/services/claude_service.py
  (устаревшая копия), test_claude_service.py; ключевые правила-кейсы
  перенесены в test_rules_analysis.py (+тест отсутствия LLM-упоминаний).
- docker-compose/.env.example: ANTHROPIC_API_KEY удалён.
- Фронт: бейдж 'ИИ-анализ' -> 'Локальный расчёт'.
- Доки: DEPLOY/SERVICES_README/ANALYZE_API переписаны, FIXES_REPORT
  помечен историческим, vector_tasks B20: zones/probability — из движка.

pytest: 187 passed (было 214; -27 удалённых LLM-тестов, +тест rules).
Контракт /analyze не изменён (фронт совместим).
This commit is contained in:
2026-09-09 18:30:44 +03:00
parent 11015a7883
commit d8723582c9
17 changed files with 362 additions and 1377 deletions
+3 -3
View File
@@ -1,6 +1,6 @@
"""B14: юнит-тесты чистого движка services/search_engine.py.
claude_analyze мокается (движок тестируем изолированно, без httpx/ANTHROPIC).
Анализатор мокается (движок тестируем изолированно, без geo/httpx).
"""
from __future__ import annotations
@@ -9,7 +9,7 @@ from typing import Any
import pytest
from services.claude_service import AnalysisResult, PrimaryZone
from services.rules_analysis import AnalysisResult, PrimaryZone
from services.search_engine import (
SearchInput,
build_search_model,
@@ -70,7 +70,7 @@ async def test_profiles_derived_from_diagnosis_and_transport():
)
assert 'РАС' in [p['name'] for p in model.active_profiles]
assert model.critical_warnings == [] or isinstance(model.critical_warnings, list)
# Профили дошли и до claude (case_data), и в скорер
# Профили дошли и до анализатора (case_data), и в скорер
assert 'РАС' in analyzer.captured['profiles']
assert 'велосипед' in analyzer.captured['profiles']
assert 'не_умеет_плавать' in analyzer.captured['profiles']