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.
Жоден не замінює інший. Один дає компоненти, другий — стан і маршрутизацію, третій — спостережуваність та оцінювання, четвертий — візуальний спосіб складати й публікувати потоки. Використовуйте найменше поєднання, яке команда ще може зрозуміти, протестувати й якому може довіряти.