📝 LLM и AI

RAG: чат с документами через векторный поиск

P
Автор
Pyland
📅
Опубликовано
30.06.2026
⏱️
Время чтения
1 мин
👁️
Просмотров
92
📊
Уровень
Статья
🐦 💼 ✈️

RAG (Retrieval-Augmented Generation) — паттерн для работы с собственными документами. Вместо того чтобы переобучать модель, мы находим нужные фрагменты и передаём их в контекст.

Проблема: LLM галлюцинирует

Claude обучен до определённой даты и не знает о твоих документах. Когда спрашиваешь о них, модель генерирует правдоподобный, но выдуманный текст.

RAG решает это

Вопрос пользователя
      ↓
Векторный поиск по базе документов
      ↓
Найдены релевантные фрагменты (chunks)
      ↓
Фрагменты → в system prompt Claude
      ↓
Claude отвечает на основе реального текста

Реализация

import chromadb
import anthropic

client_ai = anthropic.Anthropic()
chroma = chromadb.PersistentClient(path="./chroma_db")
collection = chroma.get_or_create_collection("docs")

SYSTEM_BASE = "Ты — ассистент. Отвечай только на основе предоставленных документов."

def search(query: str, n: int = 3) -> list[dict]:
    results = collection.query(
        query_texts=[query],
        n_results=n,
        include=["documents", "metadatas", "distances"]
    )
    return [
        {"text": doc, "source": meta["source"], "distance": dist}
        for doc, meta, dist in zip(
            results["documents"][0],
            results["metadatas"][0],
            results["distances"][0]
        )
        if dist < 0.5  # фильтр по релевантности
    ]

def build_context(chunks: list[dict]) -> str:
    if not chunks:
        return ""
    parts = []
    for i, chunk in enumerate(chunks, 1):
        relevance = 1 - chunk["distance"]
        parts.append(
            f"[Фрагмент {i} | Источник: {chunk['source']} | Релевантность: {relevance:.0%}]\n"
            f"{chunk['text']}"
        )
    return "\n\n".join(parts)

def rag_chat(question: str, history: list[dict]) -> str:
    chunks = search(question)
    context = build_context(chunks)

    system = SYSTEM_BASE
    if context:
        system += f"\n\nДокументы:\n{context}"
    else:
        system += "\n\nДокументы не найдены. Сообщи пользователю об этом."

    history.append({"role": "user", "content": question})
    response = client_ai.messages.create(
        model="claude-sonnet-4-6",
        max_tokens=1024,
        system=system,
        messages=history,
    )
    answer = response.content[0].text
    history.append({"role": "assistant", "content": answer})
    return answer

Ключевые решения RAG

Решение Влияние
chunk_size Точность поиска
n_results Объём контекста
distance threshold Отсечение нерелевантного
System prompt Поведение при отсутствии данных

Ваша реакция на статью

💬 Комментарии (0)

🔐 Войдите в систему, чтобы оставить комментарий
🚪 Войти
💭

Комментариев пока нет

Станьте первым, кто поделится мнением об этой статье!

🔗 Похожие

Похожие статьи

Продолжите изучение с этими материалами

📝

httpx: современный HTTP-клиент для Python

httpx — HTTP-клиент нового поколения. Интерфейс похож на requests, но с поддержкой async/await из коробки.

📅 30.06.2026 👁️ 108
📝

AI-агенты: ReAct loop и автономные действия

Чат-бот отвечает на вопросы. Агент — действует: вызывает инструменты, получает реальные данные и использует их...

📅 30.06.2026 👁️ 100
📝

Typer: CLI-приложения без boilerplate

Typer создаёт CLI из аннотаций типов Python. Никаких argparse, никакого ручного парсинга — только декораторы...

📅 30.06.2026 👁️ 88

Понравилась статья?

Подпишитесь на наши обновления и получайте новые статьи первыми. Развивайтесь вместе с PyLand!