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

Grok

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

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

Grok Build — агент xAI для работы с файлами, командами и внешними инструментами. Готовый шаблон grok содержит официальный CLI. Приложение запускает его через API команд AgentBox и получает ответ или файл результата.

Подключение

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

Ключ xAI берётся из XAI_API_KEY и передаётся только процессу агента. В примерах выбрана модель grok-4.3. Доступные модели можно посмотреть командой grok models внутри песочницы с переданным ключом.

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

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

Подготовьте сводку по доставкам

Пример передаёт выгрузку доставок и просит Grok записать задержанные заказы с известными причинами в exceptions.md. Затем приложение читает файл через SDK.

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

const apiKey = process.env.XAI_API_KEY;
if (!apiKey) throw new Error("XAI_API_KEY is required");
const proxy =
  process.env.SANDBOX_PROXY_URL ?? "https://sandbox-proxy.agentbox.ru:65181";
const sandbox = await Sandbox.create("grok", { timeoutMs: 600_000 });
try {
  await sandbox.files.makeDir("/home/user/work");
  await sandbox.files.write(
    "/home/user/work/shipments.csv",
    `order,customer,status,note
1042,Acme,delayed,Awaiting warehouse pickup
1043,Northwind,delivered,Delivered on September 18
1044,Contoso,delayed,Address confirmation required
`,
  );
  await sandbox.files.write(
    "/home/user/work/task.txt",
    "Read shipments.csv and write exceptions.md for the logistics team: delayed orders and their known reasons.",
  );
  const result = await sandbox.commands.run(
    "grok --always-approve --sandbox off --model grok-4.3 --prompt-file task.txt",
    {
      cwd: "/home/user/work",
      timeoutMs: 300_000,
      envs: {
        XAI_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(
    "exceptions.md\n" +
      (await sandbox.files.read("/home/user/work/exceptions.md")),
  );
} finally {
  await sandbox.kill();
}

--prompt-file task.txt задаёт один вызов без интерактивного интерфейса. --always-approve разрешает выполнение инструментов без подтверждений. --sandbox off отключает дополнительную изоляцию самого Grok. Границы окружения обеспечивает песочница AgentBox.

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

События и продолжение сессии

С --output-format streaming-json Grok выдаёт JSON-объекты, разделённые переводами строк. Пример выводит текст ответа и названия инструментов, ждёт завершения и продолжает ту же сессию с уточнённым статусом доставки.

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

const apiKey = process.env.XAI_API_KEY;
if (!apiKey) throw new Error("XAI_API_KEY is required");
const proxy =
  process.env.SANDBOX_PROXY_URL ?? "https://sandbox-proxy.agentbox.ru:65181";
const sandbox = await Sandbox.create("grok", { timeoutMs: 600_000 });
try {
  await sandbox.files.makeDir("/home/user/work");
  await sandbox.files.write(
    "/home/user/work/shipments.csv",
    `order,customer,status,note
1042,Acme,delayed,Awaiting warehouse pickup
1043,Northwind,delivered,Delivered on September 18
1044,Contoso,delayed,Address confirmation required
`,
  );
  async function execute(prompt, sessionId) {
    await sandbox.files.write("/home/user/work/task.txt", prompt);
    let pending = "",
      nextSessionId,
      terminal,
      failure;
    function event(message) {
      if (message.type === "text") process.stdout.write(message.data);
      if (message.type === "tool_call") console.log("Tool:", message.title);
      if (message.type === "end") {
        terminal = message.stopReason;
        nextSessionId = message.sessionId;
      }
      if (message.type === "error") failure = new Error(message.message);
    }
    function onStdout(chunk) {
      pending += chunk;
      let newline;
      while ((newline = pending.indexOf("\n")) !== -1) {
        const line = pending.slice(0, newline);
        pending = pending.slice(newline + 1);
        if (line.trim()) event(JSON.parse(line));
      }
    }
    await sandbox.commands.run(
      "grok --always-approve --sandbox off --model grok-4.3 --prompt-file task.txt --output-format streaming-json" +
        (sessionId ? ' --resume "$AGENT_SESSION_ID"' : ""),
      {
        cwd: "/home/user/work",
        timeoutMs: 300_000,
        envs: {
          XAI_API_KEY: apiKey,
          HTTPS_PROXY: proxy,
          HTTP_PROXY: proxy,
          NO_PROXY: "localhost,127.0.0.1",
          AGENT_SESSION_ID: sessionId ?? "",
        },
        onStdout,
        onStderr: (chunk) => process.stderr.write(chunk),
      },
    );
    if (pending.trim()) event(JSON.parse(pending));
    if (failure) throw failure;
    if (terminal !== "end_turn")
      throw new Error("Agent did not finish normally: " + terminal);
    if (!nextSessionId) throw new Error("Agent did not return a session ID");
    console.log("\nSession:", nextSessionId);
    return nextSessionId;
  }
  const sessionId = await execute(
    "Read shipments.csv and write exceptions.md for the logistics team: delayed orders and their known reasons.",
  );
  await execute(
    "The warehouse confirmed that order 1042 was picked up. Update exceptions.md and keep the other order details.",
    sessionId,
  );
  console.log(
    "exceptions.md\n" +
      (await sandbox.files.read("/home/user/work/exceptions.md")),
  );
} finally {
  await sandbox.kill();
}

В событии text поле data содержит фрагмент ответа. tool_call сообщает о вызове инструмента. Событие end содержит sessionId и причину остановки stopReason. Пример принимает end_turn как нормальное завершение и передаёт полученный ID в --resume. --session-id предназначен для новой сессии с заданным UUID, а не для продолжения существующей.

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