Мы неоднократно рассказывали о библиотеках и фреймворках, которые ускоряют разработку парсеров, например, для Python, Java и Golang. Существуют разные подходы — от простейших HTTP-клиентов, которые умеют читать только «голый» HTML, до максимально сложных алгоритмов, которые включают в себя компьютерное зрение и помощь искусственного интеллекта (ИИ). В этом материале расскажем о наиболее продвинутых фреймворках для интеграции больших языковых моделей (LLM) в ваши парсеры — LangChain vs LangGraph.
Что такое LangChain и LangGraph и чем они отличаются друг от друга
Напомним, ИИ бывает разным. Нейросети, которые работают с текстовым содержимым, называются LLM. Они умеют не только генерировать текст или давать краткие ответы по существу, но и выполнять простые задания: анализировать текст из документов и выдавать по нему краткую справку, изучать содержимое HTML-кода и извлекать конкретное содержимое, а также многое другое. Нас, как можно догадаться из контекста, интересует всё, что связано с парсингом.
Многие современные нейросети работают в виде общедоступных web-сервисов и имеют свой API-интерфейс. Отдельные нейросети уже обзавелись возможностью обработки документов и файлов, включая изображения, презентации, PDF, аудио, видео и пр. Но, в любом случае, при работе по API они имеют свои ограничения. Основная проблема — токенизация. Условно: каждый новый запрос LLM воспринимает как новый (без учёта истории обращений). А так как объём запроса лимитирован неким количеством токенов (токены выступают скорее в роли слов, хотя алгоритм их расчёта выглядит немного сложнее). В итоге получается, что при отправке большого запроса к LLM нужно:
- разбить его на составляющие (в соответствии с лимитами по токенам)
- и сохранить историю (чтобы LLM не потеряла контекст).
За это отвечают так называемые чанки (в англ. chains), то есть цепочки запросов.
Для удобства автоматизации работы с цепочками запросов нужен специальный софт или библиотеки. И вот тут мы подходим к потребности в LangChain и LangGraph
Вкратце о LangChain
LangChain— это фреймворк для создания цепочек (chains) вызовов языковых моделей и интеграции их с внешними инструментами: базами данных, парсерами, API и т.п.
На текущий моменте LangChain реализован в виде самостоятельных библиотек (для языков программирования Python, JavaScript и TypeScript), а также в виде готовой платформы (web-сервиса, который работает по API, имеет все необходимые интеграции и готовые инструменты для оркестрации и оценивания — в надёжном облаке, удобном для корпоративного применения).
Основные возможности (функционал) LangChain:
- Открытый код библиотеки и лицензия MIT.
- Простая интеграция с популярными LLM (языковыми моделями), а также с внешними источниками данных. В доступе более 600 вариантов готовых интеграций: Groq, OpenAI, Google Gemini, YandexGPT, xAI и пр.
- Создание последовательных цепочек вызовов LLM (например, вопрос, поиск в интернете, ответ) и токенизация. Возможно даже объединение нескольких моделей для решения одной задачи.
- Возможность создания корпоративных баз знаний (RAG, Retrieval-Augmented Generation) на основе предоставленных документов и информации.
- Сохранение истории диалога (обеспечение предметной «памяти» нейросети и учёта контекста), поддержка векторных хранилищ и хранилищ типа «ключ-значение».
- Создание агентов, которые могут выбирать наиболее подходящие инструменты для своей работы.
Если упростить ещё, то LangChain — это минимальная база для продвинутой интеграции LLM в свои скрипты и программы. Например, на её основе создаются более сложные решения, в том числе и с использованием систем оркестрации, таких как LangGraph.
Вкратце о LangGraph
LangGraph — это фреймворк для быстрого и удобного проектирования агентов LangChain. Именно LangGraph берёт на себя всё, что связано с созданием точек входа и выхода, проектированием фоновых задач, контролем состояний, масштабированием и отказоустойчивостью.
Грубо говоря, это готовая реализация типовых агентов на базе существующих LLM, которые быстро можно перенастроить под себя или под нужды своих проектов. В итоге можно сосредоточиться не на написании всего с нуля, а только на конфигурировании логики.
Как и LangChain, библиотека LangGraph распространяется по модели с исходным кодом, по лицензии MIT.
Не стоит путать фреймворк LangGraph и платформу LangGraph, Платформа — это уже готовая облачная инфраструктура со своими подписками и тарифами. Она имеет закрытый исходный код.
Специально для удобного визуального проектирования логики LLM-агентов предоставляется среда разработки (IDE-система) — LangGraph Studio. Она предназначена для установки на ПК. В коммерческой версии платформы LangGraph есть облачная реализация LangGraph Studio.
LangChain vs LangGraph — различия
Итак, LangChain — это фреймворк для интеграции LLM в свои скрипты и программы, некая база, с которой может начаться разработка сложных цепочек обмена данными. LangChain выступает в роли прослойки, отвечающей за подключение LLM.
А LangGraph — это инструмент для проектирования LLM-агентов, технически это тоже фреймворк. Он работает поверх LangChain и позволяет быстрее запускать типовые задачи. Самая главная функция — оркестрация большого числа ИИ-агентов.
Технические различия LangChain vs LangGraph:
- Архитектура LangChain выстроена вокруг последовательных цепочек (последовательных шагов). А архитектура LangGraph — вокруг графа состояний. Узлы в графе могут иметь несколько переходов и условий.
- В LangGraph условия и циклы встроены в архитектуру. Можно задать, что делать при ошибке, как повторить шаг или куда перейти в зависимости от результата. В LangChain аналогичное поведение тоже программируется, но достаточно сложно.
В итоге, если вам нужно только подключить LLM и организовать разбивку больших объёмов данных на цепочки, то стоит использовать LangChain.
Если вам нужно быстро и точно спроектировать своего LLM-агента или большое число таких агентов (с оркестрацией), то тут уже логично задействовать LangGraph.
Парсинг с помощью LangChain: возможности и ограничения
Библиотека LangChain сама по себе ничего не парсит. Она отвечает за взаимодействие с нейросетями. А вот нейросети в свою очередь можно привлечь к задачам извлечения данных, Например, для поиска закономерностей (выявления CSS-классов, идентификаторов и специфических атрибутов, помогающих вычленить нужный HTML-элемент и его содержимое), распознавания изображений, их обработки (в том числе для поиска образов и объектов на картинках/видео), транскрибации аудио и т.п.
Предметные примеры ИИ-скраперов в материале про ИИ скрапинг.
Возможности LangChain скрапинга:
- Организация выборки содержимого конкретных элементов из чистого или подготовленного HTML-кода.
- Настройка сложной логики с выбором дальнейших шагов: какой из алгоритмов парсинга нужно задействовать в зависимости от содержимого страницы (скачивание видео, распознавание изображений, поиск цены/описаний товаров, извлечение мета-тегов и т.п.).
- Построение последовательных цепочек обработки: поиск контента, создание списка страниц для обхода, обход (извлечение).
- Задействование сразу нескольких внешних нейросетей (у каждой из них могут быть свои наборы промтов для конкретных прикладных задач).
- Разбивка больших объёмов данных и чанки (сериализация), работа с историей запросов/контекстом.
Ограничения LangChain скрапинга:
- Сама библиотека не умеет рендерить страницы или извлекать HTML-код с указанных URL-адресов. Соответственно, нужны дополнительные библиотеки и инструменты: HTTP-клиенты, headless-браузеры, веб-драйверы, такие как Puppeteer, Playwright, Selenium и т.п.
- Всю работу в реальности выполняют нейросети. А они либо требуют оплаты за доступ к API, либо дорого обходятся при локальном запуске (нужно высокопроизводительное оборудование, особо это касается видеоускорителей и вместительных жёстких дисков, желательно твердотельных — для максимальной скорости).
- Чтобы сэкономить на токенах (а именно они используются для оценки работы ИИ), нужно детально поработать над предварительной подготовкой содержимого, которое отправляется в нейросеть. Всё это повышает сложность скрипта и «обвязки» для LangChain-скрапинга.
- В некоторых случаях, когда вы работаете только с одной нейросетью/агентом, проще написать свой коннектор для API, чем использовать LangChain в роли прослойки.
Инструменты и агенты для парсинга с помощью LangChain
LangChain позволяет стандартизировать синтаксис обращения к LLM. Специально для этого из коробки предлагаются: готовые пакеты интеграции, базовые абстракции (langchain-core), цепочки, агенты и инструменты (tools), отвечающие за построение когнитивной архитектуры вашего приложения.
К инструментам, которые облегчают процесс парсинга через LangChain, можно отнести:
- Готовые методы для работы со структурированными данными (JSON, XML, YAML и т.п.) и встроенные инструменты для анализа/разборки текста сообщений LLM.
- Управление нагрузкой и скоростью запросов по API.
- Подсчёт используемых токенов.
- Разбивка на чанки — для отправки больших текстов и HTML-страниц.
- Быстрая смена промтов (по ситуации).
- Локальное кэширование ответов нейросетей.
Поддержка прокси в LangChain
Так как LangChain не работает с web-сайтами напрямую, ему не нужны прокси. Но если вы пишите комплексный парсер, то ему однозначно потребуются прокси. Дело в том, что многие целевые сайты активно защищаются от ботов и автоматического трафика. Чтобы обойти их защиту, могут потребоваться разные средства и подходы. Ротируемые прокси с точным геотаргетингом — одно из самых надёжных средств, которое может работать в тесной связке с другими.
Самый логичный подход — управлять прокси на уровне HTTP-клиента, которым вы пользуетесь для подключения к целевым сайтам. Например, если вы работаете в среде Node.js, то вам нужно настроить прокси для node-fetch. Если работаете через антидетект-браузер или через headless-браузер, то прокси нужно установить для них (с помощью плагинов или специальных переменных/API).
Простой агент скрапинга LangChain через прокси
Вполне дееспособный скрипт парсинга на языке Python. Он обеспечивает настройку и работу LangChain через прокси-сервер:
import sqlite3
import json
import time
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from langchain.llms import OpenAI
from langchain.agents import initialize_agent, Tool, AgentType
# -------------------------------
# Настройка базы данных SQLite
# -------------------------------
conn = sqlite3.connect("products.db")
cursor = conn.cursor()
cursor.execute('''
CREATE TABLE IF NOT EXISTS products (
id INTEGER PRIMARY KEY AUTOINCREMENT,
url TEXT,
title TEXT,
price TEXT,
description TEXT
)
''')
conn.commit()
# -------------------------------
# Настройка Selenium с прокси
# -------------------------------
chrome_options = Options()
chrome_options.add_argument("--headless")
proxy = "http://username:password@your_proxy_ip:port" # Если без логина: "http://ip:port"
chrome_options.add_argument(f'--proxy-server={proxy}')
driver = webdriver.Chrome(options=chrome_options)
# -------------------------------
# Настройка LLM
# -------------------------------
llm = OpenAI(model_name="gpt-4o", temperature=0)
# -------------------------------
# Функция для парсинга HTML через LLM
# -------------------------------
def extract_product_data(html_content: str) -> str:
prompt = f"""
Вот HTML содержимое страницы товара:
{html_content}
Вытащи из него название товара, цену и описание. Отдай ответ строго в формате JSON, например:
Отвечай только JSON без лишнего текста.
"""
response = llm(prompt)
return response
# -------------------------------
# Описание инструмента для агента
# -------------------------------
extract_tool = Tool(
name="ExtractProductData",
func=extract_product_data,
description="Извлекает название, цену и описание товара из HTML страницы и возвращает JSON"
)
# -------------------------------
# Инициализация агента
# -------------------------------
agent = initialize_agent(
tools=[extract_tool],
llm=llm,
agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
verbose=True
)
# -------------------------------
# Функция парсинга страницы
# -------------------------------
def parse_product(url):
driver.get(url)
time.sleep(3) # Ждём рендер, в секундах
html = driver.page_source
# Запрос к агенту
query = f"Используй инструмент ExtractProductData, чтобы извлечь данные о товаре из этого HTML: {html}"
response = agent.run(query)
try:
data = json.loads(response)
title = data.get("title", "")
price = data.get("price", "")
description = data.get("description", "")
except json.JSONDecodeError:
print(f"JSON parsing error for {url}")
return None
# Сохраняем в БД
cursor.execute('INSERT INTO products (url, title, price, description) VALUES (?, ?, ?, ?)',
(url, title, price, description))
conn.commit()
print(f"Data saved for page: {url}")
return data
# -------------------------------
# Список страниц для парсинга
# -------------------------------
urls = [
"https://example.com/product/1",
"https://example.com/product/2",
# Добавьте свои URL
]
for u in urls:
parse_product(u)
# -------------------------------
# Завершаем работу
# -------------------------------
driver.quit()
conn.close()
Этот скрипт последовательно обходит список целевых страниц с задействованием прокси и headless-браузера через веб-драйвер Selenium. HTML-код страниц передаётся на анализ в LLM, а та, в соответствии с промтом, возвращает ответ в JSON-формате. Со страниц извлекаются названия товаров, их цена и описание. Данные сохраняются в базу SQlite.
Скрапинг с LangGraph: больше контроля, меньше абстракции
LangGraph работает в паре с LangChain. Это своего рода настройка, которая облегчает построение сложных ИИ-агентов.
Почему LangGraph подходит для сложных рабочих процессов парсинга
- LangGraph позволяет создавать гибкие многоступенчатые сценарии, которые легко описываются визуальными блок-схемами. Собственно, как раз для этой задачи есть специальный софт — LangGraph Studio. Архитектуру приложения легко переделать или доработать под новые задачи.
- В наличии поддержка условных переходов. Например, можно задать условия выбора тех или иных сценариев: пропуск парсинга, работа через прокси при наличии капчи (или принудительная ротация) и т.п.
- Циклы и повторы для типовых действий.
- Поддержка многопоточности.
- Адекватный контроль состояния агента: доступен он или занят. Легко можно понять на каком шаге общий процесс.
- Готовые шаблоны приложений — для работы с памятью, с поиском и т.п.
Прокси в LangGraph: практическая настройка
Как и в случае с LangChain, прокси в LangGraph не работают из коробки. Их нужно добавлять только на уровне HTTP-клиентов (приложений и библиотек, которые отвечают за подключение к целевым сайтам):
- requests и node-fetch,
- Playwright, Selenium, Puppeteer,
- переменные среды,
- настройки хоста (операционной системы),
- headless-браузер/антидетект (через который осуществляется подключение).
Узел LangGraph + настройка прокси
Пример кода на Python — парсинг с LangGraph через прокси:
import requests
import random
from langgraph.graph import StateGraph, END
# --- Состояние, которое передаётся между узлами ---
class ScraperState:
def __init__(self, url="", html="", proxy_used=""):
self.url = url
self.html = html
self.proxy_used = proxy_used
# --- Список прокси для ротации ---
proxy_list = [
"http://user:pass@ip1:port",
"http://user:pass@ip2:port",
"http://user:pass@ip3:port",
]
# --- Узел LangGraph: запрос страницы через прокси ---
def fetch_page_with_proxy(state: ScraperState):
# Выбираем случайный прокси
proxy = random.choice(proxy_list)
proxies = {
"http": proxy,
"https": proxy,
}
try:
print(f"Using proxy: {proxy}")
response = requests.get(state.url, proxies=proxies, timeout=10)
state.html = response.text
state.proxy_used = proxy
except Exception as e:
print(f"Request error with proxy {proxy}: {e}")
state.html = ""
state.proxy_used = proxy
return state
# --- Создаём граф ---
graph = StateGraph(ScraperState)
graph.add_node("fetch_with_proxy", fetch_page_with_proxy)
graph.set_entry_point("fetch_with_proxy")
graph.add_edge("fetch_with_proxy", END)
compiled_graph = graph.compile()
# --- Запуск графа ---
start_state = ScraperState(url="https://example.com")
final_state = compiled_graph.invoke(start_state)
print("Final HTML snippet:", final_state.html[:500])
print("Proxy used:", final_state.proxy_used)
Пара слов о логике работы скрипта с ротацией прокси в LangGraph:
- Узел — это функция, которая принимает состояние (в нашем случае State), делает запрос к целевому URL через прокси и возвращает обновлённое состояние.
- Прокси: может быть фиксированный или ротироваться из списка.
- В примере используем библиотеку requests, так как это самый простой вариант HTTP-клиента (для демонстрации).
LangChain против LangGraph: когда и что использовать для парсинга
Итак, можно заметить, что ни LangGraph, на LangChain не умеют работать с прокси. Всё из-за того, что эти библиотеки не умеют обращаться к сайтам и веб-ресурсам напрямую. Им обязательно нужны посредники. Их фишка — работа с нейросетями и LLM. И здесь они действительно повышают продуктивность, особенно если речь о сложной архитектуре или о большом количестве LLM.
Выберите LangChain, если хотите обслуживать простые цепочки действий.
Этот фреймворк идеально подходит для реализации прослойки, отвечающей за подключение и «общение» в любыми нейросетями. В наборе её возможностей масса мелких профильных инструментов, которые вы получаете в режиме одного окна. Нужно посчитать токены, разбить на чанки, задать разные промты для разных задач? Без проблем.
Но LangChain — это «база», поэтому с ней удобно работать только по линейным сценариям парсинга.
Выберите LangGraph, если хотите выстроить сложную логику
Этот фреймворк дополняет LangChain и облегчает создание кастомных условий, переходов и циклов между разными сценариями и узлами. Соответственно, в LangGraph можно описать (или спроектировать) максимально сложный парсер.
И LangGraph, и LangChain могут использоваться в вашем проекте параллельно. Более того, тот же разработчик предлагает ряд вспомогательных продуктов, но уже на коммерческой основе — это LangSmith и LangGraph Platform (готовая облачная платформа).
Заключение и рекомендации
Парсинг становится сложнее и часто требует участия ИИ/нейросетей. Чтобы не писать своих коннекторов и не запутаться в синтаксисе отдельных внешних сервисов, можно воспользоваться слоем абстракции, который реализуется фреймворком LangChain. Он облегчает взаимодействие с 600+ внешними инструментами: векторные хранилища, базы данных, системы кеширования и т.п. Но самый главный элемент — LLM (большие языковые модели).
Если вам нужно что-то большее, чем линейные скрипты обработки цепочек запросов, то можно добавить в свой парсер фреймворк LangGraph. Он отвечает за создание графов и позволяет выстраивать сложные многоуровневые рабочие процессы с разными условиями переходов и циклами.
Нельзя сказать, что в сравнении LangChain vs LangGraph кто-то будет лучше. У каждой библиотеки своя сфера применения.
Ни LangChain, ни LangGraph не умеют работать с прокси. Всё из-за того, что у них нет интерфейса для прямого обращения к веб-ресурсам.
Тем не менее, прокси критически необходимы любому парсеру. Как и с помощью чего интегрировать прокси в LangChain или в LangGraph мы рассказали выше.