Add destructive confirmation and import guidance

This commit is contained in:
github-ops
2026-06-21 01:42:45 +00:00
parent ef2912855b
commit 5447e1bad0
29 changed files with 1099 additions and 24 deletions
+166
View File
@@ -0,0 +1,166 @@
# Проектирование MCP-инструментов
Этот документ описывает, как делать REST-инструменты, с которыми LLM-клиент работает предсказуемо.
## Главная идея
Хороший инструмент решает одну понятную задачу. Модель должна легко понять:
- когда вызывать инструмент;
- какие параметры нужны;
- что считается успешным результатом;
- что делать при ошибке.
Плохой инструмент обычно слишком общий: `call_api`, `manage_user`, `execute_request`. Такие названия и описания заставляют модель угадывать.
## Название и описание
Имя инструмента должно быть техническим и стабильным:
```text
get_customer_by_email
create_support_ticket
delete_draft_invoice
```
Описание должно начинаться с действия и объяснять сценарий:
```text
Получает карточку клиента по email. Используйте, когда нужно найти клиента перед созданием обращения или проверкой статуса заказа. Возвращает идентификатор клиента, имя, email и текущий статус.
```
Не используйте расплывчатые формулировки:
```text
Работает с клиентами.
Обрабатывает данные.
Выполняет запрос к API.
```
## Входные параметры
Каждый параметр должен иметь понятный смысл. Если значение выбирается из небольшого набора, лучше задать `enum`.
Плохо:
```json
{
"action": "string",
"data": "object"
}
```
Хорошо:
```json
{
"email": "user@example.com",
"include_orders": true
}
```
Если endpoint делает несколько разных действий через параметр `action`, чаще всего лучше разделить его на несколько инструментов.
## Ответ инструмента
Не отдавайте модели весь ответ внешнего API без необходимости. Лучше выбрать только поля, которые нужны для следующего шага рассуждения.
Плохо:
```json
{
"response": "{ весь JSON от внешнего API }"
}
```
Хорошо:
```json
{
"customer_id": "cus_123",
"status": "active",
"open_orders_count": 2
}
```
Для массивов ограничивайте размер ответа и возвращайте только важные поля.
## Ошибки
Crank возвращает структурированные ошибки. MCP-клиент получает код ошибки, сообщение, признак повторяемости и рекомендацию.
Пример:
```json
{
"error_code": "upstream_rate_limited",
"message": "Внешний API вернул HTTP 429.",
"recoverable": true,
"suggested_action": "Повторите запрос позже.",
"request_id": "req_123"
}
```
Это лучше, чем отдавать сырой ответ внешнего API или stack trace.
## Повторное выполнение POST/PATCH
Для операций, которые меняют состояние, используйте idempotency key. Это защищает от повторного создания сущности, если MCP-клиент повторит вызов после таймаута.
Пример входа:
```json
{
"request_id": "order-2026-06-21-001",
"customer_id": "cus_123",
"amount": 1200
}
```
В конфигурации операции можно указать, что `request_id` используется как ключ идемпотентности и передается во внешний API через заголовок `Idempotency-Key`.
## Опасные операции
Для `DELETE` Crank использует двухшаговое подтверждение.
Первый вызов не отправляет запрос во внешний API. Он возвращает confirmation token:
```json
{
"error_code": "confirmation_required",
"message": "Операция требует подтверждения. Повторите вызов с _crank_confirmation_token=\"ct_...\"."
}
```
Второй вызов должен повторить те же аргументы и добавить токен:
```json
{
"order_id": "ord_123",
"_crank_confirmation_token": "ct_..."
}
```
Токен одноразовый, имеет короткий срок жизни и привязан к агенту, операции, версии и исходным аргументам.
## Каталог агента
Не привязывайте к одному агенту весь API. Лучше создать несколько агентов под конкретные задачи:
- агент для курсов валют;
- агент для поддержки клиентов;
- агент для заявок и инцидентов;
- агент для отчетов.
Если у агента слишком много похожих инструментов, модель чаще ошибается при выборе.
## Проверочный список
- Имя инструмента конкретное и не похоже на `call_api`.
- Описание объясняет, когда вызывать инструмент.
- У каждого важного параметра есть понятное назначение.
- Multi-action endpoint разделен на отдельные инструменты.
- Ответ не содержит лишний большой JSON.
- Для POST/PATCH задан idempotency key, если повторный вызов может создать дубль.
- Для DELETE пользователь видит двухшаговое подтверждение.
- Агенту привязаны только инструменты, нужные для его задачи.