Kitobni o'qish: «Создание AI-агента на LangChain и OpenRouter»
Глава 1. Введение и настройка окружения
Введение и настройка окружения
Добро пожаловать в практическое руководство по созданию интеллектуальных агентов на стыке мощи крупных языковых моделей и гибкости современных фреймворков. Эта книга посвящена тому, как объединить доступ к сотням моделей через единый концентратор OpenRouter и модульную экосистему LangChain для построения надежных, autonomных и полезных агентов. Здесь мы не просто разберем теорию, а последовательно пройдем все этапы: от настройки окружения и понимания архитектуры до реализации сложных сценариев с планированием, инструментами, долгосрочной памятью, устойчивостью к ошибкам и безопасностью. Если ваша цель – превратить потенциал современного ИИ в рабочий инструмент, который выполняет задачи, взаимодействует с внешним миром и масштабируется в продакшене, вы на верном пути.
Зачем нужен такой подход. Мир LLM переживает взрывной рост: появляются новые модели, улучшаются возможности, снижается стоимость. Но простой вызов модели с промптом уже недостаточен для решения реальных задач. Реальность требует структуры: агент должен разбивать сложную задачу на подзадачи, выбирать инструменты, запоминать контекст, корректировать поведение и взаимодействовать с API, базами данных и внешними сервисами. OpenRouter дает вам ключи к множеству моделей через единый интерфейс, устраняя фрагментацию провайдеров и упрощая эксперименты. LangChain предоставляет строительные блоки для цепочек, агентов, инструментов и памяти, позволяя собирать из этих блоков надежные системы. Вместе они образуют связку, которая делает разработку практичной, гибкой и воспроизводимой.
Ключевые идеи и обещания книги. Мы будем подходить к созданию агентов системно: проектировать логику, выбираем модели под задачу, настраиваем стабильные цепочки, встроим инструменты, отладим ошибки и подготовим к работе под нагрузкой. Вы увидите, как превратить «разговорную» модель в исполнителя команд, который может проводить вычисления, искать данные, хранить историю и корректировать свои действия. Мы будем использовать практические примеры: от простых агентов-помощников до многопроцессных конвейеров с очередями и дашбордами. Особое внимание уделим качеству промптов, стабильности работы и безопасности: как не допустить утечек данных, как ограничить действия агента и как контролировать ресурсы.
Структура книги. Первая часть посвящена основам: знакомству с OpenRouter, LangChain и настройке окружения. Вторая часть посвящена архитектуре агента: циклу размышлений, планированию, выбору инструментов, обработке ошибок и рефлексии. Третья часть фокусируется на интеграциях: базы данных, файловые системы, веб-скрапинг, вызовы внешних API, обработка документов. Четвертая часть – про производительность и надежность: кеширование, параллелизация, логирование, метрики, тестирование. Пятая часть – про безопасность и соответствие требованиям: валидация ввода, изоляция исполнения, ограничение прав, мониторинг. Шестая часть – продвинутые сценарии: мультиагентные системы, обучение на собственных данных, настройка под конкретные вертикали. В каждой главе есть код, примеры конфигураций, чек-листы и практические советы.
Ожидания и целевая аудитория. Книга рассчитана на разработчиков, инженеров данных, продакт-менеджеров и технических лидеров, которые хотят создавать рабочие AI-агенты. Предполагается знакомство с Python и базовыми понятиями API, но сложные моменты мы объясняем по ходу дела. Если вы новичок, начинайте с главы по настройке и медленно продвигайтесь, повторяя примеры. Если вы опытный инженер, вам будут интересны главы про масштабирование, надежность и безопасность – там мы затрагиваем архитектурные решения для продакшена.
Основные понятия. Агент – программа, которая получает цель, разбивает её на шаги, использует инструменты и принимает решения на основе выводов модели. Инструмент – внешняя функция или API, которую агент может вызвать для получения информации или выполнения действия. Цепочка – последовательность шагов, которые выполняются для получения результата. Память – способ сохранять контекст между вызовами, чтобы агент помнил предыдущие действия и пользовательские данные. Планировщик – компонент, который формирует план действий и корректирует его по мере поступления новой информации. Рефлексия – механизм, с помощью которого агент анализирует свои ошибки и улучшает дальнейшие шаги. OpenRouter – агрегатор моделей, предоставляющий доступ к разным LLM через единый API. LangChain – фреймворк для построения цепочек, агентов и инструментов.
Почему OpenRouter и LangChain. OpenRouter позволяет оперативно переключаться между моделями, сравнивать их производительность, управлять квотами и токенами без кастомной интеграции под каждый провайдер. Это экономит время и дает гибкость: можно использовать легкие модели для простых задач и мощные модели для сложных размышлений, распределять нагрузку и бюджет. LangChain, в свою очередь, предоставляет богатую экосистему: загрузчики документов, сплиттеры, векторные хранилища, инструменты, готовые агенты и интеграции. Он позволяет описывать логику в декларативном стиле, но при этом оставляет контроль над низкоуровневыми деталями. Связка OpenRouter + LangChain дает вам универсальность моделей и структуру для их эффективного использования.
Первые шаги, которые мы сделаем вместе. Мы настроим виртуальное окружение, установим зависимости, заведем ключи OpenRouter и проверим подключение к модели. Затем создадим минимального агента: примем запрос от пользователя, выберем инструмент, получим результат и отформатируем ответ. После этого добавим память, чтобы агент мог работать в диалоге, и расширим функционал: добавим планировщик и рефлексию. Мы подключим внешние инструменты – например, запросы к веб–API, поиск по базе данных, чтение файлов. Научимся обрабатывать ошибки, ограничивать число шагов, логировать промежуточные состояния и тестировать цепочки. И наконец, подготовим продакшен-версию: контейнеризацию, переменные окружения, обработку лимитов, мониторинг и дашборд.
Архитектурные рекомендации. Агент должен быть профилирован: четко определите его роль, допустимые инструменты и границы поведения. Используйте модульность: отдельные модули для промптов, инструментов, памяти, планировщика и мониторинга. Сделайте промпты управляемыми через шаблоны и версионируйте их. Предусмотрите механизмы fallback: если основная модель не отвечает, переключитесь на более легкую или используйте заглушку. Внедрите рефлексию: на каждом шаге анализируйте, удалось ли достичь цели, и корректируйте план. Собирайте телеметрию: токены, время ответа, количество вызовов инструментов, ошибки. Соблюдайте безопасность: валидируйте ввод, ограничивайте доступ к инструментам, изолируйте выполнение, храните секреты в защищенном хранилище.
Типичные сценарии использования. Автоматизация рутинных задач: ответы на запросы пользователей, классификация тикетов, составление отчетов. Аналитика: извлечение данных из документов, обобщение, построение выдержек и ответов с ссылками. Работа с данными: запросы к CRM, обновление записей, создание задач в таск-менеджерах. Разработка: генерация кода по описанию, отладка, документирование. Исследование: поиск информации, реферирование, проверка гипотез. Обучение: создание обучающих материалов, тестирование знаний, персонализация.
Ограничения и риски. Модели могут галлюцинировать, инструменты могут возвращать неожиданные результаты, внешние API могут падать. Важно проектировать систему с учетом этих рисков: добавлять валидацию результатов инструментов, просить модель проверять свои выводы, ограничивать число попыток, поддерживать человеко-вмешательство в критических сценариях. Не доверяйте агенту выполнять необратимые действия без подтверждения. Используйте песочницу для опасных операций. Соблюдайте регуляторные требования при работе с персональными данными.
Чек-лист успеха на старте. Определите цель агента и критерии успеха. Выберите стартовую модель через OpenRouter. Подготовите ключи API и переменные окружения. Напишите простой цикл: запрос -> планировщик -> выбор инструмента -> выполнение -> ответ. Добавьте память для диалога. Внедрите логирование и базовую рефлексию. Протестируйте на 10–20 разнообразных запросах. Замерьте метрики: точность, токены, время, стоимость. Сделайте бэкап промптов и конфигураций. Начните с ограниченного круга пользователей и соберите обратную связь.
Тонкости формулировок. Хороший промпт – это не просто вопрос, а инструкция, которая задает роль, формат вывода, критерии принятия решений и ограничения. Мы будем много работать с шаблонами промптов, чтобы агент четко следовал схеме: структурировать мысль, определить план, выполнить шаги, проверить результат. В LangChain есть удобные примитивы для этого: системные сообщения, few-shot примеры, разделение на шаги. Мы будем использовать их для повышения стабильности.
План работы над ошибками. С самого начала мы заложим практику: логирование всех промежуточных состояний, сохранение «хлебных крошек» по пути агента, трассировку вызовов инструментов, трекинг токенов. Если агент зацикливается, мы введем ограничение на число итераций. Если ответ не соответствует формату – валидация и повторный запрос с уточнением. Если инструмент падает – fallback и альтернативный способ решения. Мы будем строить устойчивую систему, а не просто «рабочий скрипт».
Экономика. Стоимость токенов и вызовов API влияет на архитектуру. Мы покажем, как выбирать модель под задачу: тяжелые модели для планирования и рефлексии, легкие для форматирования и простых ответов. Обсудим кеширование повторяющихся запросов, батчинг, снижение числа вызовов за счет более четких промптов. OpenRouter позволяет легко мониторить расходы – мы интегрируем эти метрики в нашу систему.
Качество и UX. Ответы агента должны быть понятными, структурированными и полезными. Мы будем учить форматировать выводы, прикреплять источники, четко обозначать неопределенности. Пользователь должен видеть, почему агент выбрал тот или иной инструмент, и иметь возможность запросить подробности. Мы добавим режимы «показать мысль» и «краткий ответ», а также подтверждение для опасных действий.
Производительность. Мы рассмотрим асинхронность, очереди задач, балансировку нагрузки между моделями, ограничение параллельных вызовов, таймауты. Для долгих операций мы сделаем фоновые задачи и статусы выполнения. Для интерактивных сценариев – streaming ответы и прогресс-бары. Мы подойдем к этому как инженеры: с профилированием, бенчмарками и оптимизациями.
Безопасность и соответствие. Мы будем избегать хранения чувствительных данных в промптах, использовать переменные окружения и секрет-менеджеры, валидировать ввод и вывод, ограничивать доступ к инструментам. Мы обсудим политики, когда необходимо участие человека, и как аудировать действия агента. Это важно не только для соответствия регламентам, но и для выстраивания доверия пользователей.
Культура разработки. Внедрим ревью промптов, версионирование конфигураций, тесты для цепочек, интеграционные тесты для инструментов, дашборды для мониторинга. Мы будем подходить к агенту как к системе, требующей поддержки и улучшений. Инструменты, которые мы используем, будут открытыми и стандартными, чтобы вы могли легко адаптировать их под свой стек.
Давайте резюмируем. Ваш агент будет получать задачу, разбивать её на шаги, выбирать инструменты через LangChain, обращаться к моделям через OpenRouter, хранить историю, корректировать себя по мере работы и возвращать структурированный результат. Мы будем строить его так, чтобы он был стабильным, безопасным, понятным и экономичным. Каждый этап будет подкреплен примерами кода, конфигурациями и чек-листами. Итогом станет не просто прототип, а готовая к использованию система, которую можно масштабировать и поддерживать.
Начальная дорожная карта. После этой главы мы сразу перейдем к настройке окружения и первого запуска. В ближайших главах построим минимального агента, добавим память и инструменты, затем улучшим стабильность и надежность. Параллельно мы будем отвечать на вопросы: как выбирать модель, как писать эффективные промпты, как тестировать и как готовить систему к продакшену. Вы сможете повторять примеры шаг за шагом и в конце получить работающего агента под ваши задачи.
Поехали. Следующий шаг – подготовка окружения, установка зависимостей и первый запрос к модели через OpenRouter в контексте LangChain.
Переходим к практической части. Начнем с подготовки рабочего места: установим Python, создадим виртуальное окружение, установим необходимые библиотеки, настроим переменные окружения и проверим базовый вызов модели через OpenRouter в LangChain. Мы будем использовать современные подходы, чтобы сразу заложить основу для надежного агента.
Установка Python и виртуальное окружение. Рекомендуем версию Python 3.10 или новее. Проверьте версию:
python –version
Если у вас несколько версий, используйте явный вызов через python3. Создайте каталог проекта и активируйте виртуальное окружение:
mkdir ai_agent_project
cd ai_agent_project
python -m venv .venv
Активация в Linux/macOS:
source .venv/bin/activate
Активация в Windows:
.venv\Scripts\activate
Обновите pip:
pip install –upgrade pip
Установка LangChain и интеграций. Начнем с основных пакетов:
pip install langchain langchain-core langchain-community
Пакет langchain-community содержит множество инструментов и интеграций. Для работы с OpenRouter мы будем использовать стандартные HTTP-вызовы или готовый клиент, если он доступен в экосистеме. Для удобства также установим поддержку асинхронности и логирования:
pip install httpx tenacity pydantic dotenv
Для локального хранения секретов и конфигурации:
pip install python-dotenv
Если вы планируете использовать векторные хранилища и обработку документов, добавьте:
pip install langchain-text-splitters langchain-chroma sentence-transformers
Для интерактивных experiments и визуализации логов полезны:
pip install rich streamlit
Для тестов и статического анализа:
pip install pytest black isort
Настройка ключей OpenRouter. Зарегистрируйтесь на openrouter.ai, создайте ключ API в настройках. Откройте файл .env в корне проекта и добавьте:
OPENROUTER_API_KEY=your_key_here
OPENROUTER_BASE_URL=https://openrouter.ai/api/v1
Это базовые переменные. Можно также добавить:
OPENROUTER_DEFAULT_MODEL=anthropic/claude-3.5-sonnet
OPENROUTER_TIMEOUT=60
При желании добавьте SITE_URL и SITE_NAME – они иногда используются провайдерами для идентификации запросов. Никогда не коммитьте .env в репозиторий. Добавьте .env в .gitignore:
.env
.env.local
secrets.*
Тестовый скрипт для проверки подключения. Создадим минимальный скрипт, который отправляет запрос через OpenRouter и получает ответ. Используем прямой HTTP-вызов, чтобы убедиться, что ключ работает. Файл check_openrouter.py:
import os
import httpx
from dotenv import load_dotenv
load_dotenv()
API_KEY = os.getenv("OPENROUTER_API_KEY")
BASE_URL = os.getenv("OPENROUTER_BASE_URL", "https://openrouter.ai/api/v1")
MODEL = os.getenv("OPENROUTER_DEFAULT_MODEL", "anthropic/claude-3.5-sonnet")
def test_call():
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json",
"HTTP-Referer": "https://example.com",
"X-Title": "AI Agent Test"
}
payload = {
"model": MODEL,
"messages": [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Привет! Напиши слово 'тест' и цифру 42."}
],
"max_tokens": 100
}
try:
resp = httpx.post(f"{BASE_URL}/chat/completions", json=payload, headers=headers, timeout=60)
resp.raise_for_status()
data = resp.json()
content = data["choices"][0]["message"]["content"]
print("Ответ модели:", content)
print("Проверка пройдена!")
except Exception as e:
print("Ошибка:", e)
if __name__ == "__main__":
test_call()
Запустите:
python check_openrouter.py
Если вы видите ответ – ключ настроен верно.
Интеграция с LangChain. LangChain позволяет описывать цепочки и агенты декларативно. Для OpenRouter можно использовать класс ChatOpenAI с переопределением базового URL, либо любой другой провайдер, совместимый с OpenAI-форматом. Пример инициализации модели через LangChain:
from langchain_core.messages import HumanMessage, SystemMessage
from langchain_community.chat_models import ChatOpenAI
import os
from dotenv import load_dotenv
load_dotenv()
model = ChatOpenAI(
model="anthropic/claude-3.5-sonnet",
openai_api_key=os.getenv("OPENROUTER_API_KEY"),
openai_api_base=os.getenv("OPENROUTER_BASE_URL"),
temperature=0.3,
max_tokens=500
)
messages = [
SystemMessage(content="Ты полезный ассистент. Отвечай кратко и по делу."),
HumanMessage(content="Скажи слово 'успех' и текущий год.")
]
result = model.invoke(messages)
print(result.content)
Если по какой-то причине прямой класс ChatOpenAI не работает с OpenRouter, можно создать кастомный LLM-обертку через RunnableLambda или использовать прямой HTTP-вызов внутри LangChain через LLM-интеграцию. Главное – сохранить формат чата и авторизацию.
Первый агент на LangChain. Построим минимального агента, который просто вызывает модель и форматирует ответ. Этот агент будет базовым каркасом для будущих расширений. Файл simple_agent.py:
from langchain_core.messages import HumanMessage, SystemMessage
from langchain_community.chat_models import ChatOpenAI
from dotenv import load_dotenv
import os
load_dotenv()
model = ChatOpenAI(
model="anthropic/claude-3.5-sonnet",
openai_api_key=os.getenv("OPENROUTER_API_KEY"),
openai_api_base=os.getenv("OPENROUTER_BASE_URL"),
temperature=0.1,
max_tokens=500
)
def run_agent(query: str):
system = SystemMessage(content="Ты – агент, который отвечает точно и по факту. Форматируй ответ структурированно.")
user = HumanMessage(content=query)
response = model.invoke([system, user])
return response.content
if __name__ == "__main__":
print(run_agent("Перечисли три цвета радуги через запятую."))
Запустите и убедитесь, что ответ приходит. Этот простой цикл – ядро будущего сложного агента.
Установка дополнительных инструментов для LangChain. Чтобы агент мог выполнять действия, нужны инструменты. Примеры:
pip install duckduckgo-search # поиск
pip install wikipedia # энциклопедия
pip install sqlalchemy # базы данных
pip install beautifulsoup4 # парсинг веб-страниц
Это расширит возможности агента. Мы подключим их позже, когда будем строить цикл «мыслить – действовать – проверять».
Проверка лимитов и политик. Убедитесь, что ваш аккаунт OpenRouter имеет доступ к выбранной модели. Если вы получаете ошибку 402 или 429, проверьте баланс и квоты. Настройте таймауты и повторные попытки с экспоненциальной задержкой. Для этого используем библиотеку tenacity:
from tenacity import retry, stop_after_attempt, wait_exponential
@retry(stop=stop_after_attempt(3), wait=wait_exponential(multiplier=1, min=2, max=10))
def call_model_safe(payload, headers):
import httpx
resp = httpx.post("https://openrouter.ai/api/v1/chat/completions", json=payload, headers=headers, timeout=60)
resp.raise_for_status()
return resp.json()
Это повысит устойчивость к временным сбоям сети или API.
Логирование и отладка. Добавим простой логгер, чтобы видеть шаги агента. В Python стандартный logging подойдет:
import logging
logging.basicConfig(level=logging.INFO, format="%(asctime)s – %(levelname)s – %(message)s")
logger = logging.getLogger("agent")
logger.info("Запуск агента")
Вставляйте логи в ключевых точках: вызов модели, вызов инструментов, ошибка, успешное завершение. Для красивого вывода можно использовать Rich:
from rich.console import Console
console = Console()
console.print("[bold green]Агент[/bold green] запущен")
Это упрощает отладку при работе в терминале.
Структура проекта. Рекомендуемая структура для масштабируемой разработки:
src/
__init__.py
llm.py # инициализация модели OpenRouter
tools.py # набор инструментов агента
memory.py # управление контекстом и памятью
planner.py # компонент планирования
reflexion.py # анализ ошибок и корректировка
agent.py # основной цикл агента
tests/
test_tools.py
test_agent.py
config/
prompts.yaml # шаблоны промптов
settings.py # настройки и переменные
.env
.gitignore
README.md
requirements.txt
Такой проект легко поддерживать, тестировать и деплоить.
Зависимости в requirements.txt. После установки всех пакетов создайте файл:
pip freeze > requirements.txt
Убедитесь, что в нем есть:
langchain
langchain-core
langchain-community
httpx
tenacity
python-dotenv
rich
duckduckgo-search
wikipedia
sqlalchemy
beautifulsoup4
sentence-transformers
langchain-chroma
streamlit (если нужен веб-интерфейс)
Это обеспечит воспроизводимость окружения.
Конфигурация через переменные окружения. Помимо ключей, добавьте флаги для режимов:
AGENT_DEBUG=true # включить подробные логи
AGENT_MAX_STEPS=10 # лимит шагов агента
AGENT_TOOL_TIMEOUT=30 # таймаут для инструментов
MODEL_TEMPERATURE=0.1 # температура по умолчанию
Используйте их в коде:
debug = os.getenv("AGENT_DEBUG", "false").lower() == "true"
if debug:
logger.setLevel(logging.DEBUG)
Это позволит включать детальные логи в dev и отключать в prod.
Первый запуск цепочки с инструментом. Соберем простую цепочку: модель -> инструмент поиска -> форматирование. Пример:
from langchain_community.utilities import DuckDuckGoSearchAPIWrapper
from langchain.agents import Tool
from langchain_core.messages import HumanMessage, SystemMessage
from langchain_community.chat_models import ChatOpenAI
import os
from dotenv import load_dotenv
load_dotenv()
search = DuckDuckGoSearchAPIWrapper()
tool = Tool(name="search", func=search.run, description="Используй для поиска информации в интернете.")
model = ChatOpenAI(
model="anthropic/claude-3.5-sonnet",
openai_api_key=os.getenv("OPENROUTER_API_KEY"),
openai_api_base=os.getenv("OPENROUTER_BASE_URL"),
temperature=0.1
)
def simple_agent_with_tool(query: str):
# Сначала спросим модель, нужно ли искать информацию
sys_msg = SystemMessage(content="Ты агент. Если в запросе нужна актуальная информация, используй инструмент поиска. Форматируй ответ.")
user_msg = HumanMessage(content=query)
# В этом примере мы просто выполняем поиск и подаем результат в модель
search_result = tool.func(query)
augmented_messages = [
sys_msg,
HumanMessage(content=f"Вопрос: {query}\nРезультаты поиска:\n{search_result}\n\nСформулируй четкий ответ.")
]
response = model.invoke(augmented_messages)
return response.content
if __name__ == "__main__":
print(simple_agent_with_tool("Какая погода в Лондоне сегодня?"))
Этот подход имитирует «мысль – действие – ответ». Более продвинутые версии мы реализуем с помощью LangChain Agents в следующих главах.
Тестирование и валидация. Напишем простой тест для функции запуска агента:
# tests/test_agent.py
import sys
sys.path.append("src")
from simple_agent import run_agent
def test_run_agent():
res = run_agent("Скажи слово 'проверка'")
assert "проверка" in res.lower()
Вам понадобится pytest для запуска:
pytest tests/
Если тесты падают из-за проблем с сетью или лимитами, добавьте моки для вызовов API или используйте записанные ответы.
Безопасность и секреты. Никогда не храните ключи в коде. Используйте .env и системные переменные в продакшене. Если вы работаете в облаке, используйте менеджеры секретов: AWS Secrets Manager, Google Secret Manager, Azure Key Vault. При локальной разработке защищайте файл .env: права доступа 600 и исключение из бэкапов. В коде используйте валидацию, чтобы не передавать ключи в логах и сообщениях модели.
Проверка поддержки 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
import os
load_dotenv()
key = os.getenv("OPENROUTER_API_KEY")
if key:
print("Ключ найден. Длина ключа:", len(key))
print("Первые 5 символов:", key[:5] + "…")
else:
print("Ключ не найден в переменных окружения.")
# Проверка соединения
try:
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(
model="openai/gpt-4o-mini",
openai_api_key=key,
openai_api_base="https://openrouter.ai/api/v1",
max_tokens=10
)
response = llm.invoke("Hi")
print("Соединение успешно! Ответ:", response.content)
except Exception as e:
print("Ошибка соединения:", e)
Запустите этот скрипт. Если вы видите "Соединение успешно!", ваше окружение настроено идеально для написания AI-агентов.
Отладка запросов
Если агент ведет себя странно, включите логирование запросов. В Python это можно сделать, установив уровень логирования:
import logging
logging.basicConfig(level=logging.DEBUG)
Но будьте осторожны: это залогирует ваш API-ключ в stdout. Используйте это только в безопасной среде.
Также OpenRouter в личном кабинете предоставляет историю запросов, где видно, какой промпт пришел от вашего клиента. Это полезно для отладки форматов сообщений.
Оптимизация стоимости
OpenRouter списывает средства за токены (вход + выход).
1. Используйте дешевые модели для простых задач (GPT-3.5, GPT-4o-mini, Mixtral).
2. Ограничивайте `max_tokens` и `temperature`.
3. Используйте кэширование: если вы часто спрашиваете одно и то же, сохраняйте ответы в Redis или SQLite.
4. Модель "openai/gpt-4o-mini" – оптимальный баланс цены и качества для большинства агентов.
Итог главы
Мы прошли полный цикл настройки: от создания виртуального окружения до написания работающего графа агента с инструментами. Вы научились:
– Безопасно хранить ключи.
– Устанавливать необходимые модули LangChain без лишнего мусора.
– Настраивать ChatOpenAI для работы с OpenRouter.
– Создавать цепочки (Chains) и инструменты (Tools).
– Собирать агента на LangGraph.
В следующей главе мы погрузимся в проектирование агента: как разбить сложную задачу на подзадачи, как настроить память (Memory) для запоминания контекста и как заставить агента планировать свои действия заранее.
Bepul matn qismi tugad.