
В этой статье мы сравним, как три основных поставщика LLM — OpenAI, Anthropic и open-source фреймворки — реализуют функциональные вызовы (function calling / tool use). Вы получите конкретные примеры кода, таблицу ключевых отличий и практические рекомендации, которые помогут выбрать подходящий инструмент для вашего агента ИИ.
Что такое function calling и как он встраивается в архитектуру агента
Function calling — это механизм, который позволяет LLM возвращать структурированные вызовы внешних функций, а не просто текст. Агент ИИ с function calling работает в цикле: модель получает описание доступных инструментов (название, параметры, описание), решает, какой инструмент вызвать, и возвращает JSON с именем функции и аргументами. Разработчик выполняет реальный вызов (API, база данных, файловая система) и передаёт результат обратно модели. Этот цикл может повторяться, пока модель не придёт к финальному ответу.
Главное преимущество — агент может получать актуальные данные, выполнять действия и обрабатывать результаты, оставаясь в рамках единого контекстного диалога.
Реализация OpenAI: возможности и подводные камни
OpenAI ввела function calling в июне 2023 года. В API передаётся массив `tools`, каждый элемент содержит `type: “function”` и `function` с `name`, `description`, `parameters` в формате JSON Schema. Модель возвращает `tool_calls` — массив вызовов, которые могут быть параллельными (параметр `parallel_tool_calls`). Всторенный `strict` режим включает строгую проверку соответствия JSON Schema при генерации, что уменьшает число невалидных вызовов.
Пример вызова функции с проверкой и повторными попытками:
python
import json
from openai import OpenAI
client = OpenAI()
def get_bitcoin_price(currency: str) -> float:
# имитация вызова API
return 65000.0 if currency == “USD” else 56000.0
tools = [{
“type”: “function”,
“function”: {
“name”: “get_bitcoin_price”,
“description”: “Get current Bitcoin price in given currency”,
“parameters”: {
“type”: “object”,
“properties”: {
“currency”: {“type”: “string”, “enum”: [“USD”, “EUR”, “RUB”]}
},
“required”: [“currency”]
}
}
}]
response = client.chat.completions.create(
model=”gpt-4o”,
messages=[{“role”: “user”, “content”: “Какой курс биткоина в долларах?”}],
tools=tools,
tool_choice=”auto”
)
if response.choices[0].message.tool_calls:
call = response.choices[0].message.tool_calls[0]
args = json.loads(call.function.arguments)
result = get_bitcoin_price(args[“currency”])
print(f”Курс: {result} USD”)
Подводные камни: при частых параллельных вызовах растёт потребление токенов — каждый вызов добавляет к ответу сотни токенов. Режим `strict` не гарантирует 100% валидности, особенно при сложных вложенных JSON Schema.
Реализация Anthropic: особенности tool use
Anthropic называет аналогичный механизм tool use. В API передаётся массив `tools` с полями `name`, `description`, `input_schema` (аналог JSON Schema). Claude возвращает блоки `content` типа `tool_use`. Важная особенность: Claude может вызывать инструменты одновременно с анализом изображений, что полезно для визуальных агентов. Anthropic рекомендует ограничивать количество инструментов до 16 на запрос.
Пример с Anthropic Python SDK:
python
import anthropic
client = anthropic.Anthropic()
response = client.messages.create(
model=”claude-3-5-sonnet-20241022″,
max_tokens=1024,
tools=[{
“name”: “get_weather”,
“description”: “Get current weather for a city”,
“input_schema”: {
“type”: “object”,
“properties”: {
“city”: {“type”: “string”}
},
“required”: [“city”]
}
}],
messages=[{“role”: “user”, “content”: “Какая погода в Москве?”}]
)
for block in response.content:
if block.type == “tool_use”:
print(f”Вызов {block.name} с аргументами {block.input}”)
Ограничение: Claude не поддерживает `parallel_tool_calls` в том же смысле, что OpenAI — он может вернуть только один `tool_use` на шаг, хотя в одном ответе может быть несколько блоков. Для многократных вызовов требуется цикл.
Open-source альтернативы: LangChain и Vercel AI SDK
Фреймворки, такие как LangChain и Vercel AI SDK, предоставляют единый интерфейс для работы с function calling независимо от провайдера. LangChain использует декоратор `@tool` для быстрого объявления функций, а затем автоматически конвертирует их в формат нужной модели. Vercel AI SDK (AI SDK) предлагает React-компоненты и стриминг с поддержкой tool calls, что удобно для фронтенд-приложений.
Пример LangChain с OpenAI:
python
from langchain.tools import tool
from langchain.agents import initialize_agent, AgentType
from langchain_openai import ChatOpenAI
@tool
def get_btc_price(currency: str) -> float:
“””Get Bitcoin price in given currency.”””
return 65000.0 if currency == “USD” else 56000.0
llm = ChatOpenAI(model=”gpt-4o”, temperature=0)
agent = initialize_agent(
tools=[get_btc_price],
llm=llm,
agent=AgentType.OPENAI_FUNCTIONS,
verbose=True
)
agent.run(“Какой курс биткоина сейчас?”)
Преимущество open-source: бесплатная лицензия (MIT, Apache 2.0), прозрачность кода, возможность кастомизации. Недостаток: зависимость от активного сообщества, иногда запаздывание в поддержке новых фич провайдеров.
Сравнительная таблица function calling
| Провайдер / Фреймворк | Формат инструментов | Параллельные вызовы | Стриминг | Лицензия | Сложность внедрения |
|---|---|---|---|---|---|
| OpenAI (GPT-4o) | JSON Schema (tools) | Да (parallel_tool_calls) | Да | Проприетарная | Низкая |
| Anthropic (Claude 3.5) | JSON Schema (tools) | Да (несколько блоков в одном ответе) | Да | Проприетарная | Средняя |
| LangChain (любая модель) | @tool, BaseTool | Зависит от модели | Да (через провайдера) | MIT | Средняя |
| Vercel AI SDK | Tool schema | Да (через провайдера) | Да (встроенный) | Apache 2.0 | Высокая (требуется React/Next.js) |
Практические ограничения и ловушки
Стоимость: каждый вызов функции генерирует дополнительные токены на входе (описание инструмента) и на выходе (JSON-вызов). При цепочке из 5 вызовов с использованием GPT-4o стоимость может превысить $0.05 за диалог. Используйте кэширование результатов и сокращайте количество шагов.
Валидация: модель может вернуть невалидный JSON, особенно при сложных схемах. Всегда проверяйте аргументы через `json.loads` с обработкой ошибок или используйте библиотеку Pydantic для валидации.
Безопасность: никогда не передавайте модели секреты (API-ключи, пароли) — они могут быть включены в лог запроса или выведены в ответе. Разграничивайте права инструментов: агент должен иметь доступ только к тем функциям, которые необходимы для конкретной задачи.
Контекстное окно: длинные цепочки вызовов могут превысить лимит токенов. Рекомендуется ограничивать максимальное количество шагов (например, до 10) и принудительно завершать агента при превышении.
Как тестировать function calling в своем проекте
Начните с простого сценария: одна функция с одним обязательным параметром (например, получение даты или курса валют). Убедитесь, что модель корректно вызывает её в 90%+ случаев. Затем добавьте вторую функцию и проверьте, что модель выбирает правильную. Для тестирования используйте:
– Playground OpenAI (прямая отправка запросов с tools)
– Инструмент `langsmith` для трассировки вызовов LangChain
– Юнит-тесты для каждой функции с эталонными промптами
Заключение: что выбрать для стартапа и для enterprise?
Для быстрого прототипирования выбирайте OpenAI — самый простой и документированный вариант. Если вам нужна поддержка изображений или работа с большими контекстами — присмотритесь к Claude от Anthropic. Для проектов, где важна кастомизация и контроль над данными, используйте LangChain или Vercel AI SDK. В любом случае, начните с одного провайдера, а затем при необходимости мигрируйте, используя абстракцию фреймворка.
Function calling — не универсальное решение, но для большинства практических задач (поиск документов, бронирование, обработка заказов) это самый быстрый способ превратить LLM из болталки в рабочего агента.