Интеграция LlamaIndex для RAG и индексации данных

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

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

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

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

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

Интеграция 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 недели