Работа с запросами

Вызов инструментов

Как использовать tools и function calling в AllTokens через совместимый chat/completions API.

Вызов инструментов позволяет модели не просто отвечать текстом, а предлагать вызвать внешнюю функцию. Сама модель не вызывает инструмент напрямую: она только возвращает tool_calls, а уже ваш код выполняет нужную функцию, получает результат и отправляет его обратно модели.

Это удобно для:

  • поиска данных во внешнем API
  • работы с базой данных
  • вызова внутренних сервисов
  • построения простых агентных сценариев

Что поддерживается

В совместимом POST /api/v1/chat/completions можно использовать:

  • tools
  • tool_choice
  • сообщения с role: "tool"
  • возврат результата инструмента через tool_call_id

Если хотите подобрать модель с поддержкой инструментов, смотрите supported_parameters=tools в каталоге моделей или на alltokens.ru/models.

Как это работает

Обычно цикл состоит из трёх шагов:

  1. Вы отправляете запрос с tools
  2. Модель возвращает tool_calls
  3. Вы выполняете инструмент локально и отправляете результат вторым запросом

Шаг 1. Первый запрос с tools

Пример тела запроса:

{
  "model": "google/gemini-3-flash-preview",
  "messages": [
    {
      "role": "user",
      "content": "Какие книги написал Джеймс Джойс?"
    }
  ],
  "tools": [
    {
      "type": "function",
      "function": {
        "name": "search_gutenberg_books",
        "description": "Ищет книги в библиотеке Project Gutenberg",
        "parameters": {
          "type": "object",
          "properties": {
            "search_terms": {
              "type": "array",
              "items": { "type": "string" },
              "description": "Список поисковых фраз"
            }
          },
          "required": ["search_terms"]
        }
      }
    }
  ]
}

Шаг 2. Выполнение инструмента в вашем коде

После ответа модели вы читаете tool_calls, вызываете нужную функцию у себя и готовите результат:

const toolResult = await searchGutenbergBooks(["James", "Joyce"]);

Шаг 3. Второй запрос с результатом инструмента

Во втором запросе важно передать:

  • исходное пользовательское сообщение
  • ответ модели с tool_calls
  • сообщение role: "tool" с результатом вызова
  • тот же массив tools
{
  "model": "google/gemini-3-flash-preview",
  "messages": [
    {
      "role": "user",
      "content": "Какие книги написал Джеймс Джойс?"
    },
    {
      "role": "assistant",
      "content": null,
      "tool_calls": [
        {
          "id": "call_abc123",
          "type": "function",
          "function": {
            "name": "search_gutenberg_books",
            "arguments": "{\"search_terms\": [\"James\", \"Joyce\"]}"
          }
        }
      ]
    },
    {
      "role": "tool",
      "tool_call_id": "call_abc123",
      "content": "[{\"id\": 4300, \"title\": \"Ulysses\"}]"
    }
  ],
  "tools": [
    {
      "type": "function",
      "function": {
        "name": "search_gutenberg_books",
        "description": "Ищет книги в библиотеке Project Gutenberg",
        "parameters": {
          "type": "object",
          "properties": {
            "search_terms": {
              "type": "array",
              "items": { "type": "string" }
            }
          },
          "required": ["search_terms"]
        }
      }
    }
  ]
}

tools лучше передавать в обоих запросах: и в первом, и во втором. Так схема инструмента остаётся в контексте и повторно валидируется одинаково.

Полный пример

Ниже пример с Project Gutenberg: модель просит инструмент, ваш код выполняет поиск книг, а затем возвращает результат модели.

Подготовка

const messages = [
  {
    role: 'system',
    content: 'Ты полезный помощник.',
  },
  {
    role: 'user',
    content: 'Какие книги написал Джеймс Джойс?',
  },
];

const tools = [
  {
    type: 'function',
    function: {
      name: 'search_gutenberg_books',
      description: 'Ищет книги в библиотеке Project Gutenberg',
      parameters: {
        type: 'object',
        properties: {
          search_terms: {
            type: 'array',
            items: { type: 'string' },
            description: 'Список поисковых фраз',
          },
        },
        required: ['search_terms'],
      },
    },
  },
];

async function searchGutenbergBooks(searchTerms: string[]) {
  const query = searchTerms.join(' ');
  const response = await fetch(`https://gutendex.com/books?search=${query}`);
  const data = await response.json();

  return data.results.map((book: any) => ({
    id: book.id,
    title: book.title,
    authors: book.authors,
  }));
}

Первый вызов модели

const firstResponse = await fetch('https://api.alltokens.ru/api/v1/chat/completions', {
  method: 'POST',
  headers: {
    Authorization: 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    model: 'google/gemini-3-flash-preview',
    messages,
    tools,
  }),
});

const firstData = await firstResponse.json();
const assistantMessage = firstData.choices[0].message;
messages.push(assistantMessage);

Обработка tool_calls

for (const toolCall of assistantMessage.tool_calls ?? []) {
  const toolName = toolCall.function.name;
  const toolArgs = JSON.parse(toolCall.function.arguments);

  if (toolName === 'search_gutenberg_books') {
    const toolResult = await searchGutenbergBooks(toolArgs.search_terms);

    messages.push({
      role: 'tool',
      tool_call_id: toolCall.id,
      content: JSON.stringify(toolResult),
    });
  }
}

Второй вызов модели

const secondResponse = await fetch('https://api.alltokens.ru/api/v1/chat/completions', {
  method: 'POST',
  headers: {
    Authorization: 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    model: 'google/gemini-3-flash-preview',
    messages,
    tools,
  }),
});

const secondData = await secondResponse.json();
console.log(secondData.choices[0].message.content);

tool_choice

Параметр tool_choice позволяет контролировать использование инструментов.

Примеры:

{ "tool_choice": "auto" }
{ "tool_choice": "none" }
{
  "tool_choice": {
    "type": "function",
    "function": {
      "name": "search_gutenberg_books"
    }
  }
}

Практические рекомендации

  • давайте инструментам понятные и точные имена
  • подробно описывайте description, чтобы модели было проще выбрать правильный инструмент
  • делайте схему параметров максимально конкретной
  • валидируйте аргументы перед реальным вызовом функции
  • не забывайте добавлять в messages и ответ модели, и результат инструмента

Что важно учитывать

  • не каждая модель поддерживает tools
  • лучше заранее проверять supported_parameters
  • сам инструмент вызывается вашим кодом, а не моделью
  • для надёжных продакшен-сценариев стоит обрабатывать ошибки инструмента отдельно

Частые вопросы

Нет. Модель только возвращает tool_calls. Сам вызов делает ваш код, а результат вы затем отправляете обратно модели.

Да, это хороший и безопасный вариант. Так схема инструмента остаётся доступной и во втором шаге.

Смотрите supported_parameters в каталоге моделей. Если там есть tools, модель подходит для такого сценария.

В вашем серверном коде или в контролируемом backend-слое. Не стоит доверять модели прямой доступ к внешним системам без вашей валидации.