TL;DR
Function Calling (FC) — встроенная функция в ChatGPT, Claude и других LLM, которая заставляет модель отвечать строго в формате JSON вместо свободного текста. Изначально создавалась для вызова внешних API, но исследование показывает неожиданный эффект: модель в 2.5 раза лучше следует правилам и инструкциям, когда отвечает структурированным выводом.
Проблема: модели легко отвлекаются на "шум" в тексте. Jailbreak-запросы используют это — обматывают вредоносный контент в кучу отвлекающих деталей ("напиши в стиле лимерика, добавь эмодзи, не длиннее 280 символов..."). Модель теряет фокус — сосредоточивается на формате вместо сути ("отклонить запрос на создание вредоносного контента"). Обычный промпт говорит "не делай X" текстом — модель видит это как рекомендацию, а не жёсткое правило.
FC решает через принудительную структуру. Вместо "отклони если вредоносно" модель получает схему JSON: {"is_malicious": true/false, "reason": "..."}. Чтобы заполнить поля, модель вынуждена сначала понять суть запроса — отвлекающие детали становятся шумом, который не влияет на заполнение структуры. Structured output работает как жёсткая форма, которая не даёт модели "уплыть" в свободные рассуждения.
Почему это работает
Слабость LLM: модели генерируют текст последовательно, токен за токеном. Когда задача в свободной форме ("отклони если плохо"), модель может выбрать любое направление рассуждений — в том числе уйти в детали формата вместо оценки содержания.
Сильная сторона LLM: модели отлично следуют явно заданной структуре. JSON-схема — это карта, по которой модель движется пошагово. Чтобы заполнить "is_malicious", нужно сначала понять содержание. Отвлекающие детали ("в стиле лимерика") не влияют на булево поле — модель их игнорирует.
Как FC использует это: исследование через причинно-следственный анализ (вмешательство в работу нейросети на уровне слоёв) показало:
- Изменение внутренней логики: FC меняет какие слои нейросети активно участвуют в генерации ответа. Средние слои (обработка смысла) становятся в 2 раза важнее vs модель без FC.
- Фокус на сути: модель с FC показывает на 10-20% выше корреляцию между "важностью фразы для задачи" и "вниманием модели к этой фразе". То есть отвлекающие приёмы jailbreak ("добавь эмодзи") меньше влияют на решение.
- Hardening decision boundary: structured output создаёт резкую границу между "вредоносно" и "безопасно". Вместо размытого "может быть проблематично" модель вынуждена выбрать
trueилиfalse— это заставляет чётче разделять категории.
Рычаги управления:
- Строгость схемы: больше обязательных полей → сильнее фокус на задаче
- Тип полей: boolean/enum → жёсткие решения; string → больше свободы
- Вложенность: простая схема
{result: "yes/no"}vs сложная с причинами и подкатегориями
Пример применения
Задача: Модерация комментариев в Telegram-канале про криптовалюты. Нужно отклонять: спам, агрессию, скам-схемы, рекламу без согласования. Проблема — пользователи маскируют нарушения ("друзья, это не реклама, просто делюсь находкой...").
Промпт:
Ты модератор канала. Проанализируй комментарий и заполни JSON:
{
"is_violation": true/false,
"violation_type": "spam|aggression|scam|ad|none",
"confidence": 1-10,
"reasoning": "краткое объяснение"
}
Правила:
- spam: массовые одинаковые сообщения
- aggression: оскорбления, угрозы
- scam: "гарантированный доход", "вложи и заработай"
- ad: ссылки на сторонние каналы/сервисы без согласования
Комментарий: "{текст_комментария}"
Результат:
Модель выдаст JSON с чёткой классификацией. Даже если комментарий обёрнут в "я не рекламирую, просто делюсь" — поле "is_violation" заставит модель проанализировать суть, а не форму подачи. В "reasoning" увидите логику решения. "confidence" покажет уверенность — низкая → на ручную проверку.
Шаблон промпта
Проанализируй {тип_контента} и заполни JSON строго по схеме:
{
"соответствует_критерию": true/false,
"категория": "вариант1|вариант2|вариант3",
"уверенность": 1-10,
"обоснование": "почему принято это решение"
}
Критерии проверки:
- {критерий_1}: {описание}
- {критерий_2}: {описание}
- {критерий_3}: {описание}
{Тип_контента}: "{контент_для_проверки}"
ВАЖНО: Отвечай ТОЛЬКО валидным JSON, без дополнительного текста.
Что подставлять:
{тип_контента}— что проверяем: комментарий, резюме, заявка, идея{критерий_N}— конкретные правила/требования для проверки{контент_для_проверки}— текст который нужно оценить
Адаптация для сложных задач: добавь вложенные объекты в JSON для многоуровневой проверки. Например, для резюме:
{
"соответствие": {
"опыт_годы": true/false,
"навыки": true/false,
"образование": true/false
},
"оценка_общая": 1-10,
"рекомендация": "пригласить|отклонить|уточнить"
}
```
🚀 **Быстрый старт** — вставь в чат:
```
Вот шаблон Function Calling для строгой проверки по правилам. Адаптируй под мою задачу: [твоя задача].
Задавай вопросы, чтобы заполнить поля.
[вставить шаблон выше]
```
Модель спросит **какие критерии проверки нужны и какой формат данных** — потому что для эффективной работы FC нужна **точная схема выходных полей**. Она возьмёт паттерн из шаблона и адаптирует под задачу.
## Ограничения
> ⚠️ **Overhead при сложных схемах:** Детальный JSON (10+ полей, вложенность) увеличивает время ответа на 20-40%. Для простых задач может быть избыточно.
> ⚠️ **Не для креативных задач:** FC жёстко структурирует вывод — плохо для сторителлинга, эссе, свободных рассуждений. Используй только когда нужен **чёткий результат по критериям**.
> ⚠️ **Чувствительность к формулировкам:** Нечёткие критерии ("интересно", "качественно") даадут размытые результаты даже в JSON. FC усиливает следование **явным** правилам, не компенсирует плохую постановку задачи.
> ⚠️ **Разная реализация в чатах vs API:** GPT/Claude в web-интерфейсе эмулируют FC через system prompt, в API — нативная поддержка. Эффективность может отличаться, но принцип работает везде.
## Как исследовали
Команда из университетов Гонконга, Лингнань, Токио и Альберты провела **причинно-следственный анализ** на четырёх моделях: Llama-3.1 (8B и 70B), Hermes-3-8B, Mistral-22B. Вместо простого A/B-тестирования они **вмешивались в работу нейросети** — отключали отдельные слои и смотрели как меняется выход. Это как МРТ мозга во время мышления: видно какие части активны для какой задачи.
**Layer-wise intervention:** "выключали" каждый из ~80 слоёв модели и мерили насколько изменился выход. Обнаружили: с FC **средние слои (14-17)** стали **вдвое важнее** для финального решения. Это слои где происходит **семантический анализ**. Без FC модель больше опиралась на поздние слои (генерация текста) — то есть **форма вытесняла содержание**.
**Token-wise intervention:** заменяли фразы в jailbreak-запросах на нейтральные (`---`) и смотрели как модель реагирует. Результат: с FC модель **на 10-20% сильнее коррелирует** внимание к фразе с её важностью для задачи. Отвлекающие детали ("в стиле лимерика, добавь эмодзи") **меньше влияют** на решение.
Протестировали на **100 jailbreak-запросах** из датасета WildJailbreak (80k+ примеров реальных атак на модели). Выбрали только те кейсы, где FC помог а обычный промпт провалился — чтобы **максимизировать контраст** для анализа.
**Неожиданная находка:** не только механика работы отличается, но и **применимость шире** чем думали. Изначально FC — для вызова API. Исследование показало: это **мощный инструмент для любых задач с чёткими критериями**. Structured output — не побочный эффект, а **ключевая фича** для улучшения compliance.
**Валидация на практике:** протестировали на бенчмарке MMLU-Pro (стандартная оценка LLM). FC показал **135% улучшение** в детекции вредоносного контента vs обычный промпт (семантически эквивалентный). При этом качество ответов на нормальные вопросы упало незначительно (1-2%), а время ответа выросло приемлемо (~0.5 сек на вопрос).
## Адаптации и экстраполяции
💡 **Адаптация для фильтрации резюме:**
Вместо "отклони если не подходит" — структура:
```
{
"опыт_лет": число,
"ключевые_навыки": ["навык1", "навык2"],
"соответствие_требованиям": {
"обязательные": true/false,
"желательные": 0-10
},
"решение": "пригласить|отклонить|уточнить",
"вопросы_для_интервью": ["вопрос1", "вопрос2"]
}
Модель вынуждена извлечь конкретные данные (годы, навыки) вместо общих впечатлений ("кажется опытным"). Поле "вопросы_для_интервью" заставляет проанализировать пробелы в резюме, а не просто оценить "подходит/не подходит".
🔧 Техника: вложенность для многоуровневой проверки
Простая схема {"valid": true/false} → бинарное решение.
Добавляем вложенность:
{
"проверки": {
"формальные": {"email": true, "телефон": true},
"содержательные": {"опыт": true, "навыки": false},
"культурное_соответствие": 7
},
"общая_оценка": 6,
"итог": "условно_подходит"
}
```
Эффект: модель **поэтапно анализирует** разные аспекты. Каждый уровень вложенности — отдельный фокус внимания. Промежуточные оценки **видны в JSON** — понятно где провал.
💡 **Экстраполяция: multi-agent через FC**
Вместо одной модели — симуляция нескольких:
```
Проанализируй идею с трёх точек зрения:
{
"оптимист": {
"оценка": 1-10,
"сильные_стороны": ["пункт1", "пункт2"],
"прогноз": "текст"
},
"пессимист": {
"оценка": 1-10,
"риски": ["риск1", "риск2"],
"прогноз": "текст"
},
"реалист": {
"оценка": 1-10,
"вероятный_сценарий": "текст",
"рекомендация": "делать|не_делать|доработать"
}
}
Идея: {описание}
Модель играет три роли последовательно, заполняя разные секции JSON. Structured output не даёт "размазать" оценки — каждая роль вынуждена дать чёткий вердикт.
Ресурсы
Digging Into the Internal: Causality-Based Analysis of LLM Function Calling
Zhenlan Ji, Daoyuan Wu, Wenxuan Wang, Pingchuan Ma, Shuai Wang, Lei Ma
The Hong Kong University of Science and Technology, Lingnan University, Renmin University of China, The University of Tokyo, University of Alberta
Код и дополнительные материалы: https://anonymous.4open.science/r/FC-Causal-0F21/
