Интеграция LlamaIndex для RAG-систем
LlamaIndex (ранее GPT Index) — фреймворк, специализированный для RAG: загрузка, индексирование, запрос документов. В отличие от LangChain с его универсальностью, LlamaIndex фокусируется на data ingestion, advanced retrieval и query understanding. Отличается богатой экосистемой загрузчиков (150+ источников) и продвинутыми индексами.
Базовый RAG с LlamaIndex
from llama_index.core import VectorStoreIndex, SimpleDirectoryReader, Settings
from llama_index.core.node_parser import SentenceSplitter
from llama_index.llms.openai import OpenAI
from llama_index.embeddings.openai import OpenAIEmbedding
# Настройка глобальных настроек
Settings.llm = OpenAI(model="gpt-4o", temperature=0)
Settings.embed_model = OpenAIEmbedding(model="text-embedding-3-small")
Settings.node_parser = SentenceSplitter(chunk_size=512, chunk_overlap=50)
# Загрузка документов
documents = SimpleDirectoryReader("./data", recursive=True).load_data()
# Создание индекса
index = VectorStoreIndex.from_documents(documents)
# Запрос
query_engine = index.as_query_engine(similarity_top_k=5)
response = query_engine.query("Каков срок гарантии на оборудование?")
print(response)
# Доступ к источникам
for node in response.source_nodes:
print(f"Score: {node.score:.3f}, Source: {node.metadata.get('file_name')}")
Интеграция с векторными хранилищами
from llama_index.vector_stores.qdrant import QdrantVectorStore
from llama_index.core import StorageContext
import qdrant_client
# Подключение к Qdrant
client = qdrant_client.QdrantClient(url="http://localhost:6333")
vector_store = QdrantVectorStore(client=client, collection_name="docs")
storage_context = StorageContext.from_defaults(vector_store=vector_store)
# Индексирование в Qdrant
index = VectorStoreIndex.from_documents(
documents,
storage_context=storage_context,
show_progress=True,
)
# Повторная загрузка существующего индекса
index = VectorStoreIndex.from_vector_store(vector_store)
SubQuestionQueryEngine: разбивка сложных вопросов
from llama_index.core.query_engine import SubQuestionQueryEngine
from llama_index.core.tools import QueryEngineTool
# Создаём инструменты из разных источников
financial_tool = QueryEngineTool.from_defaults(
query_engine=financial_index.as_query_engine(),
name="financial_data",
description="Финансовые показатели компании за 2023–2025",
)
contracts_tool = QueryEngineTool.from_defaults(
query_engine=contracts_index.as_query_engine(),
name="contracts",
description="Договоры с поставщиками и клиентами",
)
# SubQuestion движок автоматически разбивает запрос на подзапросы
engine = SubQuestionQueryEngine.from_defaults(
query_engine_tools=[financial_tool, contracts_tool],
use_async=True,
)
response = engine.query(
"Сравни выручку Q1 2025 с бюджетом и проверь, есть ли просроченные платежи по контрактам"
)
# Агент создаст 2 подзапроса и объединит результаты
RouterQueryEngine: маршрутизация по индексам
from llama_index.core.query_engine.router_query_engine import RouterQueryEngine
from llama_index.core.selectors import LLMSingleSelector
router_engine = RouterQueryEngine(
selector=LLMSingleSelector.from_defaults(),
query_engine_tools=[
QueryEngineTool.from_defaults(
query_engine=summary_index.as_query_engine(response_mode="tree_summarize"),
description="Для обобщающих вопросов о документе в целом",
),
QueryEngineTool.from_defaults(
query_engine=vector_index.as_query_engine(),
description="Для поиска конкретных фактов и деталей",
),
],
)
IngestionPipeline: продвинутый препроцессинг
from llama_index.core.ingestion import IngestionPipeline, IngestionCache
from llama_index.core.node_parser import SentenceSplitter, SemanticSplitterNodeParser
from llama_index.core.extractors import TitleExtractor, QuestionsAnsweredExtractor
from llama_index.core.vector_stores import SimpleVectorStore
pipeline = IngestionPipeline(
transformations=[
SentenceSplitter(chunk_size=512, chunk_overlap=64),
TitleExtractor(nodes=3), # Добавляет заголовок документа в metadata каждого чанка
QuestionsAnsweredExtractor(questions=5), # Генерирует гипотетические вопросы для HyDE
OpenAIEmbedding(model="text-embedding-3-small"),
],
vector_store=vector_store,
cache=IngestionCache(), # Кэширует обработанные документы
)
nodes = await pipeline.arun(documents=documents, show_progress=True)
Retrieval-Augmented Fine-Tuning: тонкая настройка эмбеддингов
from llama_index.finetuning import EmbeddingAdapterFinetuneEngine, generate_qa_embedding_pairs
# Генерация обучающих пар из документов
train_dataset = generate_qa_embedding_pairs(
nodes=train_nodes,
llm=OpenAI(model="gpt-4o-mini"),
)
# Файнтюнинг адаптера эмбеддингов
finetune_engine = EmbeddingAdapterFinetuneEngine(
train_dataset,
base_embed_model=OpenAIEmbedding(),
model_output_path="embed_adapter",
epochs=4,
batch_size=8,
)
finetune_engine.finetune()
# Применение адаптера
from llama_index.embeddings.adapter import AdapterEmbeddingModel
adapted_embed = AdapterEmbeddingModel(
OpenAIEmbedding(),
adapter_path="embed_adapter",
)
Практический кейс: корпоративная база знаний страховой компании
Исходная ситуация: 15 000 страниц документов (полисы, правила страхования, регуляторные инструкции, внутренние регламенты). Операторы тратили 8–12 минут на поиск ответа на вопрос клиента.
Архитектура на LlamaIndex:
- Источники: 4 типа документов в отдельных индексах в Qdrant
- RouterQueryEngine: маршрутизация по типу вопроса
- SubQuestionQueryEngine: для вопросов, охватывающих несколько типов
- IngestionPipeline: автоматическое переиндексирование при обновлении документов
- Metadata фильтрация: по виду страхования, дате документа, региональному регулятору
Результаты:
- Среднее время ответа оператора: 10 мин → 1.5 мин
- Точность ответов (оценка экспертов): 91%
- Ошибочные ссылки на устаревшие редакции полисов: ~8% → 0.4%
- Охват документов: 73% (ранее операторы не знали о существовании многих документов)
LlamaIndex vs LangChain для RAG
| Аспект | LlamaIndex | LangChain |
|---|---|---|
| Специализация | RAG, document QA | Универсальные LLM-приложения |
| Загрузчики данных | 150+ нативных | Через community |
| Advanced retrieval | SubQuestion, Router встроены | Требует кастомизации |
| Агентные возможности | Есть (LlamaAgents) | Более зрелые (LangGraph) |
| Экосистема | LlamaHub | LangChain Hub |
Сроки
- Базовый RAG на LlamaIndex: 3–5 дней
- Мульти-источниковый RAG с RouterQueryEngine: 1–2 недели
- IngestionPipeline с автоматическим обновлением: 1 неделя
- Файнтюнинг эмбеддингов под домен: 2–3 недели







