Read the book: «Практическая реализация AI-агента в Chrome с LangChain»
Глава 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` и условия использования.
The free sample has ended.