# Архитектура системы обработки книг через ИИ

## Содержание

1. [Введение и обзор](#введение-и-обзор)
2. [Архитектура системы](#архитектура-системы)
3. [Пайплайн обработки](#пайплайн-обработки)
4. [Модели ИИ и Ollama](#модели-ии-и-ollama)
5. [Хранение данных](#хранение-данных)
6. [Функциональность системы](#функциональность-системы)
7. [Операционные аспекты](#операционные-аспекты)
8. [Приложения](#приложения)
9. [Актуализация по каталогам этапов](#актуализация-по-каталогам-этапов)

---

## Введение и обзор

### Назначение системы

Система обрабатывает EPUB файлы, переводит их в JSON с главами, анализирует каждую главу через ИИ, валидирует результаты, создает эмбеддинги и сохраняет в Qdrant. На основе анализа глав генерируются коуч-планы для освоения навыков из книг с детализацией техник и методик. **Цель** — не только извлечь информацию, но и научиться применять знания в жизни: техники выводятся из инсайтов при необходимости, при сборке плана дубли сводятся в уникальные практики, отдельно формируется план применения (когда/где/как применять).

### Основной поток обработки

```
EPUB → JSON с главами → Анализ по блокам (framework → insights → application → limitations)
  → Валидация каждого блока → Склейка → Финальная валидация согласованности →
→ Извлечение тегов → Валидация тегов → Мерж анализа и тегов (5) → Генерация эмбеддингов (6) →
→ Сохранение в Qdrant/Postgres → Генерация коуч-плана → Сохранение плана
```

---

## Архитектура системы

### Компоненты системы

1. **epub-parser** (FastAPI) - парсинг EPUB в JSON
2. **chapter-processor** (новый сервис) - обработка глав
   - FastAPI - API слой (прием запросов, постановка задач в очередь)
   - Celery/RQ Workers - пайплайн обработки (анализ, валидация, эмбеддинг)
3. **Redis** - очередь задач и кэширование
4. **Ollama** - LLM для анализа и валидации
5. **Qdrant** - векторная БД для эмбеддингов
6. **Postgres** - реляционная БД для структурированных данных (книги, главы, анализы, коуч-планы)

### Разделение ответственности

**FastAPI:**
- Принимает запросы на обработку книги
- Ставит задачи в очередь (Redis)
- Возвращает task_id и статус
- НЕ выполняет долгие операции

**Воркеры (Celery/RQ):**
- Забирают задачи из очереди
- Выполняют весь пайплайн обработки
- Работают асинхронно, не блокируют API

---

## Пайплайн обработки

### Концепция: максимум пользы из книги

**Цель системы** — не просто извлечь информацию, а научиться применять знания из книги в жизни. Многие главы (особенно в книгах вроде «Чёрный лебедь») содержат много инсайтов и мало явных техник. Поэтому:

- **Техника** — повторяемое правило: «в ситуации X делай Y». **Инсайт** — понимание («вот в чём ловушка», «вот что мы переоцениваем»). Из инсайтов можно и нужно выводить техники: формулировать операциональные правила.
- **При извлечении (блок application):** извлекать все значимые техники; одну и ту же идею в разных формулировках считать одной техникой; для глав с преобладанием инсайтов — формулировать применимые техники из инсайтов (когда/в какой ситуации что делать).
- **При сборке плана по книге:** объединять повторяющиеся техники из разных глав в одну формулировку. Итог — короткий набор уникальных практик (если вся книга сводится к 1–2 техникам — это успех, а не провал).
- **План применения в жизни** — отдельный результат: в каких ситуациях какую технику применять, с какой периодичностью, как встроить в рутину. Генерируется на основе собранных техник и их применимости.

**Применимость (смыслы):** для каждой техники полезно извлекать: в каких ситуациях полезна, для каких целей применима. Это может быть отдельный проход ИИ (по главе или по книге) или часть блока application / этапа генерации коуч-плана.

### Этапы обработки (с lazy loading)

**Подход: анализ и валидация по блокам**  
Цель — качество и согласованность. Анализ главы разбит на 4 блока (framework, insights, application, limitations). Генерация блоков — последовательно; после каждого блока — валидация по блоку; затем склейка и финальная валидация согласованности всего анализа.

#### 1. Анализ главы по блокам (qwen3-14b:8bit)

- **Вход этапа 1:** один JSON на главу с полями `book_id`, `chapter_id`, `chapter_number`, `chapter_title`, `book_title`, `chapter_text`, опционально `author`. Спецификация и пример: `1_анализ_главы/вход_главы.spec.json`, `вход_главы.example.json`. Метаданные передаются по пайплайну до шага 7 (payload в Qdrant).
- **Порядок генерации:** framework → insights → application → limitations (последовательно). Подробнее: `1_анализ_главы/README.md`.
- **Вход каждого шага:** текст главы + **весь накопленный JSON** (все уже завалидированные предыдущие блоки), а не только последний блок. Подстановки в промптах: `{book_title}`, `{chapter_title}`, `{chapter_text}`; в шагах 2–4 дополнительно `{previous_blocks_json}` — накопленный JSON предыдущих блоков.
- **Промпты по блокам:** `extract_framework_v2.txt` → `extract_insights_v3.txt` → `extract_application_v2.txt` → `extract_limitations_v3.txt` (каталог `1_анализ_главы/`).
- **Блок framework (каркас):** извлекаются фундаментальные принципы и опорные идеи автора. Для каждого принципа — цепочки cause → mechanism → result; глоссарий специальных терминов главы (`terms`: термин → пояснение в 3–7 слов); у каждого принципа — поле `example` (один бытовой пример). Один принцип = одна опорная мысль, перекрывающиеся идеи объединяются. Выход — JSON с единственным ключом верхнего уровня `"framework"`.
- **Блок application (применение):** извлекать все значимые техники без раздувания списка: одну и ту же идею — одной техникой. Если в главе много инсайтов и мало явных «шагов» — выводить техники из инсайтов (операциональные правила: когда/что делать). Опционально для каждой техники: ситуации применения, цели (для чего полезна).
- **Отдельный промпт на каждый блок** — модель решает одну задачу за раз, меньше пропусков и галлюцинаций.
- **Выход шага:** JSON одного блока. После генерации блока — сразу валидация этого блока (см. п. 2).
- Модель: загрузить → N вызовов по цепочке → выгрузить (`keep_alive: 0`).
- Время: суммарно ~2–5+ минут на главу (4 блока последовательно).
- Память: ~20–21GB максимум (модель + контекст).

#### 2. Валидация каждого блока (qwen3-14b:8bit)

- **После генерации блока** — сразу валидация: соответствие тексту главы, галлюцинации, пропуски. Проверяется только этот блок: на вход валидатора подаётся **только JSON этого блока** + текст главы (не весь анализ). Подробнее: `2_валидация_анализа_по_блокам/README.md`.
- **Промпты:** `validate_framework.txt`, `validate_insights.txt`, `validate_application.txt`, `validate_limitations.txt` (каталог `2_валидация_анализа_по_блокам/`). Подстановки: `{book_title}`, `{chapter_title}`, `{chapter_text}` и соответствующий `{framework_json}` / `{insights_json}` / `{application_json}` / `{limitations_json}`. В блоке application проверяются техники (name, goal, steps).
- **При вердикте bad:** один retry того же блока с тем же контекстом. Если снова bad — флаг `needs_review` по главе, дальнейшая обработка по политике (останов или продолжение).
- **Выход:** завалидированный блок (или флаг `needs_review`).
- Время: ~30 секунд на блок.
- Память: ~3.5–4.5GB максимум (модель + контекст).

#### 2a. Склейка блоков

- Объединение четырёх JSON (framework, insights, application, limitations) в один анализ. **Без вызова LLM** — только слияние структур.

#### 2b. Финальная валидация (согласованность всего анализа)

- **Промпт:** `validate_consistency.txt` (каталог `2b_финальная_валидация_согласованности/`). Подстановки: `{book_title}`, `{chapter_title}`, `{full_analysis_json}`. Подробнее: `2b_финальная_валидация_согласованности/README.md`.
- **Назначение:** проверка **только связей между блоками** (техники опираются на принципы, инсайты не противоречат framework, ограничения относятся к описанному). Перепроверка «каждое слово по тексту» не выполняется — она уже сделана по блокам.
- **При рассогласованности:** флаг `needs_review` и сохранение как есть; опционально — «примиряющий» промпт (минимальные правки для согласованности), если таких кейсов много.
- Модель: qwen3-14b:8bit. Время: ~30–60 секунд.

#### 3. Извлечение тегов (qwen3-14b:8bit)

- **Промпт:** `extract_tags.txt` (каталог `3_извлечение_тегов/`). Подстановки: `{book_title}`, `{chapter_title}`, `{framework}`, `{insights}`, `{application}`, `{limitations}` (опционально), `{chapter_text}`, `{allowed_tags_json}` — актуальный список допустимых тегов из БД. Подробнее: `3_извлечение_тегов/README.md`.
- Вход: валидированный анализ главы (все блоки) + оригинальный текст главы + словарь допустимых тегов.
- Выход: JSON с тегами по категориям (`principle`, `psychology`, `method`, `result`, `context`) и confidence для каждого; при необходимости кандидаты в `proposed` с полем `category`.
- Время: ~1–2 минуты на главу. Память: ~20–21GB максимум (модель + контекст).
- **Преимущество отдельного шага:** ИИ использует уже структурированные данные (каркас, инсайты, применение) для более точного понимания сути.

#### 4. Валидация тегов (qwen3-14b:8bit)

- **Промпт:** `validate_tags.txt` (каталог `4_валидация_тегов/`). Подстановки: `{book_title}`, `{chapter_title}`, `{extracted_tags_json}`, `{framework}`, `{insights}`, `{application}`, `{chapter_text}`. Подробнее: `4_валидация_тегов/README.md`.
- Вход: извлечённые теги (шаг 3) + валидированный анализ главы + оригинальный текст главы.
- Выход: JSON — проверенные теги по категориям с обновлёнными confidence; теги, снятые при валидации, — в блоке `removed` (tag, category, reason). Формат `tags` совпадает с выходом шага 3 для передачи в мерж (шаг 5) и далее в эмбеддинг/БД.
- Время: ~20–30 секунд. Память: ~3.5–4.5GB максимум (модель + контекст).

#### 5. Мерж анализа и тегов (без LLM)

- **Назначение:** объединение выхода 2b (финальная валидация согласованности) и выхода 4 (валидация тегов) в один JSON. Этапы 2b и 4 разнесены по времени; шаг 5 выполняется после того, как оба результата готовы.
- **Вход:** merge.json (2b): framework, insights, application, limitations; выход_valid_tag.json (4): tags по категориям, removed.
- **Выход:** один JSON с полями анализа и тегами для передачи в шаг 6 (генерация эмбеддингов). Подробнее: `5_мерж_анализа_и_тегов/README.md`.
- Без вызова LLM — только слияние структур (скрипт merge_analysis_tags.py).

#### 6. Генерация эмбеддингов (BAAI/bge-m3)

- **Спецификация входа:** `6_генерация_эмбеддингов/embed_input_spec.txt`. В текст для эмбеддинга входят только блоки framework, insights, application (сериализованные); limitations и теги — опционально/в payload. Подробнее: `6_генерация_эмбеддингов/README.md`.
- **Что эмбеддим:** валидированный анализ главы (каркас, инсайты, применение), а не сырой текст. Теги в вектор не входят; хранятся в payload Qdrant для фильтрации. Поиск идёт по смыслу, а не по формулировкам — это целевой выбор архитектуры.
- **Модель по умолчанию:** **BAAI/bge-m3** (bge-m3). Мультиязычная модель, хорошая поддержка русского; размерность вектора **1024**, лимит контекста **8192 токенов** — полный анализ главы обычно укладывается без обрезки. Размер модели ~1.2GB, время ~5–15 сек на главу.
- **Альтернативы:** при необходимости более лёгкой модели — nomic-embed-text (~0.5GB, 512 токенов), evilfreelancer/enbeddrus (337MB, 512 токенов, заточена под en/ru). Выбор модели — конфигурация (env/конфиг).
- **Длина входа:** у bge-m3 лимит 8192 токенов. Если текст для эмбеддинга длиннее — явное правило: truncation до лимита (приоритет полей — см. embed_input_spec.txt) или разбиение на чанки с агрегацией векторов. Лимит и стратегию задавать в конфиге.
- **Смена модели:** архитектура допускает замену модели эмбеддингов без смены формата входа; размерность вектора и коллекции Qdrant зависят от модели (bge-m3 → 1024). При смене модели — пересоздание коллекций/пересчёт эмбеддингов.
- Выход: вектор размерности 1024. Память: ~1.2GB (bge-m3).

#### 7. Сохранение в Qdrant
- **Скрипт:** `7_сохранение_qdrant/save_to_qdrant.py`. Вход: merged JSON (шаг 5), вектор (шаг 6), метаданные главы/книги (book_id, chapter_id, chapter_number, chapter_title и др.). Upsert точки в коллекцию `chapter_analyses` (id = chapter_id).
- Связь с главой через `chapter_id` (id точки в Qdrant).
- Payload: `bookId`, `chapterId`, `chapterNumber`, `chapterTitle`, `validationScore`, `tags`, `title`, `author`. Теги из merged JSON — в payload для фильтрации.

#### 8. Сохранение в Postgres
- **Скрипт:** `8_сохранение_postgres/save_to_postgres.py`. Вход: merged JSON (шаг 5) с метаданными из этапа 1. Схема: `8_сохранение_postgres/schema.sql` (books, chapters, chapter_analyses, tags, chapter_tags).
- Upsert книги (books) и главы (chapters), запись в `chapter_analyses` (analysis_result = framework + insights + application + limitations), get-or-create тегов в `tags`, связи в `chapter_tags` (confidence, validated, source='ai_validation').
- Подключение: DATABASE_URL или POSTGRES_HOST/USER/PASSWORD/DB. Подробнее: `8_сохранение_postgres/README.md`.

#### 9. Генерация коуч-плана (после обработки всех глав книги)

- Анализ всех глав → выделение навыков → группировка → пункты плана → поиск техник по книге (семантический поиск) → связи с главами → агрегация концепций → сведение техник → применимость → план применения в жизни (см. раздел «Генерация коуч-планов»).
- **Ограничение контекста:** для длинных книг (30+ глав) не передавать в один вызов LLM все анализы целиком — не влезет в контекст или синтез будет поверхностным. Использовать: сжатые выжимки по главам (каркас + ключевые инсайты + список техник), или поэтапную агрегацию (сначала синтез по частям книги, затем финальный проход по агрегатам), или явный лимит (например, топ-N глав по релевантности). Стратегию зафиксировать в конфиге/документации.
- **Качество плана = качество анализов глав.** Если в блоках application по главам мало техник или они слабо выведены из инсайтов, план будет бедным. Перед генерацией плана опционально проверять «плотность» применения по книге; при необходимости — дообогащать application (повторный проход по слабым главам).

### Оптимизация памяти

**Lazy loading моделей:**
- Не держать все модели в памяти одновременно
- Загружать модель перед использованием
- Выгружать через `keep_alive: 0` после обработки
- Экономия: одна модель (qwen3-14b:8bit) загружается только на время этапа, затем выгружается

**Оптимизация промптов:**
- Минимальные системные промпты (~200-300 токенов вместо 1000-2000)
- Экономия контекста: ~1500-1700 токенов
- Больше места для текста главы при том же `OLLAMA_NUM_CTX`

**Последовательная обработка:**
- Одна глава за раз
- Одна модель за раз в памяти
- Максимальное использование памяти: ~20-21GB (влезет в 30GB)

### Обработка ошибок

- **Retry логика**: экспоненциальный backoff при ошибках
- **Dead letter queue**: для проблемных глав
- **Circuit breaker**: для LLM вызовов
- **Graceful degradation**: при падении валидатора - сохранять с флагом `needs_review`

---

## Модели ИИ и Ollama

### Конфигурация моделей

- **qwen3-14b:8bit** → анализ глав по блокам (шаг 1), валидация блоков (шаг 2), финальная валидация согласованности (шаг 2b), извлечение тегов (шаг 3), валидация тегов (шаг 4). Одна модель для всего пайплайна LLM; загружается по требованию, выгружается через `keep_alive: 0` после этапа.
- **bge-m3** (BAAI/bge-m3) → генерация эмбеддингов (шаг 6, по умолчанию). Мультиязычная модель, хорошая поддержка русского; размерность 1024, контекст 8192 токенов. Модель задаётся конфигом; при смене — пересоздание коллекций Qdrant и пересчёт эмбеддингов по необходимости.

### Использование памяти

- `qwen3-14b:8bit`: ~20–21GB максимум (модель + контекст при анализе); ~3.5–4.5GB при валидации (меньший контекст).
- `bge-m3`: ~1.2GB
- **Итого при одновременной загрузке**: ~24–32GB (если бы все модели были в памяти)
- **С lazy loading**: ~20–21GB максимум (одна модель за раз: анализ или валидация)

### API эндпоинты Ollama

- `POST http://ollama:11434/api/chat` - для анализа (рекомендуется)
- `POST http://ollama:11434/api/generate` - для простой генерации
- `GET http://ollama:11434/api/tags` - проверка доступных моделей

### Структура запроса

```json
{
  "model": "qwen3-14b:8bit",
  "messages": [
    {"role": "system", "content": "Промпт для анализа"},
    {"role": "user", "content": "Текст главы..."}
  ],
  "stream": false,
  "format": "json"
}
```

### Особенности работы с Ollama

- **Таймауты**: длинные запросы могут занимать минуты (устанавливать 5-10 минут)
- **Streaming**: для длинных ответов использовать `stream: true`
- **JSON формат**: использовать `format: "json"` для структурированных ответов
- **Контекст**: настраивается через `OLLAMA_NUM_CTX`
- **Выгрузка моделей**: через параметр `keep_alive: 0` в запросах
  - `keep_alive: 0` - выгрузить сразу после запроса
  - `keep_alive: "5m"` - держать 5 минут (по умолчанию)
  - Автоматическая выгрузка через 5 минут неактивности

### Настройки Ollama

#### Рекомендуемые параметры (для 30GB RAM)

```yaml
ollama:
  environment:
    - OLLAMA_NUM_CTX=9000  # Контекст для анализа глав
    - OLLAMA_NUM_THREAD=8  # По количеству ядер CPU
    - OLLAMA_NUM_PARALLEL=1  # Последовательная обработка (экономия памяти)
```

#### Ограничения контекста

**При 30GB RAM с lazy loading:**
- `qwen3-14b:8bit`: оптимально 9000 токенов (даёт ~7000–8000 для текста главы)
- **Эмбеддинги:** bge-m3 — 8192 токенов на вход, размерность 1024. Текст для эмбеддинга — сериализованный анализ главы; при превышении лимита — truncation или стратегия из embed_input_spec.txt (см. этап 6 пайплайна).

**Анализ книг:**
- Самая большая глава: 11,119 токенов ("Атомные привычки", глава 5)
- Все главы влезают в контекст 9000 токенов
- С оптимизированными промптами (~200-300 токенов) остается достаточно места

**Для 20000 токенов контекста:**
- Требуется минимум 48-64GB RAM
- GPU не решает проблему памяти, только ускоряет обработку
- Приоритет: увеличить RAM, GPU опционально для ускорения

### Управление моделями в Ollama

**Выгрузка модели:**
```bash
# Через /api/generate
curl http://localhost:11434/api/generate -d '{
  "model": "qwen3-14b:8bit",
  "prompt": "",
  "keep_alive": 0
}'

# Через /api/chat
curl http://localhost:11434/api/chat -d '{
  "model": "qwen3-14b:8bit",
  "messages": [],
  "keep_alive": 0
}'
```

**Проверка загруженных моделей:**
```bash
ollama ps
```

---

## Хранение данных

### Распределение данных по БД

**Postgres (структурированные данные):**
- Книги, главы, анализы, коуч-планы, связи
- Полный оригинальный текст глав
- JSONB для гибких структур данных

**Qdrant (векторный поиск):**
- Эмбеддинги валидированного анализа глав
- Эмбеддинги пунктов плана и техник
- Минимум метаданных в payload для фильтрации

**Redis (кэш и очереди):**
- Кэш результатов анализа
- Кэш текста глав
- Очереди задач обработки

### Схема базы данных Postgres

#### Таблицы книг и глав

**`books`**
- `id` (UUID, PK)
- `title` (VARCHAR)
- `author` (VARCHAR)
- `metadata` (JSONB) - дополнительные метаданные
- `created_at` (TIMESTAMP)
- `updated_at` (TIMESTAMP)

**`chapters`**
- `id` (UUID, PK)
- `book_id` (UUID, FK → books.id)
- `chapter_number` (INTEGER)
- `chapter_title` (VARCHAR)
- `content` (TEXT) - полный оригинальный текст главы
- `file_path` (VARCHAR) - путь к исходному файлу
- `tokens` (INTEGER) - количество токенов
- `characters` (INTEGER) - количество символов
- `footnotes_count` (INTEGER)
- `essential_for_core_skill` (BOOLEAN) - критична ли глава для главного навыка
- `relevance_to_core_skill` (FLOAT) - релевантность главному навыку (0.0-1.0)
- `core_skill_contribution` (TEXT) - описание вклада главы в главный навык
- `created_at` (TIMESTAMP)

**`book_statistics`**
- `id` (UUID, PK)
- `book_id` (UUID, FK → books.id, UNIQUE)
- `total_chapters` (INTEGER)
- `total_tokens` (INTEGER)
- `total_characters` (INTEGER)
- `max_chapter_tokens` (INTEGER)
- `created_at` (TIMESTAMP)

#### Таблицы анализов

**`chapter_analyses`**
- `id` (UUID, PK)
- `chapter_id` (UUID, FK → chapters.id, UNIQUE)
- `analysis_result` (JSONB) - структурированный анализ. Блок framework (реализован, промпт протестирован):
  ```json
  {
    "framework": {
      "terms": {
        "термин1": "пояснение в 3–7 слов для обычного человека",
        "термин2": "пояснение в 3–7 слов"
      },
      "principles": [
        {
          "title": "Краткое название принципа",
          "description": "Живая формулировка с пояснением, как проявляется в жизни",
          "example": "Один бытовой пример в одну фразу: работа, дом или отношения",
          "chains": [
            {
              "cause": "Причина или ситуация, с которой всё начинается",
              "mechanism": "Что происходит / какой процесс запускается",
              "result": "К какому результату это приводит для человека"
            }
          ]
        }
      ]
    },
    "инсайты": ["инсайт1", "инсайт2", ...],
    "применение": ["шаг1", "шаг2", ...],
    "применимость": [{"техника": "...", "ситуации": [...], "цели": [...]}]
  }
  ```
  Опционально в «применение» или отдельно: для каждой техники — ситуации применения, цели (смыслы). Валидатор блока framework должен проверять структуру (terms, principles с chains и example) и соответствие тексту главы.
- `validation_score` (FLOAT) - оценка качества (0.0-1.0)
- `validated_at` (TIMESTAMP)
- `created_at` (TIMESTAMP)

**`chapter_relations`**
- `id` (UUID, PK)
- `from_chapter_id` (UUID, FK → chapters.id)
- `to_chapter_id` (UUID, FK → chapters.id)
- `relation_type` (VARCHAR) - 'sequence', 'concept', 'dependency'
- `relevance_score` (FLOAT)
- `created_at` (TIMESTAMP)

**`book_concepts`**
- `id` (UUID, PK)
- `book_id` (UUID, FK → books.id)
- `concept_type` (VARCHAR) - 'framework', 'insights_summary', 'application_plan', 'core_skill'
- `content` (JSONB) - агрегированные концепции
- `core_skill` (TEXT) - главный навык книги (для concept_type='core_skill')
- `core_skill_description` (TEXT) - описание главного навыка
- `essential_chapters_count` (INTEGER) - количество критичных глав для главного навыка
- `created_at` (TIMESTAMP)

#### Таблицы тегов

**`tags`**
- `id` (UUID, PK)
- `name` (VARCHAR, UNIQUE) - название тега
- `category` (VARCHAR) - категория тега: `principle` | `psychology` | `method` | `result` | `context` (см. маппинг ниже)
- `description` (TEXT) - описание тега
- `parent_tag_id` (UUID, FK → tags.id) - для иерархии тегов
- `created_at` (TIMESTAMP)
- Словарь тегов: только утверждённые теги; в промпт ИИ передаётся актуальный список.

**Маппинг категорий тегов (ключ в JSON/БД ↔ описание):**

| Ключ (JSON, БД) | Описание категории |
|-----------------|---------------------|
| `principle` | По сути правила/принципа: название правила/принципа, ключевые концепции, связанные принципы |
| `psychology` | По психологическому механизму: психологические концепции, проблемы, механизмы работы |
| `method` | По методу/технике: конкретные методики, подходы, процессы |
| `result` | По результату/цели: достигаемые результаты, цели применения |
| `context` | По контексту книги: связь с концепцией книги, автор и подход, общая тематика |

Выход шага «Извлечение тегов» (промпт `3_извлечение_тегов/extract_tags.txt`): JSON с ключами `tags.principle`, `tags.psychology`, `tags.method`, `tags.result`, `tags.context` — массивы объектов `{ "tag", "confidence" }`. Поле `proposed[].category` использует те же ключи.

**`tag_candidates`** (кандидаты в теги от ИИ, до ревью)
- `id` (UUID, PK)
- `chapter_id` (UUID, FK → chapters.id) - глава, для которой предложен тег
- `name` (VARCHAR) - предложенное название тега
- `category` (VARCHAR) - категория
- `confidence` (FLOAT) - уверенность ИИ
- `status` (VARCHAR) - 'pending', 'approved', 'rejected'
- `created_at` (TIMESTAMP)
- После одобрения: создаётся запись в `tags`, связи в `chapter_tags`; кандидат помечается approved или удаляется.

**`chapter_tags`**
- `id` (UUID, PK)
- `chapter_id` (UUID, FK → chapters.id)
- `tag_id` (UUID, FK → tags.id)
- `confidence` (FLOAT) - уверенность ИИ в релевантности тега (0.0-1.0)
- `validated` (BOOLEAN) - проверен ли тег валидатором
- `source` (VARCHAR) - источник тега ('ai_extraction', 'ai_validation', 'manual')
- `created_at` (TIMESTAMP)

#### Таблицы коуч-планов

**`coach_plans`**
- `id` (UUID, PK)
- `book_id` (UUID, FK → books.id)
- `version` (INTEGER) - версия плана
- `title` (VARCHAR)
- `description` (TEXT)
- `plan_type` (VARCHAR) - 'essential', 'full', 'thematic'
- `core_skill` (TEXT) - главный навык плана (для essential планов)
- `application_plan` (JSONB) - план применения в жизни: когда/как часто/в каких ситуациях какую технику применять, как встроить в рутину (опционально)
- `created_at` (TIMESTAMP)
- `updated_at` (TIMESTAMP)

**`plan_items`**
- `id` (UUID, PK)
- `plan_id` (UUID, FK → coach_plans.id)
- `order` (INTEGER) - порядок в плане
- `title` (VARCHAR) - название навыка/компетенции
- `description` (TEXT) - описание навыка
- `skill_name` (VARCHAR) - название навыка
- `created_at` (TIMESTAMP)

**`plan_item_details`**
- `id` (UUID, PK)
- `item_id` (UUID, FK → plan_items.id)
- `type` (VARCHAR) - 'technique', 'method', 'exercise'
- `title` (VARCHAR)
- `content` (TEXT) - описание техники/методики
- `source_chapter_id` (UUID, FK → chapters.id) - ссылка на главу
- `source_text_position` (JSONB) - позиция в тексте: `{start: int, end: int}`
- `situations` (JSONB) - ситуации, в которых техника полезна (опционально)
- `goals` (JSONB) - цели, для которых применима (опционально)
- `created_at` (TIMESTAMP)

**`item_chapter_links`**
- `id` (UUID, PK)
- `item_id` (UUID, FK → plan_items.id)
- `chapter_id` (UUID, FK → chapters.id)
- `relevance_score` (FLOAT) - релевантность навыка главе
- `link_type` (VARCHAR) - 'primary', 'secondary', 'reference'
- `created_at` (TIMESTAMP)

**`text_excerpts`**
- `id` (UUID, PK)
- `chapter_id` (UUID, FK → chapters.id)
- `start_pos` (INTEGER) - начало фрагмента в тексте
- `end_pos` (INTEGER) - конец фрагмента
- `excerpt_text` (TEXT) - выделенный фрагмент
- `linked_to_item_id` (UUID, FK → plan_items.id) - связанный навык
- `created_at` (TIMESTAMP)

#### Индексы

- `books.id`, `books.title`, `books.author`
- `chapters.book_id`, `chapters.chapter_number`, `chapters.id`
- `chapter_analyses.chapter_id`
- `coach_plans.book_id`
- `plan_items.plan_id`, `plan_items.order`
- `plan_item_details.item_id`, `plan_item_details.source_chapter_id`
- `item_chapter_links.item_id`, `item_chapter_links.chapter_id`
- `tags.name`, `tags.category`
- `tag_candidates.status`, `tag_candidates.chapter_id`
- `chapter_tags.chapter_id`, `chapter_tags.tag_id`
- JSONB индексы на `analysis_result`, `content` для быстрого поиска

### Структура данных в Qdrant

#### Коллекция: `chapter_analyses`
- **Вектор**: эмбеддинг валидированного анализа главы
- **Payload**:
  ```json
  {
    "bookId": "uuid",
    "chapterId": "uuid",
    "chapterNumber": 1,
    "chapterTitle": "string",
    "title": "string",
    "author": "string",
    "validationScore": 0.95,
    "tags": []
  }
  ```
  Теги добавляются в payload для фильтрации (из шага 4 пайплайна).

#### Коллекция: `plan_items`
- **Вектор**: эмбеддинг пункта плана (навыка)
- **Payload**:
  ```json
  {
    "planId": "uuid",
    "itemId": "uuid",
    "bookId": "uuid",
    "skillName": "string",
    "order": 1
  }
  ```

#### Коллекция: `techniques`
- **Вектор**: эмбеддинг техники/методики
- **Payload**:
  ```json
  {
    "itemId": "uuid",
    "detailId": "uuid",
    "type": "technique|method|exercise",
    "chapterId": "uuid",
    "bookId": "uuid"
  }
  ```

#### Коллекция: `skills_techniques` (для кросс-книжного поиска)
- **Вектор**: эмбеддинг навыка/техники
- **Payload**:
  ```json
  {
    "bookId": "uuid",
    "bookTitle": "string",
    "author": "string",
    "chapterId": "uuid",
    "chapterNumber": 1,
    "chapterTitle": "string",
    "skillName": "string",
    "techniqueType": "skill|technique|method|exercise",
    "itemId": "uuid",
    "detailId": "uuid"
  }
  ```

### Связь данных

- Один `chapter_id` → множество `qdrant_point_ids[]` (если разбиваешь на чанки)
- Отдельная таблица/коллекция для связи (опционально)

### Навигация и связи

**Двусторонняя навигация:**
- Навык → глава → полный текст главы
- Техника → фрагмент текста → расширенный контекст
- Глава → связанные навыки и техники

**API endpoints:**
- `GET /api/books/{book_id}/chapters/{chapter_id}` - полный текст главы
- `GET /api/books/{book_id}/chapters/{chapter_id}/excerpts` - выделенные фрагменты
- `GET /api/plan-items/{item_id}/source` - исходный текст с контекстом
- `GET /api/chapters/{chapter_id}/related-skills` - связанные навыки

**Кэширование в Redis:**
- Кэш текста главы: `chapter:{chapter_id}:content` (TTL: 1 час)
- Кэш связанных навыков: `chapter:{chapter_id}:skills` (TTL: 1 час)
- Кэш результатов анализа: `analysis:{chapter_id}` (TTL: 24 часа)
- Кэш эмбеддингов популярных запросов: `ask:{hash_of_query}` (TTL: 1 час)

---

## Функциональность системы

### Генерация коуч-планов

#### Процесс генерации коуч-плана

1. **Анализ всех глав** → структурированный JSON (каркас, инсайты, применение)
2. **Выделение навыков** из применений всех глав
3. **Группировка навыков** → пункты плана (plan_items)
4. **Для каждого пункта**: поиск техник/методик по всей книге через семантический поиск
5. **Связывание с исходными главами**: создание ссылок (item_chapter_links) и выделение фрагментов (text_excerpts)
6. **Агрегация концепций**: создание общих концепций книги (book_concepts)
7. **Определение главного навыка**: выделение основного навыка книги
8. **Выделение критических глав**: определение минимального набора глав для освоения главного навыка
9. **Генерация плана**: создание коуч-плана с упорядоченными пунктами
   - Эссенциальный план (только критичные главы)
   - Полный план (все главы)
10. **Сведение техник**: объединение повторяющихся техник из разных глав в одну формулировку; итог — короткий набор уникальных практик (дедупликация по смыслу).
11. **Применимость (смыслы)**: для каждой техники — ситуации, в которых полезна, и цели, для которых применима (отдельный проход ИИ по собранным техникам или при генерации плана).
12. **План применения в жизни**: на основе техник и **вывода шага применимости (11)** — когда, как часто, в каких триггерах/ситуациях что делать; как встроить в рутину. Строится **после** шага применимости и использует ситуации/цели по техникам; иначе риск получить общие фразы. Сохраняется как часть коуч-плана или отдельный артефакт.

#### Ограничения контекста, дедупликация техник и качество плана

**Объём контекста при генерации плана:**
- Для книг с большим числом глав (30+) один вызов LLM на «все анализы» нецелесообразен: лимит контекста и/или поверхностный синтез. Варианты:
  - **Сжатые выжимки:** по каждой главе передавать в промпт только каркас + ключевые инсайты + список техник (без полного текста применения).
  - **Поэтапная агрегация:** сначала синтез по частям книги (например, по 5–10 глав), затем финальный проход по агрегатам — выделение навыков, главного навыка, сведение техник.
  - **Лимит на вход:** передавать в финальный синтез только топ-N глав по релевантности или по числу техник.
- Стратегию выбирать в конфиге; документировать в архитектуре, что именно попадает в промпт генерации плана.

**Дедупликация техник (шаг 10):**
- Способ объединения «повторяющихся» техник из разных глав нужно формализовать, иначе реализация размыта. Варианты:
  - **По эмбеддингам:** техники уже в Qdrant; кластеризация или порог косинусной близости — техники ближе порога считаются одной, оставляем каноническую формулировку (например, из самой релевантной главы).
  - **Отдельный вызов LLM:** пары или группы техник на вход — модель отвечает «одна техника или разные?»; объединять по её вердикту.
  - **Эвристики:** совпадение ключевых слов, нормализация названий и т.п.
- В архитектуре зафиксировать выбранный способ (или комбинацию) и пороги (если по эмбеддингам).

**Качество плана:**
- План не лучше анализов глав: если в блоках application мало техник или они слабо выведены из инсайтов, план будет бедным. Опционально перед генерацией плана проверять «плотность» применения по книге (например, доля глав с непустым application); при необходимости — повторный проход по слабым главам или дообогащение application.

#### Эссенциальный план - минимальный путь к навыку

**Концепция:**
Не все главы книги необходимы для освоения главного навыка. Система определяет минимальный набор критических глав, достаточный для получения значимого результата.

**Пример:**
- Книга: "Атомные привычки"
- Главный навык: "Системное формирование привычек через сверхмалые шаги"
- Эссенциальный план: 5-7 критичных глав вместо всех 32
- Результат: быстрый путь к освоению навыка без лишней информации

**Процесс определения главного навыка:**

1. **Анализ всех глав книги:**
   - ИИ анализирует все главы и их анализы (каркас, инсайты, применение)
   - Выделяет общие темы и навыки
   - Определяет центральный навык, который объединяет книгу

2. **Формулировка главного навыка:**
   - ИИ формулирует главный навык на основе анализа
   - Пример: "Системное формирование привычек через сверхмалые шаги"
   - Сохраняется в `book_concepts.core_skill`

3. **Оценка релевантности глав:**
   - Для каждой главы ИИ оценивает релевантность главному навыку
   - Критерии:
     - Глава содержит ключевые принципы навыка
     - Глава описывает основные техники
     - Глава необходима для понимания системы
     - Глава критична для практического применения
   - Оценка: `relevance_to_core_skill` (0.0-1.0)

4. **Выделение критических глав:**
   - Ранжирование глав по релевантности
   - Выбор критических глав (например, топ-5-7 с релевантностью >0.8)
   - Проверка логической последовательности
   - Убедиться, что критичные главы покрывают все аспекты навыка

**Типы планов:**

**1. Эссенциальный план:**
- Только критичные главы для освоения главного навыка
- Минимальный путь к результату
- Быстрое освоение навыка
- Пример: 5-7 глав вместо 32

**2. Полный план:**
- Все главы книги
- Глубокое понимание темы
- Расширенный контекст и примеры
- Для тех, кто хочет изучить книгу полностью

**3. Тематический план:**
- План по конкретной теме из разных книг
- Кросс-книжный подход

**Пример структуры эссенциального плана:**

```
Книга: "Атомные привычки"
Главный навык: "Системное формирование привычек через сверхмалые шаги"

Эссенциальный план (5 глав):
  1. Глава 5: "Удивительная сила атомных привычек"
     Релевантность: 0.95
     Вклад: Основа концепции атомных привычек
     
  2. Глава 6: "Как привычки формируют идентичность"
     Релевантность: 0.90
     Вклад: Ключевой принцип - связь привычек и идентичности
     
  3. Глава 7: "Четыре простых шага для формирования лучших привычек"
     Релевантность: 0.95
     Вклад: Методология - основа системы
     
  4. Глава 19: "Правило двух минут"
     Релевантность: 0.85
     Вклад: Ключевая техника сверхмалых шагов
     
  5. Глава 22: "Главное правило изменения поведения"
     Релевантность: 0.90
     Вклад: Применение системы на практике

Расширенный план (32 главы):
  [все главы для глубокого понимания и контекста]
```

**API endpoints:**

- `POST /api/plans/essential/{book_id}` - создание эссенциального плана
- `GET /api/books/{book_id}/core-skill` - получение главного навыка книги
- `GET /api/books/{book_id}/chapters/essential` - список критичных глав

**Преимущества эссенциального плана:**

- **Быстрый результат**: минимальный путь к освоению навыка
- **Фокус**: только необходимое, без лишнего
- **Эффективность**: экономия времени
- **Гибкость**: можно выбрать эссенциальный или полный план
- **Персонализация**: адаптация под уровень пользователя

### Тегирование глав

#### Концепция

Многоуровневое тегирование глав для улучшения поиска, категоризации и связывания контента. Теги отражают суть главы по разным аспектам: принципы, психологические механизмы, методы, результаты, контекст.

#### Категории тегов

**1. По сути правила/принципа:**
- Название правила/принципа (например, "Правило двух минут")
- Ключевые концепции (например, "Атомные привычки", "Начало привычки")
- Связанные принципы (например, "Снижение барьера входа", "Порог входа")

**2. По психологическому механизму:**
- Психологические концепции (например, "Поведенческая психология")
- Проблемы, которые решает (например, "Прокрастинация", "Мотивация")
- Механизмы работы (например, "Инерция", "Эффект запуска")

**3. По методу/технике:**
- Конкретные методики (например, "Метод Кайдзен", "Микро-привычки")
- Подходы (например, "Системы vs цели")
- Процессы (например, "Формирование привычек", "Цепочка привычек")

**4. По результату/цели:**
- Достигаемые результаты (например, "Продуктивность", "Самодисциплина")
- Цели применения (например, "Преодоление прокрастинации", "Построение рутины")

**5. По контексту книги:**
- Связь с общей концепцией книги (например, "Законы изменения поведения")
- Автор и его подход (например, "Джеймс Клир")
- Общая тематика (например, "Самосовершенствование")

#### Процесс извлечения и валидации тегов

**Отдельный этап в пайплайне:**
- Тегирование выполняется **после** анализа и валидации анализа
- ИИ использует уже структурированные данные (каркас, инсайты, применение)
- Это позволяет лучше понять суть главы на основе полного контекста

**1. Извлечение тегов (qwen3-14b:8bit) — шаг 3 пайплайна:**
- Вход: валидированный анализ + оригинальный текст главы + словарь допустимых тегов (`allowed_tags_json`)
- Промпт: `3_извлечение_тегов/extract_tags.txt`. Извлечение тегов по категориям (principle, psychology, method, result, context) на основе полного понимания главы
- Результат: JSON с тегами по категориям и confidence; кандидаты в `proposed` при необходимости

**2. Валидация тегов (qwen3-14b:8bit) — шаг 4 пайплайна:**
- Вход: извлечённые теги + валидированный анализ + оригинальный текст главы
- Промпт: `4_валидация_тегов/validate_tags.txt`. Проверка релевантности каждого тега содержанию главы, соответствие каркасу/инсайтам/применению
- Фильтрация нерелевантных и слишком общих тегов; обновление confidence
- Выход: проверенные теги; снятые при валидации — в блоке `removed` (tag, category, reason)
- Время: ~20–30 секунд на главу

**3. Онтология/таксономия и правила работы ИИ с тегами:**

- **Фиксированный словарь:** ИИ навешивает теги из предопределённого набора (по категориям). Словарь хранится в БД (`tags`), в промпт передаётся актуальный список допустимых тегов.
- **Правило добавления новых тегов:** новый тег предлагать **только если ни один существующий не подходит по смыслу**. Сначала — выбор из текущего набора; если глава требует концепта, которого нет в словаре — ИИ возвращает кандидата в новом теге с пометкой «предложен к добавлению».
- **Ревью новых тегов:** предложенные ИИ теги не попадают в общий словарь автоматически. Они сохраняются в отдельной очереди/таблице (кандидаты); добавление в `tags` — после ручного подтверждения или отдельного прохода валидатора. Так таксономия остаётся под контролем при росте числа книг.
- **Периодическая очистка:** объединять синонимы (один канонический тег, остальные — алиасы или миграция связей); удалять или архивировать редко используемые теги. Это предотвращает раздувание словаря при масштабировании на множество книг.
- **Итог:** ИИ + фиксированный набор + строгое правило на новые + ревью + очистка = стабильные теги как фильтр при кросс-книжном поиске, без хаоса формулировок.

**4. Многоуровневая проверка:**
- Проверка 1: теги соответствуют содержанию главы?
- Проверка 2: теги логично связаны с другими главами?
- Проверка 3: теги отражают суть, а не поверхностные упоминания?
- Финальная проверка: сравнение с похожими главами

#### Структурированный промпт для извлечения тегов

**Важно:** Промпт использует уже проанализированные данные для более точного понимания сути. Категории в ответе — на английском (ключи `principle`, `psychology`, `method`, `result`, `context`), соответствуют полю `tags.category` в БД. Маппинг см. в разделе «Хранение данных» → таблица `tags`.

```
На основе анализа главы "{chapter_title}" из книги "{book_title}" извлеки теги.

У тебя есть следующие данные:
- Каркас главы (фундаментальные принципы): {framework}
- Инсайты: {insights}
- Применение: {application}
- Оригинальный текст главы: {chapter_text}

Извлеки теги по следующим категориям:

1. ПО СУТИ ПРАВИЛА/ПРИНЦИПА:
   - Название правила/принципа
   - Ключевые концепции
   - Связанные принципы
   
2. ПО ПСИХОЛОГИЧЕСКОМУ МЕХАНИЗМУ:
   - Психологические концепции
   - Проблемы, которые решает
   - Механизмы работы
   
3. ПО МЕТОДУ/ТЕХНИКЕ:
   - Конкретные методики
   - Подходы
   - Процессы
   
4. ПО РЕЗУЛЬТАТУ/ЦЕЛИ:
   - Достигаемые результаты
   - Цели применения
   
5. ПО КОНТЕКСТУ КНИГИ:
   - Связь с общей концепцией книги
   - Автор и его подход
   - Общая тематика

ВАЖНО:
- Теги должны отражать СУТЬ главы, а не просто упоминания
- Каждый тег должен быть релевантен содержанию
- Избегай слишком общих тегов
- Приоритет: качество над количеством

ПРАВИЛО ДЛЯ ТЕГОВ:
- Выбирай теги ТОЛЬКО из переданного списка допустимых тегов (по категориям)
- Если для главы нужен смысл, которого нет в списке — верни его как кандидат в новом теге с флагом "предложен_к_добавлению"; не придумывай теги «в обход» словаря
- Один и тот же смысл — один тег; не дублируй синонимами из списка

Верни JSON с тегами по категориям и confidence score для каждого тега.
```

#### Использование тегов

**Поиск и фильтрация:**
- Фильтрация глав по тегам: "найти все главы с тегом 'прокрастинация'"
- Комбинированные фильтры: теги + семантический поиск
- Поиск по категориям: "все главы о методах продуктивности"

**Рекомендации:**
- Похожие главы по общим тегам
- Рекомендации на основе тегов пользователя
- Кросс-книжные связи через общие теги

**Кластеризация:**
- Группировка глав по тегам
- Выявление общих тем между книгами
- Создание тематических коллекций

**Аналитика:**
- Популярные теги по библиотеке
- Распределение тегов по категориям
- Связи между тегами (граф знаний)

**Гибридный поиск:**
- Семантический поиск (Qdrant) + фильтрация по тегам (Postgres)
- Взвешенное ранжирование: релевантность + теги
- Улучшение точности поиска

### Семантический поиск

#### Кросс-книжный поиск

**Концепция:**
Создание комплексных коуч-планов, объединяющих навыки и техники из нескольких книг. Один навык может быть представлен в разных книгах с разными подходами и техниками.

**Архитектура поиска:**
- Единое пространство эмбеддингов в Qdrant
- Все навыки/техники из всех книг в одной коллекции `skills_techniques`
- Эмбеддинги создаются на основе анализа глав (каркас, инсайты, применение)
- Payload содержит метаданные для фильтрации и группировки

**Процесс кросс-книжного поиска:**

1. **Семантический поиск по навыку:**
   - Пользователь ищет "управление временем"
   - Qdrant находит все похожие навыки/техники из всех книг
   - Результаты ранжируются по релевантности (косинусное расстояние)

2. **Фильтрация и группировка:**
   - Фильтр по книгам: `bookId IN [book1, book2, ...]`
   - Группировка похожих навыков из разных книг
   - Выделение общих принципов и уникальных техник

3. **Агрегация результатов:**
   - Объединение техник из разных источников
   - Приоритизация: навыки, встречающиеся в нескольких книгах
   - Выявление комплементарных техник (дополняют друг друга)

4. **Построение комплексного плана:**
   - Выбор навыка → поиск всех техник из всех книг
   - Сортировка по релевантности и качеству валидации
   - Объединение в единый план с указанием источников

**Пример структуры кросс-книжного плана:**

```
Комплексный коуч-план: "Управление временем"
  ├─ Навык: "Приоритизация задач"
  │   ├─ Техника 1: "Матрица Эйзенхауэра" (книга А, глава 5)
  │   ├─ Техника 2: "Метод ABC" (книга Б, глава 12)
  │   └─ Техника 3: "Правило 2 минут" (книга В, глава 8)
  │
  ├─ Навык: "Фокус и концентрация"
  │   ├─ Техника 1: "Помодоро" (книга А, глава 7)
  │   └─ Техника 2: "Глубокое погружение" (книга Б, глава 15)
  │
  └─ Навык: "Планирование дня"
      ├─ Техника 1: "Блокировка времени" (книга В, глава 3)
      └─ Техника 2: "Ежедневный обзор" (книга А, глава 10)
```

**API для кросс-книжного поиска:**

- `POST /api/search/skills` - поиск навыков по запросу
  - Параметры: `query`, `bookIds[]`, `limit`, `threshold`
  - Возвращает: список навыков с релевантностью и источниками

- `POST /api/plans/complex` - создание плана из нескольких книг
  - Параметры: `skillNames[]`, `bookIds[]`, `preferences`
  - Возвращает: комплексный план с техниками из разных книг

- `GET /api/skills/cluster?skillName=X` - похожие навыки из разных книг
- `GET /api/skills/complementary?skillId=Y` - комплементарные навыки

**Дополнительные возможности:**

- **Кластеризация похожих навыков**: автоматическое группирование похожих навыков из разных книг
- **Выявление противоречий**: поиск противоречащих техник из разных книг
- **Рекомендации**: "Если изучаешь X из книги А, посмотри Y из книги Б"

#### RAG-поиск через Qdrant (ИИ-ассистент)

**Концепция:**
Пользователь задает вопрос на естественном языке (например, "что почитать на тему достигаторства?"), система находит релевантные главы через семантический поиск в Qdrant и ИИ формирует персонализированные рекомендации с объяснениями.

**Архитектура RAG pipeline:**

1. **Обработка запроса пользователя:**
   - Пользователь: "Что почитать на тему достигаторства?"
   - Создание эмбеддинга запроса через модель эмбеддингов (по умолчанию bge-m3)
   - Семантический поиск в Qdrant по коллекциям:
     - `chapter_analyses` - анализ глав
     - `skills_techniques` - навыки и техники
   - Получение top-k релевантных результатов (например, top-10)

2. **Формирование контекста для ИИ:**
   - Извлечение метаданных найденных глав из Qdrant payload
   - Получение полной информации о главах из Postgres
   - Формирование структурированного контекста для промпта

3. **Генерация ответа через ИИ:**
   - Использование LLM (по умолчанию qwen3-14b:8bit или конфигурируемая модель) для генерации ответа
   - Промпт включает:
     - Вопрос пользователя
     - Список релевантных глав с метаданными
     - Инструкции по форматированию ответа

4. **Структурированный ответ:**
   - Список рекомендованных глав с рейтингом релевантности
   - Краткое объяснение, почему каждая глава подходит
   - Ссылки на полный текст глав
   - Предложения связанных навыков и техник

**Структура промпта для ИИ:**

```
Ты помощник по библиотеке развивающих книг. 
Пользователь задал вопрос: "{user_query}"

На основе семантического поиска найдены следующие релевантные главы:

1. Книга: "{book_title}", Автор: "{author}"
   Глава {chapter_number}: "{chapter_title}"
   Релевантность: {score}
   Краткое описание: {analysis_summary}

2. [повторяется для каждой найденной главы]

Сформируй персонализированный ответ с рекомендациями:
- Укажи конкретные главы и книги
- Объясни, почему каждая глава подходит для вопроса
- Предложи порядок чтения (если уместно)
- Упомяни связанные навыки и техники

Формат ответа: структурированный список с объяснениями.
```

**API endpoint:**

**`POST /api/ask` - ИИ-ассистент для поиска книг/глав**

**Запрос:**
```json
{
  "query": "Что почитать на тему достигаторства?",
  "limit": 10,
  "bookIds": ["uuid1", "uuid2"],  // опционально: фильтр по книгам
  "includeRelated": true  // включить связанные навыки
}
```

**Ответ:**
```json
{
  "answer": "На основе вашего запроса рекомендую следующие главы...",
  "recommendations": [
    {
      "bookId": "uuid",
      "bookTitle": "string",
      "author": "string",
      "chapterId": "uuid",
      "chapterNumber": 1,
      "chapterTitle": "string",
      "relevanceScore": 0.95,
      "explanation": "Эта глава подходит, потому что...",
      "relatedSkills": ["skill1", "skill2"]
    }
  ],
  "relatedSkills": [
    {
      "skillName": "string",
      "sources": ["book1", "book2"]
    }
  ]
}
```

**Процесс обработки запроса:**

1. Эмбеддинг запроса (модель эмбеддингов, по умолчанию bge-m3) → вектор запроса
2. Семантический поиск в Qdrant → top-k релевантных глав
3. Получение метаданных из Postgres для найденных глав
4. Формирование контекста для промпта ИИ
5. Генерация ответа через LLM (qwen3-14b:8bit или конфиг)
6. Структурирование ответа с ссылками и объяснениями
7. Кэширование результата в Redis (TTL: 1 час)

**Оптимизация:**

- **Кэширование**: кэш эмбеддингов популярных запросов в Redis
- **Фильтрация**: опциональная фильтрация по книгам, авторам, тематикам
- **Гибридный поиск**: комбинация семантического поиска (Qdrant) и полнотекстового (Postgres)

**Дополнительные возможности:**

- **Уточняющие вопросы**: ИИ может задать уточняющие вопросы для более точного поиска
- **История диалога**: сохранение контекста предыдущих вопросов
- **Обратная связь**: пользователь может оценить полезность рекомендаций

### Тематические коуч-планы на основе тегов

#### Концепция

Пользователь хочет прокачать конкретный навык или тему (например, "внимательность"). Система находит все релевантные главы из разных книг по тегам, использует семантический поиск для дополнительных результатов и ИИ составляет комплексный коуч-план, объединяя техники из разных источников.

#### Процесс создания тематического плана

**1. Поиск по тегам:**
- Пользователь: "Хочу прокачать внимательность"
- Система ищет теги: прямое совпадение ("внимательность") + семантически похожие ("фокус", "концентрация", "осознанность", "mindfulness")
- Находятся все главы с релевантными тегами из разных книг
- Результаты ранжируются по релевантности тегов

**2. Комбинированный поиск:**
- **Теги (Postgres)**: точная фильтрация по релевантным тегам
- **Семантический поиск (Qdrant)**: поиск похожих концепций через эмбеддинги
- **Объединение результатов**: дедупликация и ранжирование
- **Приоритизация**: главы с несколькими релевантными тегами выше

**3. Генерация плана через ИИ:**
- ИИ получает найденные главы с их тегами, анализами и метаданными
- Формирует структурированный тематический план:
  - Группировка по подтемам (на основе тегов и анализа)
  - Последовательность изучения (логический порядок)
  - Техники из разных книг с объяснениями
  - Объяснение, почему каждая техника подходит для темы

**4. Структура тематического плана:**

```
Тема: "Внимательность"
  ├─ Подтема 1: "Фокус и концентрация"
  │   ├─ Техника: "Метод помодоро" (книга А, глава 5)
  │   │   Теги: [фокус, концентрация, продуктивность]
  │   └─ Техника: "Глубокое погружение" (книга Б, глава 12)
  │       Теги: [концентрация, фокус, работа]
  │
  ├─ Подтема 2: "Осознанность и mindfulness"
  │   ├─ Техника: "Медитация осознанности" (книга В, глава 8)
  │   │   Теги: [осознанность, медитация, mindfulness]
  │   └─ Техника: "Практика присутствия" (книга А, глава 15)
  │       Теги: [осознанность, присутствие, практика]
  │
  └─ Подтема 3: "Управление отвлечениями"
      ├─ Техника: "Цифровой детокс" (книга Б, глава 20)
      │   Теги: [отвлечения, цифровая гигиена, фокус]
      └─ Техника: "Создание среды для фокуса" (книга В, глава 3)
          Теги: [окружение, фокус, продуктивность]
```

**API endpoint:**

**`POST /api/plans/thematic` - создание тематического коуч-плана**

**Запрос:**
```json
{
  "theme": "внимательность",
  "tags": ["фокус", "концентрация", "осознанность"],  // опционально: конкретные теги
  "bookIds": ["uuid1", "uuid2"],  // опционально: фильтр по книгам
  "excludeBookIds": ["uuid3"],  // опционально: исключить книги
  "maxChapters": 20,  // максимум глав для анализа
  "preferences": {
    "focusOnTechniques": true,
    "includeTheory": false
  }
}
```

**Ответ:**
```json
{
  "planId": "uuid",
  "theme": "внимательность",
  "title": "Коуч-план: Развитие внимательности",
  "description": "Комплексный план из 5 книг...",
  "subthemes": [
    {
      "name": "Фокус и концентрация",
      "order": 1,
      "items": [
        {
          "itemId": "uuid",
          "title": "Метод помодоро",
          "techniques": [
            {
              "techniqueId": "uuid",
              "title": "Техника помодоро",
              "description": "...",
              "bookId": "uuid",
              "bookTitle": "string",
              "chapterId": "uuid",
              "chapterNumber": 5,
              "chapterTitle": "string",
              "tags": ["фокус", "концентрация"],
              "relevanceScore": 0.95,
              "explanation": "Эта техника подходит, потому что..."
            }
          ]
        }
      ]
    }
  ],
  "statistics": {
    "totalBooks": 5,
    "totalChapters": 12,
    "totalTechniques": 18
  }
}
```

**Процесс обработки:**

1. **Поиск тегов** (Postgres): прямой поиск + семантический поиск похожих тегов
2. **Семантический поиск** (Qdrant): создание эмбеддинга темы запроса
3. **Объединение и ранжирование**: дедупликация, взвешенное ранжирование
4. **Получение данных** (Postgres): полная информация о найденных главах
5. **Генерация плана** (LLM, по умолчанию qwen3-14b:8bit): формирование структурированного плана
6. **Сохранение плана**: создание записи в БД

**Дополнительные возможности:**

- **Рекомендации связанных тем**: "Если изучаешь внимательность, посмотри про продуктивность"
- **Прогресс по темам**: отслеживание освоения навыков
- **Адаптация плана**: обновление при добавлении новых книг
- **Аналитика**: популярные темы, эффективность планов

### UX навигации

- В карточке навыка: кнопка "Читать главу полностью"
- В тексте главы: маркеры связанных навыков (подсветка)
- Быстрый переход: навык ↔ глава
- Контекстное меню: "Показать связанные навыки" в главе
- Навигация по иерархии: план → пункт → техника → исходный текст

---

## Операционные аспекты

### Масштабирование

#### Горизонтальное масштабирование

- **Воркеры**: запускать несколько контейнеров с воркерами
- **FastAPI**: несколько инстансов за балансировщиком (stateless)
- **Ollama**: один контейнер = один запрос за раз (если не настроен параллелизм)

#### Ограничения

- **Ollama**: основной узкое место
- **Решение**: несколько инстансов Ollama или настройка `OLLAMA_NUM_PARALLEL`
- **CPU обработка**: медленно, но стабильно (без GPU)

#### Рекомендации по масштабированию

- Начать с 1-2 воркеров (последовательная обработка)
- Мониторить длину очереди в Redis
- Масштабировать воркеры по потребности
- При высокой нагрузке - несколько инстансов Ollama

### Мониторинг

#### Метрики

- Время обработки каждой главы
- Успешность валидации
- Качество анализа
- Длина очереди в Redis
- Использование памяти Ollama
- Загрузка CPU

#### Логирование

- Все этапы обработки
- Ошибки с контекстом
- Время выполнения каждого этапа

### Рекомендации по конфигурации

#### Для 30GB RAM (оптимальная конфигурация)

1. **Lazy loading моделей** - загружать по требованию, выгружать через `keep_alive: 0`
2. **Оптимизировать промпты** - минимум токенов (~200-300 вместо 1000-2000)
3. **OLLAMA_NUM_CTX=9000** - компромисс между памятью и возможностями
4. **Обработка строго последовательно** - одна глава, одна модель за раз
5. **Мониторить память** - следить за использованием RAM

**Итого памяти: ~18-22GB максимум (влезет в 30GB с запасом)**

#### Для масштабирования

1. Увеличить количество воркеров (при наличии памяти)
2. Настроить несколько инстансов Ollama
3. Использовать приоритетные очереди
4. Кэшировать эмбеддинги

#### Для большого контекста (20000 токенов)

1. Увеличить RAM до 48-64GB минимум
2. GPU опционально для ускорения
3. **НЕ разбивать главы на чанки** - качество анализа упадет

### Альтернативы n8n

**Проблемы n8n:**
- Таймауты выполнения
- Ограничения памяти
- Сложная отладка
- Плохая параллелизация

**Решение:**
- Нативный Python сервис с очередями (Celery/RQ)
- n8n оставить для триггеров и оркестрации между сервисами

---

## Приложения

### A. Примеры промптов

#### Анализ главы по блокам

Анализ выполняется **отдельным промптом на каждый блок** (framework → insights → application → limitations). Пример первого блока:

**Блок framework** — промпт `1_анализ_главы/extract_framework_v2.txt`:
- Вход: `book_title`, `chapter_title`, `chapter_text`.
- Задача: извлечь только блок «каркас» — принципы и цепочки причина–механизм–результат; глоссарий терминов (`terms`); у каждого принципа — `example` (бытовой пример в одну фразу).
- Правила: не пересказывать текст, язык простой и приземлённый к поведению, один принцип = одна опорная мысль.
- Выход: строго один JSON с ключом верхнего уровня `"framework"` и вложенной структурой `terms` + `principles` (каждый с `title`, `description`, `example`, `chains` с полями `cause`, `mechanism`, `result`).

Остальные блоки: `extract_insights_v3.txt`, `extract_application_v2.txt`, `extract_limitations_v3.txt` (каталог `1_анализ_главы/`). После каждого блока — валидация по блоку (каталог `2_валидация_анализа_по_блокам/`), затем склейка и финальная валидация согласованности (`2b_финальная_валидация_согласованности/validate_consistency.txt`).

#### Промпт для валидации анализа

```
Проверь качество анализа главы "{chapter_title}".

Оригинальный текст главы:
{chapter_text}

Результат анализа:
{analysis_result}

Проверь:
1. Соответствие анализа содержанию главы
2. Отсутствие галлюцинаций
3. Полноту покрытия темы
4. Качество структурирования

Верни оценку качества (0.0-1.0) и комментарии.
```

### B. Схема взаимодействия компонентов

```
┌─────────────┐
│   Client    │
└──────┬──────┘
       │
       ▼
┌─────────────────┐
│  FastAPI (API)  │
└──────┬──────────┘
       │
       ▼
┌─────────────┐
│    Redis    │◄──┐
│   (Queue)   │   │
└──────┬──────┘   │
       │          │
       ▼          │
┌─────────────┐   │
│   Workers   │───┘
│  (Celery)   │
└──────┬──────┘
       │
       ├──► Ollama (LLM)
       ├──► Postgres (DB)
       ├──► Qdrant (Vector DB)
       └──► Redis (Cache)
```

---

## Актуализация по каталогам этапов

Документ синхронизирован с README этапов пайплайна:

| Этап | Каталог | Ключевые файлы |
|------|---------|----------------|
| 1. Анализ главы по блокам | `1_анализ_главы/` | extract_framework_v2.txt, extract_insights_v3.txt, extract_application_v2.txt, extract_limitations_v3.txt |
| 2. Валидация блоков | `2_валидация_анализа_по_блокам/` | validate_framework.txt, validate_insights.txt, validate_application.txt, validate_limitations.txt |
| 2a. Склейка | — | Без LLM, слияние JSON |
| 2b. Финальная валидация | `2b_финальная_валидация_согласованности/` | validate_consistency.txt |
| 3. Извлечение тегов | `3_извлечение_тегов/` | extract_tags.txt |
| 4. Валидация тегов | `4_валидация_тегов/` | validate_tags.txt |
| 5. Мерж анализа и тегов | `5_мерж_анализа_и_тегов/` | merge_analysis_tags.py |
| 6. Генерация эмбеддингов | `6_генерация_эмбеддингов/` | embed_input_spec.txt |
| 7. Сохранение в Qdrant | `7_сохранение_qdrant/` | save_to_qdrant.py |
| 8. Сохранение в Postgres | `8_сохранение_postgres/` | save_to_postgres.py, schema.sql |

Модель LLM для шагов 1–4: **qwen3-14b:8bit**. Модель эмбеддингов (шаг 6): **BAAI/bge-m3**.

*Документ обновлен: 2026-01-31*
