AGTCloud API Docs
РуководстваСправочник APIИнтеграции и ресурсыОбновления и помощь

Tool Calling

Пусть модель предлагает вызовы инструментов, а приложение безопасно выполняет их и возвращает результаты.

Tool Calling позволяет модели выбирать один или несколько инструментов на основе диалога и формировать структурированные аргументы вызова. Модель не обращается к базе данных, не вызывает внутренние сервисы и не выполняет операции записи вместо приложения: инструменты всегда выполняет ваша программа.

Это подходит для поиска заказов, получения погоды, поиска в базе знаний, вычислений и выполнения конкретных бизнес-операций после проверки полномочий.

Не выполняйте аргументы модели напрямую

Имена инструментов и аргументы — это вывод модели. Перед выполнением необходимы разбор JSON, проверка Schema, прав доступа и бизнес-списка разрешений. Платежи, удаление, отправка сообщений и другие рискованные операции также требуют подтверждения пользователя и контроля идемпотентности.

Полный цикл вызова

1. Определите инструменты

Укажите понятные имена, назначение и JSON Schema, чтобы модель знала, когда вызывать инструмент и какую структуру аргументов использовать.

2. Отправьте запрос модели

Отправьте пользовательский ввод вместе с определениями инструментов. Модель может ответить напрямую либо вернуть ноль, один или несколько вызовов.

3. Проверьте и выполните

Найдите локальную реализацию по имени инструмента, проверьте все аргументы и права вызывающей стороны, затем выполните операцию с тайм-аутом. Не позволяйте модели выбирать произвольные функции, URL, SQL или команды Shell.

4. Верните результат инструмента

С помощью идентификатора вызова, возвращённого протоколом, свяжите результат с исходным вызовом инструмента и снова отправьте запрос модели.

5. Прочитайте итоговый ответ

Модель может сформировать ответ пользователю на основе результата или предложить новые вызовы. Приложение должно ограничивать число итераций и определять условия завершения.

Определение инструмента только для чтения

Следующий инструмент только запрашивает погоду и не выполняет внешних операций записи:

{
  "type": "function",
  "function": {
    "name": "get_weather",
    "description": "Получить текущую погоду в указанном городе",
    "parameters": {
      "type": "object",
      "properties": {
        "city": {
          "type": "string",
          "description": "Название города, например Шанхай"
        },
        "unit": {
          "type": "string",
          "enum": ["celsius", "fahrenheit"]
        }
      },
      "required": ["city", "unit"],
      "additionalProperties": false
    }
  }
}

Описание инструмента должно объяснять, что он делает и когда его использовать. Сохраняйте стабильные имена параметров, сужайте перечисления и ограничивайте ненужный ввод с помощью required и additionalProperties.

Один полный цикл инструмента в Chat

Ниже показан основной путь: объявление инструмента, чтение вызова, выполнение локальной функции, возврат результата и чтение итогового ответа.

import json

from openai import OpenAI

client = OpenAI(
    api_key="your-api-key",
    base_url="https://api.agtcloud.cn/v1",
)

tools = [
    {
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "Получить текущую погоду в указанном городе",
            "parameters": {
                "type": "object",
                "properties": {
                    "city": {"type": "string"},
                    "unit": {
                        "type": "string",
                        "enum": ["celsius", "fahrenheit"],
                    },
                },
                "required": ["city", "unit"],
                "additionalProperties": False,
            },
        },
    }
]


def get_weather(city: str, unit: str) -> dict[str, str | int]:
    if city != "Шанхай" or unit != "celsius":
        raise ValueError("В примере разрешён только запрос температуры в Шанхае в градусах Цельсия")
    return {"city": city, "unit": unit, "temperature": 25}


messages = [{"role": "user", "content": "Какая сейчас температура в Шанхае?"}]
response = client.chat.completions.create(
    model="MODEL_ID",
    messages=messages,
    tools=tools,
    tool_choice="auto",
)

assistant_message = response.choices[0].message
messages.append(assistant_message)

for tool_call in assistant_message.tool_calls or []:
    if tool_call.function.name != "get_weather":
        raise ValueError("Модель запросила незарегистрированный инструмент")

    arguments = json.loads(tool_call.function.arguments)
    result = get_weather(**arguments)
    messages.append(
        {
            "role": "tool",
            "tool_call_id": tool_call.id,
            "content": json.dumps(result, ensure_ascii=False),
        }
    )

if assistant_message.tool_calls:
    final_response = client.chat.completions.create(
        model="MODEL_ID",
        messages=messages,
        tools=tools,
    )
    print(final_response.choices[0].message.content)
else:
    print(assistant_message.content)

В рабочем приложении проверяйте arguments библиотекой валидации JSON Schema и задавайте для каждого инструмента отдельные права доступа, тайм-ауты, типы ошибок и записи аудита.

Представление вызовов в разных протоколах

ПротоколОпределение инструментаВызов модельюВозврат результата
Chat Completionstools[].functiontool_calls в Assistant Messagerole: tool и tool_call_id
ResponsesFunction Tool в toolsOutput Item function_callfunction_call_output и call_id
Anthropic Messagestools и input_schemaContent Block tool_useContent Block tool_result
GeminifunctionDeclarationsfunctionCall в PartfunctionResponse в Part

Нельзя смешивать имена полей и вложенные структуры. Полные определения приведены в справочниках Chat Completions, Responses, Anthropic Messages и Gemini Generate Content.

Несколько вызовов и Streaming

  • Не предполагайте, что возможен только один вызов: отдельно проверяйте, выполняйте и возвращайте результат каждого вызова по его ID.
  • Параллельно выполняйте только независимые операции чтения, если это разрешено бизнес-правилами.
  • Потоковые аргументы могут поступать частями: соберите их полностью и только затем разбирайте JSON.
  • После возврата результата модель может предложить следующий вызов: ограничивайте число итераций и общее время.
  • При повторе одной операции записи используйте бизнес-ключ идемпотентности, чтобы не списать средства, не отправить сообщение и не создать ресурс повторно.

Обработка ошибок

Если инструмент завершился с ошибкой, не подделывайте успешный результат. Можно вернуть модели обезличенную категорию ошибки, например неверные аргументы, недостаточные права или временную недоступность сервиса, чтобы она объяснила ситуацию пользователю или выбрала разрешённый вариант.

Не передавайте модели или пользователю напрямую внутренние стеки, структуру базы данных, токены доступа, адреса частной сети и необезличенные ответы сторонних сервисов.

Проверка перед запуском

  • Инструменты выбираются только из реестра или списка разрешений.
  • Перед выполнением аргументы проходят проверку Schema и бизнес-правил.
  • Для каждого инструмента определены права доступа, тайм-аут, максимальный размер результата и обработка ошибок.
  • Рискованные операции записи требуют подтверждения пользователя, поддерживают идемпотентность и аудит.
  • Число итераций ограничено: модель не может бесконечно продолжать цикл.
  • Потоковые аргументы инструмента выполняются только после полного получения.

Для сборки аргументов по мере поступления см. Streaming. Для итогового ответа по JSON Schema см. Structured Output.

На этой странице