Files
tech/ARCHITECTURE_SUMMARY.md
2026-02-01 23:59:39 +03:00

90 KiB
Raw Blame History

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

Содержание

  1. Введение и обзор
  2. Архитектура системы
  3. Пайплайн обработки
  4. Модели ИИ и 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): извлекать все значимые техники; одну и ту же идею в разных формулировках считать одной техникой; для глав с преобладанием инсайтов — формулировать применимые техники из инсайтов (когда/в какой ситуации что делать).
  • При сборке плана по книге: объединять повторяющиеся техники из разных глав в одну формулировку. Итог — короткий набор уникальных практик (если вся книга сводится к 12 техникам — это успех, а не провал).
  • План применения в жизни — отдельный результат: в каких ситуациях какую технику применять, с какой периодичностью, как встроить в рутину. Генерируется на основе собранных техник и их применимости.

Применимость (смыслы): для каждой техники полезно извлекать: в каких ситуациях полезна, для каких целей применима. Это может быть отдельный проход ИИ (по главе или по книге) или часть блока 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}; в шагах 24 дополнительно {previous_blocks_json} — накопленный JSON предыдущих блоков.
  • Промпты по блокам: extract_framework_v2.txtextract_insights_v3.txtextract_application_v2.txtextract_limitations_v3.txt (каталог 1_анализ_главы/).
  • Блок framework (каркас): извлекаются фундаментальные принципы и опорные идеи автора. Для каждого принципа — цепочки cause → mechanism → result; глоссарий специальных терминов главы (terms: термин → пояснение в 37 слов); у каждого принципа — поле example (один бытовой пример). Один принцип = одна опорная мысль, перекрывающиеся идеи объединяются. Выход — JSON с единственным ключом верхнего уровня "framework".
  • Блок application (применение): извлекать все значимые техники без раздувания списка: одну и ту же идею — одной техникой. Если в главе много инсайтов и мало явных «шагов» — выводить техники из инсайтов (операциональные правила: когда/что делать). Опционально для каждой техники: ситуации применения, цели (для чего полезна).
  • Отдельный промпт на каждый блок — модель решает одну задачу за раз, меньше пропусков и галлюцинаций.
  • Выход шага: JSON одного блока. После генерации блока — сразу валидация этого блока (см. п. 2).
  • Модель: загрузить → N вызовов по цепочке → выгрузить (keep_alive: 0).
  • Время: суммарно ~25+ минут на главу (4 блока последовательно).
  • Память: ~2021GB максимум (модель + контекст).

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.54.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. Время: ~3060 секунд.

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.
  • Время: ~12 минуты на главу. Память: ~2021GB максимум (модель + контекст).
  • Преимущество отдельного шага: ИИ использует уже структурированные данные (каркас, инсайты, применение) для более точного понимания сути.

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) и далее в эмбеддинг/БД.
  • Время: ~2030 секунд. Память: ~3.54.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, время ~515 сек на главу.
  • Альтернативы: при необходимости более лёгкой модели — 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: ~2021GB максимум (модель + контекст при анализе); ~3.54.5GB при валидации (меньший контекст).
  • bge-m3: ~1.2GB
  • Итого при одновременной загрузке: ~2432GB (если бы все модели были в памяти)
  • С lazy loading: ~2021GB максимум (одна модель за раз: анализ или валидация)

API эндпоинты Ollama

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

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

{
  "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)

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

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

При 30GB RAM с lazy loading:

  • qwen3-14b:8bit: оптимально 9000 токенов (даёт ~70008000 для текста главы)
  • Эмбеддинги: bge-m3 — 8192 токенов на вход, размерность 1024. Текст для эмбеддинга — сериализованный анализ главы; при превышении лимита — truncation или стратегия из embed_input_spec.txt (см. этап 6 пайплайна).

Анализ книг:

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

Для 20000 токенов контекста:

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

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

Выгрузка модели:

# Через /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
}'

Проверка загруженных моделей:

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 (реализован, промпт протестирован):
    {
      "framework": {
        "terms": {
          ермин1": "пояснение в 37 слов для обычного человека",
          ермин2": "пояснение в 37 слов"
        },
        "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:
    {
      "bookId": "uuid",
      "chapterId": "uuid",
      "chapterNumber": 1,
      "chapterTitle": "string",
      "title": "string",
      "author": "string",
      "validationScore": 0.95,
      "tags": []
    }
    
    Теги добавляются в payload для фильтрации (из шага 4 пайплайна).

Коллекция: plan_items

  • Вектор: эмбеддинг пункта плана (навыка)
  • Payload:
    {
      "planId": "uuid",
      "itemId": "uuid",
      "bookId": "uuid",
      "skillName": "string",
      "order": 1
    }
    

Коллекция: techniques

  • Вектор: эмбеддинг техники/методики
  • Payload:
    {
      "itemId": "uuid",
      "detailId": "uuid",
      "type": "technique|method|exercise",
      "chapterId": "uuid",
      "bookId": "uuid"
    }
    

Коллекция: skills_techniques (для кросс-книжного поиска)

  • Вектор: эмбеддинг навыка/техники
  • Payload:
    {
      "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 на «все анализы» нецелесообразен: лимит контекста и/или поверхностный синтез. Варианты:
    • Сжатые выжимки: по каждой главе передавать в промпт только каркас + ключевые инсайты + список техник (без полного текста применения).
    • Поэтапная агрегация: сначала синтез по частям книги (например, по 510 глав), затем финальный проход по агрегатам — выделение навыков, главного навыка, сведение техник.
    • Лимит на вход: передавать в финальный синтез только топ-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)
  • Время: ~2030 секунд на главу

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 - ИИ-ассистент для поиска книг/глав

Запрос:

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

Ответ:

{
  "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 - создание тематического коуч-плана

Запрос:

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

Ответ:

{
  "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 для шагов 14: qwen3-14b:8bit. Модель эмбеддингов (шаг 6): BAAI/bge-m3.

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