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

- -
- 100%
- +
Проверка поддержки 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


