Практическая реализация AI-агента в Chrome с LangChain

- -
- 100%
- +

Глава 1. Подготовка среды и установка Chrome и LangChain
Подготовка среды и установка Chrome и LangChain в контексте практической реализации создания AI‑агента для браузера подразумевают пошаговый процесс, который начинается с выбора и настройки операционной системы, переходит к установке последней стабильной версии Google Chrome, включает подготовку виртуального окружения Python, инсталляцию необходимых зависимостей, а затем происходит конфигурация самой библиотеки LangChain, её модулей и адаптеров, специфичных для взаимодействия с веб‑страницей; при этом важно убедиться, что все компоненты совместимы, что их версии не конфликтуют, а пути к исполняемым файлам Chrome добавлены в переменные окружения, что позволяет агенту запускать браузер в headless‑режиме или с пользовательским интерфейсом в зависимости от задачи, после чего следует проверка корректности установки путем выполнения простого скрипта, который открывает браузер, загружает указанный URL и выводит в консоль заголовок страницы, тем самым демонстрируя базовый цикл "инициализация‑загрузка‑выполнение‑завершение", и далее необходимо создать и настроить переменные конфигурации, такие как путь к драйверу ChromeDriver, параметры прокси, таймауты и стратегии повторных попыток, которые будут использоваться в последующих модульных вызовах LangChain, включающих цепочки (chains), агенты (agents), инструменты (tools) и memory‑компоненты, где каждый из этих элементов должен быть тщательно описан в виде JSON‑ или YAML‑файлов с соответствующими ключами, значениями и комментариями, чтобы облегчить репликацию кода на разных машинах; далее стоит выполнить установку менеджера пакетов, например pip, добавить в него возможность работы через виртуальное окружение, затем выполнить команду `pip install langchain[all]`, которая автоматически подтянет ядро LangChain и все необходДимые подмодули, включая integrations, tools и memory, а также важно выполнить отдельную установку драйвера ChromeDriver, скачав соответствующую версию, соответствующую конфлигующей версии Chrome, и разместив её в каталоге, доступном из PATH, или указав путь к ней вручную при инициализации WebDriver; в процессе настройки необходимо также установить дополнительные библиотеки, такие как `beautifulsoup4` для парсинга HTML, `lxml` для ускоренного парсинга, `httpx` или `requests` для сетевых запросов, а также `playwright` в качестве альтернативного инструмента автоматизации браузера, поскольку LangChain предоставляет готовые интеграции, которые можно импортировать через выражения `from langchain_community.tools import PlaywrightTool`, `from langchain_community.tools import SeleniumTool` и т.д., после чего следует проверить их работоспособность через простые команды в интерактивной консоли Python, например создать объект `PlaywrightTool` с параметром `headless=False` и выполнить `tool.run('https://example.com')`, получив в ответ структурированные данные о найденных элементах страницы, а также синхронизировать их с пользовательским интерфейсом, открывая браузер в видимом режиме; следующий шаг – создастся файл с переменными окружения, обычно `.env`, где будут записаны секретные токены API, ключи доступа к внешним сервисам, такие как OpenAI, Google Cloud Vision, а также параметры для аутентификации в сервисах, используемых LangChain, чтобы обеспечить безопасный доступ к внешним моделям и API, и при этом необходимо добавить в `.env` строку `OPENAI_API_KEY=your_key_here`, а затем загрузить её через использование `python-dotenv` с командами `load_dotenv()` в начале скрипта; также важно настроить логирование (logging) в соответствии с best‑practice, указав уровень INFO или DEBUG, добавить форматтер, выводящий время, уровень и сообщение, чтобы отслеживать выполнение цепочек и возникающие ошибки, а дополнительно настроить сбор логов в файлы с ротацией, чтобы обеспечить长期 сохранность информации о работе агента; при подготовке к запуску первого агента в реальном времени рекомендуется создать базовый скрипт `agent_main.py`, который будет импортировать необходимые модули, инициализировать модели (например,ChatGPT или локальный LLM), загрузить конфигурацию инструментов, определить цель (например, собрать данные о цене товара на сайте), сформировать цепочку инструкций с использованием `SequentialChain` или `ZeroShotAgent`, заполнить её набором шагов, которые включают поиск в поисковой системе через `WikipediaSearchTool`, открытие браузера через `SeleniumTool`, извлечение данных через `ScrapeTool`, последующий анализ через `LLMMathCalculator` или `SQLDatabaseChain`, и в конце вернуть итоговый результат пользователю через встроенный `AgentExecutor` с поддержкой памяти (memory) для хранения контекста диалога; в этом процессе необходимо позаботиться о том, чтобы правильно определить переменные в системе, такие как `tool_names` и их алиасы, чтобы пользователь мог их вызывать в терминале, а также включить обработку исключений, чтобы при возникновении проблем, например, не найденного элемента на странице или таймаута, агент мог корректно логировать ошибку и предлагать повторный запуск или альтернативную стратегию; после того, как базовый скрипт достигнет рабочего состояния, следует провести тестирование всех возможных веток поведения, проверив как сценарии с успешным завершением, так и сценарии, требующие отката, перехода к другим инструментам или запроса у пользователя, что позволит выявить «узкие места» и подготовить документацию (README.md) с инструкциями по запуску, объяснениям параметров командной строки, рекомендациями по настройке окружения и примерами полезных запросов; дополнительно, в целях оптимизации и масштабирования, рекомендуется внедрить процесс сборки контейнеров (Docker) для воспроизводимости окружения, где в `Dockerfile` описаны базовые образы, копируются файлы проекта, устанавливаются зависимости, добавляются права доступа к ChromeDriver, указывается точка входа `CMD ["python","agent_main.py"]`, а также в `docker-compose.yml` описаны переменные окружения и том для логирования; в рамках подготовки к продакшн‑развёртыванию становится актуальным настройка мониторинга (Prometheus, Grafana) и централизованного логирования (ELK), чтобы отслеживать нагрузку на агента, частоту ошибок и время выполнения цепочек; все эти шаги по подготовке среды, установке Chrome и LangChain формируют фундаментальную базу, на которой будет построен полноценный AI‑агент, способный самостоятельно взаимодействовать с веб‑контентом, принимать решения на основе полученных данных и выполнять цепочки действий, предопределённые в проекте, при этом соблюдая строгие стандарты кодирования, безопасность данных и масштабируемость; однако, несмотря на тщательность подготовки, важно помнить, что конечный результат зависит от качества описаний целей, от точности настройки инструментов и от способности агента адаптировать стратегию в реальном времени под новые условия и ограничения, поэтому после завершения базовой установки следует перейти к детальному проектированию архитектуры агента, определению его ролей, целей и задач, а также написать небольшой но очень информативный раздел в документации «Что дальше?», где будет указано, как добавлять новые инструменты, улучшать память, интегрировать внешние API и обучать агента на новых примерах, чтобы постепенно превратить простую инфраструктуру в сложный, самодостаточный и масштабируемый AI‑сервис, который будет использовать возможности Chrome и LangChain для решения реальных бизнес‑проблем, таких как автоматизация закупок, мониторинг цен, проверка соответствия контента и т.д., при этом пользователь будет руководствоваться конкретными примерами кода, конфигурационных файлов, команд запуска и примерами вывода, чтобы без сложных размышлений сразу приступить к практической реализации, а значит, подготовка среды и установка Chrome и LangChain становятся первым и самым важным шагом, открывающим путь к созданию полноценного авtonomous AI‑агента, способного взаимодействовать с миром через браузерный интерфейс.
Глава 2. Основы работы с Chromium и Playwright
В этом разделе рассматривается полное построение браузерного AI‑агента, который использует возможности Chromium (через Playwright) и легко интегрируется в цепочки обработки данных, управляемые LangChain. Мы подробно опишем архитектуру, подготовку окружения, написание кода, обработку ошибок, оптимизацию производительности и механизмы масштабируемости, а также продемонстрируем несколько практических сценариев применения.
### 1. Почему комбинировать Chromium, Playwright и LangChain
Chromium предоставляет полностью программируемый движок рендеринга, позволяющий запускать браузер в «головном» или «фоновом» режиме без GUI, а Playwright добавляет к этому удобный API для контроля над страницами, элементами и сетью. Вместе они позволяют создавать автоматизированные скрипты, которые могут открывать веб‑страницы, извлекать Structured Data, взаимодействовать с динамическим контентом и выполнять действия, какие в обычном браузере делал человек.
LangChain же предоставляет фреймворк для построения цепочек (chains) и агентов, которые могут использовать внешние инструменты (tools) в качестве «действий». Подключив Playwright как инструмент к LangChain, мы получаем возможность формировать цепочки, где каждый шаг – это вызов браузера, а решение о дальнейшем движении агента принимается на основе LLM‑модели. Таким образом, LLM автоматически генерирует запрос к браузеру, а браузер возвращает результат, который снова передаётся в LLM для дальнейшего планирования.
Эта синергия делает возможным Creation of AI‑агентов, способных выполнять поиск, сбор информации, проверку форм, визуализацию и даже взаимодействие с API без прямого написания скриптов под каждый конкретный случай.
### 2. Установка и настройка окружения
Для начала требуется установить Python 3.11+ и несколько системных зависимостей.
```bash
# Обновление пакетов
sudo apt-get update && sudo apt-get upgrade -y
# Установка Chromium в режиме headless
sudo apt-get install -y chromium-browser
# Установка Playwright и его зависимостей
python -m pip install –upgrade pip
python -m pip install playwright
# Инициализация браузерных бинарников Playwright
python -m playwright install chromium
# Установка LangChain и вспомогательных пакетов
python -m pip install langchain[all] langchain-community chromadb unstructured tiktoken
```
После установки необходимо убедиться, что путь к исполняемому файлу Chromium доступен в переменной окружения `CHROME_PATH`.
```python
import os
os.environ["CHROME_PATH"] = "/usr/bin/chromium-browser"
```
Если вы используете контейнер Docker, в Dockerfile обычно добавляют:
```Dockerfile
FROM python:3.11-slim
# Установка Chromium и зависимостей
RUN apt-get update && apt-get install -y chromium-browser wget gnupg && \
wget -q -O – https://dl.google.com/linux/linux_signing_key.pub | apt-key add – && \
echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" > /etc/apt/sources.list.d/google-chrome.list && \
apt-get update && apt-get install -y google-chrome-stable && \
rm -rf /var/lib/apt/lists/*
# Установка Python‑зависимостей
COPY requirements.txt .
RUN pip install –no-cache-dir -r requirements.txt
# Установка браузерных бинарников Playwright
RUN python -m playwright install chromium
WORKDIR /app
COPY . .
CMD ["python", "main.py"]
```
### 3. Интеграция Playwright как инструмента в LangChain
LangChain позволяет объявлять кастомные инструменты, реализующие интерфейс `BaseTool`. Мы создадим класс `PlaywrightBrowserTool`, который будет инкапсулировать все операции с браузером.
```python
from langchain.tools import BaseTool
from playwright.sync_api import sync_playwright
import json
import time
class PlaywrightBrowserTool(BaseTool):
name = "playwright_browser"
description = """
Инструмент для управления headless‑Chromium через Playwright.
При необходимости вызывается с JSON‑параметрами:
– url: строка с адресом страницы
– query_selector: CSS‑селектор (по желанию)
– fill: словарь с полями для заполнения (по желанию)
– click: CSS‑селектор элемента для клика (по желанию)
– wait_until: строка, например 'networkidle' или 'domcontentloaded'
– screenshot: true/false, сохранить ли скриншот
– extract_text: true/false, выполнить извлечение текста
Возвращает JSON с результатом (HTML, скриншот в base64, ошибки).
"""
def __init__(self, headless: bool = True):
self.headless = headless
def _run(self, **kwargs) -> dict:
# Доступ к Playwright через контекст
with sync_playwright() as p:
browser = p.chromium.launch(headless=self.headless)
page = browser.new_page()
try:
url = kwargs.get("url")
if url:
page.goto(url, wait_until=kwargs.get("wait_until", "domcontentloaded"))
# Заполнение полей
fill_data = kwargs.get("fill")
if fill_data:
for selector, value in fill_data.items():
page.fill(selector, value)
# Клик по элементу
click_selector = kwargs.get("click")
if click_selector:
page.click(click_selector)
# Возможный скриншот
screenshot = kwargs.get("screenshot")
if screenshot:
screenshot_bytes = page.screenshot()
screenshot_b64 = base64.b64encode(screenshot_bytes).decode()
else:
screenshot_b64 = None
# Извлечение текста или HTML
extract_text = kwargs.get("extract_text")
if extract_text:
result = page.content()
else:
result = None
return {
"status": "ok",
"url": url,
"page_source": result,
"screenshot_b64": screenshot_b64,
}
except Exception as e:
return {"status": "error", "error": str(e)}
finally:
browser.close()
def _serialize(self):
return json.dumps({"headless": self.headless})
@classmethod
def _deserialize(cls, data):
return cls()
```
Данный инструмент полностью написан на синхронном API Playwright (для простоты), но его можно адаптировать под асинхронный режим с `asyncio`. Ключевой момент – передача JSON‑параметров через метод `_run`, который возвращает словарь, пригодный для последующей обработки LLM.
### 4. Создание агента с помощью LangChain Agent
В LangChain есть несколько реализаций агентов: `ZeroShotAgent`, `Chains` с `ToolCallingAgent` и более современный `AgentType`/`AgentExecutor`. Для нашего сценария удобно использовать `AgentType.CONVERSATIONAL_REACT_DECOMPOSE`.
```python
from langchain_experimental.agents import create_react_agent
from langchain_community.tools import Tool
from langchain_openai import ChatOpenAI
from langchain.prompts import PromptTemplate
# 1️⃣ Описание инструмента для LangChain
browse_tool = Tool(
name="Browse",
func=lambda input: PlaywrightBrowserTool()._run(**json.loads(input)),
description="Используйте для открытия веб‑страницы, навигации и извлечения данных."
)
# 2️⃣ Создание LLM‑модели
llm = ChatOpenAI(model="gpt-4o", temperature=0.2, streaming=True)
# 3️⃣ Формирование промпта для агента
agent_prompt = PromptTemplate.from_template("""
Ты – AI‑агент, способный управлять браузером через инструмент Browse.
Твоя задача – выполнить запрос пользователя, используя инструменты, доступные тебе.
Когда тебе нужно выполнить действие в браузере, выводи команду в формате JSON,
соответствующее полям инструмента (url, fill, click, wait_until, extract_text, screenshot).
Вопрос пользователя: {input}
Ответ:
""")
# 4️⃣ Создание агента
agent = create_react_agent(
llm=llm,
tools=[browse_tool],
prompt=agent_prompt,
verbose=True,
memory=None
)
# 5️⃣ Обёртка Executor
from langchain_experimental.agents import AgentExecutor
agent_executor = AgentExecutor(agent=agent, tools=[browse_tool], verbose=True)
```
После запуска `agent_executor.invoke({"input": "Открой https://ru.wikipedia.org/wiki/Искусственный_интеллект и извлеки первый абзац текста."})` агент сгенерирует JSON‑команду, передаст её в `PlaywrightBrowserTool`, получит HTML‑страницу, извлечёт абзац и вернёт его в виде окончательного ответа пользователю.
### 5. Практическая реализация: сценарии использования
#### 5.1. Скрапинг динамических страниц с подгрузкой контента
Многие сайты используют Infinite Scroll или React‑router, поэтому обычный `page.content()` не содержит полностью загруженного контента. В таком случае нужно выполнить скрипт прокрутки до тех пор, пока количество элементов не изменится.
```python
def infinite_scroll_and_extract(page, target_selector=".article-item"):
previous_height = 0
while True:
page.evaluate("window.scrollBy(0, document.body.scrollHeight)")
time.sleep(2)
new_height = page.evaluate("document.body.scrollHeight")
if new_height == previous_height:
break
previous_height = new_height
# После завершения скролла извлекаем содержимое
items = page.query_selector_all(target_selector)
texts = [item.inner_text() for item in items]
return "\n".join(texts)
```
Эту функцию можно добавить в `PlaywrightBrowserTool` как отдельный метод `scroll_and_extract`. При отработке агента запрос «Собери 10 последних статей из раздела новостей» будет автоматически преобразован в цепочку вызовов: открытие URL, скролл, извлечение текста, возврат результата в LLM.
#### 5.2. Автозаполнение форм и отправка данных
Для автоматизации взаимодействия с веб‑формами часто требуется ввести данные, выбрать вариант из выпадающего списка и отправить форму. Пример: заполнить форму заявки на вакансию на hh.ru.
```python
def fill_and_submit_form(page, form_data: dict, submit_selector=".submit-button"):
# Заполнение полей
for selector, value in form_data.items():
page.fill(selector, value)
# Ожидание элемента отправки
page.wait_for_selector(submit_selector)
page.click(submit_selector)
# Ожидание перехода к результату
page.wait_for_url("**/thanks*", timeout=10000)
```
Эту функцию можно добавить в `PlaywrightBrowserTool` под именем `fill_form`. Агент получив запрос «Заполнить форму заявки на hh.ru и отправить её», сформирует JSON‑структуру вида:
```json
{
"url": "https://hh.ru/vacancy/123456",
"fill": {
"input[name='name']": "Иван Петров",
"input[name='email']": "ivan@example.com",
"textarea[name='cover_letter']": "Уверен в своих силах…"
},
"click": ".submit-button",
"wait_until": "networkidle"
}
```
После выполнения агент получит подтверждение отправки, что можно передать дальше для анализа ответа сервера (например, наличие сообщения «Спасибо за заявку»).
#### 5.3. Сбор ценовых данных с динамических таблиц
Некоторые маркетплейсы отображают цены в виде таблиц, которые меняются без перезагрузки страницы. Для получения актуальных цен необходимо выполнить JavaScript‑запрос к элементам таблицы.
```python
def extract_price_table(page, table_css=".price-table"):
# Выполняем скрипт, который возвращает массив цен
prices = page.evaluate("""
() => {
const rows = document.querySelectorAll('.price-table tbody tr');
return Array.from(rows).map(r => r.innerText.trim());
}
""")
return prices
```
Эта функция может быть использована как часть цепочки «получить список цен», после чего LLM может проанализировать их, сравнить с историческими значениями и принять решение о покупке.
### 6. Управление ресурсами и масштабирование
#### 6.1. Параллельные запросы
Playwright позволяет открывать несколько контекстов в рамках одного процесса, но каждый контекст требует отдельного браузерного процесс‑потока. Чтобы эффективно обслуживать множество запросов одновременно, удобно использовать пул контекстов или отдельный сервис, который принимает задачи через очередь (Redis, RabbitMQ).
```python
from concurrent.futures import ThreadPoolExecutor
class BrowserPool:
def __init__(self, max_workers=4):
self.executor = ThreadPoolExecutor(max_workers=max_workers)
def run_task(self, func, **kwargs):
return self.executor.submit(func, **kwargs)
# Пример использования:
pool = BrowserPool(max_workers=8)
def browse_task(url, **params):
return PlaywrightBrowserTool()._run(url=url, **params)
result = pool.run_task(browse_task, url="https://example.com")
```
Таким образом, каждый запрос получает собственный браузерный контекст, а количество одновременных задач ограничено конфигурируемым параметром `max_workers`.
#### 6.2. Управление памятью и временем жизни
Одним из типичных проблем при длительной работе браузера является утечка памяти из‑за открытых страниц и контекстов. Регулярно закрывайте браузерные экземпляры и пере‑создавайте их. Для долгосрочных сервисов рекомендуется использовать `process`‑level restart каждые N запросов или при достижении определённого объёма потребления RAM (пример – 500 МБ).
#### 6.3. Отказоустойчивость
Идеальная архитектура подразумевает распределённые агенты, где каждый узел может «умереть» и автоматически восстановиться. Для этого храните состояние задачи (например, URL, параметры) в durable store (PostgreSQL или DynamoDB) и при восстановлении вызывайте очередной запрос.
### 7. Лучшие практики в написании AI‑агентов на основе LangChain и Playwright
1. **Сохраняйте запросы в лог** – храните входной запрос, сгенерированный JSON‑команду и полученный ответ. Это упрощает отладку и позволяет построить датасет для улучшения промптов.
2. **Избегайте «бесконечных» циклов** – в инструментах вроде скроллинга устанавливайте лимит количества итераций (например, 10 раз) и таймаут.
3. **Ограничивайте размер получения данных** – если требуется собрать большой объём текста, стройте пагинацию (offset/limit) вместо полного сканирования страницы.
4. **Контролируйте уровень привилегий** – запускайте браузер от имени ограниченного пользователя, чтобы минимизировать влияние потенциальных уязвимостей.
5. **Проверяйте политику сайта** – убедитесь, что ваш скрейпинг не нарушает `robots.txt` и условия использования.
6. **Тестируйте в headless‑режиме и в режиме с GUI** – в некоторых случаях UI‑элементы отображаются только в обычном режиме, тогда как в headless‑режиме могут возникать различия в размерах и координатах.
7. **Тестируйте резистивные изменения** – сайты часто меняют структуру CSS‑классов. Для устойчивого селектора используйте XPath с атрибутами или даже собственный парсер, который проверяет наличие нужного текста.
8. **Сохраняйте скриншоты при ошибках** – это упрощает диагностику проблем с загрузкой страницы или с отсутствием элементов.
### 8. Полный пример: «Собрать текущую стоимость биткоина в USD и вывести топ‑5 новостей из крупных финансовых источников»
```python
def ask_agent(task: str):
response = agent_executor.invoke({"input": task})
return response["output"]
# Пример запроса:
task = ("Открой https://coinmarketcap.com/, извлеки текущую цену биткоина в USD, "
"запиши её в переменную price, затем открой https://cointelegraph.com/ и "
"выведи первые 5 заголовков новостей, связанных с биткоином.")
answer = ask_agent(task)
print(answer)
```
В результате агент вернёт отформатированный ответ примерно такого вида:
```
Price of Bitcoin (USD): $27,845.12
Top 5 news headlines about Bitcoin:
1. "Institutional adoption of Bitcoin accelerates in 2025"
2. "Regulators propose new framework for crypto exchanges"
3. "Bitcoin mining becomes greener with renewable energy"
4. "Analysts predict bullish trend for Q4 2025"
5. "New layer‑2 solutions boost Bitcoin scalability"
```
Этот пример демонстрирует, как одна цепочка вызовов браузера может обслуживать несколько шагов, а каждое действие легко комбинировать с последующей обработкой в LLM.


