Менеджер написал: «Верни заказ и предупреди клиента». Copilot составил письмо и сразу отменил доставку. Через минуту выяснилось, что «верни» означало открыть карточку возврата. Естественный язык снял трение заодно с последней проверкой смысла.
Команда превращается в план, не в действие
Copilot получает состояние открытой сущности и права пользователя. Модель выбирает только операции из реестра, backend повторно проверяет аргументы и показывает diff. Чтение можно выполнить сразу. Запись требует явного подтверждения, а необратимая операция иногда требует второго сотрудника.
TOOLS = {
"draft_customer_message": Tool(risk="read", handler=draft_message),
"change_shipping_address": Tool(risk="write", handler=change_address),
"refund_payment": Tool(risk="money", handler=refund),
}
async def execute(call, actor, confirmed=False):
tool = TOOLS[call.name]
authorize(actor, call.name, call.arguments)
validate_business_rules(call)
if tool.risk != "read" and not confirmed:
return Preview(diff=await tool.handler.preview(**call.arguments))
return await tool.handler.run(idempotency_key=call.id, **call.arguments)UI должен показывать, какие поля изменятся, от чьего имени уйдёт сообщение и можно ли отменить действие. Audit log хранит исходную фразу, plan, подтверждение, результат и версии. Секреты и скрытые поля не попадают в контекст только потому, что пользователь открыл соседнюю вкладку.
Failure modes
Модель выбирает несуществующий ID, повторяет действие после таймаута, использует данные из другой вкладки или выполняет старый preview после изменения записи. Защита обычная: foreign key validation, idempotency, optimistic locking и короткий срок жизни плана. Copilot не отменяет транзакции и права доступа.
Правило: интерфейс может быть разговорным, но исполнение остаётся типизированным, авторизованным и скучным.
Практикум 50.1
Добавьте в тестовую админку три read-only инструмента и один обратимый write-инструмент. Реализуйте preview, подтверждение, idempotency и audit log. Проверьте попытки изменить чужую запись, повторить call и подтвердить устаревший plan. Измерьте не число сообщений, а время завершения операции и долю отменённых preview.