Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

LangChain и LlamaIndex

🎯 Цель

После прочтения этой главы:

  • Знаете разницу между фреймворками LangChain и LlamaIndex
  • Можете построить Document loading, splitting, embedding pipeline
  • Можете работать с chains и agent (LangChain)
  • Быстро создаёте RAG через indexes (LlamaIndex)
  • Также знакомитесь с современными alternatives (Pydantic AI, Instructor, raw API)

**Внимание:**В 2024-2026 industry sentiment отворачиваетсяот LangChain (слишком сложный, лишний abstraction). Современный подход: raw API + Instructor + minimal framework. Но LangChain всё ещё используется во многих проектах — знать нужно.

Что нужно изучить

  • LangChain: chains, agents, memory, callbacks
  • LangChain LCEL(LangChain Expression Language)
  • LlamaIndex: indexes, retrievers, query engines
  • Document loaders — PDF, HTML, Notion, GitHub
  • Text splitters — RecursiveCharacter, Markdown, Code
  • Modern alternatives — Pydantic AI, Instructor, raw API
  • LangGraph — multi-agent workflows
  • LangSmith — observability

Библиотеки

pip install langchain langchain-openai langchain-anthropic langchain-community
pip install llama-index llama-index-llms-openai
pip install pydantic-ai instructor
pip install unstructured pypdf                # document loading

Framework comparison

LangChainLlamaIndexRaw API + Instructor
Learning curveКрутаяСредняяНизкая
RAG supportХорошаяExcellentManual
AgentsСложноХорошаяНужен LangGraph
ProductionMixed reviewsХорошаяЛучшее
PerformanceSlowOKСамый быстрый
Industry trend⬇️⬆️⬆️⬆️
Code clarityAbstractBetterСамый чёткий

Рекомендация:

  • Новый проект → raw API + Instructor + LlamaIndex(для RAG)
  • Существующий LangChain — оставьте, но новые feature мигрируйте
  • Complex agent workflows → LangGraph

Примеры кода

LangChain — basic chain

from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser

# LCEL syntax (новый, рекомендуется)
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0.7)

prompt = ChatPromptTemplate.from_messages([
    ("system", "Ты вспомогательный assistant. Язык: {language}"),
    ("user", "{question}"),
])

chain = prompt | llm | StrOutputParser()

# Run
result = chain.invoke({"language": "узбекский", "question": "Что такое Python?"})
print(result)

LangChain — RAG (simple)

from langchain_community.document_loaders import PyPDFLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_openai import OpenAIEmbeddings
from langchain_community.vectorstores import Chroma

# 1. Load
loader = PyPDFLoader("document.pdf")
docs = loader.load()

# 2. Split
splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=100)
chunks = splitter.split_documents(docs)

# 3. Embed + store
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
vectorstore = Chroma.from_documents(chunks, embeddings)

# 4. Retrieve + answer
retriever = vectorstore.as_retriever(search_kwargs={"k": 5})

from langchain.chains import RetrievalQA

qa_chain = RetrievalQA.from_chain_type(
    llm=ChatOpenAI(model="gpt-4o-mini"),
    retriever=retriever,
    return_source_documents=True,
)

result = qa_chain.invoke({"query": "Что говорится о документе?"})
print(result["result"])

LlamaIndex — quickest RAG

from llama_index.core import VectorStoreIndex, SimpleDirectoryReader
from llama_index.llms.openai import OpenAI
from llama_index.embeddings.openai import OpenAIEmbedding
from llama_index.core import Settings

# Settings (global)
Settings.llm = OpenAI(model="gpt-4o-mini")
Settings.embed_model = OpenAIEmbedding(model="text-embedding-3-small")

# 1. Load (PDF, txt, markdown — разное)
documents = SimpleDirectoryReader("data/").load_data()

# 2. Index (автоматический embedding + chunk)
index = VectorStoreIndex.from_documents(documents)

# 3. Query
query_engine = index.as_query_engine(similarity_top_k=5)
response = query_engine.query("Об этом документе")
print(response)
print(response.source_nodes)  # из каких chunks взято

LlamaIndex — Chat engine (multi-turn)

from llama_index.core.memory import ChatMemoryBuffer

memory = ChatMemoryBuffer.from_defaults(token_limit=4000)

chat_engine = index.as_chat_engine(
    chat_mode="context",
    memory=memory,
    system_prompt="Ты опытный assistant. Отвечай только на основе данного контекста.",
)

response = chat_engine.chat("Объясните про этот проект")
print(response.response)

# Follow-up
response = chat_engine.chat("Каковы основные сложности?")

Pydantic AI — современная alternative

from pydantic_ai import Agent
from pydantic import BaseModel

class WeatherInfo(BaseModel):
    temperature: float
    condition: str
    humidity: int

weather_agent = Agent(
    model="openai:gpt-4o-mini",
    result_type=WeatherInfo,
    system_prompt="Ты погодный агент. Сделай прогноз для указанного города.",
)

result = weather_agent.run_sync("Погода в Ташкенте")
print(result.data)  # Type-safe WeatherInfo object

Instructor — fully type-safe

import instructor
from openai import OpenAI
from pydantic import BaseModel

client = instructor.from_openai(OpenAI())

class Person(BaseModel):
    name: str
    age: int
    occupation: str

# Guaranteed structured output (retries on failure)
person = client.chat.completions.create(
    model="gpt-4o-mini",
    response_model=Person,
    messages=[{"role": "user", "content": "Меня зовут Али, 30 лет, я developer"}],
)

print(person)  # Person(name="Али", age=30, occupation="developer")

LangGraph — multi-agent

from langgraph.graph import StateGraph, END
from typing import TypedDict

class AgentState(TypedDict):
    question: str
    research: str
    answer: str

# Node functions
def researcher(state):
    # Search/research
    return {"research": "Найденная информация..."}

def writer(state):
    # Generate answer
    return {"answer": f"Ответ: {state['research']}"}

def reviewer(state):
    # Review
    if len(state["answer"]) < 50:
        return {"answer": state["answer"], "needs_revision": True}
    return {"answer": state["answer"], "needs_revision": False}

# Build graph
workflow = StateGraph(AgentState)
workflow.add_node("researcher", researcher)
workflow.add_node("writer", writer)
workflow.add_node("reviewer", reviewer)

workflow.set_entry_point("researcher")
workflow.add_edge("researcher", "writer")
workflow.add_edge("writer", "reviewer")

workflow.add_conditional_edges(
    "reviewer",
    lambda x: "writer" if x.get("needs_revision") else END,
)

app = workflow.compile()
result = app.invoke({"question": "Что такое Python?"})

Document loaders — variety

# PDF
from langchain_community.document_loaders import PyPDFLoader
docs = PyPDFLoader("file.pdf").load()

# HTML / Website
from langchain_community.document_loaders import WebBaseLoader
docs = WebBaseLoader("https://example.com").load()

# YouTube transcript
from langchain_community.document_loaders import YoutubeLoader
docs = YoutubeLoader.from_youtube_url("https://...", add_video_info=True).load()

# Notion
from langchain_community.document_loaders import NotionDirectoryLoader
docs = NotionDirectoryLoader("notion_export/").load()

# GitHub
from langchain_community.document_loaders import GitHubIssuesLoader
docs = GitHubIssuesLoader("owner/repo", access_token="...").load()

# CSV/Excel
from langchain_community.document_loaders import CSVLoader
docs = CSVLoader("data.csv").load()

Text splitters

from langchain.text_splitter import (
    RecursiveCharacterTextSplitter,
    MarkdownHeaderTextSplitter,
    CharacterTextSplitter,
)

# Recursive — самый распространённый (с разными separator)
splitter = RecursiveCharacterTextSplitter(
    chunk_size=1000,
    chunk_overlap=200,
    separators=["\n\n", "\n", ". ", " ", ""],
)

# Markdown — по header
md_splitter = MarkdownHeaderTextSplitter(headers_to_split_on=[
    ("#", "Header 1"),
    ("##", "Header 2"),
    ("###", "Header 3"),
])

# Code — semantic splitting
from langchain.text_splitter import Language, RecursiveCharacterTextSplitter
py_splitter = RecursiveCharacterTextSplitter.from_language(
    language=Language.PYTHON, chunk_size=1000, chunk_overlap=100
)

Интеграция с backend

FastAPI + LlamaIndex RAG service

from fastapi import FastAPI
from llama_index.core import VectorStoreIndex, StorageContext, load_index_from_storage
from contextlib import asynccontextmanager

@asynccontextmanager
async def lifespan(app):
    # Load persisted index
    storage_context = StorageContext.from_defaults(persist_dir="./index_storage")
    app.state.index = load_index_from_storage(storage_context)
    app.state.query_engine = app.state.index.as_query_engine(similarity_top_k=5)
    yield

app = FastAPI(lifespan=lifespan)

class QueryRequest(BaseModel):
    question: str

@app.post("/query")
async def query(req: QueryRequest):
    response = await app.state.query_engine.aquery(req.question)
    return {
        "answer": str(response),
        "sources": [
            {"text": node.text[:200], "score": node.score}
            for node in response.source_nodes
        ],
    }

Production architecture

User → FastAPI → LlamaIndex (in-memory) → Qdrant (vectors) → LLM API
                       ↓
                   Redis (cache)
                       ↓
                 Postgres (history, logs)
                       ↓
                  Langfuse (observability)

Ресурсы

LangChain

  • docs: python.langchain.com
  • LangChain Academy — бесплатный курс
  • LangGraph docs — multi-agent

LlamaIndex

Modern alternatives

Observability

  • Langfuselangfuse.com (open source)
  • LangSmith — от LangChain
  • Phoenix (Arize) — open source

🏋️ Упражнения

🟢 Easy

  1. Простой chain через LangChain LCEL (prompt | llm | parser).
  2. Сделайте RAG над PDF в 5 строк через LlamaIndex.
  3. Resume → structured Pydantic через Instructor.

🟡 Medium

  1. Multi-source RAG: объединённый index из PDF + website + YouTube transcript.
  2. Conversational RAG: multi-turn с chat history.
  3. LangGraph workflow: pipeline из 3 agent (researcher → writer → reviewer).

🔴 Hard

  1. Production RAG service: LlamaIndex + Qdrant + FastAPI + Langfuse. 100+ документов, async query, source citations, monitoring.
  2. Framework comparison: напишите один и тот же RAG в LangChain, LlamaIndex и raw API, сравните время и точность.
  3. Migration: перенесите существующий LangChain код на Pydantic AI или raw API.

Capstone

notebooks/month-05/04_langchain_llamaindex.md:

  • 50+ документов на узбекском (PDF, websites)
  • RAG index через LlamaIndex
  • Multi-turn chat engine
  • Source citations
  • FastAPI + Streamlit UI

✅ Чек-лист

  • LangChain LCEL syntax
  • LlamaIndex basic RAG
  • Pydantic AI / Instructor (современный)
  • Document loaders и text splitters
  • Multi-source RAG
  • Chat engine memory
  • LangGraph multi-agent
  • Production observability (Langfuse)

Переходим к Vector Databases.