Перейти к содержанию

ADR-005: Шаблонные ответы без LLM на MVP-этапе

Статус: ✅ Принято
Дата: 2025-06
Авторы: cognitive-core contributors


Контекст

DialogueResponder должен формировать текстовые ответы пользователю. Система имеет ActionSelector, который определяет тип действия (respond_direct, respond_hedged, ask_clarification, refuse, learn). Вопрос: как генерировать текст ответа?

Рассмотренные варианты

Вариант 1: LLM (OpenAI GPT / Anthropic Claude / local Llama)

Плюсы: Естественный язык, гибкость, контекстуальность
Минусы: Внешний API (зависимость, стоимость, latency); local LLM требует GPU или много RAM; не соответствует CPU-only платформе; усложняет тестирование (недетерминированность)

Вариант 2: Шаблоны по ActionType с hedging phrases

Плюсы: Детерминированность, тестируемость, нет внешних зависимостей, быстро
Минусы: Ограниченная выразительность, шаблонность ответов

Вариант 3: Retrieval-Augmented Generation (RAG) без LLM

Плюсы: Использует реальные факты из памяти
Минусы: Без LLM сложно связно объединить факты в текст

Решение

Выбраны шаблонные ответы на MVP-этапе с явным TODO для LLM Bridge (Этап N).

Реализация в brain/output/dialogue_responder.py:

FALLBACK_TEMPLATES_RU = {
    "respond_direct":    "Ответ на ваш вопрос.",
    "respond_hedged":    "Возможно, ответ связан с данной темой.",
    "ask_clarification": "Уточните, пожалуйста, ваш вопрос.",
    "refuse":            "У меня недостаточно данных для ответа.",
    "learn":             "Факт сохранён.",
}

# Hedging phrases по confidence bands
HEDGING_PHRASES_RU = {
    (0.75, 1.01): [],                                    # без оговорок
    (0.60, 0.75): ["Вероятно,", "Скорее всего,"],
    (0.45, 0.60): ["Возможно,", "Я думаю,"],
    (0.30, 0.45): ["Не уверен, но", "Предположительно,"],
    (0.00, 0.30): ["Очень неуверенно:", "Это лишь предположение:"],
}

Ответ формируется как: [hedging_phrase] [template_or_content]

Последствия

Положительные: - 100% детерминированные ответы — тесты стабильны - Нет внешних зависимостей — работает offline - Быстро (< 1ms на генерацию) - Явная точка расширения: TODO: LLM bridge Stage H+ в коде

Отрицательные: - Ответы шаблонные — не подходят для production демо - Нет контекстуальной генерации текста

Нейтральные: - OutputPipeline спроектирован так, что замена DialogueResponder на LLM-версию не требует изменений в остальных компонентах - Двуязычность (RU/EN) через detect_language() из brain/core/text_utils.py

Путь к LLM Bridge (Этап N)

brain/bridges/llm_bridge.py
├── LLMBridgeProtocol  — абстракция (generate(prompt) -> str)
├── OpenAIBridge       — OpenAI API
├── AnthropicBridge    — Anthropic API
└── LocalLlamaBridge   — llama.cpp / ollama

DialogueResponder получит опциональный llm_bridge: Optional[LLMBridgeProtocol] — при наличии использует LLM, иначе шаблоны.

Связанные решения

  • ADR-007: CPU-only платформа — причина отложить LLM
  • TODO.md P3-13: LLM Bridge — стратегический unlock