TL;DR
Tool calling — это когда LLM сама решает вызвать внешний инструмент (функцию, API) вместо того чтобы генерировать ответ. Видит запрос "какая погода в Москве?" → понимает что нужен API погоды → формирует структурированный вызов get_weather(city="Москва") → получает данные → отвечает пользователю. Модель должна уметь три вещи: распознать когда нужен инструмент, выбрать правильный из списка, заполнить аргументы в нужном формате.
Исследователи проверили как работает tool calling на арабском языке. Главная находка: модель переносит способность вызывать инструменты между языками (тренировали на английском → работает на арабском), но проваливается на точности аргументов. Если тренировали на английских примерах, модель на арабском запросе выдаёт translate(text="Hello", from="en") вместо translate(text="مرحبا", from="ar") — правильный инструмент, но язык аргумента перепутан. Ещё хуже с форматом: 50% ошибок — это когда модель поняла правильно, но сформатировала иначе ("Что такое ислам?" vs "Расскажи что такое ислам").
Решение простое: few-shot примеры на целевом языке и в точном формате. Показали модели 10-20 примеров на арабском с правильным форматом аргументов → точность с 45% до 99%. Работает даже для инструментов, которых не было в тренировочных данных — модель обобщает паттерн.
Схема исследования
ТЕСТ 1: Тренировка на английском → тест на арабском
└─ Распознавание инструмента: ✓ работает (recall ~0.80)
└─ Точность аргументов: ✗ провал (ArgA ~0.45)
ТЕСТ 2: Тренировка на арабском → тест на английском
└─ Распознавание: ✓ работает (recall ~0.82)
└─ Аргументы: ✗ провал (ArgA ~0.56)
ТЕСТ 3: Билингвальная тренировка (EN + AR)
└─ Распознавание: ✓ отлично (recall ~0.86)
└─ Аргументы: ✓ хорошо (ArgA ~0.80)
ТЕСТ 4: Добавили примеры конкретных инструментов
└─ Распознавание: ✓ идеально (recall ~0.99)
└─ Аргументы: ✓ идеально (ArgA ~0.99)
Все эксперименты — это fine-tuning моделей. Но принципы применимы через few-shot в обычном чате.
Пример применения
⚠️ Это исследование про тренировку моделей, но принципы работают в чате через few-shot.
Задача: Ты используешь Claude/ChatGPT с доступом к API переводчика, новостей и ИИ-генератора изображений. Хочешь чтобы модель сама решала когда вызывать какой инструмент, а не ты вручную.
Промпт:
У тебя есть три инструмента:
1. translate(text, from_lang, to_lang) — перевести текст
2. get_news(query) — найти свежие новости
3. generate_image(prompt) — создать изображение
Примеры правильного использования:
Запрос: "Переведи 'привет' на английский"
Ответ: translate(text="привет", from_lang="ru", to_lang="en")
Запрос: "Что нового в мире ИИ?"
Ответ: get_news(query="искусственный интеллект новости")
Запрос: "Нарисуй кота в космосе"
Ответ: generate_image(prompt="кот в скафандре в космосе")
Запрос: "Столица Франции?"
Ответ: Париж. (инструмент не нужен)
---
Теперь ты. Запрос: "Найди последние новости про нейросети на русском"
Результат: Модель выдаст структурированный вызов в правильном формате с аргументами на русском языке. Без примеров (few-shot) она может перепутать язык аргументов или формат.
Почему это работает
LLM не "понимают" API в человеческом смысле — они распознают паттерны в тексте. Когда видят описание инструмента + запрос пользователя, генерируют текст похожий на то что видели в тренировочных данных.
Проблема №1: Кросс-языковой перенос работает для распознавания ("нужен переводчик"), но ломается на деталях (язык аргумента, формат даты, порядок параметров). Модель обучена на английских примерах → привыкла к "text": "Hello" → на арабском запросе выдаёт "text": "Hello" вместо "text": "مرحبا".
Проблема №2: 50% ошибок — это парафразы. Ground truth: translate(text="Что такое ислам?"). Модель выдала: translate(text="Расскажи что такое ислам"). Семантически идентично, синтаксически — провал. LLM не знает что "расскажи" и "что такое" — это одно и то же для API.
Решение: Few-shot убирает двусмысленность. Показал 3-5 примеров в точном формате → модель запоминает паттерн и воспроизводит синтаксически, не только семантически. Билингвальные примеры учат модель переключать язык аргументов под язык запроса.
Рычаги управления:
- Количество примеров: 1-2 для простых форматов, 5-10 для сложных или билингвальных
- Язык примеров: Всегда совпадает с языком работы — если запросы на русском, примеры на русском
- Детализация формата: Укажи точный формат даты, кавычки, регистр — модель скопирует
- Негативные примеры: Покажи когда инструмент НЕ нужен — снизит ложные срабатывания
Шаблон промпта
У тебя есть следующие инструменты:
{список_инструментов_с_описанием}
Примеры использования:
Запрос: {пример_запроса_1}
Ответ: {пример_вызова_1}
Запрос: {пример_запроса_2}
Ответ: {пример_вызова_2}
Запрос: {пример_БЕЗ_инструмента}
Ответ: {прямой_ответ} (инструмент не нужен)
---
Теперь ты. Запрос: {твой_запрос}
Что подставлять:
{список_инструментов}— каждый инструмент с именем, параметрами, описанием{пример_запроса_N}— типичный пользовательский запрос на языке работы{пример_вызова_N}— структурированный вызов в точном формате (с кавычками, запятыми, языком){пример_БЕЗ_инструмента}— запрос где инструмент не нужен + прямой ответ{твой_запрос}— реальный запрос
Ключевые правила:
- Примеры на том же языке что запросы — кросс-языковой перенос ломается на деталях
- Формат вызова идентичен между примерами — порядок параметров, кавычки, регистр
- Минимум один негативный пример (без вызова) — снижает ложные срабатывания
Ограничения
⚠️ Язык примеров: Если примеры на английском, а запросы на русском — точность аргументов падает с 80% до 45%. LLM может вызвать правильный инструмент, но заполнить аргументы на английском вместо русского.
⚠️ Паттерн-матчинг, не понимание: LLM копирует формат из примеров. Если формат в примерах отличается от того что ожидает API — будут ошибки. Нужен идентичный синтаксис.
⚠️ Новые инструменты: Для инструментов которых нет в примерах, recall падает с 99% до 66-82% для обычных инструментов и до 25-47% для узкоспециализированных. Few-shot помогает, но не гарантирует обобщение.
Как исследовали
Взяли открытую арабскую модель Fanar-9B и два публичных датасета tool calling (Glaive и xLAM) — в сумме ~100 тысяч примеров вызовов ~4000 разных инструментов. Перевели на арабский через Gemini. Добавили два собственных датасета: CustomTools (синтетические инструменты типа перевода, генерации изображений, исламских знаний) и IslamicRAGTool (реальные логи вопросов-ответов).
Прогнали 5 экспериментов с разными комбинациями:
- Тренировка на английском
- Тренировка на арабском
- Общий instruction tuning + английский tool calling
- Общий instruction tuning + билингвальный tool calling (EN + AR)
- Всё вместе + примеры конкретных инструментов
Измеряли precision (из того что модель назвала инструментом, сколько правильно) и recall (из того что надо было вызвать, сколько вызвали), плюс ArgA — процент вызовов где и инструмент и все аргументы идеально совпали.
Неожиданность: 50% ошибок ArgA — это парафразы. Ground truth: "Что такое ислам?". Модель: "Расскажи что такое ислам". Семантически то же самое, синтаксически — провал. Это объясняет почему добавление примеров конкретных инструментов дало скачок ArgA с 58% до 99% — модель запомнила синтаксис, а не только смысл.
Второй блок ошибок (38%) — язык аргументов. Тренировали на английском → модель на арабском запросе выдаёт английские значения параметров. Билингвальные примеры решили проблему.
Ресурсы
Tool Calling for Arabic LLMs: Data Strategies and Instruction Tuning
Датасеты и модели: https://huggingface.co/collections/QCRI/arabictoolcalling-68b82e0b8f0865d6e3b179e7
Asim Ersoy, Enes Altinisik, Husrev Taha Sencar, Kareem Darwish
Qatar Computing Research Institute, HBKU
