90 KiB
Архитектура системы обработки книг через ИИ
Содержание
- Введение и обзор
- Архитектура системы
- Пайплайн обработки
- Модели ИИ и Ollama
- Хранение данных
- Функциональность системы
- Операционные аспекты
- Приложения
- Актуализация по каталогам этапов
Введение и обзор
Назначение системы
Система обрабатывает EPUB файлы, переводит их в JSON с главами, анализирует каждую главу через ИИ, валидирует результаты, создает эмбеддинги и сохраняет в Qdrant. На основе анализа глав генерируются коуч-планы для освоения навыков из книг с детализацией техник и методик. Цель — не только извлечь информацию, но и научиться применять знания в жизни: техники выводятся из инсайтов при необходимости, при сборке плана дубли сводятся в уникальные практики, отдельно формируется план применения (когда/где/как применять).
Основной поток обработки
EPUB → JSON с главами → Анализ по блокам (framework → insights → application → limitations)
→ Валидация каждого блока → Склейка → Финальная валидация согласованности →
→ Извлечение тегов → Валидация тегов → Мерж анализа и тегов (5) → Генерация эмбеддингов (6) →
→ Сохранение в Qdrant/Postgres → Генерация коуч-плана → Сохранение плана
Архитектура системы
Компоненты системы
- epub-parser (FastAPI) - парсинг EPUB в JSON
- chapter-processor (новый сервис) - обработка глав
- FastAPI - API слой (прием запросов, постановка задач в очередь)
- Celery/RQ Workers - пайплайн обработки (анализ, валидация, эмбеддинг)
- Redis - очередь задач и кэширование
- Ollama - LLM для анализа и валидации
- Qdrant - векторная БД для эмбеддингов
- 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- проверка доступных моделей
Структура запроса
{
"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 токенов (даёт ~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
Выгрузка модели:
# Через /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, principles с chains и example) и соответствие тексту главы.{ "framework": { "terms": { "термин1": "пояснение в 3–7 слов для обычного человека", "термин2": "пояснение в 3–7 слов" }, "principles": [ { "title": "Краткое название принципа", "description": "Живая формулировка с пояснением, как проявляется в жизни", "example": "Один бытовой пример в одну фразу: работа, дом или отношения", "chains": [ { "cause": "Причина или ситуация, с которой всё начинается", "mechanism": "Что происходит / какой процесс запускается", "result": "К какому результату это приводит для человека" } ] } ] }, "инсайты": ["инсайт1", "инсайт2", ...], "применение": ["шаг1", "шаг2", ...], "применимость": [{"техника": "...", "ситуации": [...], "цели": [...]}] }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.authorchapters.book_id,chapters.chapter_number,chapters.idchapter_analyses.chapter_idcoach_plans.book_idplan_items.plan_id,plan_items.orderplan_item_details.item_id,plan_item_details.source_chapter_iditem_chapter_links.item_id,item_chapter_links.chapter_idtags.name,tags.categorytag_candidates.status,tag_candidates.chapter_idchapter_tags.chapter_id,chapter_tags.tag_id- JSONB индексы на
analysis_result,contentдля быстрого поиска
Структура данных в Qdrant
Коллекция: chapter_analyses
- Вектор: эмбеддинг валидированного анализа главы
- Payload:
Теги добавляются в payload для фильтрации (из шага 4 пайплайна).
{ "bookId": "uuid", "chapterId": "uuid", "chapterNumber": 1, "chapterTitle": "string", "title": "string", "author": "string", "validationScore": 0.95, "tags": [] }
Коллекция: 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 час)
Функциональность системы
Генерация коуч-планов
Процесс генерации коуч-плана
- Анализ всех глав → структурированный JSON (каркас, инсайты, применение)
- Выделение навыков из применений всех глав
- Группировка навыков → пункты плана (plan_items)
- Для каждого пункта: поиск техник/методик по всей книге через семантический поиск
- Связывание с исходными главами: создание ссылок (item_chapter_links) и выделение фрагментов (text_excerpts)
- Агрегация концепций: создание общих концепций книги (book_concepts)
- Определение главного навыка: выделение основного навыка книги
- Выделение критических глав: определение минимального набора глав для освоения главного навыка
- Генерация плана: создание коуч-плана с упорядоченными пунктами
- Эссенциальный план (только критичные главы)
- Полный план (все главы)
- Сведение техник: объединение повторяющихся техник из разных глав в одну формулировку; итог — короткий набор уникальных практик (дедупликация по смыслу).
- Применимость (смыслы): для каждой техники — ситуации, в которых полезна, и цели, для которых применима (отдельный проход ИИ по собранным техникам или при генерации плана).
- План применения в жизни: на основе техник и вывода шага применимости (11) — когда, как часто, в каких триггерах/ситуациях что делать; как встроить в рутину. Строится после шага применимости и использует ситуации/цели по техникам; иначе риск получить общие фразы. Сохраняется как часть коуч-плана или отдельный артефакт.
Ограничения контекста, дедупликация техник и качество плана
Объём контекста при генерации плана:
- Для книг с большим числом глав (30+) один вызов LLM на «все анализы» нецелесообразен: лимит контекста и/или поверхностный синтез. Варианты:
- Сжатые выжимки: по каждой главе передавать в промпт только каркас + ключевые инсайты + список техник (без полного текста применения).
- Поэтапная агрегация: сначала синтез по частям книги (например, по 5–10 глав), затем финальный проход по агрегатам — выделение навыков, главного навыка, сведение техник.
- Лимит на вход: передавать в финальный синтез только топ-N глав по релевантности или по числу техник.
- Стратегию выбирать в конфиге; документировать в архитектуре, что именно попадает в промпт генерации плана.
Дедупликация техник (шаг 10):
- Способ объединения «повторяющихся» техник из разных глав нужно формализовать, иначе реализация размыта. Варианты:
- По эмбеддингам: техники уже в Qdrant; кластеризация или порог косинусной близости — техники ближе порога считаются одной, оставляем каноническую формулировку (например, из самой релевантной главы).
- Отдельный вызов LLM: пары или группы техник на вход — модель отвечает «одна техника или разные?»; объединять по её вердикту.
- Эвристики: совпадение ключевых слов, нормализация названий и т.п.
- В архитектуре зафиксировать выбранный способ (или комбинацию) и пороги (если по эмбеддингам).
Качество плана:
- План не лучше анализов глав: если в блоках application мало техник или они слабо выведены из инсайтов, план будет бедным. Опционально перед генерацией плана проверять «плотность» применения по книге (например, доля глав с непустым application); при необходимости — повторный проход по слабым главам или дообогащение application.
Эссенциальный план - минимальный путь к навыку
Концепция: Не все главы книги необходимы для освоения главного навыка. Система определяет минимальный набор критических глав, достаточный для получения значимого результата.
Пример:
- Книга: "Атомные привычки"
- Главный навык: "Системное формирование привычек через сверхмалые шаги"
- Эссенциальный план: 5-7 критичных глав вместо всех 32
- Результат: быстрый путь к освоению навыка без лишней информации
Процесс определения главного навыка:
-
Анализ всех глав книги:
- ИИ анализирует все главы и их анализы (каркас, инсайты, применение)
- Выделяет общие темы и навыки
- Определяет центральный навык, который объединяет книгу
-
Формулировка главного навыка:
- ИИ формулирует главный навык на основе анализа
- Пример: "Системное формирование привычек через сверхмалые шаги"
- Сохраняется в
book_concepts.core_skill
-
Оценка релевантности глав:
- Для каждой главы ИИ оценивает релевантность главному навыку
- Критерии:
- Глава содержит ключевые принципы навыка
- Глава описывает основные техники
- Глава необходима для понимания системы
- Глава критична для практического применения
- Оценка:
relevance_to_core_skill(0.0-1.0)
-
Выделение критических глав:
- Ранжирование глав по релевантности
- Выбор критических глав (например, топ-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 содержит метаданные для фильтрации и группировки
Процесс кросс-книжного поиска:
-
Семантический поиск по навыку:
- Пользователь ищет "управление временем"
- Qdrant находит все похожие навыки/техники из всех книг
- Результаты ранжируются по релевантности (косинусное расстояние)
-
Фильтрация и группировка:
- Фильтр по книгам:
bookId IN [book1, book2, ...] - Группировка похожих навыков из разных книг
- Выделение общих принципов и уникальных техник
- Фильтр по книгам:
-
Агрегация результатов:
- Объединение техник из разных источников
- Приоритизация: навыки, встречающиеся в нескольких книгах
- Выявление комплементарных техник (дополняют друг друга)
-
Построение комплексного плана:
- Выбор навыка → поиск всех техник из всех книг
- Сортировка по релевантности и качеству валидации
- Объединение в единый план с указанием источников
Пример структуры кросс-книжного плана:
Комплексный коуч-план: "Управление временем"
├─ Навык: "Приоритизация задач"
│ ├─ Техника 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:
-
Обработка запроса пользователя:
- Пользователь: "Что почитать на тему достигаторства?"
- Создание эмбеддинга запроса через модель эмбеддингов (по умолчанию bge-m3)
- Семантический поиск в Qdrant по коллекциям:
chapter_analyses- анализ главskills_techniques- навыки и техники
- Получение top-k релевантных результатов (например, top-10)
-
Формирование контекста для ИИ:
- Извлечение метаданных найденных глав из Qdrant payload
- Получение полной информации о главах из Postgres
- Формирование структурированного контекста для промпта
-
Генерация ответа через ИИ:
- Использование LLM (по умолчанию qwen3-14b:8bit или конфигурируемая модель) для генерации ответа
- Промпт включает:
- Вопрос пользователя
- Список релевантных глав с метаданными
- Инструкции по форматированию ответа
-
Структурированный ответ:
- Список рекомендованных глав с рейтингом релевантности
- Краткое объяснение, почему каждая глава подходит
- Ссылки на полный текст глав
- Предложения связанных навыков и техник
Структура промпта для ИИ:
Ты помощник по библиотеке развивающих книг.
Пользователь задал вопрос: "{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"]
}
]
}
Процесс обработки запроса:
- Эмбеддинг запроса (модель эмбеддингов, по умолчанию bge-m3) → вектор запроса
- Семантический поиск в Qdrant → top-k релевантных глав
- Получение метаданных из Postgres для найденных глав
- Формирование контекста для промпта ИИ
- Генерация ответа через LLM (qwen3-14b:8bit или конфиг)
- Структурирование ответа с ссылками и объяснениями
- Кэширование результата в 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
}
}
Процесс обработки:
- Поиск тегов (Postgres): прямой поиск + семантический поиск похожих тегов
- Семантический поиск (Qdrant): создание эмбеддинга темы запроса
- Объединение и ранжирование: дедупликация, взвешенное ранжирование
- Получение данных (Postgres): полная информация о найденных главах
- Генерация плана (LLM, по умолчанию qwen3-14b:8bit): формирование структурированного плана
- Сохранение плана: создание записи в БД
Дополнительные возможности:
- Рекомендации связанных тем: "Если изучаешь внимательность, посмотри про продуктивность"
- Прогресс по темам: отслеживание освоения навыков
- Адаптация плана: обновление при добавлении новых книг
- Аналитика: популярные темы, эффективность планов
UX навигации
- В карточке навыка: кнопка "Читать главу полностью"
- В тексте главы: маркеры связанных навыков (подсветка)
- Быстрый переход: навык ↔ глава
- Контекстное меню: "Показать связанные навыки" в главе
- Навигация по иерархии: план → пункт → техника → исходный текст
Операционные аспекты
Масштабирование
Горизонтальное масштабирование
- Воркеры: запускать несколько контейнеров с воркерами
- FastAPI: несколько инстансов за балансировщиком (stateless)
- Ollama: один контейнер = один запрос за раз (если не настроен параллелизм)
Ограничения
- Ollama: основной узкое место
- Решение: несколько инстансов Ollama или настройка
OLLAMA_NUM_PARALLEL - CPU обработка: медленно, но стабильно (без GPU)
Рекомендации по масштабированию
- Начать с 1-2 воркеров (последовательная обработка)
- Мониторить длину очереди в Redis
- Масштабировать воркеры по потребности
- При высокой нагрузке - несколько инстансов Ollama
Мониторинг
Метрики
- Время обработки каждой главы
- Успешность валидации
- Качество анализа
- Длина очереди в Redis
- Использование памяти Ollama
- Загрузка CPU
Логирование
- Все этапы обработки
- Ошибки с контекстом
- Время выполнения каждого этапа
Рекомендации по конфигурации
Для 30GB RAM (оптимальная конфигурация)
- Lazy loading моделей - загружать по требованию, выгружать через
keep_alive: 0 - Оптимизировать промпты - минимум токенов (~200-300 вместо 1000-2000)
- OLLAMA_NUM_CTX=9000 - компромисс между памятью и возможностями
- Обработка строго последовательно - одна глава, одна модель за раз
- Мониторить память - следить за использованием RAM
Итого памяти: ~18-22GB максимум (влезет в 30GB с запасом)
Для масштабирования
- Увеличить количество воркеров (при наличии памяти)
- Настроить несколько инстансов Ollama
- Использовать приоритетные очереди
- Кэшировать эмбеддинги
Для большого контекста (20000 токенов)
- Увеличить RAM до 48-64GB минимум
- GPU опционально для ускорения
- НЕ разбивать главы на чанки - качество анализа упадет
Альтернативы 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