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)
Комментариев пока нет
Станьте первым, кто поделится мнением об этой статье!