LangChain на собеседовании Data Scientist
chi-square?Содержание:
Что такое LangChain
LangChain — фреймворк для приложений поверх LLM. Его главная идея — provider-agnostic абстракции: код пишется против единого интерфейса, а провайдера модели (OpenAI, Anthropic, локальная модель через Ollama) можно подменить, не переписывая логику. Из кирпичиков — модели, промпт-шаблоны, цепочки, агенты, память, ретриверы — собираются пайплайны от простого запроса до RAG и агентов.
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="gpt-4o-mini")
response = llm.invoke("Привет") # современный вызов — через .invoke()На собесе DS LangChain спрашивают в блоке про LLM и generative AI. Интервьюер проверяет, понимаете ли вы базовые абстракции (чем chain отличается от agent, зачем нужна память), и — что важнее — когда фреймворк оправдан, а когда достаточно прямого вызова API. Умение сказать «здесь LangChain не нужен» ценится не меньше, чем знание его компонентов.
Chains
Chain — это конвейер вызовов со структурированными входом и выходом: промпт-шаблон подставляет переменные, модель отвечает, парсер приводит ответ к нужному формату. В современном LangChain цепочки собирают через LCEL (LangChain Expression Language) — композицию компонентов оператором |:
from langchain_core.prompts import PromptTemplate
prompt = PromptTemplate.from_template("Переведи на {lang}: {text}")
chain = prompt | llm # LCEL: промпт → модель
result = chain.invoke({"lang": "русский", "text": "Hello"})Оператор | читается как «выход слева подаётся на вход справа», поэтому цепочки легко наращивать: prompt | llm | output_parser. Ключевое свойство chain — детерминированный маршрут: вы сами задаёте порядок шагов, и модель не решает, что делать дальше. Старый API LLMChain делал то же самое, но объявлялся классом; в свежих версиях он считается устаревшим в пользу LCEL.
Agents
Агент — это когда модель сама решает, какой инструмент вызвать и в каком порядке, чтобы выполнить задачу. Классическая схема — ReAct (reasoning + acting): модель рассуждает, выбирает инструмент, смотрит результат и повторяет цикл, пока не придёт к ответу.
from langchain.agents import initialize_agent, Tool
tools = [
Tool(name="search", func=search_web, description="поиск в интернете"),
Tool(name="calc", func=calculate, description="калькулятор"),
]
agent = initialize_agent(tools, llm, agent="react")
agent.run("Какая погода в Москве, умножь температуру на 2")Здесь маршрут недетерминированный: в отличие от chain, порядок вызовов определяет сама модель. Это гибко, но платно и рискованно — агент тратит много токенов на рассуждения, может зациклиться или выбрать не тот инструмент. initialize_agent — классический API; в актуальных версиях LangChain агентную часть перенесли в LangGraph, о котором ниже.
Memory
По умолчанию LLM не помнит предыдущие сообщения — каждый вызов независим. Память (memory) хранит состояние между вызовами: историю диалога, её краткую сводку или векторное хранилище фактов, — и подмешивает это в промпт.
from langchain.memory import ConversationBufferMemory
memory = ConversationBufferMemory()
chain = ConversationChain(llm=llm, memory=memory)ConversationBufferMemory дословно складывает всю историю и на каждом шаге вставляет её в промпт. Просто, но опасно: длинный диалог быстро упирается в лимит контекстного окна и раздувает стоимость. Поэтому на длинных сессиях берут ConversationSummaryMemory (модель суммирует историю) или ретривер поверх векторной базы, который подтягивает только релевантные куски.
LangGraph
LangGraph — развитие LangChain для сложных агентных сценариев. Вместо линейной цепочки процесс описывается графом: узлы — это шаги, рёбра — переходы, причём переходы могут быть условными и образовывать циклы.
from langgraph.graph import StateGraph
builder = StateGraph(AgentState)
builder.add_node("classify", classifier)
builder.add_node("route_a", handler_a)
builder.add_node("route_b", handler_b)
builder.add_conditional_edges("classify", route) # ветвление по результату
graph = builder.compile()Ключевое отличие от «магии» агентов — явное состояние (AgentState), которое проходит через узлы, и явные переходы, которые вы контролируете. Это даёт то, чего не хватает production-системам: предсказуемость, обработку ошибок, чекпоинты (можно возобновить прогон с места сбоя) и human-in-the-loop (пауза на подтверждение человеком). Поэтому для прода агентов сегодня чаще собирают на LangGraph, а не на старом initialize_agent.
Альтернативы
LangChain — не единственный вариант, и на собесе полезно знать, чем он отличается от соседей:
- LlamaIndex — заточен под RAG и индексацию документов. Если задача — «отвечать по корпусу документов», часто удобнее его.
- Haystack — зрелый фреймворк для поисковых и QA-пайплайнов, сильная сторона — production-ready retrieval.
- Pydantic AI — делает ставку на типобезопасность и валидацию структурированного вывода через Pydantic.
- Vercel AI SDK — TypeScript-first, для LLM-фич во фронтенде и Node.js-бэкенде.
- OpenAI Assistants API — нативный путь без стороннего фреймворка, но с привязкой к одному провайдеру (vendor lock-in).
У LangChain самая большая экосистема и интеграции, но его же и чаще всего критикуют за избыточные абстракции — для простых задач слои фреймворка добавляют сложности больше, чем пользы.
Частые ошибки
Тащить LangChain туда, где хватит одного вызова API. Для одиночного запроса к модели фреймворк — лишний слой. Хороший ответ на собесе включает «а нужен ли здесь вообще LangChain».
Путать chain и agent. Chain — детерминированный конвейер, маршрут задаёте вы. Agent — модель сама решает, что вызвать. Смешивать их в голове — типичный провал.
Недооценивать стоимость и непредсказуемость агентов. Каждый шаг рассуждения — это токены и латентность, а цикл может не сойтись. Для прода нужны лимиты на число шагов и явное состояние (LangGraph).
Не следить за контекстом в памяти. ConversationBufferMemory растёт неограниченно и однажды превышает окно модели. На длинных диалогах нужна суммаризация или ретрив по релевантности.
Связанные темы
- AI agents для DS
- BERT vs GPT для DS
- RAG на собесе DS
- Prompt engineering для DS
- Подготовка к собесу Data Scientist
FAQ
Чем chain отличается от agent?
Chain — это фиксированный конвейер: вы заранее задаёте последовательность шагов, и она всегда одинаковая. Agent даёт модели свободу самой выбирать инструменты и порядок вызовов под конкретный запрос. Chain предсказуем и дёшев, agent гибок, но дороже и рискованнее. На собесе за этот вопрос цепляются часто, так что держите разницу наготове.
Когда LangChain использовать не стоит?
Когда задача решается одним-двумя вызовами модели без сложной оркестрации. Прямой запрос к API провайдера будет проще, прозрачнее и легче в отладке, чем цепочка абстракций LangChain. Фреймворк оправдан, когда появляются несколько шагов, инструменты, память или RAG — то есть когда оркестрация действительно нужна.
В чём разница между LangChain и LangGraph?
LangChain хорош для линейных цепочек и быстрых прототипов. LangGraph описывает процесс как граф с явным состоянием, условными переходами и циклами, добавляет чекпоинты и human-in-the-loop. Для сложных агентов в проде берут LangGraph — там важны предсказуемость и восстановление после сбоев, чего линейным цепочкам не хватает.
LangChain или LlamaIndex для RAG?
LlamaIndex изначально заточен под RAG: индексация документов, ретрив, работа с разными источниками — из коробки и с меньшим количеством ручной сборки. LangChain тоже умеет RAG, но как одну из многих возможностей. Если продукт целиком про «вопросы-ответы по корпусу документов», LlamaIndex обычно даёт результат быстрее; если RAG — лишь часть большого пайплайна с агентами, удобнее оставаться в LangChain/LangGraph.
Как бороться с переполнением контекстного окна в памяти?
Не хранить весь диалог дословно. Варианты: суммаризировать историю (ConversationSummaryMemory), держать только последние N сообщений (скользящее окно) или вынести факты в векторную базу и подтягивать ретривером лишь релевантные фрагменты. Иначе ConversationBufferMemory растёт, упирается в лимит модели и раздувает стоимость каждого запроса.
Это официальная информация?
Нет. Статья основана на документации LangChain и LangGraph и типовых практиках. Конкретные требования зависят от компании, продукта и уровня позиции.
Тренируйте Data Science — откройте тренажёр с 1500+ вопросами для собесов.