Бэкенд вызова инструментов (function calling): изолированные HTTP-обработчики для LLM
Модели OpenAI, Anthropic и Google вызывают обычные HTTP-эндпоинты. В Inquir у каждого маршрута инструмента — свой контейнер, API-ключ и секреты вне промпта.
Обновлено: 2026-06-28
Кратко
Суть ответа
Бэкенд вызова инструментов (function calling): изолированные HTTP-обработчики для LLM. Каждая функция инструмента — отдельный HTTP-обработчик с API-ключом. Оркестратор (OpenAI, Anthropic и др.) вызывает URL со структурированным JSON.
Когда подходит и когда нет
- Инструмент работает с секретными данными или вызывает платные API
- Нужна изоляция зависимостей и логи с привязкой к конкретному инструменту
На что обратить внимание
- Все инструменты в одном процессе — один баг в зависимости ломает всё сразу. Откат затрагивает весь сервис.
- Без изоляции контейнеров утечка памяти в одном инструменте бьёт по остальным.
- Secrets in environment variables shared across all tools: rotating one breaks everything.
Ситуация: нагрузка и где обычно ломается
Почему function calling нужен настоящий бэкенд
Function calling (OpenAI, Anthropic, Gemini) позволяет модели запрашивать вызовы инструментов. В демо они выполняются рядом с циклом модели. В проде нужны аутентификация, секреты, rate limiting, трассировка и async для шагов длиннее одного round-trip.
Без отдельного бэкенда каждый вызов инструмента — открытая функция с теми же привилегиями, что и всё остальное. Скомпрометированный контекст модели может утянуть секреты или вызвать нежелательные побочные эффекты.
Компромиссы
Почему монолит под function calling не масштабируется
Все инструменты в одном процессе — один баг в зависимости ломает всё сразу. Откат затрагивает весь сервис.
Без изоляции контейнеров утечка памяти в одном инструменте бьёт по остальным.
Secrets in environment variables shared across all tools: rotating one breaks everything.
Как Inquir помогает в этом сценарии
Изолированная serverless-модель для вызова функций моделью
Каждая функция инструмента — отдельный HTTP-обработчик с API-ключом. Оркестратор (OpenAI, Anthropic и др.) вызывает URL со структурированным JSON.
Секреты — в переменных окружения. Тёплый пул смягчает холодный старт при частых циклах вызова инструментов. Пайплайн продолжит работу, если один вызов занимает больше секунды.
Что вы получаете на платформе
Что нужно надёжному бэкенду вызова инструментов
Структурированный JSON в ответе
Стабильный контракт ответа — оркестратор не ломается при эволюции схемы.
Проверка доступа до обработчика
API-ключ на маршруте — инструмент не получает неаутентифицированный вызов.
Передача в фон
Долгий инструмент: сразу вернуть { jobId }, оркестратор опрашивает статус — либо включить тёплый контейнер.
Наблюдаемость
Каждый вызов инструмента — запись в истории с телом запроса и ответом; при инциденте проще найти причину.
Что сделать дальше, по шагам
Как подключить бэкенд инструментов к LLM
Описать схему инструмента
JSON Schema в системном промпте; у каждого инструмента — URL шлюза Inquir и маршрут.
Написать обработчик
Разобрать структурированный JSON из event.body, вызвать внешний сервис, вернуть JSON.
Настроить ключ и задержку
API-ключ на маршруте; при частых вызовах — тёплый пул.
Пример кода
Tool calling flow: schema to handler
The model sees a function definition; your orchestrator maps it to a gateway route; the gateway enforces auth; the handler runs in isolation.
{ "type": "function", "function": { "name": "search_customer", "description": "Look up a customer by ID or email", "parameters": { "type": "object", "properties": { "query": { "type": "string", "description": "Customer ID or email" } }, "required": ["query"] } } }
export async function handler(event) { // Auth enforced at gateway — API key checked before this code runs const { query } = JSON.parse(event.body || '{}'); if (!query) return { statusCode: 400, body: JSON.stringify({ error: 'query required' }) }; const results = await db.customers.search(query); // DB_URL from workspace secrets return { statusCode: 200, body: JSON.stringify({ customers: results }) }; }
// When the model returns a tool_call, dispatch it to the gateway async function dispatchToolCall(toolCall) { const { name, arguments: args } = toolCall.function ?? toolCall; // Map tool name to gateway route const routeMap = { search_customer: process.env.GATEWAY_URL + '/tools/search-customer', }; const url = routeMap[name]; if (!url) throw new Error(`Unknown tool: ${name}`); const res = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Api-Key': process.env.TOOLS_API_KEY, // auth enforced at gateway route }, body: JSON.stringify(typeof args === 'string' ? JSON.parse(args) : args), }); if (!res.ok) throw new Error(`Tool ${name} returned ${res.status}`); return res.json(); // structured result passed back to the model }
Когда подходит и когда нет
Когда нужен отдельный бэкенд под вызов инструментов
Когда это уместно
- Инструмент работает с секретными данными или вызывает платные API
- Нужна изоляция зависимостей и логи с привязкой к конкретному инструменту
Когда лучше выбрать другое
- Инструмент только форматирует строку без побочных эффектов
Вопросы и ответы
Вопросы и ответы
Как связать определение инструмента с URL Inquir?
OpenAI/Anthropic принимают JSON Schema в tools/functions; URL шлюза Inquir задаёт ваш оркестратор: при tool call POST на маршрут с API-ключом. Модель видит имя и схему, не секреты и не сырой URL в промпте.
Поддерживается параллельный вызов нескольких инструментов?
Да. Каждый параллельный вызов — отдельный HTTP-запрос к своему маршруту; Inquir масштабирует их независимо.