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

Kimi Code

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

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

Kimi Code — агент Moonshot AI с инструментами чтения и записи файлов, выполнения команд и поиска. Используйте шаблон kimi, чтобы запустить официальный CLI в отдельной песочнице и получить результат из приложения.

Подключение

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

В примерах модель moonshotai/kimi-k2.5 вызывается через OpenRouter. Приложение читает OPENROUTER_API_KEY и передаёт его CLI в KIMI_MODEL_API_KEY. Переменные KIMI_MODEL_PROVIDER_TYPE, KIMI_MODEL_BASE_URL и KIMI_MODEL_NAME выбирают OpenAI-совместимый протокол, адрес OpenRouter и модель. Эти настройки действуют для запуска процесса и не требуют интерактивного входа.

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

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

Подготовьте ответ клиенту

Пример передаёт сведения о заказе и просит Kimi записать черновик ответа в reply.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("kimi", { timeoutMs: 600_000 });
try {
  await sandbox.files.makeDir("/home/user/work");
  await sandbox.files.write(
    "/home/user/work/request.txt",
    "Customer Acme asks when order 1042 will arrive. Order 1042 shipped on September 18, 2026. Estimated delivery is September 21, 2026. Tracking number: AB1042.\n",
  );
  const result = await sandbox.commands.run('kimi -p "$AGENT_PROMPT"', {
    cwd: "/home/user/work",
    timeoutMs: 300_000,
    envs: {
      HTTPS_PROXY: proxy,
      HTTP_PROXY: proxy,
      NO_PROXY: "localhost,127.0.0.1",
      AGENT_PROMPT:
        "Read request.txt and write reply.md with a short response to the customer.",
      KIMI_MODEL_API_KEY: apiKey,
      KIMI_MODEL_PROVIDER_TYPE: "openai",
      KIMI_MODEL_BASE_URL: "https://openrouter.ai/api/v1",
      KIMI_MODEL_NAME: "moonshotai/kimi-k2.5",
      KIMI_MODEL_MAX_CONTEXT_SIZE: "262144",
      KIMI_MODEL_CAPABILITIES: "tool_use",
    },
    onStderr: (chunk) => process.stderr.write(chunk),
  });
  console.log(result.stdout);
  console.log(
    "reply.md\n" + (await sandbox.files.read("/home/user/work/reply.md")),
  );
} finally {
  await sandbox.kill();
}

-p выполняет задание без интерактивного интерфейса. В этом режиме обычные инструменты автоматически работают без запросов подтверждения, отдельные флаги --auto или --yolo не нужны. Текст задания передаётся через переменную окружения и раскрывается в кавычках, поэтому shell сохраняет его как один аргумент.

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

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

--output-format stream-json возвращает сообщения в JSONL. Пример показывает ответы и названия инструментов, получает ID сессии и передаёт уточнение по доставке в ту же сессию.

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("kimi", { timeoutMs: 600_000 });
try {
  await sandbox.files.makeDir("/home/user/work");
  await sandbox.files.write(
    "/home/user/work/request.txt",
    "Customer Acme asks when order 1042 will arrive. Order 1042 shipped on September 18, 2026. Estimated delivery is September 21, 2026. Tracking number: AB1042.\n",
  );
  async function execute(prompt, sessionId) {
    let pending = "",
      nextSessionId;
    function event(message) {
      if (message.role === "assistant") {
        if (message.content) console.log(message.content);
        for (const call of message.tool_calls ?? [])
          console.log("Tool:", call.function.name);
      }
      if (message.type === "session.resume_hint")
        nextSessionId = message.session_id;
    }
    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(
      'kimi -p "$AGENT_PROMPT" --output-format stream-json' +
        (sessionId ? ' --session "$AGENT_SESSION_ID"' : ""),
      {
        cwd: "/home/user/work",
        timeoutMs: 300_000,
        envs: {
          HTTPS_PROXY: proxy,
          HTTP_PROXY: proxy,
          NO_PROXY: "localhost,127.0.0.1",
          AGENT_PROMPT: prompt,
          KIMI_MODEL_API_KEY: apiKey,
          KIMI_MODEL_PROVIDER_TYPE: "openai",
          KIMI_MODEL_BASE_URL: "https://openrouter.ai/api/v1",
          KIMI_MODEL_NAME: "moonshotai/kimi-k2.5",
          KIMI_MODEL_MAX_CONTEXT_SIZE: "262144",
          KIMI_MODEL_CAPABILITIES: "tool_use",
          AGENT_SESSION_ID: sessionId ?? "",
        },
        onStdout,
        onStderr: (chunk) => process.stderr.write(chunk),
      },
    );
    if (pending.trim()) event(JSON.parse(pending));
    if (!nextSessionId) throw new Error("Agent did not return a session ID");
    console.log("\nSession:", nextSessionId);
    return nextSessionId;
  }
  const sessionId = await execute(
    "Read request.txt and write reply.md with a short response to the customer.",
  );
  await execute(
    "Logistics has confirmed delivery on September 22, 2026 instead. Update reply.md with the new date.",
    sessionId,
  );
  console.log(
    "reply.md\n" + (await sandbox.files.read("/home/user/work/reply.md")),
  );
} finally {
  await sandbox.kill();
}

Сообщения с role: assistant содержат текст в content и вызовы в tool_calls. Результат инструмента приходит с role: tool. В конце session.resume_hint сообщает session_id. Пример передаёт этот ID в --session. Это поток сообщений и результатов инструментов, а не отдельных токенов. Процесс должен завершиться успешно до чтения итогового файла.

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