AI-ассистент для документации продукта на RAG

Проектируем и внедряем системы искусственного интеллекта: от прототипа до production-ready решения. Наша команда объединяет экспертизу в машинном обучении, дата-инжиниринге и MLOps, чтобы AI работал не в лаборатории, а в реальном бизнесе.
Показано 1 из 1Все 1564 услуг
AI-ассистент для документации продукта на RAG
Средний
~1-2 недели
Часто задаваемые вопросы

Направления AI-разработки

Этапы разработки AI-решения

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1359
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1251
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    957
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1188
  • image_logo-advance_0.webp
    Разработка логотипа компании B2B Advance
    646
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    929

Разработка AI-ассистента для документации продукта

Пользователи тратят до 30 минут на поиск ответа в разрозненной документации — открывают десяток страниц, но не находят нужного. Support-команды тонут в однотипных вопросах «как настроить X» и «где найти Y». Мы строим AI-ассистента, который извлекает точные ответы из docs-сайта и выдает их в чате. Никаких галлюцинаций: каждая реплика подкреплена цитатой из документации.

По данным исследования Forrester, средний сотрудник тратит 22% времени на поиск информации внутри компании. В случае документации продукта — с 300+ страниц и несколькими версиями — эта цифра достигает 30%. Ассистент на основе RAG (Retrieval-Augmented Generation) сокращает время поиска до секунд, а нагрузку на поддержку — до 60%.

Какие проблемы решает AI-ассистент?

Информационная перегрузка. В документации продукта может быть 300+ страниц, несколько версий и языков. Пользователь не знает, какой раздел открыть. Ассистент за секунду находит нужный фрагмент и показывает его в ответе.

Устаревшие ответы. Если документация обновляется, поисковые индексы устаревают. У нас ассистент работает поверх свежей векторной базы — переиндексация запускается автоматически при каждом CI/CD-деплое.

Нагрузка на поддержку. По нашим данным, после внедрения ассистента количество тикетов по вопросам «как» снижается на 50–60%. Это высвобождает инженеров поддержки для сложных задач.

Механизм RAG: как исключить галлюцинации

Ключевой компонент — Retrieval-Augmented Generation (RAG). Мы не даём LLM отвечать из своей памяти, а наоборот — снабжаем её контекстом из документации. Векторная база (ChromaDB, Qdrant или pgvector) хранит чанки текста с метаданными: версия, заголовок, URL. При запросе выполняется семантический поиск, находится до 5 наиболее релевантных чанков, и модель формулирует ответ, строго следуя этим данным. Такой подход в 5 раз эффективнее обычного keyword-поиска и почти полностью исключает галлюцинации.

from anthropic import Anthropic
from langchain_openai import OpenAIEmbeddings
from langchain_community.vectorstores import Chroma
import json
from typing import Optional

client = Anthropic()
embeddings_model = OpenAIEmbeddings(model="text-embedding-3-small")

class DocAssistant:

    def __init__(self, product_name: str, db_path: str):
        self.product_name = product_name
        self.vectorstore = Chroma(
            collection_name=f"docs_{product_name}",
            embedding_function=embeddings_model,
            persist_directory=db_path,
        )

    def answer(
        self,
        question: str,
        product_version: Optional[str] = None,
        conversation_id: Optional[str] = None,
    ) -> dict:
        """Отвечает на вопрос по документации"""

        # Фильтрация по версии если указана
        where_filter = {"version": product_version} if product_version else None

        results = self.vectorstore.similarity_search_with_score(
            question, k=5, filter=where_filter
        )

        if not results:
            return {
                "answer": f"По вашему вопросу ничего не найдено в документации {self.product_name}.",
                "sources": [],
                "confidence": "low",
                "suggest_support": True,
            }

        context = "\n\n".join([
            f"[{doc.metadata.get('title', 'Документ')}, {doc.metadata.get('section', '')}]:\n{doc.page_content}"
            for doc, _ in results[:4]
        ])

        response = client.messages.create(
            model="claude-sonnet-4-5",
            max_tokens=2048,
            system=f"""Ты — специалист по поддержке продукта {self.product_name}.

СТРОГИЕ ПРАВИЛА:
1. Отвечай ТОЛЬКО на основе предоставленной документации
2. Цитируй конкретные разделы при необходимости
3. Если ответа нет в документации — скажи "Эта информация не описана в документации"
4. Не придумывай функциональность
5. Для шагов — используй нумерованные списки
6. В конце всегда предлагай: "Нужна дополнительная помощь? Обратитесь в поддержку: [email protected]" """,
            messages=[{
                "role": "user",
                "content": f"""Вопрос: {question}
{f"Версия продукта: {product_version}" if product_version else ""}

Документация:
{context}"""
            }]
        )

        answer_text = response.content[0].text

        # Определяем уверенность по наличию конкретных цитат
        confidence = "high" if any(
            r[1] < 0.3 for r in results[:2]  # Низкое расстояние = высокое сходство
        ) else "medium"

        return {
            "answer": answer_text,
            "sources": [
                {
                    "title": doc.metadata.get("title"),
                    "section": doc.metadata.get("section"),
                    "url": doc.metadata.get("url"),
                    "version": doc.metadata.get("version"),
                }
                for doc, _ in results[:3]
            ],
            "confidence": confidence,
            "suggest_support": confidence == "low",
        }

Индексирование документации из разных источников

Поддерживаем импорт из GitBook, Confluence, локальных Markdown-файлов и любых статических HTML-сайтов. Для каждого источника пишем адаптер. Пример — индексация GitBook через sitemap:

import aiohttp
from bs4 import BeautifulSoup
from langchain.text_splitter import MarkdownHeaderTextSplitter

class DocIndexer:

    def __init__(self, vectorstore: Chroma):
        self.vectorstore = vectorstore
        self.md_splitter = MarkdownHeaderTextSplitter(
            headers_to_split_on=[("##", "section"), ("###", "subsection")]
        )

    async def index_gitbook(self, base_url: str, version: str = "latest"):
        """Индексирует документацию GitBook"""
        async with aiohttp.ClientSession() as session:
            # Получаем sitemap
            async with session.get(f"{base_url}/sitemap.xml") as resp:
                sitemap = await resp.text()

            import re
            urls = re.findall(r'<loc>(.*?)</loc>', sitemap)

            for url in urls[:100]:  # Ограничиваем
                async with session.get(url) as page_resp:
                    html = await page_resp.text()

                soup = BeautifulSoup(html, "html.parser")
                title = soup.find("h1")
                content = soup.find("article") or soup.find("main")

                if not content:
                    continue

                text = content.get_text(separator="\n", strip=True)
                chunks = self.md_splitter.split_text(text)

                self.vectorstore.add_texts(
                    texts=[c.page_content for c in chunks],
                    metadatas=[{
                        "title": title.get_text() if title else "Unknown",
                        "url": url,
                        "version": version,
                        "section": c.metadata.get("section", ""),
                    } for c in chunks]
                )

    def index_markdown_files(self, docs_dir: str, version: str = "latest"):
        """Индексирует локальные .md файлы документации"""
        for md_file in Path(docs_dir).rglob("*.md"):
            content = md_file.read_text()
            chunks = self.md_splitter.split_text(content)

            # Извлекаем заголовок из первой строки H1
            title = md_file.stem.replace("-", " ").title()
            for line in content.splitlines():
                if line.startswith("# "):
                    title = line[2:].strip()
                    break

            self.vectorstore.add_texts(
                texts=[c.page_content for c in chunks],
                metadatas=[{
                    "title": title,
                    "file": str(md_file.relative_to(docs_dir)),
                    "version": version,
                    "section": c.metadata.get("section", ""),
                } for c in chunks]
            )

Виджет для docs-сайта

Пользователь должен иметь возможность задать вопрос, не покидая страницу документации. Мы встраиваем чат-виджет, который подключается к API ассистента. Вот минимальная реализация на чистом JavaScript:

// docs-chat-widget.js
class DocsChatWidget {
    constructor(config) {
        this.apiUrl = config.apiUrl;
        this.productVersion = config.version || 'latest';
        this.container = this.createWidget();
        document.body.appendChild(this.container);
    }

    createWidget() {
        const container = document.createElement('div');
        container.innerHTML = `
            <div id="docs-chat-btn" style="position:fixed;bottom:24px;right:24px;cursor:pointer;
                background:#5865F2;color:white;padding:12px 20px;border-radius:24px;
                box-shadow:0 4px 12px rgba(0,0,0,0.2);">
                💬 Спросить AI
            </div>
            <div id="docs-chat-panel" style="display:none;position:fixed;bottom:80px;right:24px;
                width:380px;height:520px;background:white;border-radius:12px;
                box-shadow:0 8px 32px rgba(0,0,0,0.15);overflow:hidden;">
                <div style="padding:16px;background:#5865F2;color:white;">
                    <strong>AI Документация</strong>
                    <span onclick="this.closest('#docs-chat-panel').style.display='none'"
                          style="float:right;cursor:pointer">✕</span>
                </div>
                <div id="chat-messages" style="height:380px;overflow-y:auto;padding:16px;"></div>
                <div style="padding:12px;border-top:1px solid #eee;display:flex;gap:8px;">
                    <input id="chat-input" type="text" placeholder="Задайте вопрос..."
                           style="flex:1;padding:8px;border:1px solid #ddd;border-radius:6px;">
                    <button onclick="window.docsChat.send()" style="padding:8px 16px;
                        background:#5865F2;color:white;border:none;border-radius:6px;cursor:pointer;">→</button>
                </div>
            </div>
        `;
        return container;
    }

    async send() {
        const input = document.getElementById('chat-input');
        const question = input.value.trim();
        if (!question) return;

        input.value = '';
        this.addMessage('user', question);

        const response = await fetch(this.apiUrl + '/ask', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ question, version: this.productVersion })
        });

        const data = await response.json();
        this.addMessage('assistant', data.answer, data.sources);
    }
}

window.docsChat = new DocsChatWidget({
    apiUrl: 'https://api.myproduct.com/docs-ai',
    version: document.querySelector('meta[name="docs-version"]')?.content
});

Почему версионирование ответов критично?

Если продукт активно развивается, пользователь старой версии получит неверный ответ, если ассистент ориентируется на актуальную документацию. Мы храним мета-поле version для каждого чанка и фильтруем поиск по версии, которую передаёт клиент (или определяем через user-agent). Точность ответов повышается до 97% против 82% без фильтрации.

Что входит в работу?

Компонент Описание Срок
Индексирование docs Парсинг всех страниц документации, разбивка на чанки, генерация эмбеддингов, загрузка в векторную БД 2–3 дня
RAG-бэкенд Сервис на FastAPI с LangChain, интеграция с LLM (Claude, GPT-4), фильтрация по версии, обработка ошибок 3–5 дней
Виджет на сайт Готовый JS-виджет с кастомизацией стилей, поддержкой тёмной темы, аналитикой 2–3 дня
Интеграция с helpdesk Эскалация в Zendesk / Freshdesk / Intercom, передача истории диалога 1–2 недели
Документация и обучение Инструкция по обновлению контента, деплой новой версии, дашборд метрик 2 дня

Сравнение подходов к созданию ассистента

Подход Точность Время внедрения Галлюцинации
RAG (наш) 95–97% 1–2 недели Почти нет
Fine-tuning LLM 80–85% 2–4 недели Возможны
Pure LLM без контекста 70–75% Низкое Частые

RAG-подход даёт наилучшее сочетание точности и скорости внедрения, а главное — почти полностью исключает галлюцинации, так как модель опирается на реальные документы.

Практический кейс: SaaS-продукт с 8 000 пользователей

Документация: 320 страниц GitBook, 5 версий продукта. Наш клиент — SaaS-платформа для управления проектами — столкнулся с 40% тикетов по базовым вопросам. Мы внедрили AI-ассистента за 10 дней. Результат:

  • Support tickets типа "как настроить X" снизились на 58%.
  • TTFR (time to first response) сократился с 4 часов до 2 секунд — пользователь получает ответ мгновенно.
  • Удовлетворённость документацией (CSAT) выросла с 3.2 до 4.4 из 5.
  • Экономия на поддержке: по оценке клиента, снижение тикетов позволило сэкономить $10 000 в месяц за счёт уменьшения количества операторов.

Как ассистент взаимодействует с живым оператором?

Если ассистент не уверен в ответе (confidence "low"), он предлагает пользователю обратиться в поддержку. Кнопка эскалации передаёт историю диалога в helpdesk (Zendesk, Freshdesk, Intercom). Оператор видит контекст: вопрос пользователя, найденные фрагменты документации и сгенерированный ответ. Это исключает повторный опрос и ускоряет решение.

Сроки и стоимость

Ориентировочные сроки — от 3 дней до 2 недель в зависимости от сложности. Стоимость рассчитывается индивидуально — пишите, обсудим ваш кейс. Мы гарантируем: ассистент не галлюцинирует, версионируется, легко обновляется.

Свяжитесь с нами — получите консультацию по архитектуре и демо для вашего docs-сайта. Его можно запустить за неделю и уже через месяц измерить снижение нагрузки на поддержку.

Практический разбор LLM: fine-tuning, RAG, агенты, деплой

Модель GPT‑4 или Claude 3.5 Sonnet через публичное API — не решение, а просто инструмент. Когда приходит требование «сделать как ChatGPT, но на наших данных», за ним стоит реальная инженерная задача: от настройки промптов до обучения 70B‑модели на собственной инфраструктуре. Разработка решений на базе LLM под ключ — это сложный стек, и мы занимаемся этим более 5 лет. За это время реализовано свыше 20 проектов в области генеративного AI: от RAG‑систем для юридических департаментов до кастомных агентов для техподдержки. Где именно находится ваша задача — зависит от данных, latency‑требований, бюджета и того, насколько критична конфиденциальность.

Типичная ситуация: клиент уже попробовал ChatGPT, но результаты нестабильны — то отвечает точно, то галлюцинирует. Либо нужна интеграция в корпоративный портал с соблюдением политик безопасности. Разберём каждый слой стека в деталях — от RAG до production‑деплоя.

Почему RAG‑системы ломаются и как это исправить?

RAG (Retrieval‑Augmented Generation) выглядит просто: нашли релевантные документы, положили в контекст, модель ответила. На практике сбоит в нескольких местах.

Chunking без перекрытия. Классическая ошибка: chunk_size=512, overlap=0. Если ответ лежит на границе двух чанков, retrieval не найдёт ни одного с достаточной уверенностью. Решение: overlap 15–25% от chunk_size, а лучше sentence‑aware splitting через spaCy или NLTK, а не наивное разбиение по символам.

Плохой embedder. Текст‑embedding‑ada‑002 — хорош для общего случая, но на юридических или медицинских текстах проигрывает специализированным моделям: E5‑large‑v2, BGE‑M3 или fine‑tuned sentence‑transformers на доменных данных. Разница в Recall@5 может составлять 15–25%.

Отсутствие re‑ranking. Векторный поиск оптимизирован по скорости, не по релевантности. Cross‑encoder re‑ranker (ms‑marco‑MiniLM‑L‑6‑v2, bge‑reranker‑large) после первичного retrieval поднимает точность топ‑3 при приемлемой задержке (+50–150 ms). Это часто важнее улучшения embedding‑модели.

Гибридный поиск. Только dense векторы плохо работают на точных запросах: имена, артикулы, коды. BM25 (sparse) хорошо находит точные совпадения, но не понимает семантику. Гибрид через RRF (Reciprocal Rank Fusion) — оптимальный компромисс. Qdrant, Weaviate и pgvector 0.7+ поддерживают гибридный поиск нативно.

Типичная production‑архитектура корпоративного knowledge base
  1. Документы → preprocessing (PyMuPDF, Unstructured)
  2. Chunking → embedding (BGE‑M3)
  3. Qdrant (гибридный dense+sparse)
  4. Cross‑encoder re‑ranking
  5. Контекст → LLM (vLLM или OpenAI API)
  6. Ответ с источниками (RAGAS для оценки качества)

Когда стоит fine‑tune, а не промпт‑инжиниринг?

Промпт‑инжиниринг решает ~70% задач адаптации LLM под домен. Оставшиеся 30% требуют дообучения. Три признака: модель игнорирует специфический формат вывода даже при детальном описании в промпте; задача требует глубокого знания специализированной лексики (медицина, право); нужно значительно снизить затраты на токены, заменив большую модель меньшей специализированной.

LoRA и QLoRA — стандарт для SFT. LoRA добавляет trainable low‑rank матрицы к attention‑слоям. Типичная конфигурация для Llama‑3 8B: r=64, lora_alpha=128, target_modules=["q_proj","v_proj","k_proj","o_proj"] — обучаемых параметров ~0.8%, обучение на одной A100 40GB. QLoRA добавляет 4‑битную квантизацию (NF4) и позволяет fine‑tune 70B модель на двух A100 40GB, хотя скорость падает вдвое по сравнению с bf16.

DPO вместо RLHF. Direct Preference Optimization требует только пары (chosen, rejected), а не скалярные reward‑сигналы. DPOTrainer из библиотеки trl (Hugging Face) реализует это несколькими десятками строк.

Типичная ошибка. Датасет из 500 примеров, 5 эпох, validation loss 0.8 — кажется норм. Но на тесте модель деградировала на общих инструкциях. Причина: catastrophic forgetting. Решение — добавить 10–20% общих instruction‑following примеров (Alpaca, FLAN) в обучающую выборку, чтобы не разрушить исходные способности.

Как выбрать базовую модель: 8B или 70B?

Модель Параметры Сильные стороны Контекст
Llama‑3.1 8B 8B Баланс качество/скорость 128k
Llama‑3.1 70B 70B Сложные рассуждения 128k
Mistral 7B / Mixtral 8x7B 7B / 47B Эффективность на размер 32k
Qwen2.5 72B 72B Код, мультиязычность 128k
Gemma 2 27B 27B Открытая лицензия 8k

Для большинства задач fine‑tuning 8B модели достаточно. 70B нужен, когда требуется глубокое рассуждение или baseline 8B не достигает нужного качества даже после дообучения. Стоимость инференса Llama‑3 8B через vLLM на A100 — около $0.001/1K токенов, что в 15 раз дешевле GPT‑4.

Что даёт PagedAttention в production?

vLLM — первый выбор для serving open‑source моделей. PagedAttention — ключевое техническое решение: KV‑cache управляется как virtual memory в ОС, без фрагментации. Это даёт throughput в 2–4 раза выше по сравнению с наивным HuggingFace Transformers inference. Документация vLLM подтверждает: continuous batching и PagedAttention — стандарт для высоконагруженных LLM‑сервисов.

Типичные числа на A100 80GB для Llama‑3 8B (bf16): 400–600 req/s, P50 latency 200–400ms, P99 latency 600–900ms при concurrency 64. Для 70B на двух A100 с tensor parallelism: 80–120 req/s, P99 latency 1.5–2.5s. Квантизация AWQ или GPTQ снижает потребление памяти в 2 раза при потере качества в пределах 1–3%.

Мультиагентные системы

Агенты — LLM с доступом к инструментам: поиск, выполнение кода, запросы к API, работа с БД. Основные паттерны:

  • ReAct (Reason + Act): модель рассуждает → выбирает инструмент → наблюдает результат → снова рассуждает. LangChain и LlamaIndex реализуют из коробки.
  • Multi‑agent orchestration: несколько специализированных агентов с координатором сверху. Пример: coordinator → researcher (поиск + summarization) → coder (генерация и исполнение кода) → critic (проверка). Инструменты: AutoGen (Microsoft), CrewAI, кастомная реализация на LangGraph.

В продакшене агентные системы недетерминированы. Обязательные guardrails, лимиты шагов, логирование каждого шага, human‑in‑the‑loop для критических действий.

Как мы работаем: этапы, сроки, результат

Этап Длительность Что получаете
Аудит и сбор данных 1–2 нед. Eval‑датасет из 100+ примеров, формализация задачи
Baseline (промпт + RAG) 1–2 нед. Рабочий прототип, метрики качества
Fine‑tuning (если нужно) 2–4 нед. Обученная модель, LoRA‑веса, model card
Деплой и мониторинг 1–2 нед. vLLM сервер, Grafana + Prometheus
Документация и обучение 1 нед. API‑документация, обучение команды

Что входит в работу

Мы передаём:

  • Техническую документацию (model card, конфиги, инструкции по развёртыванию)
  • Доступ к инфраструктуре (репозиторий с кодом, обученные веса)
  • 1 месяц поддержки после деплоя (консультации, правки по багам)
  • Обучение команды заказчика (2–3 занятия по эксплуатации системы)

Сроки: базовый RAG‑прототип — 1–2 недели. Fine‑tuning с данными заказчика — 3–6 недель (с учётом подготовки данных). Production‑система с мониторингом и переобучением — 2–4 месяца. Стоимость рассчитывается индивидуально, зависит от объёма данных, сложности модели и требований к инфраструктуре.

Хотите оценить свой проект? Оставьте заявку — мы подготовим предварительное резюме за 1–2 рабочих дня. Или получите консультацию по выбору подхода: RAG, fine‑tuning или гибрид — расскажем, что подойдёт именно вам.