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 при прямом доступе к провайдеру).
Базовое использование
Самый простой способ — метод chat(): передайте сообщение, получите строку в ответ:
from run_agent import AIAgent
agent = AIAgent(
model="anthropic/claude-sonnet-4.6",
quiet_mode=True,
)
response = agent.chat("What is the capital of France?")
print(response)
chat() самостоятельно ведёт весь цикл разговора — вызовы инструментов, повторные попытки, всё остальное — и возвращает только финальный текстовый ответ.
Всегда задавайте quiet_mode=True при встраивании Hermes в свой код. Без этого агент будет печатать спиннеры CLI, индикаторы прогресса и другой вывод для терминала, который засорит вывод вашего приложения.
Полный контроль над разговором
Для более тонкого управления используйте run_conversation() напрямую. Метод возвращает словарь с полным ответом, историей сообщений и метаданными:
agent = AIAgent(
model="anthropic/claude-sonnet-4.6",
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'])}")
Возвращаемый словарь содержит:
final_response— финальный текстовый ответ агентаmessages— полная история сообщений (system, user, assistant, вызовы инструментов)
(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.6",
enabled_toolsets=["web"],
quiet_mode=True,
)
# Enable everything except terminal access
agent = AIAgent(
model="anthropic/claude-sonnet-4.6",
disabled_toolsets=["terminal"],
quiet_mode=True,
)
Используйте enabled_toolsets, когда хотите минимального агента с жёстким ограничением (например, только веб-поиск для исследовательского бота). Используйте disabled_toolsets, когда хотите оставить большинство возможностей, но заблокировать конкретные (например, без доступа к терминалу в общей среде).
Многоходовые разговоры
Сохраняйте состояние разговора между ходами, передавая историю сообщений обратно:
agent = AIAgent(
model="anthropic/claude-sonnet-4.6",
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.6",
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 | "" | Модель в формате OpenRouter (по умолчанию пусто; определяется из конфига hermes во время выполнения) |
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), чтобы предотвратить бесконечные циклы вызовов инструментов и контролировать расходы.