Перейти к содержимому

Hermes

Обновление образов

Готовые образы агентов обновляются каждое утро и содержат актуальную версию CLI. Чтобы использовать фиксированную версию образа, закрепите версию шаблона.

Hermes — AI-агент с инструментами терминала и файловой системы, навыками и сохранением контекста. Готовый шаблон hermes позволяет запускать его из приложения. Команды агента выполняются внутри песочницы AgentBox.

Подключение

Установите SDK AgentBox и задайте AGENTBOX_API_KEY.

В примерах используется OpenRouter. Передайте OPENROUTER_API_KEY процессу агента. Флаги --provider openrouter и --model qwen/qwen3-coder-next выбирают провайдера и модель.

Для доступа к модели можно использовать HTTPS-прокси AgentBox https://sandbox-proxy.agentbox.ru:65181.

В примерах HTTPS_PROXY, HTTP_PROXY и NO_PROXY передаются процессу агента. Эти настройки могут влиять и на другие запросы агента и его дочерних процессов. Соединения с localhost и 127.0.0.1 остаются прямыми.

Подготовьте ответы на заявки

Пример загружает CSV с заявками компаний. Hermes читает файл и сохраняет черновики ответов в follow-up.md. Приложение получает этот файл через SDK.

mjs
import { Sandbox } from "@abox-dev/sdk";

const apiKey = process.env.OPENROUTER_API_KEY;
if (!apiKey) throw new Error("OPENROUTER_API_KEY is required");
const proxy =
  process.env.SANDBOX_PROXY_URL ?? "https://sandbox-proxy.agentbox.ru:65181";
const sandbox = await Sandbox.create("hermes", { timeoutMs: 600_000 });
try {
  await sandbox.files.makeDir("/home/user/work");
  await sandbox.files.write(
    "/home/user/work/leads.csv",
    `company,request
Acme,Needs a quote for 20 office chairs
Northwind,Asks for delivery options for 8 desks
`,
  );
  await sandbox.files.write(
    "/home/user/work/task.txt",
    "Read leads.csv and write follow-up.md with a short draft response for each company. Use only the details in the file.",
  );
  const result = await sandbox.commands.run(
    "hermes chat -Q --yolo --provider openrouter --model qwen/qwen3-coder-next --query-file task.txt",
    {
      cwd: "/home/user/work",
      timeoutMs: 300_000,
      envs: {
        OPENROUTER_API_KEY: apiKey,
        HTTPS_PROXY: proxy,
        HTTP_PROXY: proxy,
        NO_PROXY: "localhost,127.0.0.1",
      },
      onStderr: (chunk) => process.stderr.write(chunk),
    },
  );
  console.log(result.stdout);
  console.log(
    "follow-up.md\n" +
      (await sandbox.files.read("/home/user/work/follow-up.md")),
  );
} finally {
  await sandbox.kill();
}

--query-file task.txt читает задание из файла, поэтому текст не нужно вставлять в shell-команду. -Q выводит итоговый ответ в stdout, а ID сессии — в stderr. --yolo отключает запросы подтверждения инструментов. Hermes использует локальное окружение внутри песочницы, отдельный backend для терминала настраивать не требуется.

Пример читает результат до удаления песочницы. finally освобождает её и при ошибке. В Go для очистки используется отдельный контекст.

Вывод и продолжение сессии

После первого ответа пример получает ID сессии из строки session_id: в stderr. Затем запускает новый процесс с --resume, передаёт уточнение по заявке и читает обновлённый файл.

mjs
import { Sandbox } from "@abox-dev/sdk";

const apiKey = process.env.OPENROUTER_API_KEY;
if (!apiKey) throw new Error("OPENROUTER_API_KEY is required");
const proxy =
  process.env.SANDBOX_PROXY_URL ?? "https://sandbox-proxy.agentbox.ru:65181";
const sandbox = await Sandbox.create("hermes", { timeoutMs: 600_000 });
try {
  await sandbox.files.makeDir("/home/user/work");
  await sandbox.files.write(
    "/home/user/work/leads.csv",
    `company,request
Acme,Needs a quote for 20 office chairs
Northwind,Asks for delivery options for 8 desks
`,
  );
  async function execute(prompt, sessionId) {
    await sandbox.files.write("/home/user/work/task.txt", prompt);
    const result = await sandbox.commands.run(
      "hermes chat -Q --yolo --provider openrouter --model qwen/qwen3-coder-next --query-file task.txt" +
        (sessionId ? ' --resume "$AGENT_SESSION_ID"' : ""),
      {
        cwd: "/home/user/work",
        timeoutMs: 300_000,
        envs: {
          OPENROUTER_API_KEY: apiKey,
          HTTPS_PROXY: proxy,
          HTTP_PROXY: proxy,
          NO_PROXY: "localhost,127.0.0.1",
          AGENT_SESSION_ID: sessionId ?? "",
        },
        onStdout: (chunk) => process.stdout.write(chunk),
        onStderr: (chunk) => process.stderr.write(chunk),
      },
    );
    const nextSessionId = /^session_id: (\S+)$/m.exec(result.stderr)?.[1];
    if (!nextSessionId) throw new Error("Agent did not return a session ID");
    console.log("\nSession:", nextSessionId);
    return nextSessionId;
  }
  const sessionId = await execute(
    "Read leads.csv and write follow-up.md with a short draft response for each company. Use only the details in the file.",
  );
  await execute(
    "Acme confirmed a preference for blue chairs. Update its draft in follow-up.md with this detail.",
    sessionId,
  );
  console.log(
    "follow-up.md\n" +
      (await sandbox.files.read("/home/user/work/follow-up.md")),
  );
} finally {
  await sandbox.kill();
}

Обработчики stdout и stderr передают вывод по мере поступления. В режиме -Q ответ печатается после завершения задания, это не поток токенов модели.

История сессии и файлы находятся в песочнице. Для следующего вызова сохраните её вместе с ID сессии или поставьте на паузу. Полный протокол и параметры CLI описаны в документации Hermes.