Инженер
Практическая реализация 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` и условия использования.

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.

### 9. Развёртывание в продакшн‑окружении

Для реального продукта необходимо Packaging‑упаковать весь код в Docker‑контейнер и разместить за reverse‑proxy (NGINX) с поддержкой HTTP/2.

**Dockerfile** (минимальная конфигурация)

```Dockerfile

FROM python:3.11-slim

# Установка системных зависимостей

RUN apt-get update && apt-get install -y –no-install-recommends \

chromium-browser \

wget \

ca-certificates \

&& rm -rf /var/lib/apt/lists/*

# Копирование зависимостей и кода

WORKDIR /app

COPY requirements.txt .

RUN pip install –no-cache-dir -r requirements.txt

# Установка браузерных бинарников Playwright

RUN python -m playwright install chromium

# Копирование проекта

COPY . .

# Параметры окружения

ENV CHROME_PATH=/usr/bin/chromium-browser

# Запуск приложения

CMD ["python", "main.py"]

```

В `docker-compose.yml` добавляем ограничения ресурсов и стратегии перезапуска:

```yaml

services:

browser-agent:

build: .

restart: unless-stopped

deploy:

resources:

limits:

cpus: "2"

memory: "2g"

environment:

– OPENAI_API_KEY=${OPENAI_API_KEY}

– CHROME_PATH=/usr/bin/chromium-browser

ports:

– "8000:8000"

```

После деплоя каждый запрос от клиента попадает в FastAPI‑эндпоинт, который вызывает `agent_executor.invoke`. Это позволяет масштабировать сервис горизонтально, добавляя новые реплики в Kubernetes.

### 10. Заключение

В результате этой главы мы вывели полную картину того, как собрать AI‑агент на базе LangChain, который использует Chromium через Playwright для взаимодействия с веб‑страницами. Мы начали с установки окружения, продвинулись до создания кастомного инструмента, построили агента, продемонстрировали несколько реальных сценариев (скроллинг, заполнение форм, извлечение динамических данных) и завершили описанием подходов к масштабированию и развертыванию в продакшн.

Ключевые идеи, которые следует помнить:

* LangChain предоставляет гибкую модель агента, позволяющую интерпретировать естественный язык как команду для браузера.

* Playwright дает мощный и надёжный способ контроля над Chromium, включая работу в headless‑режиме, управление сетью и скриншоты.

* Интеграция инструмента в виде JSON‑команды делает процесс полностью детерминированным и удобным для отладки.

* Продвинутая архитектура (пул контекстов, очередь задач, долговечное хранилище) позволяет построить масштабируемый сервис, который будет работать в условиях высокой нагрузки.

С этой базой вы можете переходить к более сложным проектам: от автоматизации поиска вакансий и составления резюме до построения аналитических панелей, собирающих данные из десятков источников в реальном времени. Основы уже заложены, а дальше – лишь творчество и уточнение требований к вашему конкретному сценарию.

Глава 3. Создание экземпляра LLM в браузере

Создание экземпляра LLM в браузере представляет собой ключевой шаг в практической реализации AI‑агентов с помощью LangChain, поскольку именно в этом месте происходит переход от поиска и подготовки данных к непосредственному использованию модели для генерации ответов, планирования действий и взаимодействия с пользователем; в данном разделе мы подробно рассмотрим, как собрать и запустить локальную или облачную LLM напрямую в окружении Chrome, используя возможности WebAssembly, промисы и динамические импорты, а также как интегрировать её в цепочку происходящих в браузере вычислений через LangChain.

Первым делом нужно выбрать подходящий движок модели, который может работать в клиентском JavaScript‑окружении; наиболее популярными являются проекты, такие как GGUF‑формат модели с поддержкой llama.cpp, а также специализированные библиотеки вроде of‑the‑shelf‑transformers‑js, которые предоставляют готовые обёртки над TensorFlow.js и ONNX‑runtime‑web. Для целей демонстрации возьмём небольшую модель «Phi‑2» (≈256 МБ в GGUF‑формате), поскольку она достаточно лёгка, чтобы полностью загрузиться в память браузера без превышения обычных ограничений на размер скриптов и ресурсов. Загрузка модели осуществляется асинхронно через fetch API, после чего её байты конвертируются в бинарный буфер, из которого создаётся внутренний объект llama.cpp‑engine, экспортируемый в виде WebAssembly‑модуля.

В коде мы начинаем с импорта необходимых модулей LangChain:

```javascript

import { LLM } from "langchain/llms";

import { PromptTemplate } from "langchain/prompts";

import { AgentType } from "langchain/agents";

```

а затем объявляем собственный класс `BrowserLLM`, наследующий от `LLM` базового класса LangChain и реализующий требуемый интерфейс `generate(prompt: string) : Promise<string>`. Внутри конструктора мы инициализируем трансформер модели, указываем путь к файлу `.bin` (например, `"phi2-q4_0.gguf"`), и запускаем асинхронную функцию `loadModel` которая загружает весовые данные через `fetch`, начинает трансформацию в `Wasm.Decoder` и сохраняет ссылку на готовый `llamaEngine` в поле инстанса; важно добавить обработчики прогресса и ошибок, чтобы пользователь видел индикатор загрузки и мог отменить процесс, если он оказался слишком тяжёлым для конкретного устройства.

После того как модель полностью готова, метод `generate` принимает строку‑запрос, формирует её в виде токенов с помощью встроенного токенизатора (в нашем случае токенизатор, экспортированный из той же скачанной модели), передаёт массив токенов в `llamaEngine.evaluate(promptTokens, maxNewTokens, temperature, topP)`, ждёт завершения вычислений через `await engine.run(…)`, получает обратно массив новых токенов, преобразует их в строку и возвращает её как результат. Этот метод автоматически использует `Promise` и поэтому полностью совместим с цепочками `then`/`await`, что делает его идеальным для использования в агентах LangChain, где каждый шаг обработки может быть асинхронным и зависеть от внешних запросов.

Конец ознакомительного фрагмента.

Текст предоставлен ООО «Литрес».

Прочитайте эту книгу целиком, купив полную легальную версию на Литрес.

Безопасно оплатить книгу можно банковской картой Visa, MasterCard, Maestro, со счета мобильного телефона, с платежного терминала, в салоне МТС или Связной, через PayPal, WebMoney, Яндекс.Деньги, QIWI Кошелек, бонусными картами или другим удобным Вам способом.