API инструментов ИИ-агента: защищённые конечные точки для LLM
Каждый инструмент агента — отдельный HTTP-маршрут на шлюзе с API-ключом. Секреты провайдера в переменных окружения функции, изолированный контейнер, тёплый пул для частых вызовов инструментов.
Обновлено: 2026-04-20
Кратко
Суть ответа
API инструментов ИИ-агента: защищённые конечные точки для LLM. Одна функция на инструмент: `/search-customer`, `/create-invoice`, `/check-inventory`. API-ключ на уровне маршрута — без кода проверки авторизации внутри обработчика.
Когда подходит и когда нет
- Инструмент работает с регулируемыми данными или секретами
- Нужна изоляция зависимостей между инструментами
На что обратить внимание
- Если все инструменты в одной функции — зависимости конфликтуют, логи смешиваются, и по ним почти нельзя понять, что именно сломалось.
- Без аутентификации на шлюзе инструмент открыт любому, кто знает URL.
Ситуация: нагрузка и где обычно ломается
Почему инструменты агентов нужно изолировать
- Authenticated HTTP endpoints — model cannot call open routes
- Secrets off the model path — API keys never in prompts or context windows
- Isolated execution — one tool failure cannot contaminate another
- Low latency on the warm path — tight tool loops need sub-100ms response
- Observability — trace which tool failed and why, per model call
Один монолитный сервис для всех инструментов смешивает зависимости, секреты и логи. Один деплой ломает все инструменты разом.
Компромиссы
Почему serverless-монолит не подходит для агентов
Если все инструменты в одной функции — зависимости конфликтуют, логи смешиваются, и по ним почти нельзя понять, что именно сломалось.
Без аутентификации на шлюзе инструмент открыт любому, кто знает URL.
Как Inquir помогает в этом сценарии
Как строить API инструментов на Inquir
Одна функция на инструмент: `/search-customer`, `/create-invoice`, `/check-inventory`. API-ключ на уровне маршрута — без кода проверки авторизации внутри обработчика.
Секреты провайдера (OpenAI, Stripe, БД) в переменных окружения функции; ротация без повторного деплоя. Тёплый пул уместен при частых циклах вызова инструментов, когда важна стабильно низкая задержка.
Что вы получаете на платформе
Что нужно для API инструментов ИИ-агента
Одна функция на инструмент
Изолированные зависимости, отдельный деплой, логи с явной привязкой к инструменту.
Авторизация на шлюзе
API-ключ проверяется до хендлера. Инструмент не получает неаутентифицированный запрос.
Секреты на уровне функции
Разные ключи для разных инструментов; ротация без изменения промптов.
Тёплый пул
Горячие контейнеры для инструментов с высокой частотой вызовов в цикле «модель → инструмент».
Что сделать дальше, по шагам
Как создать инструмент для ИИ-агента
Определить контракт
Входные поля, валидация, форма ответа — до написания кода.
Написать обработчик
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 }`; оркестратор опрашивает статус. Либо включить тёплые контейнеры, чтобы снизить задержку.