🧠 Слой 11: Reward & Motivation System (Средний мозг)¶
Подробное описание архитектуры и работы¶
Статус: ✅ Этап M — реализовано (84 теста, v0.7.0)
Зачем нужна система вознаграждения¶
Без системы вознаграждения мозг — реактивная машина. Он отвечает только когда спросят, не имеет внутренней мотивации, не знает, какие стратегии работают лучше.
С системой вознаграждения мозг становится активным: - Самостоятельно ищет пробелы в знаниях и заполняет их - Предпочитает стратегии, которые исторически давали лучшие результаты - Проявляет любопытство — исследует неизвестные концепты - Испытывает удовлетворение от разрешения противоречий - Мотивирован достигать целей, а не просто реагировать
Биологический аналог: Средний мозг¶
| Биологическая структура | Функция | Аналог |
|---|---|---|
| Вентральная область покрышки (VTA) | Источник дофамина | RewardEngine — вычисляет сигнал вознаграждения |
| Прилежащее ядро (Nucleus Accumbens) | Накопление дофамина, ощущение удовольствия | MotivationEngine — накапливает мотивационное состояние |
| Дофаминергические пути | Передача сигнала к Префронтальной коре | RewardSignal → Planner, LearningLoop |
| Система предсказания ошибки | Δ(ожидаемое - полученное) | PredictionError — разница между ожидаемым и реальным результатом |
Ключевой принцип: дофамин выделяется не при получении награды, а при предсказании награды и при ошибке предсказания (получил больше/меньше ожидаемого).
Архитектура системы¶
Результаты всех модулей (Memory, Cognition, Output, Learning)
│
▼
┌─────────────────────────────────────────────────────────────┐
│ REWARD & MOTIVATION SYSTEM │
│ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ RewardEngine │ │
│ │ вычисляет RewardSignal из исходов действий │ │
│ │ 5 типов вознаграждения + prediction error │ │
│ └──────────────────────┬───────────────────────────────┘ │
│ │ │
│ ┌──────────────────────▼───────────────────────────────┐ │
│ │ MotivationEngine │ │
│ │ накапливает мотивационное состояние │ │
│ │ → влияет на Planner, ReplayEngine, Attention │ │
│ └──────────────────────┬───────────────────────────────┘ │
│ │ │
│ ┌──────────────────────▼───────────────────────────────┐ │
│ │ CuriosityEngine │ │
│ │ внутреннее вознаграждение за исследование │ │
│ │ → генерирует цели "узнать о X" │ │
│ └──────────────────────┬───────────────────────────────┘ │
└─────────────────────────┼───────────────────────────────────┘
│
▼
Planner (приоритеты целей)
ReplayEngine (какие эпизоды воспроизводить)
AttentionController (куда направить внимание)
HypothesisEngine (что исследовать)
Что служит вознаграждением для цифрового мозга¶
Это ключевой вопрос. В отличие от биологического мозга (еда, безопасность, социальное одобрение), у цифрового мозга нет тела. Его вознаграждения — когнитивные и эпистемические:
| # | Тип вознаграждения | Триггер | Значение | Аналог |
|---|---|---|---|---|
| 1 | Epistemic (познавательное) | Узнал новый факт, закрыл пробел в знаниях | +0.8 | Любопытство — самое сильное |
| 2 | Accuracy (точность) | Пользователь подтвердил ответ | +1.0 | Внешнее подтверждение |
| 3 | Coherence (согласованность) | Разрешил противоречие, достиг внутренней согласованности | +0.6 | Удовлетворение от порядка |
| 4 | Completion (завершение) | Выполнил план/цель | +0.7 | Достижение |
| 5 | Efficiency (эффективность) | Быстрый ответ с высокой уверенностью | +0.3 | Оптимизация |
| — | Penalty (штраф) | Пользователь исправил ошибку | -0.5 | Ошибка предсказания |
| — | Contradiction (противоречие) | Обнаружено противоречие без разрешения | -0.3 | Когнитивный диссонанс |
Компонент 1: RewardEngine — Движок вознаграждения¶
Файл: brain/motivation/reward_engine.py
Структура RewardSignal¶
@dataclass
class RewardSignal:
reward_id: str # "reward_a1b2c3"
reward_type: str # "epistemic" | "accuracy" | "coherence" | "completion" | "efficiency"
value: float # -1.0 до +1.0
# Контекст
source_module: str # "memory" | "cognition" | "output" | "learning"
trigger_event: str # что вызвало вознаграждение
cycle_id: str # ID цикла
trace_id: str # ID трассировки
# Предсказание ошибки
expected_value: float # ожидаемое вознаграждение
prediction_error: float # value - expected_value (Δ дофамин)
# Метаданные
concept: str # о каком концепте (для CuriosityEngine)
confidence: float # уверенность в вознаграждении
ts: str # timestamp
Вычисление вознаграждения¶
class RewardEngine:
def on_fact_learned(self, concept: str, is_new: bool, gap_closed: bool) -> RewardSignal:
"""Вознаграждение за обучение."""
if is_new and gap_closed:
value = 0.8 # закрыл пробел — максимальное познавательное вознаграждение
elif is_new:
value = 0.5 # новый факт
else:
value = 0.1 # обновление существующего факта
return RewardSignal(
reward_type="epistemic",
value=value,
trigger_event=f"fact_learned:{concept}",
concept=concept,
...
)
def on_user_feedback(self, correct: bool, correction: str = None) -> RewardSignal:
"""Вознаграждение/штраф от пользователя."""
if correct:
value = +1.0 # пользователь подтвердил — максимальное внешнее вознаграждение
else:
value = -0.5 # пользователь исправил — штраф + обучение
return RewardSignal(
reward_type="accuracy",
value=value,
trigger_event="user_feedback",
...
)
def on_contradiction_resolved(self, conflict_id: str) -> RewardSignal:
"""Вознаграждение за разрешение противоречия."""
return RewardSignal(
reward_type="coherence",
value=0.6,
trigger_event=f"contradiction_resolved:{conflict_id}",
...
)
def on_goal_completed(self, goal_id: str, steps_count: int) -> RewardSignal:
"""Вознаграждение за завершение цели."""
# Больше шагов = больше вознаграждение (сложная цель)
value = min(0.7 + steps_count * 0.05, 1.0)
return RewardSignal(
reward_type="completion",
value=value,
trigger_event=f"goal_completed:{goal_id}",
...
)
def on_response_generated(self, confidence: float, latency_ms: float) -> RewardSignal:
"""Вознаграждение за эффективный ответ."""
# Высокая уверенность + быстрый ответ = хорошая эффективность
efficiency = confidence * (1.0 - min(latency_ms / 5000, 1.0))
value = efficiency * 0.3 # небольшое вознаграждение
return RewardSignal(
reward_type="efficiency",
value=value,
trigger_event="response_generated",
...
)
Prediction Error (ошибка предсказания)¶
Биологический принцип:
Дофамин выделяется не при получении награды,
а при ОШИБКЕ ПРЕДСКАЗАНИЯ: Δ = полученное - ожидаемое
Δ > 0: получил больше ожидаемого → сильный дофамин → усилить стратегию
Δ = 0: получил ровно ожидаемое → нейтрально
Δ < 0: получил меньше ожидаемого → снижение дофамина → ослабить стратегию
Для нашего мозга:
expected_value = MotivationEngine.predict_reward(action_type, context)
actual_value = RewardSignal.value
prediction_error = actual_value - expected_value
prediction_error > 0.2:
→ "Это сработало лучше ожидаемого!"
→ MotivationEngine.boost(action_type, context)
→ ReplayEngine.mark_as_high_value(episode)
prediction_error < -0.2:
→ "Это сработало хуже ожидаемого"
→ MotivationEngine.penalize(action_type, context)
→ LearningLoop.update_strategy(action_type, delta=-0.1)
Компонент 2: MotivationEngine — Движок мотивации¶
Файл: brain/motivation/motivation_engine.py
Аналог: Прилежащее ядро — накопление и распределение дофамина
Мотивационное состояние¶
@dataclass
class MotivationState:
"""
Текущее мотивационное состояние мозга.
Обновляется после каждого RewardSignal.
"""
# Накопленные вознаграждения по типам (скользящее среднее)
epistemic_score: float # мотивация к познанию (0.0–1.0)
accuracy_score: float # мотивация к точности
coherence_score: float # мотивация к согласованности
completion_score: float # мотивация к завершению задач
efficiency_score: float # мотивация к эффективности
# Общий уровень мотивации
overall_motivation: float # среднее взвешенное
# Исторические предпочтения (какие стратегии работали)
preferred_goal_types: Dict[str, float] # {"answer_question": 0.8, "learn_fact": 0.6}
preferred_modalities: Dict[str, float] # {"text": 0.7, "vision": 0.4}
# Состояние
is_curious: bool # высокая epistemic_score → активно ищет новое
is_satisfied: bool # высокая overall_motivation → стабильное состояние
is_frustrated: bool # низкая overall_motivation → нужна смена стратегии
updated_at: str
Влияние на другие модули¶
MotivationState.epistemic_score > 0.7 (высокое любопытство):
│
├── Planner: добавить цель "explore_unknown_concept" в стек
├── HypothesisEngine: генерировать больше гипотез
└── AttentionController: увеличить бюджет на memory.retrieve()
MotivationState.preferred_goal_types["answer_question"] = 0.9:
│
└── Planner: при прочих равных — приоритизировать answer_question цели
MotivationState.is_frustrated = True (низкая мотивация):
│
├── Planner: сменить стратегию (попробовать другой тип рассуждения)
├── ReplayEngine: запустить replay для восстановления успешных паттернов
└── Logger: warn("low_motivation_detected")
MotivationState.preferred_modalities["text"] = 0.8:
│
└── AttentionController: увеличить бюджет text при неопределённости
Decay мотивации¶
Каждые 100 циклов без вознаграждения:
epistemic_score *= 0.95 (медленное затухание)
accuracy_score *= 0.95
...
Это создаёт "голод" — мозг начинает активнее искать вознаграждение
когда давно его не получал.
Минимальный уровень: 0.1 (мозг никогда не теряет мотивацию полностью)
Компонент 3: CuriosityEngine — Движок любопытства¶
Файл: brain/motivation/curiosity_engine.py
Аналог: Внутренняя мотивация к исследованию неизвестного
Принцип работы¶
Любопытство = вознаграждение за исследование НЕИЗВЕСТНОГО.
Чем меньше мозг знает о концепте X → тем выше curiosity_score(X)
Чем больше мозг знает о концепте X → тем ниже curiosity_score(X)
Это создаёт естественную мотивацию заполнять пробелы в знаниях.
Вычисление curiosity score¶
def compute_curiosity(self, concept: str) -> float:
"""
Вычислить уровень любопытства к концепту.
Факторы:
1. knowledge_coverage: сколько мы знаем о концепте (0=ничего, 1=всё)
2. connection_density: сколько связей у концепта в SemanticGraph
3. recency: как давно мы думали об этом концепте
4. importance: насколько концепт важен для текущих целей
"""
knowledge_coverage = semantic_memory.get_coverage(concept) # 0.0–1.0
connection_density = semantic_memory.get_connections(concept) / MAX_CONNECTIONS
recency_factor = 1.0 - (cycles_since_last_thought / 1000)
importance = planner.get_relevance(concept)
# Любопытство обратно пропорционально знанию
curiosity = (1.0 - knowledge_coverage) * 0.5
curiosity += (1.0 - connection_density) * 0.3 # мало связей → интересно
curiosity += recency_factor * 0.1
curiosity += importance * 0.1
return min(curiosity, 1.0)
Генерация целей из любопытства¶
def generate_curiosity_goals(self, top_n: int = 3) -> List[Goal]:
"""
Сгенерировать цели для заполнения пробелов в знаниях.
Вызывается когда Planner не имеет срочных задач (idle state).
"""
# Найти концепты с высоким curiosity score
candidates = semantic_memory.get_all_concepts()
scored = [(c, self.compute_curiosity(c)) for c in candidates]
top_curious = sorted(scored, key=lambda x: x[1], reverse=True)[:top_n]
goals = []
for concept, score in top_curious:
if score > 0.6: # порог любопытства
goals.append(Goal(
goal_type="explore_concept",
target=concept,
priority=score,
source="curiosity_engine",
description=f"Исследовать концепт '{concept}' (curiosity={score:.2f})"
))
return goals
Полный цикл вознаграждения¶
Пользователь задаёт вопрос: "Что такое синапс?"
│
▼
[Planner] создаёт цель: answer_question("синапс")
expected_reward = MotivationEngine.predict(goal_type="answer_question") = 0.65
│
▼
[Memory] находит факт: "синапс — соединение между нейронами" (conf=0.82)
RewardEngine.on_fact_retrieved(concept="синапс", confidence=0.82)
→ RewardSignal(type="epistemic", value=0.2) # небольшое вознаграждение за поиск
│
▼
[Output] генерирует ответ с confidence=0.82, latency=95ms
RewardEngine.on_response_generated(confidence=0.82, latency_ms=95)
→ RewardSignal(type="efficiency", value=0.24)
│
▼
[Пользователь] подтверждает: "Да, правильно!"
RewardEngine.on_user_feedback(correct=True)
→ RewardSignal(type="accuracy", value=1.0)
│
▼
[MotivationEngine] обновляет состояние:
actual_reward = 0.2 + 0.24 + 1.0 = 1.44 (суммарно за цикл)
expected_reward = 0.65
prediction_error = 1.44 - 0.65 = +0.79 → "Лучше ожидаемого!"
accuracy_score += 0.1 (пользователь подтвердил)
preferred_goal_types["answer_question"] += 0.05
│
▼
[ReplayEngine] помечает эпизод как high_value (prediction_error > 0.5)
→ будет воспроизведён в следующей replay сессии
│
▼
[CuriosityEngine] обновляет:
knowledge_coverage("синапс") += 0.1 (узнали больше)
curiosity_score("синапс") -= 0.1 (стало менее интересно)
curiosity_score("нейрон") += 0.05 (связанный концепт стал интереснее)
Интеграция с другими слоями¶
RewardEngine получает сигналы от:
← Memory: on_fact_learned, on_gap_closed, on_contradiction_resolved
← Cognition: on_goal_completed, on_plan_step_completed
← Output: on_response_generated, on_user_feedback
← Learning: on_hypothesis_confirmed, on_hypothesis_rejected
MotivationEngine влияет на:
→ Planner: preferred_goal_types → приоритеты целей
→ ReplayEngine: high_value episodes → что воспроизводить
→ AttentionController: preferred_modalities → бюджет внимания
→ HypothesisEngine: curiosity_goals → что исследовать
→ Scheduler: overall_motivation → частота тиков (высокая мотивация = быстрее)
Наблюдаемость (Observability)¶
{
"ts": "2026-03-19T12:00:00.123Z",
"level": "INFO",
"module": "reward_engine",
"event": "reward_signal",
"cycle_id": "cycle_4521",
"trace_id": "trace_9fa",
"reward": {
"type": "accuracy",
"value": 1.0,
"expected": 0.65,
"prediction_error": 0.35,
"trigger": "user_feedback:correct"
},
"motivation_state": {
"overall": 0.74,
"epistemic": 0.68,
"accuracy": 0.81,
"is_curious": true,
"is_satisfied": true
},
"latency_ms": 1
}
Ресурсный бюджет (CPU-only, 32 GB RAM)¶
| Компонент | RAM | CPU | Время/операция |
|---|---|---|---|
| RewardEngine | ~2 MB | < 1% | ~1 мс |
| MotivationEngine | ~3 MB | < 1% | ~2 мс |
| CuriosityEngine | ~5 MB | < 1% | ~5–10 мс |
| Итого | ~10 MB | < 1% | ~8–13 мс |
Статус реализации¶
| Компонент | Статус | Файл | Тесты |
|---|---|---|---|
RewardSignal dataclass |
✅ Этап M.1 | brain/motivation/reward_engine.py |
— |
RewardEngine |
✅ Этап M.1 | brain/motivation/reward_engine.py |
28/28 |
MotivationState dataclass |
✅ Этап M.2 | brain/motivation/motivation_engine.py |
— |
MotivationEngine |
✅ Этап M.2 | brain/motivation/motivation_engine.py |
30/30 |
CuriosityEngine |
✅ Этап M.3 | brain/motivation/curiosity_engine.py |
26/26 |
brain/motivation/__init__.py |
✅ Этап M.1 | brain/motivation/__init__.py |
— |
ReplayEngine.mark_as_high_value() |
✅ Этап M.4 | brain/learning/replay_engine.py |
— |