/
Вопросы и ответы
/
AI-агенты
/

Что такое tool calling и как он работает под капотом

Что такое tool calling и как он работает под капотом

11 часов назад

Никита Вихров

Ответы

0

Что такое tool calling и как он работает под капотом

«Агент вызвал инструмент» звучит как магия. На самом деле — это обычный JSON туда и обратно. Никакого специального протокола: модель возвращает структурированный текст, ты его парсишь и выполняешь нужный код.


Что реально происходит

Ты отправляешь в API запрос с описанием инструментов и сообщением пользователя:

response = client.messages.create(
    model="claude-opus-4-5",
    max_tokens=1024,
    tools=[{
        "name": "get_weather",
        "description": "Возвращает погоду в городе",
        "input_schema": {
            "type": "object",
            "properties": {
                "city": {"type": "string", "description": "Название города"},
                "units": {"type": "string", "enum": ["celsius", "fahrenheit"]}
            },
            "required": ["city"]
        }
    }],
    messages=[{"role": "user", "content": "Какая погода в Москве?"}]
)

Модель решает, что нужен инструмент, и возвращает не текст, а JSON-блок:

{
  "stop_reason": "tool_use",
  "content": [
    {
      "type": "tool_use",
      "id": "toolu_01XPpQAoNBzYhxk7hDsLxsKf",
      "name": "get_weather",
      "input": {
        "city": "Москва",
        "units": "celsius"
      }
    }
  ]
}

Модель остановилась и ждёт. Она не выполнила инструмент — она только сказала, что хочет его выполнить. Выполнение — твоя работа.


Ты выполняешь инструмент и возвращаешь результат

import requests

def get_weather(city: str, units: str = "celsius") -> str:
    # Реальный вызов погодного API
    response = requests.get(
        "https://api.weather.com/v1/current",
        params={"q": city, "units": units, "key": "your_api_key"}
    )
    data = response.json()
    return f"{data['temp']}°, {data['description']}"

# Парсим ответ модели
tool_block = next(b for b in response.content if b.type == "tool_use")

# Выполняем инструмент
result = get_weather(**tool_block.input)
# → "12°, облачно"

# Возвращаем результат модели
messages = [
    {"role": "user", "content": "Какая погода в Москве?"},
    {"role": "assistant", "content": response.content},  # ответ с tool_use
    {
        "role": "user",
        "content": [{
            "type": "tool_result",
            "tool_use_id": tool_block.id,  # связываем с конкретным вызовом
            "content": result
        }]
    }
]

# Снова вызываем модель — теперь она знает результат
final_response = client.messages.create(
    model="claude-opus-4-5",
    max_tokens=1024,
    tools=tools,
    messages=messages
)

print(final_response.content[0].text)
# → "В Москве сейчас 12 градусов, облачно."

Полная схема одного цикла

Ты → API: задача + описание инструментов API → Ты: {"stop_reason": "tool_use", "content": [{"type": "tool_use", "name": "...", "input": {...}}]} Ты: выполняешь функцию с input из ответа Ты → API: history + {"type": "tool_result", "content": "результат функции"} API → Ты: {"stop_reason": "end_turn", "content": [{"type": "text", "text": "финальный ответ"}]}

Почему это важно понимать

Три следствия из этого механизма:

Модель не знает, что реально делает инструмент. Она знает только name и description. Назови инструмент delete_all_files и опиши его как «создаёт резервную копию» — модель будет вызывать его думая, что делает бэкап.

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

Ошибку в инструменте можно вернуть как результат. Не бросай исключение — верни строку с описанием ошибки. Модель прочитает её и скорректирует следующий шаг.

try:
    result = execute_tool(tool_block.name, tool_block.input)
except Exception as e:
    result = f"Инструмент завершился с ошибкой: {e}. Попробуй другой подход."

# Возвращаем ошибку как обычный результат
messages.append({
    "role": "user",
    "content": [{"type": "tool_result", "tool_use_id": tool_block.id, "content": result}]
})

11 часов назад

Никита Вихров

+7 800 100 22 47

бесплатно по РФ

+7 495 085 21 62

бесплатно по Москве

108813 г. Москва, вн.тер.г. поселение Московский,
г. Московский, ул. Солнечная, д. 3А, стр. 1, помещ. 20Б/3
ОГРН 1217300010476
ИНН 7325174845