Інтеграція LangChain для AI-пайплайнів: LCEL, RAG, агенти
LLM-пайплайни на продакшені — це не один виклик API, а десятки кроків: завантаження документів, чанкінг, ембеддинг, пошук, промптинг, парсинг відповіді, валідація, логування. Без єдиного фреймворку код перетворюється на «спагеті» з retry-логіки, обробників помилок і специфічних SDK. Коли команда зростає, кожен розробник пише свою обгортку навколо виклику LLM. Підтримка п'яти провайдерів потребує п'яти різних реалізацій зі спільними багами. Наші інженери бачать цей біль щодня. LangChain — рішення, яке ми впроваджуємо в проєктах клієнтів для уніфікації пайплайнів. Перехід на LangChain скорочує обсяг коду інтеграцій у середньому на 67% порівняно з прямими SDK (у 5 разів), а час додавання нового провайдера падає з кількох днів до годин.
Чому LCEL — основа продакшен-пайплайнів?
LCEL (LangChain Expression Language) — декларативний синтаксис, який об'єднує компоненти через оператор |. Будь-який об'єкт, що реалізує Runnable, можна з'єднати в ланцюжок. Це дає стрімінг, паралельне виконання, fallback'и та автоматичне трасування. Усе це працює незалежно від довжини ланцюжка. LCEL у 5 разів компактніший за прямий SDK при створенні RAG-пайплайну.
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser, JsonOutputParser
from langchain_core.runnables import RunnablePassthrough, RunnableParallel
from langchain_community.vectorstores import Chroma
llm = ChatOpenAI(model="gpt-4o", temperature=0)
# Простий ланцюжок
prompt = ChatPromptTemplate.from_messages([
("system", "Ти — експерт з {domain}."),
("human", "{question}"),
])
chain = prompt | llm | StrOutputParser()
result = chain.invoke({"domain": "фінансовий аналіз", "question": "Що таке EBITDA?"})
# Паралельний ланцюжок
parallel_chain = RunnableParallel({
"summary": prompt | llm | StrOutputParser(),
"keywords": ChatPromptTemplate.from_template("Витягни ключові слова: {question}") | llm | StrOutputParser(),
})
Джерело: LangChain Documentation
Як LangChain спрощує інтеграцію з LLM-провайдерами?
Єдиний інтерфейс BaseChatModel дозволяє міняти провайдера без зміни логіки. Достатньо замінити об'єкт llm:
# OpenAI
from langchain_openai import ChatOpenAI
llm_openai = ChatOpenAI(model="gpt-4o-mini", temperature=0.2)
# Anthropic
from langchain_anthropic import ChatAnthropic
llm_claude = ChatAnthropic(model="claude-3-5-sonnet-20241022")
# Google
from langchain_google_genai import ChatGoogleGenerativeAI
llm_gemini = ChatGoogleGenerativeAI(model="gemini-2.0-flash")
# Локальна Ollama
from langchain_ollama import ChatOllama
llm_local = ChatOllama(model="llama3.2:3b", temperature=0)
# Hugging Face
from langchain_huggingface import HuggingFaceEndpoint
llm_hf = HuggingFaceEndpoint(repo_id="mistralai/Mistral-7B-Instruct-v0.3")
RAG-пайплайн з векторною БД
RAG (Retrieval-Augmented Generation) — архітектура, в якій LLM отримує контекст з векторної бази даних. Ось приклад на Qdrant:
from langchain_community.document_loaders import DirectoryLoader, PyPDFLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_openai import OpenAIEmbeddings
from langchain_qdrant import QdrantVectorStore
from langchain_core.runnables import RunnablePassthrough
import json
loader = DirectoryLoader("./docs", glob="**/*.pdf", loader_cls=PyPDFLoader)
docs = loader.load()
splitter = RecursiveCharacterTextSplitter(chunk_size=800, chunk_overlap=100)
chunks = splitter.split_documents(docs)
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
vectorstore = QdrantVectorStore.from_documents(
chunks,
embedding=embeddings,
url="http://localhost:6333",
collection_name="knowledge_base",
)
retriever = vectorstore.as_retriever(search_kwargs={"k": 5})
rag_prompt = ChatPromptTemplate.from_messages([
("system", "Дай відповідь на запитання на основі контексту.\n\nКонтекст:\n{context}\n\nЗапитання: {question}\n\nЯкщо відповіді немає в контексті — скажи про це явно.")
])
def format_docs(docs):
return "\n\n".join(doc.page_content for doc in docs)
rag_chain = (
{"context": retriever | format_docs, "question": RunnablePassthrough()}
| rag_prompt
| llm
| StrOutputParser()
)
answer = rag_chain.invoke("Які умови розірвання договору?")
Управління пам'яттю в діалозі
Для тривалих діалогів використовуйте ConversationBufferWindowMemory з історією в Redis:
from langchain.memory import ConversationBufferWindowMemory
from langchain_core.chat_history import BaseChatMessageHistory
from langchain_core.runnables.history import RunnableWithMessageHistory
from langchain_community.chat_message_histories import RedisChatMessageHistory
def get_session_history(session_id: str) -> BaseChatMessageHistory:
return RedisChatMessageHistory(session_id, url="redis://localhost:6379")
chat_prompt = ChatPromptTemplate.from_messages([
("system", "Ти — асистент технічної підтримки."),
("placeholder", "{history}"),
("human", "{input}"),
])
chain_with_history = RunnableWithMessageHistory(
chat_prompt | llm | StrOutputParser(),
get_session_history,
input_messages_key="input",
history_messages_key="history",
)
config = {"configurable": {"session_id": "user_123"}}
chain_with_history.invoke({"input": "Мій додаток не запускається"}, config=config)
chain_with_history.invoke({"input": "Помилка: 'connection refused'"}, config=config)
Практичний кейс: уніфікація 5 LLM-інтеграцій
Ситуація з нашого досвіду: один із наших клієнтів — продакшн-команда підтримувала 5 окремих інтеграцій (OpenAI, Claude, корпоративний YandexGPT, локальний Llama, Gemini) з дублюючим кодом retry-логіки, форматування промптів та обробки помилок. Такі «зоопарки» виникають щоразу, коли команда швидко зростає, а архітектура не уніфікована.
Рішення: рефакторинг на LangChain LCEL з єдиним інтерфейсом. Архітектура:
- Конфігурований провайдер через env-змінну
LLM_PROVIDER - Спільні промпт-темплейти в YAML-файлах
- Єдиний шар обробки помилок через
.with_fallbacks()
from langchain_core.runnables import RunnableWithFallbacks
primary_llm = ChatOpenAI(model="gpt-4o")
fallback_llm = ChatAnthropic(model="claude-3-5-sonnet-20241022")
robust_llm = primary_llm.with_fallbacks([fallback_llm])
Результати:
- Обсяг коду інтеграцій: -67% (LCEL скорочує код у 5 разів порівняно з прямим SDK)
- Час додавання нового провайдера: 3 дні → 4 години (у 12 разів швидше)
- Uptime пайплайну: 99.1% → 99.8%
- Видимість у LangSmith: час налагодження інцидентів скоротився з 2 годин до 20 хвилин (у 6 разів швидше)
- Економія: наш клієнт зекономив $15 000 на рік на підтримці інтеграцій
Коли LangChain надлишковий?
LangChain додає абстракцію, яка виправдана при складних пайплайнах. Для простого one-shot виклику LLM пряме використання SDK (OpenAI, Anthropic) простіше та передбачуваніше.
| Критерій | Прямий SDK | LangChain LCEL |
|---|---|---|
| Код для виклику одного LLM | 3 рядки | 5 рядків |
| Код для RAG з пам'яттю | ~200 рядків | ~40 рядків |
| Час на зміну провайдера | 1-2 дні | 1 година |
| Трасування | Окрема інтеграція | Вбудована в LangSmith |
| Складність навчання | Низька | Середня |
Порівняння типів пам'яті:
| Тип пам'яті | Зберігання | Підходить для |
|---|---|---|
| ConversationBufferWindowMemory | В оперативній пам'яті | Короткі діалоги |
| RedisChatMessageHistory | Redis | Розподілені системи |
| PostgresChatMessageHistory | PostgreSQL | Довготривале зберігання |
LangChain оптимальний коли: кілька компонентів (retriever + LLM + parser), кілька провайдерів, потрібні трасування та пам'ять. Для решти випадків — залиште SDK напряму.
Деталі порівняння продуктивності LCEL vs прямий SDK
При ідентичних операціях LCEL додає менше 5% накладних витрат на latency p99, але забезпечує на порядок кращу спостережуваність. У тестах на 1000 запитів до одного LLM різниця в часі виконання не перевищувала 3%.Що входить в роботу
- Архітектурна схема ланцюжків LCEL
- Налаштована інтеграція з вибраними провайдерами (до 5)
- Векторна БД з індексами та конфігурацією
- Система пам'яті діалогів (Redis/Postgres)
- Трасування LangSmith з дашбордами
- Документація по нових ланцюжках та інструкція для розробників
- Гарантія роботи всіх пайплайнів протягом місяця після запуску
- Навчання команди роботі з LangChain (2-годинний воркшоп)
Як ми впроваджуємо LangChain
Ми — команда з 7+ років досвіду в NLP та 50+ інтеграцій LLM, на ринку з 2019 року. Процес:
- Аудит поточних LLM-інтеграцій та архітектури пайплайнів.
- Проєктування єдиної схеми ланцюжків (LCEL).
- Підключення та налаштування векторної БД (Qdrant, Chroma, pgvector).
- Інтеграція з провайдерами (OpenAI, Claude, локальні моделі).
- Налаштування пам'яті діалогів (Redis, Postgres).
- Розгортання LangSmith для трасування та налагодження.
- Документація по нових ланцюжках та інструкція для розробників.
- Гарантія роботи всіх пайплайнів протягом місяця після запуску.
Терміни та вартість
- Базова інтеграція LangChain + 1 провайдер: 2–4 дні, від $2 000
- RAG-пайплайн з векторною БД: 1–2 тижні, від $5 000
- Діалоговий агент з пам'яттю: 1–2 тижні, від $4 000
- Рефакторинг існуючого коду на LCEL: 1–3 тижні, від $3 000
Оцінимо ваш проєкт безкоштовно протягом 2 днів. Пишіть — розкажемо, як уніфікувати пайплайни та знизити витрати на підтримку. Отримайте консультацію з впровадження LangChain — ми підберемо архітектуру під ваш проєкт.







