Інтеграція LangChain для AI-пайплайнів: LCEL, RAG, агенти

Інтеграція LangChain для AI-пайплайнів: LCEL, RAG, агенти

Напрямки AI-розробки

Часті запитання

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1440
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1301
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    997
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1264
  • image_logo-advance_0.webp
    Розробка логотипу компанії B2B Advance
    712
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    1002

Інтеграція 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 року. Процес:

  1. Аудит поточних LLM-інтеграцій та архітектури пайплайнів.
  2. Проєктування єдиної схеми ланцюжків (LCEL).
  3. Підключення та налаштування векторної БД (Qdrant, Chroma, pgvector).
  4. Інтеграція з провайдерами (OpenAI, Claude, локальні моделі).
  5. Налаштування пам'яті діалогів (Redis, Postgres).
  6. Розгортання LangSmith для трасування та налагодження.
  7. Документація по нових ланцюжках та інструкція для розробників.
  8. Гарантія роботи всіх пайплайнів протягом місяця після запуску.

Терміни та вартість

  • Базова інтеграція LangChain + 1 провайдер: 2–4 дні, від $2 000
  • RAG-пайплайн з векторною БД: 1–2 тижні, від $5 000
  • Діалоговий агент з пам'яттю: 1–2 тижні, від $4 000
  • Рефакторинг існуючого коду на LCEL: 1–3 тижні, від $3 000

Оцінимо ваш проєкт безкоштовно протягом 2 днів. Пишіть — розкажемо, як уніфікувати пайплайни та знизити витрати на підтримку. Отримайте консультацію з впровадження LangChain — ми підберемо архітектуру під ваш проєкт.