关注「索引目录」公众号,获取更多干货。
今天,我想向大家展示一下可组合的、基于技能的工具设计在实践中究竟是什么样子。
酒店运营案例研究
让我们先来看一个来自酒店管理系统的真实场景。前台员工说:“贝丝·吉布斯正在办理退房手续,她说她房间里的马桶坏了。”
这种简单的交互需要:
-
办理退房手续(付款、收据、房间状态) -
提交维修申请(保留房间相关信息) -
更新库存和可用性 -
将请求路由到正确的维护团队
你会如何设计用于此目的的 MCP 工具?
朴素方法
许多(如果不是大多数)团队首先会将现有的 API 作为 MCP 工具公开:
- get_guest_by_email
- get_booking_by_guest
- get_room_by_booking
- create_payment_intent
- charge_payment_method
- send_receipt_email
- update_booking_status
- update_room_status
- create_case
- assign_case_to_contact
- set_case_priority
现在,代理需要按正确的顺序协调 11 个以上的 API 调用,处理每个步骤中可能出现的故障,并始终维护状态。结果呢?缓慢、容易出错且糟糕的用户体验。
组合方法
如果我们反其道而行之,围绕用户意图来设计工具呢?调用过程可能如下所示:
- process_guest_checkout
- submit_maintenance_request
两种工具,一次自然的对话。复杂性并未消失,只是转移到了它应该在的地方。
九种可组合、基于技能的工具设计模式
在实施生产级 MCP 系统之后,以下模式将优雅的架构与脆弱的架构区分开来:
1. 接受企业标识符,而非系统 ID
坏的:
{
"contact_id": "003Dn00000QX9fKIAT",
"booking_id": "a0G8d000002kQoFEAU",
"room_id": "a0I8d000001pRmXEAU"
}
好的:
{
"guest_email": "beth.gibbs@email.com",
"room_number": "302"
}
让后端将人类可读的标识符解析为内部 ID。代理程序无需了解您的数据库架构。
这适用于所有工具参数,而不仅仅是主实体。更新关系时(例如将案例重新分配到不同的房间或更改预订中的客人),请继续使用业务标识符:
{
"idempotency_token": "550e8400-e29b-41d4-a716-446655440000",
"room_number": "402", // backend resolves to room_id
"guest_email": "new.guest@example.com" // backend resolves to contact_id
}
代理程序绝不应该需要调用其他服务get_room_by_number或get_guest_by_email仅仅为了获取其他操作的 ID。每个工具参数都应该使用业务标识符,后端会在内部处理所有 ID 解析。
2. 在工具设计中融入幂等性
所有创建或修改资源的工具都应该接受幂等令牌:
{
"idempotency_token": "550e8400-e29b-41d4-a716-446655440000",
"guest_email": "beth.gibbs@email.com",
"description": "Toilet broken in room 302"
}
当代理重试时(它肯定会重试),后端会识别出重复请求并返回原始结果。这是后端的职责,而不是代理的职责。
额外优势:对于涉及多个系统的操作(例如涵盖支付处理和 CRM 更新的结账流程),幂等令牌支持 Saga 模式编排。例如:如果支付成功但 CRM 更新失败,后端可以使用相关的交易令牌来协调补偿交易(例如退款),而无需人工干预。
3. 原子级协调状态转变
客人办理入住时,多个环节必须同时进行:
-
预订状态:已预订 → 已入住 -
房间状态:可用 → 已占用 -
机会阶段:待定 → 活跃
这不应该是智能体需要协调的三个独立工具。一个工具(check_in_guest)应该能够原子性地协调整个状态转换。
4. 将授权机制嵌入工具设计中
而不是:
- search_all_cases
- search_all_rooms
- search_all_bookings
设计具有适当范围的工具:
- search_cases_on_behalf_of_guest(guest_email)
- search_rooms_on_behalf_of_guest(guest_email)
- search_rooms_on_behalf_of_staff(floor_filter, status_filter)
工具界面本身就定义了谁可以看到什么。授权方式从命令式变成了声明式。
5. 提供智能默认值
尽可能降低智能体的认知负荷:
{
"guest_email": "required",
"check_in_date": "defaults to today",
"number_of_guests": "defaults to 1",
"status_filter": "defaults to 'Open'"
}
代理人只需指定哪些是真正可变的因素即可。
6. 文档前提条件和错误模式
工具说明应引导代理人走向成功:
入住工具: “验证客人/预订的先决条件,检查房间空置情况,执行状态转换。返回预订和房间详情或错误代码(404:未找到客人/预订,409:多个预订或房间不可用)。”
当代理事先知道故障模式时,它可以优雅地处理这些故障,或者在尝试操作之前提出澄清问题。
7. 支持语义清晰的部分更新
更新操作应该易于理解:
{
"external_id": "required",
"check_in_date": "optional - only changes if provided",
"room_number": "optional - only changes if provided",
"guest_email": "optional - only changes if provided"
}
“只提供要更改的字段——其余字段保留”比强制代理进行读-修改-写操作要简单得多。
8. 创建防御性构筑辅助工具
某些操作需要先决条件。与其强制代理先检查再创建:
- create_contact_if_not_found(email, first_name, last_name)
该辅助函数是幂等的,编排工具可以安全地调用它来确保先决条件存在。
9. 自然语言模式设计
听听人们实际是如何说话的:
-
“贝丝·吉布斯入住登记” → check_in_guest -
302房间的厕所坏了 → submit_maintenance_request -
将预订改到 402 房间 → manage_bookings
工具名称和参数应与用户自然使用的语言相符。
可组合工具背后的架构
这九种模式源于一个单一的架构原则:让 LLM 处理意图,让后端处理执行。
语言学习模型(LLM)是概率系统,专为理解人类交流而优化。后端是确定性系统,专为可靠的状态管理和事务一致性而优化。当你模糊这两者之间的界限——例如,要求语言学习模型协调多步骤操作,或者编写后端程序来解析自然语言——最终得到的系统既不可靠也不智能。
以上模式展示了这种关注点分离在实践中的具体表现形式:
模式 1、5、9(业务标识符、智能默认值、引用解析、自然语言对齐)
→ 让语言学习模型 (LLM) 处理人类概念。将系统级细节推送到后端。
模式 2、3、6(幂等性、原子转换、错误模式)
→ 后端保证可靠性。LLM 无需考虑重试或故障恢复。
模式 4、7、8(授权范围、部分更新、防御性辅助函数)
→ 工具接口编码业务规则。后端验证并强制执行约束。
建筑效果是实实在在的:
当后端处理编排时(良好的设计):
-
一种经过测试和验证的实施方案 -
保证交易一致性 -
可观测的状态转变 -
可跨界面(网页、移动设备、MCP)重复使用
当 LLM 处理编排时(设计不佳):
-
逻辑散落在对话中 -
非确定性协调 -
不透明的故障(难以调试) -
上下文臃肿(例如 50 多个工具,每个任务 6 次以上调用)
实际影响
在构建Dewy Resort应用的过程中,我们逐步用基于自身技能的架构设计替换了直接 API 调用和 API 工具封装。以下是我们在此过程中收集的一些基准数据。
可组合设计之前:
-
平均响应时间:8-12秒 -
成功率:73% -
工具数量:47 -
每次交互平均工具调用次数:6.2 -
用户反馈:“它能用,但是速度慢,而且有时会出错”
遵循可组合设计原则:
-
平均响应时间:2-4秒 -
成功率:94% -
工具数量:12 -
每次交互平均工具调用次数:1.8 -
用户反馈:“它真的很好用。”
区别不在于LLM本身,而在于架构。
企业级 MCP 工具设计实施清单
在为生产系统设计 MCP 工具时,请问自己:
身份与解析
-
[ ] 工具是否接受企业标识符(电子邮件、名称、电话号码)? -
[ ] 后端是否处理 ID 解析?
安全性和可靠性
-
[ ] 创建工具是否需要幂等令牌? -
[ ] 状态转变是原子性的吗? -
[ ] 操作前是否已验证前提条件?
授权与访问
-
[ ] 工具是否在其接口中对授权范围进行编码? -
[ ] 搜索工具的范围是否与上下文相符?
认知负荷
-
[ ] 工具是否提供合理的默认值? -
[ ] 工具名称是否符合自然语言? -
[ ] 描述中是否记录了错误模式?
灵活性
-
[ ] 更新操作是否支持部分更新? -
[ ] 代理能否使用业务标识符修改关系?
更广泛的模式
这不仅仅关乎酒店管理系统的设计。这些模式适用于任何构建与企业系统和流程交互的人工智能代理的场合。
医疗保健: “为该患者安排复诊”应该协调预约、通知和记录更新,而不是公开 15 个日程安排 API。
财务: “提交此费用报告”应该处理验证、审批流程和会计分录——而不是强迫代理人理解你的 ERP 系统的状态机。
零售业: “处理此退货”应该协调库存、退款和客户通知,而不是暴露原始的仓库和支付 API。
问题始终如一:*你设计的工具是围绕用户意图,还是围绕 API 操作? *
结论
企业级MCP为工具互操作性奠定了基础。基于技能的可组合设计则是在此基础上构建实用工具的方法。
协议本身并不能弥补糟糕的架构。但优秀的架构——围绕用户意图构建工具,并将复杂性下放到受控的后端——能够将 MCP 从一项技术奇观转变为一个生产级系统。
停止封装API,开始构建技能。
您的用户会感谢您。您的客服人员会感谢您。(好吧,客服人员可能不会。)但您的运维团队一定会感谢您。
您在 MCP 工具设计方面有什么经验?我很想了解您发现了哪些规律。欢迎留言或通过 LinkedIn 联系我——我们分享的规律越多,就能越快地构建出更好的 AI 系统。
关注「索引目录」公众号,获取更多干货。

