Toolformer — самообучение использованию инструментов

Training-oriented идея, где модель учится сама понимать, когда нужен внешний инструмент, а не ждать ручного жёсткого сценария.

Toolformer — подход, при котором языковая модель самостоятельно учится определять, когда и какой внешний инструмент использовать (калькулятор, поисковик, переводчик, календарь), и встраивает вызовы инструментов прямо в генерируемый текст. В отличие от ReAct, где инструменты задаются вручную через промпт, Toolformer обучается этому навыку на данных, созданных самой моделью.

В 2026 году Toolformer важно понимать прежде всего как training concept, а не как то, что команды буквально разворачивают “по статье”. Практические системы чаще используют готовые tool-calling API, но сама идея self-supervised tool selection сильно повлияла на то, как теперь проектируют model-tool interfaces.

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

Суть в двух словах

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

На практике эта идея воплотилась в Function Calling (OpenAI) и Tool Use (Anthropic) — встроенных механизмах вызова инструментов.

ПромптChatGPT
Сколько дней осталось до Нового года, и какой это процент от оставшегося года?
Ответ модели

Сегодня 23 февраля 2026 года. [calculator(дней_до_нг = (date(2026,12,31) - date(2026,2,23)).days)] → 311 дней [calculator(процент = 311/365*100)] → 85.2%

До Нового года осталось 311 дней — это примерно 85.2% оставшегося года.

Ключевая идея: модель не просто может использовать инструменты — она сама определяет, когда они нужны.

Что такое Toolformer

Toolformer был предложен исследователями Meta* AI (Schick et al., 2023). Ключевое отличие от предыдущих подходов — модель обучается использовать инструменты без ручной разметки данных.

Процесс обучения:

  1. Модель получает текст и сама предлагает, где вставить вызов инструмента
  2. Вызовы выполняются, результаты подставляются
  3. Если результат инструмента улучшает предсказание следующих токенов — вызов сохраняется
  4. Модель дообучается на текстах с успешными вызовами инструментов

Какие инструменты использует Toolformer

Зачем это нужно

Языковые модели имеют известные слабости:

  • Арифметика: модели ошибаются на больших числах и дробях
  • Актуальность: знания модели ограничены датой обучения
  • Точность фактов: модели могут галлюцинировать малоизвестные факты

Toolformer решает эти проблемы, давая модели доступ к специализированным инструментам именно в тот момент, когда они нужны.

Примеры использования

Текст с автоматическими вычислениями

ПромптClaude Sonnet 4
Рассчитай стоимость ремонта квартиры 65 м²:
- Материалы: 8500 руб/м²
- Работа: 6200 руб/м²
- Мебель: 450 000 руб. фиксированно

Используй калькулятор для каждого вычисления.
Ответ модели

Расчёт стоимости ремонта квартиры 65 м²:

  1. Материалы: [calculator(8500 × 65)] = 552 500 руб.
  2. Работа: [calculator(6200 × 65)] = 403 000 руб.
  3. Мебель: 450 000 руб. (фиксированно)

Итого: [calculator(552500 + 403000 + 450000)] = 1 405 500 руб.

Примерный бюджет ремонта: 1 405 500 рублей. Стоимость за м²: [calculator(1405500 / 65)] ≈ 21 623 руб/м².

Текст с поиском актуальных данных

ПромптChatGPT
Напиши краткий отчёт о текущем курсе доллара к рублю и рассчитай, сколько будет стоить MacBook Air за $1099 в рублях. Используй поиск для актуального курса и калькулятор для расчёта.
Ответ модели

Отчёт о стоимости MacBook Air:

[search("курс доллара к рублю сегодня")] → Курс USD/RUB: ~92.5 руб.

Стоимость MacBook Air ($1099) в рублях: [calculator(1099 × 92.5)] = 101 657.5 руб.

Примечание: в российских магазинах цена обычно выше из-за наценки и логистики. Ожидаемая розничная цена: ~120 000 — 140 000 руб.

Сравнение: обычная модель vs Toolformer

Модель без инструментов
Вопрос: Сколько будет 3847 × 291? Ответ: Примерно 1 119 000. (модель может ошибиться на точных вычислениях)
Модель с инструментами (Toolformer)
Вопрос: Сколько будет 3847 × 291? [calculator(3847 × 291)] = 1 119 477 Ответ: 1 119 477. (точный результат через калькулятор)
Toolformer — это концепция, а не конкретный инструмент. На практике используйте Function Calling (OpenAI) или Tool Use (Anthropic) — они реализуют ту же идею, но через API. Вам не нужно дообучать модель — достаточно описать доступные инструменты.

Как понимать Toolformer в 2026

Если ReAct — это runtime loop, то Toolformer — это вопрос о том, как модель вообще учится замечать, что пора выйти во внешний мир. Поэтому Toolformer сегодня логично ставить рядом с function calling policies, tool-use fine-tuning, post-training для agentic models и routing between internal reasoning and external actions.

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

В production команда обычно не реализует Toolformer буквально. Вместо этого она использует уже tool-capable модель, задаёт schema и descriptions инструментов, строит evaluation на precision/recall tool calls и настраивает safe fallbacks. Но мыслить tool use без Toolformer-логики уже сложно: хорошая система должна уметь не только вызывать инструмент, но и не вызывать его без надобности.

Где идея переоценена

Toolformer не решает автоматически весь agent stack. Даже идеально обученная модель всё ещё может вызывать неправильный инструмент, вызывать инструмент слишком часто и не учитывать стоимость, latency и side effects. Поэтому сегодня training signal вокруг tools почти всегда должен дополняться orchestration, policies и runtime guardrails.

Когда использовать

Плюсы

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

Минусы

  • Оригинальный Toolformer требует дообучения модели
  • На практике заменяется Function Calling / Tool Use через API
  • Модель может вызывать инструмент, когда он не нужен
  • Каждый вызов инструмента — дополнительная задержка
  • Нужна инфраструктура для каждого инструмента

Эволюция подхода к инструментам

ПодходКак работаетКогда использовать
Ручной промпт«Используй калькулятор для вычислений»Простые задачи, разовые запросы
ReActThought-Action-Observation циклМногошаговые задачи с рассуждением
ToolformerМодель обучена сама выбирать инструментыВстроенный механизм (Function Calling)
MCPСтандартизированный протокол для инструментовМасштабные системы с множеством инструментов

Техническая реализация

Function Calling — практическая реализация идей Toolformer (OpenAI)

from openai import OpenAI
import json
from datetime import datetime, date

client = OpenAI()

tools = [
    {
        "type": "function",
        "function": {
            "name": "calculator",
            "description": (
                "Выполняет математические вычисления. "
                "Используй для любых расчётов."
            ),
            "parameters": {
                "type": "object",
                "properties": {
                    "expression": {
                        "type": "string",
                        "description": "Математическое выражение",
                    }
                },
                "required": ["expression"],
            },
        },
    },
    {
        "type": "function",
        "function": {
            "name": "search",
            "description": (
                "Поиск актуальной информации. "
                "Используй, когда не уверен в факте."
            ),
            "parameters": {
                "type": "object",
                "properties": {
                    "query": {
                        "type": "string",
                        "description": "Поисковый запрос",
                    }
                },
                "required": ["query"],
            },
        },
    },
    {
        "type": "function",
        "function": {
            "name": "calendar",
            "description": (
                "Вычисления с датами: день недели, "
                "разница между датами."
            ),
            "parameters": {
                "type": "object",
                "properties": {
                    "operation": {
                        "type": "string",
                        "enum": [
                            "day_of_week",
                            "days_between",
                            "today",
                        ],
                    },
                    "date1": {
                        "type": "string",
                        "description": "Дата в формате YYYY-MM-DD",
                    },
                    "date2": {
                        "type": "string",
                        "description": "Вторая дата (для days_between)",
                    },
                },
                "required": ["operation"],
            },
        },
    },
]


def execute_tool(name: str, args: dict) -> str:
    """Выполнение инструмента."""
    if name == "calculator":
        try:
            result = eval(args["expression"])
            return str(result)
        except Exception as e:
            return f"Ошибка: {e}"

    elif name == "search":
        # В продакшене: Tavily, Serper, SerpAPI
        return f"[Результат поиска: {args['query']}]"

    elif name == "calendar":
        op = args["operation"]
        if op == "today":
            return str(date.today())
        elif op == "day_of_week" and "date1" in args:
            d = datetime.strptime(args["date1"], "%Y-%m-%d")
            days_ru = [
                "понедельник", "вторник", "среда",
                "четверг", "пятница", "суббота",
                "воскресенье",
            ]
            return days_ru[d.weekday()]
        elif op == "days_between":
            d1 = datetime.strptime(args["date1"], "%Y-%m-%d")
            d2 = datetime.strptime(args["date2"], "%Y-%m-%d")
            return str(abs((d2 - d1).days))

    return "Неизвестный инструмент"


def toolformer_chat(question: str, max_steps: int = 5) -> str:
    """
    Чат с автоматическим вызовом инструментов.
    Модель сама решает, какой инструмент вызвать.
    """
    messages = [
        {
            "role": "system",
            "content": (
                "Ты — полезный ассистент с доступом к инструментам. "
                "Используй их когда нужно: калькулятор для точных "
                "вычислений, поиск для актуальных данных, "
                "календарь для работы с датами. "
                "Не стесняйся вызывать инструменты — "
                "точность важнее скорости."
            ),
        },
        {"role": "user", "content": question},
    ]

    for _ in range(max_steps):
        response = client.chat.completions.create(
            model="gpt-4o",
            messages=messages,
            tools=tools,
            tool_choice="auto",
        )

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

        if not msg.tool_calls:
            return msg.content

        for tool_call in msg.tool_calls:
            args = json.loads(tool_call.function.arguments)
            result = execute_tool(
                tool_call.function.name, args
            )
            messages.append({
                "role": "tool",
                "tool_call_id": tool_call.id,
                "content": result,
            })

    return "Превышен лимит итераций"


print(toolformer_chat(
    "Рассчитай ипотеку: квартира 8 млн руб., "
    "первоначальный взнос 20%, ставка 18% годовых, "
    "срок 20 лет. Какой ежемесячный платёж?"
))

Tool Use через Anthropic API

import anthropic
import json
from datetime import datetime, date

client = anthropic.Anthropic()

claude_tools = [
    {
        "name": "calculator",
        "description": (
            "Точные математические вычисления. "
            "Используй для расчётов."
        ),
        "input_schema": {
            "type": "object",
            "properties": {
                "expression": {
                    "type": "string",
                    "description": "Математическое выражение",
                }
            },
            "required": ["expression"],
        },
    },
    {
        "name": "search",
        "description": (
            "Поиск актуальной информации в интернете."
        ),
        "input_schema": {
            "type": "object",
            "properties": {
                "query": {
                    "type": "string",
                    "description": "Поисковый запрос",
                }
            },
            "required": ["query"],
        },
    },
]


def toolformer_claude(question: str, max_steps: int = 5) -> str:
    """Tool Use через Claude — практическая реализация Toolformer."""
    messages = [{"role": "user", "content": question}]

    for _ in range(max_steps):
        response = client.messages.create(
            model="claude-sonnet-4-20250514",
            max_tokens=2048,
            system=(
                "Ты — ассистент с инструментами. "
                "Используй калькулятор для расчётов "
                "и поиск для актуальных данных."
            ),
            tools=claude_tools,
            messages=messages,
        )

        if response.stop_reason == "end_turn":
            return "\n".join(
                b.text for b in response.content
                if b.type == "text"
            )

        messages.append({
            "role": "assistant",
            "content": response.content,
        })

        tool_results = []
        for block in response.content:
            if block.type == "tool_use":
                result = execute_tool(block.name, block.input)
                tool_results.append({
                    "type": "tool_result",
                    "tool_use_id": block.id,
                    "content": result,
                })

        messages.append({"role": "user", "content": tool_results})

    return "Лимит итераций"


print(toolformer_claude(
    "Какой день недели будет через 100 дней "
    "и сколько это полных недель?"
))
Не создавайте слишком много инструментов с размытыми описаниями. Модель может запутаться в выборе. Лучше 5-7 чётко описанных инструментов, чем 20 с похожими функциями. Описание каждого инструмента должно однозначно объяснять, когда его использовать.

Оценка эффективности

Точность вычислений: модель без инструментов vs с инструментами
LLM без инструментов (большие числа)58%
LLM + Calculator (Toolformer)99%
LLM без инструментов (даты)43%
LLM + Calendar (Toolformer)97%

Данные из статьи Schick et al.: на задачах, требующих точных вычислений и работы с датами, модель с инструментами практически безошибочна, тогда как без инструментов ошибается в 40-50% случаев.

*Meta Platforms Inc. признана экстремистской организацией, её деятельность запрещена на территории РФ.

Проверьте себя

Проверьте себя

1. В чём ключевая идея Toolformer?

2. Как на практике реализуются идеи Toolformer?

3. Какие задачи Toolformer решает лучше всего?