API инструментов ИИ-агента: защищённые serverless-эндпоинты для LLM
Каждый инструмент LLM — отдельный аутентифицированный HTTP-маршрут на шлюзе: проверка API-ключа до хендлера, секреты workspace, изолированный контейнер на инструмент и тёплые пулы для стабильного трафика агента. Одна функция на инструмент — проще тестировать и наблюдать.
Обновлено: 2026-06-28
Кратко
Суть ответа
API инструментов ИИ-агента: защищённые serverless-эндпоинты для LLM. Одна функция на инструмент: /search-customer, /create-invoice, /check-inventory. API-ключ на уровне маршрута — без кода проверки авторизации внутри обработчика.
Когда подходит и когда нет
- Инструмент работает с регулируемыми данными или секретами
- Нужна изоляция зависимостей между инструментами
На что обратить внимание
- Если все инструменты в одной функции — зависимости конфликтуют, логи смешиваются, и по ним почти нельзя понять, что именно сломалось.
- Без аутентификации на шлюзе инструмент открыт любому, кто знает URL.
Ситуация: нагрузка и где обычно ломается
Что нужно бэкенду инструментов LLM
- Аутентифицированные HTTP-эндпоинты — модель не вызывает открытые маршруты
- Секреты вне промпта — ключи API не в промптах и контексте модели
- Изолированное выполнение — сбой одного инструмента не заражает другие
- Низкая задержка на прогретом пути — плотные циклы tool call нуждаются в ответе <100 мс
- Наблюдаемость — видно, какой инструмент упал и почему, на каждый вызов модели
В демо все инструменты часто живут в одном сервере или Lambda. В проде нужны изоляция, scoped-секреты и трассировка сбоев по каждому инструменту отдельно.
Компромиссы
Почему serverless-монолит не подходит для агентов
Если все инструменты в одной функции — зависимости конфликтуют, логи смешиваются, и по ним почти нельзя понять, что именно сломалось.
Без аутентификации на шлюзе инструмент открыт любому, кто знает URL.
Как Inquir помогает в этом сценарии
Как строить API инструментов на Inquir
Одна функция на инструмент: /search-customer, /create-invoice, /check-inventory. API-ключ на уровне маршрута — без кода проверки авторизации внутри обработчика.
Секреты провайдера (OpenAI, Stripe, БД) в переменных окружения функции; ротация без повторного деплоя. Тёплый пул уместен при частых циклах вызова инструментов, когда важна стабильно низкая задержка.
Что вы получаете на платформе
Возможности API инструментов ИИ-агента
API-ключ на шлюзе
Auth на уровне маршрута (none, X-Api-Key или bearer) до кода хендлера. Ключи — 32 байта base64url, хранятся как SHA-256, показываются один раз; маршрут можно ограничить конкретными ключами и ротировать без правок обработчика.
Секреты на функцию
Секреты workspace на функцию. Ключ OpenAI у summarizer не попадает в connector к БД.
Изолированные контейнеры
Каждый инструмент в своём контейнере. Сломанная зависимость в одном не бьёт по остальным.
Тёплые пулы для циклов tool call
Включите тёплые контейнеры для инструментов, которые модель вызывает часто. Настраивайте размер пула по p95 под реалистичным трафиком агента.
Что сделать дальше, по шагам
Как создать инструмент для ИИ-агента
Определить контракт
Входные поля, валидация, форма ответа — до написания кода.
Написать обработчик
Node.js, Python или Go: проверка входа, вызов внешнего API, возврат JSON.
Настроить доступ и секреты
API-ключ на маршруте, секреты провайдера в переменных окружения.
Пример кода
Multi-language tool API: lookup (Node.js) + classify (Python)
Same gateway, different runtimes. The model calls both with the same API key; secrets are scoped per function.
export async function handler(event) { // API key verified at gateway — handler assumes authenticated caller const { customerId } = JSON.parse(event.body || '{}'); if (!customerId) return { statusCode: 400, body: JSON.stringify({ error: 'customerId required' }) }; const record = await db.customers.findById(customerId); // DB_URL from workspace secrets if (!record) return { statusCode: 404, body: JSON.stringify({ error: 'not found' }) }; return { statusCode: 200, body: JSON.stringify({ customer: record }) }; }
import json, os from openai import OpenAI client = OpenAI(api_key=os.environ["OPENAI_API_KEY"]) # scoped to this tool only def handler(event, context): body = json.loads(event.get("body") or "{}") text = body.get("text") if not text: return {"statusCode": 400, "body": json.dumps({"error": "text required"})} r = client.chat.completions.create(model="gpt-4o-mini", messages=[{"role": "user", "content": f"Classify intent: {text}"}]) return {"statusCode": 200, "body": json.dumps({"intent": r.choices[0].message.content})}
Когда подходит и когда нет
Когда нужен отдельный эндпоинт инструмента
Когда это уместно
- Инструмент работает с регулируемыми данными или секретами
- Нужна изоляция зависимостей между инструментами
Когда лучше выбрать другое
- Инструмент только форматирует строку без побочных эффектов — достаточно простого встроенного ответа
Вопросы и ответы
Вопросы и ответы
Как передать URL инструмента в промпт?
URL шлюза + маршрут: https://gateway.../tool-name. API-ключ — в заголовке Authorization, не в промпте.
Как обрабатывать долгие вызовы инструментов?
Сразу вернуть { jobId }; оркестратор опрашивает статус. Либо включить тёплые контейнеры, чтобы снизить задержку.