Использование Hermes в качестве Python-библиотеки

Hermes — это не просто CLI-инструмент. Вы можете импортировать AIAgent напрямую и использовать его программно в своих собственных Python-скриптах, веб-приложениях или конвейерах автоматизации. Это руководство покажет вам, как это сделать.


Установка

Установите Hermes напрямую из репозитория:

pip install git+https://github.com/NousResearch/hermes-agent.git

Или с помощью uv:

uv pip install git+https://github.com/NousResearch/hermes-agent.git

Вы также можете зафиксировать его в requirements.txt:

hermes-agent @ git+https://github.com/NousResearch/hermes-agent.git
При использовании Hermes в качестве библиотеки требуются те же переменные окружения, что и для CLI. Как минимум, установите `OPENROUTER_API_KEY` (или `OPENAI_API_KEY` / `ANTHROPIC_API_KEY` при прямом доступе к провайдеру).

Базовое использование

Самый простой способ использовать Hermes — метод chat(): отправьте сообщение и получите строку в ответ:

from run_agent import AIAgent

agent = AIAgent(
    model="anthropic/claude-sonnet-4",
    quiet_mode=True,
)
response = agent.chat("What is the capital of France?")
print(response)

chat() обрабатывает полный цикл общения внутри — вызовы инструментов, повторные попытки и всё остальное — и возвращает только итоговый текстовый ответ.

Всегда устанавливайте `quiet_mode=True` при встраивании Hermes в свой код. Без этого агент будет выводить spinner'ы CLI, индикаторы прогресса и другой терминальный вывод, который засорит вывод вашего приложения.

Полный контроль над диалогом

Для более тонкого контроля над диалогом используйте run_conversation() напрямую. Он возвращает словарь с полным ответом, историей сообщений и метаданными:

agent = AIAgent(
    model="anthropic/claude-sonnet-4",
    quiet_mode=True,
)

result = agent.run_conversation(
    user_message="Search for recent Python 3.13 features",
    task_id="my-task-1",
)

print(result["final_response"])
print(f"Messages exchanged: {len(result['messages'])}")

Возвращаемый словарь содержит:

(Переданный task_id сохраняется в экземпляре агента для изоляции VM, но не возвращается в словаре результата.)

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

result = agent.run_conversation(
    user_message="Explain quicksort",
    system_message="You are a computer science tutor. Use simple analogies.",
)

Настройка инструментов

Управляйте доступом агента к наборам инструментов с помощью enabled_toolsets или disabled_toolsets:

# Only enable web tools (browsing, search)
agent = AIAgent(
    model="anthropic/claude-sonnet-4",
    enabled_toolsets=["web"],
    quiet_mode=True,
)

# Enable everything except terminal access
agent = AIAgent(
    model="anthropic/claude-sonnet-4",
    disabled_toolsets=["terminal"],
    quiet_mode=True,
)
Используйте `enabled_toolsets`, когда вам нужен минимальный, ограниченный агент (например, только веб-поиск для исследовательского бота). Используйте `disabled_toolsets`, когда вам нужно большинство возможностей, но требуется ограничить конкретные (например, без доступа к терминалу в общей среде).

Многошаговые диалоги

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

agent = AIAgent(
    model="anthropic/claude-sonnet-4",
    quiet_mode=True,
)

# First turn
result1 = agent.run_conversation("My name is Alice")
history = result1["messages"]

# Second turn — agent remembers the context
result2 = agent.run_conversation(
    "What's my name?",
    conversation_history=history,
)
print(result2["final_response"])  # "Your name is Alice."

Параметр conversation_history принимает список messages из предыдущего результата. Агент копирует его внутренне, поэтому ваш исходный список никогда не изменяется.


Сохранение траекторий

Включите сохранение траекторий для записи диалогов в формате ShareGPT — полезно для создания обучающих данных или отладки:

agent = AIAgent(
    model="anthropic/claude-sonnet-4",
    save_trajectories=True,
    quiet_mode=True,
)

agent.chat("Write a Python function to sort a list")
# Saves to trajectory_samples.jsonl in ShareGPT format

Каждый диалог добавляется одной строкой JSONL, что упрощает сбор наборов данных из автоматических запусков.


Пользовательские системные промпты

Используйте ephemeral_system_prompt для установки собственного системного промпта, который направляет поведение агента, но не сохраняется в файлы траекторий (сохраняя ваши обучающие данные чистыми):

agent = AIAgent(
    model="anthropic/claude-sonnet-4",
    ephemeral_system_prompt="You are a SQL expert. Only answer database questions.",
    quiet_mode=True,
)

response = agent.chat("How do I write a JOIN query?")
print(response)

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


Пакетная обработка

Для параллельного выполнения множества промптов Hermes включает batch_runner.py. Он управляет конкурентными экземплярами AIAgent с надлежащей изоляцией ресурсов:

python batch_runner.py --input prompts.jsonl --output results.jsonl

Каждый промпт получает свой собственный task_id и изолированную среду. Если вам нужна своя логика пакетной обработки, вы можете создать её с помощью AIAgent напрямую:

import concurrent.futures
from run_agent import AIAgent

prompts = [
    "Explain recursion",
    "What is a hash table?",
    "How does garbage collection work?",
]

def process_prompt(prompt):
    # Create a fresh agent per task for thread safety
    agent = AIAgent(
        model="anthropic/claude-sonnet-4",
        quiet_mode=True,
        skip_memory=True,
    )
    return agent.chat(prompt)

with concurrent.futures.ThreadPoolExecutor(max_workers=3) as executor:
    results = list(executor.map(process_prompt, prompts))

for prompt, result in zip(prompts, results):
    print(f"Q: {prompt}\nA: {result}\n")
Всегда создавайте **новый экземпляр `AIAgent` для каждого потока или задачи**. Агент поддерживает внутреннее состояние (история диалога, сессии инструментов, счётчики итераций), которое не является потокобезопасным для совместного использования.

Примеры интеграции

FastAPI-эндпоинт

from fastapi import FastAPI
from pydantic import BaseModel
from run_agent import AIAgent

app = FastAPI()

class ChatRequest(BaseModel):
    message: str
    model: str = "anthropic/claude-sonnet-4"

@app.post("/chat")
async def chat(request: ChatRequest):
    agent = AIAgent(
        model=request.model,
        quiet_mode=True,
        skip_context_files=True,
        skip_memory=True,
    )
    response = agent.chat(request.message)
    return {"response": response}

Discord-бот

import discord
from run_agent import AIAgent

client = discord.Client(intents=discord.Intents.default())

@client.event
async def on_message(message):
    if message.author == client.user:
        return
    if message.content.startswith("!hermes "):
        query = message.content[8:]
        agent = AIAgent(
            model="anthropic/claude-sonnet-4",
            quiet_mode=True,
            skip_context_files=True,
            skip_memory=True,
            platform="discord",
        )
        response = agent.chat(query)
        await message.channel.send(response[:2000])

client.run("YOUR_DISCORD_TOKEN")

Шаг CI/CD-пайплайна

#!/usr/bin/env python3
"""CI step: auto-review a PR diff."""
import subprocess
from run_agent import AIAgent

diff = subprocess.check_output(["git", "diff", "main...HEAD"]).decode()

agent = AIAgent(
    model="anthropic/claude-sonnet-4",
    quiet_mode=True,
    skip_context_files=True,
    skip_memory=True,
    disabled_toolsets=["terminal", "browser"],
)

review = agent.chat(
    f"Review this PR diff for bugs, security issues, and style problems:\n\n{diff}"
)
print(review)

Ключевые параметры конструктора

Параметр Тип По умолчанию Описание
model str "anthropic/claude-opus-4.6" Модель в формате OpenRouter
quiet_mode bool False Подавлять вывод CLI
enabled_toolsets List[str] None Разрешить определённые наборы инструментов
disabled_toolsets List[str] None Заблокировать определённые наборы инструментов
save_trajectories bool False Сохранять диалоги в JSONL
ephemeral_system_prompt str None Пользовательский системный промпт (не сохраняется в траектории)
max_iterations int 90 Максимум итераций вызова инструментов за диалог
skip_context_files bool False Пропускать загрузку файлов AGENTS.md
skip_memory bool False Отключить чтение/запись постоянной памяти
api_key str None API-ключ (использует переменные окружения как запасной вариант)
base_url str None Пользовательский URL API-эндпоинта
platform str None Подсказка платформы ("discord", "telegram" и т.д.)

Важные замечания

- Установите **`skip_context_files=True`**, если вы не хотите, чтобы файлы `AGENTS.md` из рабочей директории загружались в системный промпт. - Установите **`skip_memory=True`**, чтобы предотвратить чтение или запись агентом постоянной памяти — рекомендуется для stateless API-эндпоинтов. - Параметр `platform` (например, `"discord"`, `"telegram"`) добавляет подсказки форматирования для конкретной платформы, чтобы агент адаптировал стиль своего вывода.
- **Потокобезопасность**: Создавайте один экземпляр `AIAgent` на поток или задачу. Никогда не используйте один экземпляр в конкурентных вызовах. - **Очистка ресурсов**: Агент автоматически очищает ресурсы (терминальные сессии, экземпляры браузера) по завершении диалога. Если вы работаете в долгоживущем процессе, убедитесь, что каждый диалог завершается нормально. - **Лимиты итераций**: Значение по умолчанию `max_iterations=90` является щедрым. Для простых сценариев вопросов-ответов рассмотрите возможность его уменьшения (например, `max_iterations=10`), чтобы предотвратить бесконечные циклы вызовов инструментов и контролировать расходы.