LangChain, LangGraph, LangSmith и Langflow: что делает каждый инструмент
Четыре инструмента семейства Lang решают разные задачи. Когда брать конвейеры LangChain, потоки с состоянием LangGraph, трассировку LangSmith и визуальный конструктор Langflow — с примерами кода.
Четыре названия из одной экосистемы постоянно звучат вместе: LangChain, LangGraph, LangSmith и Langflow. Их часто записывают в конкурирующие фреймворки, хотя каждый отвечает за свою задачу.
- LangChain даёт строительные блоки: обёртки над моделями, шаблоны промптов, ретриверы, привязку инструментов и парсеры вывода.
- LangGraph запускает приложения, которым нужна память между шагами, ветвление или циклы.
- LangSmith следит за тем, что произошло, и оценивает это — и в разработке, и в продакшене.
- Langflow накрывает те же идеи холстом с перетаскиванием блоков.
LangChain для линейных конвейеров
LangChain связывает модель с промптами, ретриверами, инструментами, базами данных и структурированным выводом. Когда работа идёт в одну сторону, от входа через несколько шагов к результату, это обычно самый быстрый путь. Установите его вместе с интеграцией OpenAI, импортируйте шаблон промпта и чат-модель, задайте шаблон из системной строки и пользовательской строки с плейсхолдером темы и закрепите небольшую модель с нулевой температурой, чтобы ответы были воспроизводимыми.
pip install langchain langchain-openai
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
prompt = ChatPromptTemplate.from_messages(
[
("system", "You are a concise technical writer."),
("user", "Explain {topic} in three bullet points."),
]
)
model = ChatOpenAI(
model="gpt-4.1-mini",
temperature=0,
)
Оператор «пайп» соединяет шаблон и модель в цепочку. Если вызвать цепочку со словарём, где указана тема, она вернёт ответ, текст которого лежит в атрибуте content.
chain = prompt | model
response = chain.invoke(
{"topic": "retrieval-augmented generation"}
)
print(response.content)
Шаблон и модель остаются отдельными объектами, так что любой из них можно заменить, а цепочка предоставляет одну аккуратную форму входа. Это подходит для интеграций, поиска, вызова инструментов, сборки промптов и разбора вывода.
LangGraph, когда потоку нужно принимать решения
LangGraph описывает приложение как граф. Узлы выполняют работу, рёбра говорят, что запускать дальше, а по ним путешествует типизированный объект состояния. Это окупается, когда выполнение может ветвиться, зацикливаться, повторяться, приостанавливаться или возобновляться. Пример ниже маршрутизирует вопрос в поддержку. После установки пакета он импортирует вспомогательные типы и примитивы графа.
pip install langgraph
from typing import Literal, TypedDict
from langgraph.graph import END, START, StateGraph
Общее состояние хранит вопрос, категорию и ответ. Один узел назначает категорию по тексту вопроса, а ещё два формируют ответ: один для вопросов об оплате, другой для всего остального.
class SupportState(TypedDict):
question: str
category: str
answer: str
def classify(state: SupportState) -> dict:
question = state["question"].lower()
category = (
"billing"
if "invoice" in question
else "general"
)
return {"category": category}
def answer_billing(state: SupportState) -> dict:
return {
"answer": "I will help you review the invoice."
}
def answer_general(state: SupportState) -> dict:
return {
"answer": "I will help you with your request."
}
Небольшой роутер возвращает метку, которую сохранил классификатор. При сборке регистрируются четыре узла, а затем добавляются рёбра: старт ведёт к классификатору, условное ребро расходится к подходящему узлу ответа, и оба ответа ведут к концу.
def route(
state: SupportState,
) -> Literal["billing", "general"]:
return state["category"]
builder = StateGraph(SupportState)
builder.add_node("classify", classify)
builder.add_node("billing", answer_billing)
builder.add_node("general", answer_general)
builder.add_edge(START, "classify")
builder.add_conditional_edges("classify", route)
builder.add_edge("billing", END)
builder.add_edge("general", END)
Компиляция билдера даёт готовый к запуску граф. Если подать в него вопрос о счёте с пустой категорией, запрос уйдёт в ветку оплаты, а вывод поля с ответом подтвердит, какой путь сработал.
graph = builder.compile()
result = graph.invoke(
{
"question": "Why is my invoice higher?",
"category": "",
"answer": "",
}
)
print(result["answer"])
Та же схема растягивается на циклы с инструментами, чекпоинты, взаимодействующих агентов и шаги с одобрением человеком — именно там надёжное состояние, маршрутизация, циклы и повторы себя оправдывают.
LangSmith, чтобы видеть, что сделала система
LangSmith не конкурирует с двумя предыдущими. Он делает их поведение видимым: промпты, вызовы модели, выбор инструментов, задержку, сбои, число токенов и расходы можно потом изучить. Настройка — две переменные окружения: одна включает трассировку, другая хранит API-ключ.
import os
os.environ["LANGSMITH_TRACING"] = "true"
os.environ["LANGSMITH_API_KEY"] = (
"your-langsmith-api-key"
)
os.environ["LANGSMITH_PROJECT"] = (
"agent-comparison-demo"
)
Ключ выше — заглушка. Настоящим учётным данным место в окружении или в менеджере секретов, а не в файлах с исходным кодом. Когда трассировка включена, поддерживаемые вызовы LangChain и LangGraph появляются в выбранном проекте.
Для оценки соберите датасет, похожий на реальный трафик, и сравнивайте версии по корректности, обоснованности, точности выбора инструментов, скорости и стоимости. LangSmith подходит для отладки, регрессионных наборов, трассировок в продакшене, мониторинга и анализа обратной связи.
Langflow для сборки на холсте
Langflow — визуальная low-code-среда. Входы, промпты, модели, ретриверы, векторные хранилища, инструменты и выходы перетаскиваются на холст и соединяются. Она хороша для экспериментов, демо, обучения и смешанных команд.
Развёрнутый поток можно вызвать по HTTP. Клиент ниже импортирует os и requests, читает адрес сервера из переменной окружения с локальным портом по умолчанию как запасным вариантом и оборачивает вызов во вспомогательную функцию, которая собирает URL эндпоинта.
import os
import requests
LANGFLOW_URL = os.getenv(
"LANGFLOW_URL",
"http://localhost:7860",
)
FLOW_ID = os.environ["LANGFLOW_FLOW_ID"]
API_KEY = os.environ["LANGFLOW_API_KEY"]
def run_flow(message: str) -> dict:
url = (
f"{LANGFLOW_URL}/api/v1/run/{FLOW_ID}"
)
headers = {"x-api-key": API_KEY}
payload = {
"input_value": message,
"input_type": "chat",
"output_type": "chat",
}
Вспомогательная функция отправляет данные POST-запросом с заголовками и таймаутом, проверяет HTTP-ошибки и возвращает тело JSON. Вызов с вопросом-сравнением выводит структурированный результат.
response = requests.post(
url,
headers=headers,
json=payload,
timeout=60,
)
response.raise_for_status()
return response.json()
result = run_flow(
"Compare LangChain and LangGraph."
)
print(result)
Конфигурация не попадает в исходный код, запросы не могут висеть вечно, а сбои выбрасывают исключения. Выбирайте Langflow для визуального прототипирования, переиспользуемых потоков, демо и более быстрой командной работы. Сильно кастомизированную продакшен-логику может быть проще держать в виде Python-кода под контролем версий.
Все четыре в одном продукте
В агенте клиентской поддержки LangChain связывает модель, промпт, базу знаний и инструменты. LangGraph управляет классификацией, поиском, одобрением и повторами. LangSmith записывает каждый шаг и оценивает качество, скорость и стоимость. Langflow даёт визуальный черновик, по которому заинтересованные стороны могут прокликать сценарий.
Практические правила:
- Линейный конвейер: начните с LangChain.
- Состояние, ветвление, циклы или возобновляемые запуски: добавьте LangGraph.
- Нужно доказать качество: подключите LangSmith.
- Быстрые визуальные эксперименты: попробуйте Langflow.
Ни один не заменяет другой. Один даёт компоненты, второй — состояние и маршрутизацию, третий — наблюдаемость и оценку, четвёртый — визуальный способ собирать и публиковать потоки. Используйте наименьшее сочетание, которое команда всё ещё может понять, протестировать и которому может доверять.