# Архитектура системы обработки книг через ИИ ## Содержание 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*