#AI#AI Agent#MCP

MCP 工具 Schema 设计:让模型稳定调用,而不是猜参数

MCP 工具的输入输出 schema 是模型、客户端和业务服务之间的长期契约。本文讲解参数设计、错误模型、分页、兼容性和可测试性,避免工具越多越难用。

本文要点

  • 主题聚焦:AI、AI Agent、MCP
  • 适合人群:独立开发者、全栈工程师、AI 应用开发者
  • 核心价值:快速理解背景、实践路径、常见误区和工程建议
作者 @admin·发布于 2026年3月22日·更新于 2026年7月20日

一个工具能否被模型正确调用,往往不取决于描述写得多华丽,而取决于 schema 有没有把业务边界说清楚。参数名含糊、可选字段过多、输出只有一段自然语言,都会让模型在多轮任务中不断猜测。生产级 MCP 工具应该被当成公开 API 来设计。

从一个任务而不是一个后端接口开始

后端常见接口会把所有字段暴露出来,例如 update_ticket(id, body)。模型看到这种接口时,不知道 body 能改哪些字段,也不知道哪些修改需要确认。更合适的拆分是围绕用户任务:get_ticket、add_ticket_comment、change_ticket_priority。每个工具只做一件可审计的事。

工具名使用动词加对象,避免 doAction、run 这类泛化名称。描述里写清楚前置条件、影响范围和是否会写入数据。模型不能可靠地从名字推断风险,所以“会创建外部资源”或“只返回汇总数据”这样的语义必须明写。

输入参数要少而强约束

优先使用枚举、明确的字符串格式和有限的对象层级。例如优先级不要接受任意字符串:

json
{
  "ticketId": "INC-1042",
  "priority": "high",
  "reason": "Customer-facing checkout is unavailable"
}

其中 priority 应限定为 low、medium、high、critical,而不是接受“紧急”“P0”“高”之类的自然语言。用户输入仍然可以是自然语言,但客户端或工具前的解析层负责归一化;工具 contract 不应承担模糊解释。

必填字段只保留完成任务不可缺少的部分。把可从会话、授权上下文或当前项目推导出来的信息移出参数,例如用户 ID 和 tenantId 不该让模型填写。参数越多,模型漏填、填错或跨租户猜测的概率越高。

输出同时服务模型和人

工具输出不要只返回“成功”。至少包含稳定的机器字段、用户可读摘要和下一步可用信息:

json
{
  "ticket": { "id": "INC-1042", "priority": "high", "status": "open" },
  "changed": ["priority"],
  "summary": "已将 INC-1042 的优先级更新为 high。",
  "nextActions": ["add_ticket_comment", "get_ticket"]
}

机器字段让下一次工具调用可以引用精确 ID,摘要让用户确认实际结果,nextActions 则降低模型猜测可用工具的成本。对于查询工具,返回结构化结果、分页游标和总数范围,而不是把几千行表格拼成一段 Markdown。

错误是 contract 的一部分

把错误分成至少四类:输入无效、没有权限、资源不存在、可重试的依赖失败。每类错误都应给模型一个稳定 code 和可行动建议:

json
{
  "code": "SCOPE_REQUIRED",
  "message": "The current session cannot export analytics data.",
  "retryable": false,
  "requiredScope": "analytics.export"
}

不要把数据库错误、堆栈或下游 HTML 原样返回。它们既不利于模型恢复,也可能泄露内部实现。对于限流和暂时性故障,要告诉调用方何时重试,而不是让模型连续重放同一个写操作。

演进时保持兼容

已发布的工具字段不能随意改名或改变含义。新增字段可以先做可选,并提供默认行为;废弃字段要保留一个迁移周期,在描述和响应里标明替代方案。破坏性变化使用新的工具名或明确版本,而不是悄悄改变旧 contract。

每个工具至少要有三类测试:schema 校验测试、授权边界测试、端到端示例测试。把成功样例和典型失败样例放进回归集,模型升级、描述改写或后端改造后都重新跑一遍。稳定的 schema 不是文档装饰,而是 MCP 生态能持续扩展的基础设施。

延伸阅读

Related

相关推荐