04AI-помощникГотовДемонстрационный проект

DocuMind

AI-помощник по технической документации: поиск по смыслу, ответы на основе источников, локальный бесплатный inference.

DocuMind — AI-помощник по документации: отвечает только по проиндексированным источникам, показывает их и честно отказывается, если ответа нет в базе.

Next.jsTypeScriptPostgreSQL (pgvector)OllamaSupabase

01 / ЗАДАЧА

Что требовалось изменить

Поиск ответа в объёмной технической документации занимает время, а обычный чат с LLM без привязки к документам может дать правдоподобный, но неверный ответ — модель отвечает по своим догадкам, а не по факту.

02 / РЕШЕНИЕ

Как устроено решение

DocuMind ищет по смыслу (semantic search через pgvector) внутри проиндексированного корпуса документов и строит ответ строго из найденных фрагментов. Если ничего релевантного не найдено, модель вообще не вызывается — отказ происходит на уровне поиска, а не как решение самой модели. Каждая цитата, которую вернула модель, дополнительно сверяется с реально найденными фрагментами: несуществующий источник отбрасывается, а ответ без ни одной подтверждённой цитаты показывается как честный отказ, а не как обоснованный ответ.

03 / КЛЮЧЕВЫЕ ФУНКЦИИ

Ключевые возможности

Только те функции, которые поддерживают основной пользовательский сценарий.

  1. 01Semantic search по корпусу документов через pgvector (реальные embeddings, не по ключевым словам)
  2. 02Ответы, привязанные к найденным источникам (RAG), с карточками источников — документ, раздел, цитата
  3. 03Отказ на уровне поиска: модель не вызывается, если ничего релевантного не найдено
  4. 04Валидация цитат: несуществующий источник отбрасывается, ответ без подтверждённых цитат не показывается как обоснованный
  5. 05Защита от prompt injection: содержимое документов явно помечено как недоверенные данные, а не инструкции
  6. 06Локальный бесплатный inference (Ollama, qwen3:4b + nomic-embed-text) — без внешних API-вызовов и платы за запрос; облачный провайдер (OpenAI) поддержан как отдельный вариант
  7. 07Ответы на русском языке независимо от языка корпуса, с источниками и цитатами в оригинале — для проверки ответа
  8. 08История диалогов с сохранением источников — повторное открытие переписки не обращается к модели заново
  9. 09Просмотр индексированной базы знаний: список документов и их разделов

05 / АРХИТЕКТУРА

Что происходит под интерфейсом

Документы разбиваются на смысловые фрагменты (по заголовкам, абзацам и предложениям, а не произвольной длиной) и превращаются в embeddings — локально через Ollama (nomic-embed-text) либо через OpenAI, выбор провайдера задаётся одной настройкой. Фрагменты хранятся в PostgreSQL с pgvector и HNSW-индексом. Вопрос пользователя превращается в embedding тем же способом и сопоставляется через cosine similarity в Postgres; если ни один фрагмент не проходит измеренный порог схожести, языковая модель не вызывается вовсе. Если вызывается — генерация опирается на найденные фрагменты и возвращается в структурированном, провалидированном по схеме виде; цитаты модели пересекаются с реально найденными источниками до того, как ответ попадает пользователю.

06 / ПРОВЕРКА

Результат можно проверить

Цифры относятся к зафиксированной проверенной версии проекта.

0Lintзамечаний
0Typecheckошибок
32 / 32Unit-тесты (Vitest)пройдено, 11 файлов
УспешноBuild
100%Top-1/3/5 при поиске16 проверочных вопросов, реальные embeddings Ollama
19 / 20RAG-оценка (реальная генерация)citation integrity 100%

07 / ОГРАНИЧЕНИЯ

Границы демонстрационной версии

  • —Демонстрационная реализация поверх небольшого фиксированного синтетического корпуса документов — не инструмент для произвольной загрузки файлов.
  • —Локальный inference на CPU (Ollama) заметно медленнее облачного API — единицы–десятки секунд на ответ; осознанный компромисс ради бесплатной полностью локальной работы.
  • —Провайдер OpenAI реализован по тому же интерфейсу, но не проверен вживую (квота аккаунта на момент разработки) — реально измеренный и рабочий путь — локальный Ollama.
Следующий проектLeadFlow

Сайт

Открыть кейс ↗
LeadFlow

СЛЕДУЮЩИЙ ШАГ

Есть похожая задача?

Опишите её в свободной форме — отвечу и предложу, как к ней подступиться.

Обсудить проект
Скопировано