Создание AI-агента на LangChain и OpenRouter
Создание AI-агента на LangChain и OpenRouter

Полная версия

Создание AI-агента на LangChain и OpenRouter

Язык: Русский
Год издания: 2026
Добавлена:
Настройки чтения
Размер шрифта
Высота строк
Поля
На страницу:
2 из 4

Проверка поддержки streaming. Для интерактивных сценариев полезен потоковый вывод. Если модель поддерживает streaming через OpenRouter, можно настроить постепенную выдачу токенов. В LangChain есть метод stream:

for chunk in model.stream([HumanMessage(content="Расскажи анекдот в три предложения.")]):

print(chunk.content, end="", flush=True)

Это улучшает восприятие пользователем длительных ответов.


Мониторинг и метрики. С самого начала собирайте метрики: число токенов, время выполнения, количество вызовов инструментов, количество итераций. Добавим простой трекер:

from dataclasses import dataclass

import time


@dataclass

class Metrics:

tokens_in: int = 0

tokens_out: int = 0

tool_calls: int = 0

duration_ms: int = 0


def track_metrics_start():

return {"start": time.time()}


def track_metrics_end(stats, metrics: Metrics):

metrics.duration_ms = int((time.time() – stats["start"]) * 1000)

return metrics

Заполнять поля tokens_in/tokens_out можно из ответов API, если модель возвращает usage. OpenRouter часто возвращает usage, если поддерживается провайдером. Мы будем использовать это для управления стоимостью.


Обработка ошибок и отказоустойчивость. Всегда оборачивайте вызовы модели и инструментов в try/except. При ошибке не прерывайте работу, а предлагайте альтернативу: повторить запрос, уточнить детали, переключить модель, использовать кешированный ответ. В LangChain есть встроенные механизмы повторных попыток и фолбэков – мы их добавим позже. Сейчас заложим привычку логировать ошибки и возвращать пользователю дружелюбное сообщение.


Версионирование промптов. Создайте в config/prompts.yaml файл с шаблонами:

system_agent: "Ты агент. Форматируй ответ. Не придумывай факты."

system_reflexion: "Проверь, соответствует ли ответ цели. Если нет, предложи корректировку."

system_tool_guidance: "Определи, нужен ли инструмент. Если да, выведи только вызов в формате tool:имя_инструмента|параметры."

Загружайте их в коде:

import yaml

with open("config/prompts.yaml") as f:

prompts = yaml.safe_load(f)

system = prompts["system_agent"]

Так вы сможете менять поведение без переписывания кода.


Первые шаги пользователя. После настройки окружения рекомендуем выполнить три упражнения, чтобы закрепить понимание:

1) Отправьте запрос без инструментов и убедитесь, что ответ приходит. Измените температуру и сравните результаты. 2) Добавьте инструмент поиска и попросите агента найти свежую информацию. Проверьте, что он использует результаты поиска. 3) Включите логирование и посмотрите, как формируются промежуточные сообщения. Попробуйте streaming-вывод для длинных ответов.


Когда переходить к следующей главе. Вы готовы к расширению агента, когда у вас:

– рабочее окружение и ключи;

– базовый вызов модели через LangChain;

– хотя бы один инструмент подключен;

– логирование и обработка ошибок;

– понимание формата промптов.


Заключение главы. Мы подготовили окружение для разработки AI-агента, настроили доступ к моделям через OpenRouter и создали базовые строительные блоки на LangChain. Вы получили минимального агента, способного отвечать на запросы, и набор инструментов для дальнейшего расширения. В следующих главах мы углубимся в архитектуру агента: как он мыслит, как выбирает инструменты, как хранит память и как корректирует свои действия. Мы заложим основы для надежного, масштабируемого и безопасного решения, которое можно адаптировать под любую задачу. А пока – проверьте, что все работает, и начните экспериментировать с простыми запросами. Успехов!


Глава 2. Установка и конфигурация LangChain и OpenRouter


Глава 2. Установка и конфигурация LangChain и OpenRouter

Добро плавать в практической разработке AI-агентов. Эта глава посвящена не только командам установки, но и пониманию экосистемы, выбору инструментов, настройке безопасного рабочего окружения и первой интеграции LangChain с OpenRouter. Мы пройдем весь путь от подготовки системы до написания первой цепочки, способной обращаться к моделям через единый API-интерфейс. Цель главы – создать надежный фундамент, на котором будут строиться сложные агенты.


Подготовка рабочего окружения

Прежде чем писать код, необходимо подготовить изолированную среду разработки. Работа с Python и его библиотеками требует осторожности: разные проекты могут зависеть от конфликтующих версий пакетов. Чтобы избежать проблем, мы будем использовать виртуальное окружение.


Если вы работаете на Linux или macOS:

1. Откройте терминал.

2. Создайте папку проекта: mkdir ai_agent_project && cd ai_agent_project.

3. Создайте виртуальное окружение: python3 -m venv venv.

4. Активируйте окружение: source venv/bin/activate.


Если вы работаете на Windows (PowerShell):

1. Создайте папку проекта: New-Item -ItemType Directory -Path "ai_agent_project"; Set-Location ai_agent_project.

2. Создайте виртуальное окружение: python -m venv venv.

3. Активируйте окружение: .\venv\Scripts\Activate.ps1. (Возможно, потребуется выполнить Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser для разрешения выполнения скриптов).


Если вы работаете на Windows (CMD):

1. md ai_agent_project && cd ai_agent_project.

2. python -m venv venv.

3. venv\Scripts\activate.


Внутри активированного окружения вы увидите префикс (venv) в начале строки терминала. Это означает, что все установленные пакеты будут изолированы от глобального пространства Python.


Установка Python и необходимых инструментов

Убедитесь, что у вас установлен Python версии 3.8 или выше. Рекомендуется версия 3.10 или 3.11 для лучшей совместимости с современными библиотеками AI. Проверить версию можно командой:

python –version


Обновление pip (пакетный менеджер) – обязательный шаг для избежания ошибок при установке сложных зависимостей:

pip install –upgrade pip


Для удобной работы с переменными окружения (API-ключами) установите python-dotenv:

pip install python-dotenv


Установка LangChain

LangChain – это экосистема, состоящая из множества пакетов. Начальная установка может сбить с толку из-за модульной структуры. Есть два пути: установка всех возможных компонентов сразу (не рекомендуется, так как создает тяжеловесную среду) или точечная установка необходимых модулей.


Для начала работы с OpenRouter и базовыми возможностями агента нам понадобится ядро библиотеки и клиент для работы с API.


Основной пакет:

pip install langchain


Важно понимать, что LangChain Core содержит базовые абстракции (цепочки, инструменты, агенты), но не содержит реализации подключения к конкретным LLM. Для работы с OpenRouter мы будем использовать стандартный клиент OpenAI, так как OpenRouter предоставляет совместимый API.


Также установим поддержку потоковой генерации (streaming) и логирование для отладки:

pip install langchain-core


В экосистеме LangChain 0.2.x и выше рекомендуется использовать пакет langchain-community для интеграций сторонних провайдеров, но для OpenRouter мы часто используем прямую совместимость с OpenAI SDK.


Для полноценной работы агента, который может использовать инструменты и планирование, установим дополнительные компоненты:

pip install langchain-openai # Если используем официальный клиент OpenAI как бэкенд для OpenRouter

pip install langgraph # Для построения агентов как графов (современный подход)

pip install numpy # Часто требуется для обработки данных и векторных операций

pip install requests # Для прямых HTTP запросов если потребуется


Примечание: В книге мы будем использовать подход "агента на графах" (LangGraph), так как это наиболее гибкий и прозрачный способ управления состоянием агента, его памятью и логикой переходов между задачами.


Установка OpenRouter

OpenRouter – это агрегатор моделей. У него нет собственной библиотеки Python, который нужно устанавливать отдельно. Взаимодействие с ним происходит через стандартный API, совместимый с OpenAI, или через обычные HTTP-запросы.


Однако для удобства можно установить клиент OpenAI SDK, так как OpenRouter полностью эмулирует его интерфейс:

pip install openai


Это не является обязательным для LangChain (так как LangChain имеет встроенные адаптеры), но полезно для отладки и прямых запросов.


Получение API-ключа OpenRouter

Без ключа API вы не сможете делать запросы к моделям.

1. Перейдите на сайт openrouter.ai.

2. Зарегистрируйтесь или войдите в аккаунт.

3. Перейдите в раздел "Keys" (Ключи).

4. Нажмите "Create Key" (Создать ключ).

5. Дайте ключу имя (например, "My Agent Project") и скопируйте его.

6. ВАЖНО: Сразу же сохраните ключ в безопасном месте. OpenRouter не покажет его вам снова.


Настройка переменных окружения (Security Best Practices)

Никогда не храните API-ключи прямо в коде (внутри .py файлов). Если вы случайно загрузите код на GitHub, ваши ключи будут украдены ботами в течение минут. Правильный способ – использовать переменные окружения.


В корне вашего проекта создайте файл .env. Имя файла начинается с точки.

В Linux/macOS: touch .env

В Windows (PowerShell): New-Item -ItemType File -Path ".env"


Откройте этот файл в любом текстовом редакторе и добавьте туда ваш ключ:

OPENROUTER_API_KEY=sk-or-v1-…ваш_длинный_ключ…


Также добавьте ссылку на базовый URL API OpenRouter:

OPENROUTER_API_BASE=https://openrouter.ai/api/v1


Чтобы эти переменные загружались в Python-скрипт автоматически, используйте код:

from dotenv import load_dotenv

load_dotenv()


Теперь мы готовы к написанию кода.


Первая связка: LangChain и OpenRouter

OpenRouter работает как прокси, перенаправляя запросы к различным моделям (GPT-4, Claude, Mistral, Llama и т.д.). Ключевая задача – правильно настроить LangChain, чтобы он отправлял запросы именно на URL OpenRouter с вашим ключом.


Создадим файл main.py. Разберем два способа подключения: через ChatOpenAI (рекомендуемый) и через прямой вызов.


Способ 1: Использование ChatOpenAI (LangChain OpenAI Wrapper)

Этот способ удобен, так как сохраняет все преимущества LangChain (простые промпты, форматирование сообщений, потоковую передачу данных).


Создайте файл setup_check.py и вставьте следующий код:


import os

from dotenv import load_dotenv

from langchain_openai import ChatOpenAI

from langchain_core.messages import HumanMessage


# Загружаем переменные из .env

load_dotenv()


# Получаем ключ и URL

api_key = os.getenv("OPENROUTER_API_KEY")

api_base = os.getenv("OPENROUTER_API_BASE")


if not api_key:

raise ValueError("API ключ не найден! Убедитесь, что вы создали .env файл и добавили OPENROUTER_API_KEY.")


# Инициализация модели через LangChain

# Обратите внимание на параметр base_url – это критически важно для OpenRouter

llm = ChatOpenAI(

model="openai/gpt-4o-mini", # Пример модели. Формат: провайдер/модель

openai_api_key=api_key,

openai_api_base=api_base,

temperature=0.7

)


# Простой запрос

message = HumanMessage(content="Привет! Ты работаешь через OpenRouter?")

response = llm.invoke([message])


print("Ответ агента:")

print(response.content)


# Проверка потоковой передачи (Streaming)

print("\n– Проверка потоковой передачи –")

for chunk in llm.stream([HumanMessage(content="Расскажи короткую историю о коте, который использует Python.")]):

print(chunk.content, end="", flush=True)


Объяснение кода:

1. load_dotenv() загружает ваши ключи.

2. ChatOpenAI – это класс-обертка над стандартным API LLM.

3. Параметр openai_api_base указывает на адрес сервера OpenRouter.

4. openai_api_key использует ваш ключ авторизации.

5. Метод .invoke() делает единичный запрос и возвращает полный ответ.

6. Метод .stream() позволяет получать ответ по кусочкам (токенам), что критично для интерактивных интерфейсов.


Если при запуске python setup_check.py вы получили ответ от агента – поздравляю, связка работает!


Способ 2: Прямой вызов через LangChain (BaseChatModel)

Иногда требуется более низкоуровневый контроль или исключение лишних зависимостей. Мы можем использовать класс ChatOpenAI из langchain_openai, но настроить его вручную. Мы уже сделали это выше.


Важный нюанс: форматы моделей.

OpenRouter поддерживает тысячи моделей. Чтобы использовать конкретную, нужно знать ее идентификатор.

Примеры идентификаторов:

– openai/gpt-4-turbo-preview

– anthropic/claude-3-opus:beta

– meta-llama/llama-3-8b-instruct

– google/gemini-pro-1.5


Полный список доступен в документации OpenRouter. Если вы укажете несуществующую модель, OpenRouter вернет ошибку.


Конфигурация продвинутых параметров модели

При создании экземпляра ChatOpenAI можно передать множество параметров, влияющих на поведение агента:


llm = ChatOpenAI(

model="openai/gpt-4o-mini",

openai_api_key=api_key,

openai_api_base=api_base,

temperature=0.1, # Детерминированность (0 – строгий логик, 1 – творчество/хаос)

max_tokens=1024, # Ограничение на длину ответа

top_p=0.9, # Альтернативный метод фильтрации токенов (ядерная выборка)

frequency_penalty=0.5, # Штраф за повторение фраз (от -2.0 до 2.0)

presence_penalty=0.5, # Штраф за новые темы (от -2.0 до 2.0)

request_timeout=20 # Таймаут ожидания ответа в секундах

)


Настройка температуры для агентов

Для агентов, выполняющих задачи (Code Runner, Data Analyst), температура должна быть близка к 0 (например, 0.0 – 0.2). Это минимизирует галлюцинации и делает ответы предсказуемыми.

Для творческих агентов (Копирайтер, Поэт) используйте 0.7 – 1.0.


Создание цепочки (Chain) с использованием промптов

Теперь, когда мы умеем инициализировать модель, давайте создадим простейшую цепочку, которая берет входные данные, форматирует их и передает модели. Это основа любого агента.


Используем LangChain PromptTemplate для динамического создания промптов.


Импортируем необходимые модули:

from langchain_core.prompts import ChatPromptTemplate

from langchain_core.output_parsers import StrOutputParser


Создадим шаблон промпта:

prompt = ChatPromptTemplate.from_messages([

("system", "Ты полезный ассистент, который отвечает на русском языке."),

("human", "{input}") # {input} – это переменная, которую мы будем подставлять

])


Соберем цепочку (Chain):

chain = prompt | llm | StrOutputParser()


Здесь используется оператор | (пайп), который объединяет компоненты:

1. prompt: создает структуру сообщения.

2. llm: отправляет в модель.

3. StrOutputParser(): извлекает текстовое содержимое из ответа модели (убирает внутреннюю структуру объекта Message).


Запуск цепочки:

result = chain.invoke({"input": "Что такое гравитация, объясни как пятилетнему ребенку?"})

print(result)


Использование StrOutputParser() важно для чистоты кода, так как возвращает строку вместо объекта AIMessage.


Интеграция инструментов (Tools) с OpenRouter

Агент – это не просто модель, отвечающая на вопросы. Агент способен вызывать функции, искать информацию и выполнять код. В LangChain инструменты (Tools) – это функции, которые модель может вызвать по своему усмотрению.


Давайте создадим инструмент-калькулятор. Даже если модель GPT-4 умеет считать в уме, использование инструмента гарантирует точность (через выполнение Python-кода) и демонстрирует архитектуру агента.


Шаг 1: Определение функции и инструмента

from langchain_core.tools import tool


@tool

def multiply(a: int, b: int) -> int:

"""Умножает два целых числа."""

return a * b


Шаг 2: Подключение инструментов к модели

Агенту нужно знать, какие инструменты у него есть, и когда их использовать.


from langchain.agents import create_tool_calling_agent, AgentExecutor


# Список инструментов

tools = [multiply]


# Шаблон промпта для агента (он отличается от простого промпта)

from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder


agent_prompt = ChatPromptTemplate.from_messages([

("system", "Ты полезный математик. Используй доступные инструменты для точного решения задач."),

("human", "{input}"),

MessagesPlaceholder(variable_name="agent_scratchpad"), # Сюда будут записываться шаги мысли агента

])


# Создание агента

agent = create_tool_calling_agent(llm, tools, agent_prompt)


# Создание исполнителя

agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)


# Запуск

response = agent_executor.invoke({"input": "Сколько будет 123 умножить на 456?"})

print(response['output'])


В этом коде:

1. create_tool_calling_agent создает агента, который умеет вызывать функции.

2. AgentExecutor управляет циклом "Решение -> Вызов инструмента -> Получение результата -> Формирование ответа".

3. Параметр verbose=True позволяет видеть в консоли логи вызова инструментов.


Сборка полноценного агента с OpenRouter и LangGraph

Классический AgentExecutor (используемый выше) постепенно устаревает. Современный стандарт – использование LangGraph. Это позволяет явно описывать граф состояний агента.


Давайте построим простого агента на LangGraph, который работает с OpenRouter.


Потребуется установка:

pip install langgraph


Создадим файл agent_graph.py:


import os

from dotenv import load_dotenv

from typing import Literal

from langchain_openai import ChatOpenAI

from langchain_core.tools import tool

from langgraph.prebuilt import create_react_agent

from langchain_core.messages import HumanMessage


# Настройка LLM (OpenRouter)

load_dotenv()

llm = ChatOpenAI(

model="openai/gpt-4o-mini",

openai_api_key=os.getenv("OPENROUTER_API_KEY"),

openai_api_base=os.getenv("OPENROUTER_API_BASE")

)


# Инструменты

@tool

def get_weather(city: str) -> str:

"""Получает текущую погоду в городе. Просто заглушка для примера."""

return f"В городе {city} солнечно и +25°C."


@tool

def get_stock_price(ticker: str) -> str:

"""Получает цену акции по тикеру."""

return f"Цена акции {ticker} сегодня выросла на 5%."


tools = [get_weather, get_stock_price]


# Создание агента LangGraph (React Agent – Reasoning and Acting)

# Этот агент следует циклу: Thought -> Act -> Observation -> Thought…

graph = create_react_agent(llm, tools)


# Интерфейс запуска

def run_agent(question: str):

inputs = {"messages": [HumanMessage(content=question)]}

print(f"Вопрос: {question}")


# Запуск графа потоком

for event in graph.stream(inputs, stream_mode="values"):

if "messages" in event:

last_msg = event["messages"][-1]

if isinstance(last_msg, HumanMessage):

print(f"\nUser: {last_msg.content}")

else:

print(f"\nAgent: {last_msg.content}")


if __name__ == "__main__":

# Пример сложного запроса, требующего нескольких инструментов

run_agent("Какая погода в Лондоне и сколько стоит акция AAPL?")


Разбор кода:

1. create_react_agent – это высокоуровневая функция, создающая готовый граф логики "Реакции" (ReAct). Она автоматически добавляет узлы для планирования и вызова инструментов.

2. graph.stream – позволяет в реальном времени выводить шаги агента.

3. В примере агент должен выбрать: сначала узнать погоду, потом цену акции, либо наоборот.


Почему LangGraph лучше?

– Прозрачность: вы видите каждый шаг.

– Контроль: можно вручную добавлять узлы (например, "Проверка безопасности", "Сохранение в БД").

– Поддержка потоковой передачи (streaming) агентов "из коробки".


Типичные ошибки при настройке и их решение


1. Ошибка 401 Unauthorized / Invalid API Key

Причина: Неверный ключ или отсутствие переменной окружения.

Решение: Проверьте файл .env. Убедитесь, что вы не скопировали лишние пробелы. Проверьте, что load_dotenv() вызывается до использования os.getenv().


2. Ошибка 404 Not Found (Model not found)

Причина: Неправильное имя модели в параметре model=.

Решение: Загляните в документацию OpenRouter. Имена чувствительны к регистру и слэшам. Попробуйте упростить имя (например, "openai/gpt-3.5-turbo").


3. Ошибка 402 Payment Required

Причина: На счету OpenRouter недостаточно средств.

Решение: Пополните баланс в личном кабинете OpenRouter. Некоторые модели (например, GPT-4) требуют предоплаты или имеют высокую стоимость запросов.


4. Ошибка AttributeError: 'NoneType' object has no attribute 'content'

Причина: Модель вернула пустой ответ или произошла ошибка парсинга.

Решение: Убедитесь, что вы используете StrOutputParser() или правильно извлекаете content из ответа.


5. Ограничения контекста (Context Window Exceeded)

Причина: История диалога стала слишком длинной для модели.

Решение: Используйте окна памяти (Memory) в LangChain, например ConversationBufferWindowMemory, чтобы сохранять только последние N сообщений.


Настройка продвинутых параметров OpenRouter

OpenRouter позволяет использовать специальные параметры через заголовки или передачу параметров. Например, можно принудительно использовать только определенные провайдеры или настроить "приставку" (prefix) для системных сообщений.


В LangChain при использовании ChatOpenAI мы можем передать дополнительные параметры через `extra_headers` или `extra_body`, если это поддерживается оберткой. Однако, базовые настройки (temperature, top_p) работают стандартно.


Если вам нужно использовать параметр `route`, который позволяет OpenRouter выбирать лучший провайдер автоматически, это часто происходит по умолчанию, если вы не указываете конкретную модель. Но для агентов рекомендуется жестко фиксировать модель (например, "openai/gpt-4o-mini") для стабильности работы инструментов.


Работа с системными промптами

Системный промпт – это инструкция, которая задает поведение всей цепочки. В OpenRouter это реализуется как роль `system`. В LangChain вы задаете это в ChatPromptTemplate.


Пример системного промпта для агента:

"Ты – helpful ассистент. Твоя задача – отвечать на вопросы пользователя точно и кратко. Если вопрос требует использования инструментов, ты обязан их использовать. Не придумывай факты, которые ты не можешь проверить."


Важно: Модели имеют разную чувствительность к системным промптам. Модели на базе Llama (Meta) часто требуют иного форматирования, чем GPT. OpenRouter старается стандартизировать это, но будьте готовы к экспериментам.


Модульная архитектура LangChain: что устанавливать?

В экосистеме LangChain происходит активное разграничение пакетов.

– `langchain-core`: Базовые абстракции. Обязателен.

– `langchain`: Старая "монолитная" библиотека. Сейчас часто не требуется, если не используете старые агенты.

– `langchain-community`: Интеграции с провайдерами (не OpenAI).

– `langchain-openai`: Специфичные интеграции для OpenAI (и OpenRouter).

– `langgraph`: Построение графов агентов.


Для этой книги мы рекомендуем структуру зависимостей:

```

langchain-core

langchain-openai

langgraph

python-dotenv

```

Если вы устанавливаете `langchain`, вы автоматически тянете много лишнего. Лучше установить точечные пакеты.


Пример полного кода инициализации агента с проверкой версий

Чтобы убедиться, что все работает, создадим скрипт `diagnostics.py`:


import langchain

import langchain_openai

import sys


print(f"Python version: {sys.version}")

print(f"LangChain version: {langchain.__version__ if hasattr(langchain, '__version__') else 'Not installed'}")

print(f"LangChain OpenAI version: {langchain_openai.__version__ if hasattr(langchain_openai, '__version__') else 'Not installed'}")


# Проверка ключа

from dotenv import load_dotenv

На страницу:
2 из 4