AI-инжиниринг

LangChain и LlamaIndex: оркестрация LLM pipeline

Цели урока

  • Понять ключевые абстракции LangChain: Runnable, Chain, LCEL и когда они оправданы
  • Освоить LlamaIndex: типы индексов, Query Engine, NodePostprocessors
  • Сравнить LangChain, LlamaIndex и raw SDK по объективным критериям
  • Написать custom chain и кастомный post-processor для production pipeline
  • Распознавать ловушки over-abstraction и проектировать фреймворк-агностичную архитектуру

LangChain появился в январе 2023 - за 2 месяца до того как большинство людей узнало что такое LLM. Поэтому он везде. И поэтому он переусложнён - проектировался без понимания куда всё идёт. Стартап потратил 3 месяца на LangChain-based RAG. При дебаге production-бага инженер нашёл 14 уровней абстракции между HTTP-запросом и вызовом OpenAI API. Причина - embedding dimension mismatch - была скрыта за 8 обёртками. Переписали на raw SDK за 2 дня. Баг нашли за 5 минут. Фреймворки экономят время - пока не начинают его красть.

  • Vercel AI SDK - осознанный минимализм: thin wrapper без 200 зависимостей, используется в Next.js AI apps именно потому что не LangChain
  • Perplexity AI (100M+ запросов/месяц) - начинали на LangChain, мигрировали на собственную инфраструктуру при масштабе: абстракции стали bottleneck
  • Cursor - naked Anthropic SDK без фреймворков. Полный контроль над каждым токеном, минимальная latency
  • Notion AI - LlamaIndex для indexing документов (data connectors + VectorStoreIndex), собственный retrieval pipeline для production-трафика

Предварительные знания

  • RAG: Retrieval-Augmented Generation from Theory to Implementation
  • Tool Calling / Function Calling: LLMs Controlling External Systems

LangChain и LlamaIndex: два инструмента с одного хакатона

Осенью 2022 в Robust Intelligence прошёл внутренний хакатон по работе с LLM, и из него выросли сразу два инструмента, ставшие опорой AI-инженерии. 24 октября 2022 Harrison Chase выложил первую версию LangChain как Python-пакет: библиотека склеивала промпты, цепочки, память и tools вокруг модели и быстро набрала популярность. Примерно тогда же Jerry Liu начал проект под названием GPT Index: первый коммит и анонс пришлись на ноябрь 2022, ранние версии включали идеи вроде tree index для организации документов. Позже GPT Index был переименован в LlamaIndex. Фокус у проектов разный: LangChain - про оркестрацию вызовов модели, LlamaIndex - про загрузку данных, индексирование и RAG поверх собственных документов.

LangChain: Chains, LCEL и ядро фреймворка

LangChain появился в январе 2023 - за 2 месяца до того как большинство людей узнало что такое LLM. Поэтому он везде. И поэтому он переусложнён - проектировался без понимания куда всё идёт. За 2023-2024 годы он вырос от набора утилит до экосистемы со своим языком композиции - **LCEL (LangChain Expression Language)**. 90K звёзд на GitHub. И столько же жалоб на абстракции поверх абстракций.

Ядро LangChain строится на трёх абстракциях:

АбстракцияЧто делаетАналог в backend
RunnableЕдиница вычисления с .invoke(), .stream(), .batch()Express middleware
ChainПоследовательность Runnables, связанных через pipePipeline паттерн
RetrieverИнтерфейс для поиска документов (vector DB, BM25, hybrid)Repository паттерн

**LCEL** - это способ соединять Runnables в цепочки через `.pipe()` (или `|` в Python). Каждый элемент принимает выход предыдущего, передаёт дальше. Streaming, batching и async - бесплатно, без дополнительного кода. Звучит как магия - и выглядит как магия, пока не нужно что-то продебажить.

Выглядит элегантно. Четыре импорта, три объекта, один chain - и рабочий RAG. Теперь посмотрим на **тот же самый pipeline** без LangChain - чистый OpenAI SDK и pgvector:

Два примера выше делают **абсолютно одно и то же**. LangChain - 25 строк + 4 зависимости. Raw SDK - 20 строк + 2 зависимости. Для простого RAG фреймворк добавляет сложность, не давая ничего взамен. Ценность LangChain начинается там, где появляется сложность: fallback, routing, memory, сложный tool calling.

Где LangChain реально оправдан:

  • **Agents с tools** - LangChain Agent loop с автоматическим tool calling и парсингом
  • **Memory** - встроенные стратегии управления историей (buffer, summary, token window)
  • **Callbacks/Tracing** - LangSmith интеграция из коробки для debugging и мониторинга
  • **Быстрое прототипирование** - собрать MVP за час, потом переписать на raw SDK

Какое главное преимущество LCEL в LangChain?

LlamaIndex: индексация и query engine

LangChain - швейцарский нож. **LlamaIndex** - скальпель. Один инструмент, одна задача: **подключить LLM к данным**. Фреймворк вырос из проекта "GPT Index" 2022 года - идея была простая: LLM умный, но слепой. Нужна инфраструктура, которая кладёт релевантные документы прямо в контекст. LlamaIndex строит эту инфраструктуру с data connectors, индексами и query engine из коробки.

Центральная абстракция - **Index**. Структура данных, оптимизированная для LLM-запросов. Четыре основных типа:

Index TypeКак работаетКогда использовать
VectorStoreIndexEmbedding каждого chunk → cosine similarity при поиске90% случаев: Q&A, поиск по документам, RAG
SummaryIndex (ListIndex)LLM последовательно читает каждый nodeСуммаризация документа, когда нужен весь контекст
TreeIndexИерархическое дерево: листья → summary → rootДлинные документы с иерархической структурой
KeywordTableIndexKeyword extraction → inverted indexПоиск по ключевым словам, когда embedding не нужен

Сила LlamaIndex - в абстракции **Query Engine**. Не просто поиск - полный pipeline: retrieval (text-embedding-3-small, 1536 dim, cosine similarity) → post-processing (reranking, фильтрация) → response synthesis (итоговый вызов LLM с найденным контекстом). Три шага, один вызов.

LlamaIndex - это **3 строки до рабочего RAG**: загрузить документы, создать индекс, задать вопрос. Для прототипа - идеально. Но за магией скрываются жёсткие дефолты: SentenceSplitter с chunk_size=1024, text-embedding-3-small, стандартный prompt template. В production это нужно переопределять - иначе качество будет случайным.

Что отличает LlamaIndex от LangChain: специализированные query engine, которых у конкурента нет из коробки:

  • **Sub-Question Query Engine** - разбивает сложный вопрос на подвопросы и агрегирует ответы
  • **Router Query Engine** - автоматически выбирает нужный index для вопроса
  • **Citation Query Engine** - каждое утверждение в ответе ссылается на конкретный chunk
  • **Agentic RAG** - комбинация RAG + tool calling для сложных аналитических запросов

Какой тип индекса LlamaIndex подходит для классического RAG (вопрос-ответ по документам)?

LangChain vs LlamaIndex vs Raw SDK: дерево принятия решений

State of AI Engineering 2024: **43% команд** используют raw SDK как основной подход. Ещё 31% используют LangChain - но 60% из них планируют уменьшить зависимость. Twitter заполнен мемами про "LangChain hell": простой API-вызов в 15 абстракциях. За хейтом - реальный вопрос: **когда фреймворк экономит время, а когда создаёт технический долг?**

Объективная матрица сравнения:

КритерийRaw SDK (OpenAI/Anthropic)LangChainLlamaIndex
Простой API-вызов★★★ 3 строки★★ 8 строк + 2 зависимости★ Не для этого
RAG pipeline★★ 20-30 строк★★★ 10-15 строк LCEL★★★ 3 строки до MVP
Agent с tools★★ Нужен свой loop★★★ Готовый agent executor★★ Через agent API
Memory/History★ Ручная реализация★★★ 5+ стратегий из коробки★★ Через chat engine
Debugging★★★ Всё прозрачно★ Абстракции скрывают ошибки★★ Умеренная прозрачность
Vendor lock-in★★ SDK конкретного провайдера★★★ Унифицированный интерфейс★★★ Унифицированный интерфейс
Bundle size (Node)★★★ ~2 MB★ ~50 MB★★ ~20 MB
Production stability★★★ API не меняется★ Breaking changes каждый месяц★★ Реже ломается

На практике выбор прямой. Простое правило: начинать с raw SDK, добавлять фреймворк только когда raw-код становится неуправляемым. Дерево решений:

Многие production-системы используют **гибридный подход**: LlamaIndex для indexing и retrieval (data connectors + VectorStoreIndex), raw OpenAI SDK для generation, и минимальную обвязку LangChain только для agent loop. Фреймворки не конкурируют - они решают разные части одной задачи.

Стартап строит AI-ассистента для юристов: поиск по 50K контрактам + суммаризация + ответы на вопросы. Какой подход оптимален?

Custom chains и расширение фреймворков

Готовые абстракции покрывают 70% случаев. Оставшиеся 30% - бизнес-логика конкретного продукта: проверка прав доступа, фильтрация по тенанту, compliance-проверки, кастомный reranking. Здесь фреймворк перестаёт помогать и начинает мешать - если не уметь его расширять.

В LangChain любой объект, реализующий интерфейс **Runnable**, участвует в LCEL-цепочке. `RunnableLambda` - способ завернуть любую async-функцию в Runnable без написания класса:

В LlamaIndex аналогичный механизм - **NodePostprocessors**. Они стоят между retrieval и synthesis: фильтруют, переранжируют, обогащают найденные чанки до передачи в LLM:

Custom chains - это точка, где абстракция фреймворка становится по-настоящему полезной. Подменяется один компонент (retriever, post-processor, output parser), а остальная инфраструктура - streaming, error handling, callbacks в LangSmith - остаётся от фреймворка. Не нужно строить всё с нуля, достаточно встроить свою логику в нужное место pipeline.

Для добавления проверки прав доступа в RAG pipeline на LangChain LCEL нужно:

Ловушки абстракций: когда фреймворк вредит

Январь 2024. Hacker News. Пост "Please stop using LangChain" набирает 800+ upvotes за день. Автор - senior engineer из AI-стартапа - показал: замена LangChain на raw OpenAI SDK сократила кодовую базу на 40% и убрала 3 production-бага. Не один баг случайно нашли - три системных. Это не хейт, это симптом: **over-abstraction** в AI-фреймворках стала настоящей проблемой.

Анти-паттерн 1: "Абстракция ради абстракции"

Анти-паттерн 2: "Чёрный ящик"

Абстракции скрывают детали реализации. Удобно, пока всё работает. Когда что-то ломается - debugging через 8 уровней наследования. И главное: **неясно, что именно уходит в API**. Какой промпт? Сколько токенов? Почему ответ пустой? Без LangSmith это чёрный ящик.

Анти-паттерн 3: "Версионный ад"

LangChain проектировался в 2023 году с нулевым пониманием куда пойдёт экосистема. Результат - постоянная смена API. Код из туториала трёхмесячной давности может не компилироваться:

Правила здоровой работы с фреймворками

  1. **Начинать с raw SDK** - понять, что происходит под капотом. Фреймворк добавлять, когда raw-код становится неуправляемым
  2. **Изолировать фреймворк** - обернуть LangChain/LlamaIndex в собственные интерфейсы. При смене фреймворка меняется только одна обёртка, бизнес-логика не трогается
  3. **Пинить версии** - lockfile + точная версия, никаких `^` и `~` для AI-фреймворков. Особенно для LangChain
  4. **Держать escape hatch** - в критических местах raw SDK. Фреймворк - для boilerplate и прототипа, не для core pipeline
  5. **Мониторить промпты** - через LangSmith, Langfuse или свой логгер. Иначе непонятно что уходит в API, сколько стоит каждый запрос и где теряется качество

Золотое правило: **фреймворк должен быть деталью реализации, а не архитектурой приложения**. Если удаление LangChain требует переписывания более 20% кодовой базы - зависимость слишком глубокая. Фреймворк - слуга, не хозяин.

LangChain абстракции упрощают код

В production они усложняют debugging и скрывают что именно уходит в API

На прототипе LangChain экономит время - цепочка собирается за минуты. В production начинаются вопросы: какой именно промпт отправился? Почему ответ пустой? Сколько токенов потратили? Без LangSmith это чёрный ящик. Stack trace при ошибке - 14 уровней LangChain internals вместо одной строки с реальной причиной. Raw SDK даёт полную прозрачность: видно каждый байт запроса, каждый токен ответа, каждый статус-код.

Какой подход защищает от vendor lock-in при использовании AI-фреймворков?

Итоги

  • LangChain появился в январе 2023 переусложнённым - проектировался без понимания куда идёт экосистема. Знать нужно, копировать - нет
  • LCEL (LangChain Expression Language) - pipe-композиция Runnables с бесплатным streaming и async. Полезно для сложных agent pipeline
  • LlamaIndex - специализирован для данных: data connectors, VectorStoreIndex, Sub-Question Query Engine. 3 строки до рабочего RAG
  • 43% команд используют raw SDK как основной подход - это не ретроградство, это прозрачность и отсутствие версионного ада
  • LangChain абстракции упрощают прототип, но усложняют debugging в production: скрывают промпты, стоимость, причины ошибок
  • Фреймворк должен быть деталью реализации, не архитектурой. Изоляция через собственный интерфейс + DI - защита от vendor lock-in

Вопросы для размышления

  • Perplexity мигрировал с LangChain при масштабе - на каком моменте фреймворк становится bottleneck? Что именно ломается первым?
  • LangChain популярен и ненавидим одновременно. Как инструмент с 90K GitHub-звёзд вызывает столько жалоб - это проблема фреймворка или ожиданий?
  • Cursor использует naked Anthropic SDK без фреймворков и является одним из лучших AI-продуктов. Что это говорит о связи между сложностью инструментов и качеством продукта?

Что дальше

Выбор фреймворка - это инструмент. Следующий шаг - паттерны оркестрации: как строить complex pipeline с routing, fallback, parallel execution и map-reduce.

  • Паттерны оркестрации — Sequential, parallel, routing, map-reduce - архитектурные паттерны для AI pipeline
  • Model Routing — Автоматический выбор модели (GPT-4 vs Claude vs local) в зависимости от задачи
  • Agent Frameworks — LangGraph, CrewAI, AutoGen - фреймворки для multi-step agents

Связанные уроки

  • aie-12-rag-fundamentals — Ретриверы и цепочки это строительные блоки RAG
  • aie-16-tool-calling — Абстракции инструментов оборачивают function calling
  • aie-21-orchestration-patterns — Фреймворки выражают паттерны оркестрации в коде
  • aie-18-agent-frameworks — Фреймворки агентов пересекаются с этими библиотеками оркестрации
  • sd-12-service-mesh — Фреймворк это связующий middleware, как service mesh
  • dl-01
LangChain и LlamaIndex: оркестрация LLM pipeline

0

1

Войти