MCP Python SDK · 第 4 章 工具:类型即契约


MCP Python SDK · 第 4 章 工具:类型即契约

章节摘要:工具是三大原语里模型直接驱动的那一个,也是 SDK 投注设计精力最多的地方。本章的核心命题只有四个字——类型即契约。我们要回答:为什么 def add(a: int, b: int) -> int 这一行函数定义,就足以让模型正确调用、让 SDK 正确校验、让应用拿到结构化数据?背后是 SDK 的函数元数据(func_metadata)机制在做一件事——从 Python 类型注解推断出 JSON Schema,再分发给模型与校验器。我们会讲透输入 Schema 的推断规则、结构化输出(返回类型注解即输出 Schema)、ToolAnnotations 元信息、错误如何回传模型、以及用 pydantic.Field 表达更丰富的约束。读完本章,你将能向别人讲清楚「一个工具的契约是怎么生成、怎么校验、怎么演化的」。

学习目标

阅读完本章,你应当能够:

  1. 解释函数元数据(func_metadata) 如何从 Python 类型注解推断出工具的输入 JSON Schema,并说清哪些类型会被支持、哪些不会。
  2. 用返回类型注解定义结构化输出(Structured Output),区分标量返回(包裹在 {"result": ...})与 Pydantic BaseModel 返回(直接作为 Schema)的差异。
  3. 用 ToolAnnotations(如「只读」「破坏性」「开放」等元信息)向宿主与模型声明工具的行为特征。
  4. 描述工具抛出异常时,SDK 如何把它转成回传模型的错误响应,以及如何主动返回错误内容。
  5. 用 pydantic.Field 给参数加上描述、约束(范围、正则、默认值),生成更丰富的输入 Schema。

核心概念速览

整章逻辑可浓缩为一一句话:类型注解不是文档,而是可执行的契约——它同时是给模型的说明书、给 SDK 的校验器、给应用的结构化数据来源,一份注解三处生效,这是 SDK 与传统 RPC 框架的根本差异。

子章节导航

01 输入 Schema:从类型注解到 JSON Schema

讲透函数元数据(func_metadata)的推断规则:基础类型(int/str/float/bool)、list / dict / 可选类型(Optional / X | None)、Pydantic 模型如何各映射成 JSON Schema;以及文档字符串如何成为工具描述。重点回答「为什么类型注解就够」。

02 结构化输出:返回类型注解即输出 Schema

区分两种返回:标量(如 -> int)会被包裹成 {"result": ...};Pydantic BaseModel 返回则直接以模型为输出 Schema。讲清 structured_content 与 content(给模型的文本)如何同时返回,以及如何用 output_schema 显式控制。

03 ToolAnnotations:声明工具的行为特征

工具不只是「能被调用」,还有行为特征——是否只读、是否破坏性、是否对外公开。ToolAnnotations 让宿主据此决定授权策略、让模型据此决定调用谨慎度。这一节讲清这套元信息的语义与最佳实践。

04 错误处理:抛异常即回传错误

工具执行会失败。讲清两条路径:抛异常(被 SDK 转成 isError: true 的错误响应,模型据此重试或换策略)、主动返回带错误标记的内容。对比两种写法的适用场景,以及「让模型看到错误」对工具调用循环的重要性。

05 富 Schema:用 pydantic.Field 表达约束

类型注解能表达基础契约,但现实里的约束更细——数值范围、正则、枚举、描述文本。pydantic.Field 让你在参数上叠加这些约束,生成更精确的 JSON Schema,减少模型的错误调用。这一节是「让模型少踩坑」的关键。

子章节之间的逻辑关系

本章遵循「输入契约 → 输出契约 → 行为声明 → 失败语义 → 精化约束」的递进,围绕「契约」这一核心概念层层展开:

输入 Schema (01) ── 模型靠它构造调用 │ ▼ 结构化输出 (02) ── 应用靠它拿数据 │ ▼ ToolAnnotations (03) ── 宿主靠它判行为 │ ▼ 错误处理 (04) ── 模型靠它学会重试 │ ▼ 富 Schema (05) ── 用 Field 精化约束,减少错误调用 │ ▼ 第 5 章:转向资源与提示词这两类「非模型驱动」的原语 ​

输入与输出契约是工具的「两面」,缺一不可;行为声明让工具融入宿主的授权体系;错误处理让工具调用循环能自我修复;富 Schema 是把契约写到「模型几乎不会调错」的程度。本章是全书最硬核的章节之一,与第 7、8 章共同构成「研究级」核心。

前置知识与后续延伸

前置知识:

  • 第 3 章的 @mcp.tool() 装饰器用法
  • Python 类型注解基础(知道 a: int 是什么)
  • 对 JSON Schema 有概念(非必需,有助理解)

本章为后续章节奠定的基础:

  • 结构化输出概念会在第 9 章(客户端 call_tool 的返回结构)再次出现
  • 错误处理机制是第 7 章(交互式能力中引导填写失败的处理)的铺垫
  • 富 Schema 思想会贯穿第 5 章(资源模板参数)、第 6 章(依赖解析)的参数处理
  • ToolAnnotations 会在第 12 章(中间件)被引用为拦截依据

作者与出处
原作者: 灏天文库
来源:modelcontextprotocol
许可证:MIT
整理: 灏天文库整理
由灏天文库结构化整理,提供目录导航、全文检索与在线阅读,便于系统化学习
发布者: 作者: 灏天文库 转发
评论区 (0)
U