Skip to content

Commit b097c69

Browse files
committed
Add new blog post: 语义至关重要:如何将 OpenAPI 规范转化为 MCP 工具
1 parent db0cc41 commit b097c69

File tree

1 file changed

+221
-0
lines changed
  • content/blog/semantics-matter-exposing-openapi-as-mcp-tools

1 file changed

+221
-0
lines changed
Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
---
2+
title: "语义至关重要:如何将 OpenAPI 规范转化为 MCP 工具"
3+
summary: "本文探讨了如何在 OpenAPI 规范中嵌入语义描述,并将其转换为 AI Agent 可消费的 MCP 工具。文章强调 OpenAPI 应作为 API 描述的单一事实来源,介绍了工具命名、能力描述、JSON-LD 使用、安全性注意事项及如何完成转换的建议。"
4+
authors: ["Christian Posta"]
5+
translators: ["云原生社区"]
6+
categories: ["AI"]
7+
tags: ["OpenAPI", "MCP", "AI工具", "JSON-LD", "语义建模"]
8+
draft: false
9+
date: 2025-04-24T18:09:59+08:00
10+
links:
11+
- icon: language
12+
icon_pack: fa
13+
name: 阅读英文版原文
14+
url: https://blog.christianposta.com/semantics-matter-exposing-openapi-as-mcp-tools/
15+
---
16+
17+
最近我在 [The API Experience Podcast](https://podcasts.apple.com/us/podcast/the-api-experience-podcast/id1698168565) 上和 [Matt McLarty](https://www.linkedin.com/in/mattmclartybc/) 以及 [Mike Amundsen](https://www.linkedin.com/in/mamund/) 聊了聊我最近写的一篇博客,主题是 [如何用“能力”来描述 API](https://blog.christianposta.com/from-apis-to-capabilities-what-ai-agents-mean-for-application-architecture/)。其中一个被提到的观点是,是否可以在 OpenAPI 规范中直接嵌入语义信息。我当时的一个评论是:“理想情况下,你应该可以从 OpenAPI 规范直接生成一个 MCP(Model-Computable Proxy)服务端,从而向 Agent 或 AI 模型暴露你的能力。”这个观点与 [Kevin Swiber](https://www.linkedin.com/in/kevinswiber/) 的一个深刻观察不谋而合,即 [MCP 将成为终极的 API 使用者](https://www.layered.dev/mcp-the-ultimate-api-consumer-not-the-api-killer),而不是所谓的 API 杀手。我想借此机会展开讲讲,因为这个思路非常值得深入探讨。
18+
19+
我首先想到的是,确实,如今大家普遍用 OpenAPI 规范文档来描述自己的 API。但正如 Mike Amundsen 指出的那样,这种描述在“语义信息”以及“以能力为中心的 API 表达”方面仍存在明显不足。当人类开发者直接使用 API 时,他们可以自行填补“语义上下文”的空白,选择合适的 API 并构建逻辑。但 AI agent 或工具并不具备这种人类主观判断力,LLM 需要尽可能多的上下文信息,才能做出正确的工具选择决策。
20+
21+
然而,我们并不希望由此产生“语义描述分裂”的问题:一套面向 MCP 的 API 语义描述,另一套则用于给开发者直接阅读和使用。我们更希望有一个统一的“单一真相来源(single source of truth)”,那就是 [OpenAPI 规范](https://swagger.io/specification/)。但要做到这一点,就需要我们在 OpenAPI 描述中投入更多精力,将 API 的“语义意义”以及“能力描述”表达得更加清晰、丰富。
22+
23+
## 从 API 到能力
24+
25+
在过去十几年中,许多企业投入大量精力,将内部和外部的业务能力通过 API 对外暴露。这一趋势不会消失。虽然 MCP(Model-Computable Protocol)非常令人兴奋,但归根结底,它只是一个**供 AI 模型调用工具的协议适配层**。但如果我们希望正确地向模型暴露工具,就必须[以“能力”而非单纯的 API 合约结构来描述](https://blog.christianposta.com/from-apis-to-capabilities-what-ai-agents-mean-for-application-architecture/)
26+
27+
- 工具名称应具有唯一性,且具备动词导向的动作意义(例如使用 “listAllTodoTasks” 而非简单的 “list”);
28+
- 提供详细的**用途说明**
29+
- 展示在什么场景下可以调用,并提供请求/响应示例;
30+
- 明确使用工具的**前置条件**
31+
32+
## 使用 OpenAPI 规范
33+
34+
OpenAPI 规范(OpenAPI Specification)本身包含了许多字段与结构,支持我们为 API 添加丰富的语义含义:
35+
36+
- 利用 `info` 部分添加全局信息;
37+
- 多个部分支持链接至 `externalDocs`,提供外部文档支持;
38+
- 大多数部分都支持 `title``summary``description` 字段;
39+
- 借助 [JSON-LD](https://json-ld.org/) 可将字段链接到行业通用或企业专属的数据语义模型,提供更深层的语义描述;
40+
- 如果上述方式都不满足需求,还可以使用自定义的扩展属性 `x-*` 扩展规范。
41+
42+
下面是一个具体示例:
43+
44+
`info` 字段中添加丰富语义的 Todo API 描述:
45+
46+
```yaml
47+
openapi: 3.0.3
48+
info:
49+
title: Enhanced Todo API
50+
description: >
51+
本 API 提供了管理个人或团队待办事项(todos)的能力,包括创建、更新、组织和检索任务,任务附带丰富的元数据,如截止日期、优先级和标签。
52+
该 API 专为系统和 AI Agent 设计,支持动态任务协调、进度追踪和工作流规划。
53+
特别适用于目标跟踪、工作助手或生产力工具等需要任务编排和上下文决策的场景。
54+
version: 1.0.0
55+
termsOfService: https://example.com/terms/
56+
contact:
57+
name: API Support Team
58+
url: https://example.com/support
59+
60+
license:
61+
name: Apache 2.0
62+
url: https://www.apache.org/licenses/LICENSE-2.0.html
63+
```
64+
65+
我们还应该链接该 API 的使用文档:
66+
67+
```yaml
68+
externalDocs:
69+
description: 查看该 API 所有使用场景的详细文档
70+
url: https://example.com/docs
71+
```
72+
73+
在具体 API 路径中,加入更详细的语义描述:
74+
75+
```yaml
76+
/todos:
77+
get:
78+
summary: 获取现有待办事项,用于上下文任务感知与规划
79+
description: >
80+
客户端或 AI Agent 可调用该接口,检索现有的待办事项列表,支持按完成状态过滤、分页控制。
81+
该能力可帮助理解当前任务状态、识别待办任务、规划下一步行动。
82+
特别适用于依赖实时上下文的工作流,如生产力跟踪、个人助手、自动化规划系统。
83+
operationId: listAllTodoTasks
84+
tags:
85+
- todos
86+
parameters:
87+
- name: limit
88+
in: query
89+
description: 返回的最大条目数
90+
schema:
91+
type: integer
92+
format: int32
93+
minimum: 1
94+
maximum: 100
95+
default: 20
96+
- name: completed
97+
in: query
98+
description: 按任务完成状态进行筛选
99+
schema:
100+
type: boolean
101+
responses:
102+
'200':
103+
description: JSON 格式的待办事项数组
104+
content:
105+
application/json:
106+
schema:
107+
type: object
108+
properties:
109+
data:
110+
type: array
111+
items:
112+
$ref: '#/components/schemas/Todo'
113+
pagination:
114+
$ref: '#/components/schemas/Pagination'
115+
```
116+
117+
使用 [JSON-LD(JSON 语义链接数据)](https://json-ld.org/),我们可以为请求或响应中的数据模型赋予确切的语义含义。通过链接到行业标准(如 [schema.org](https://schema.org)、[w3.org](https://www.w3.org/))或企业自定义语义本体,可以让 API 的数据结构具备强语义。以下是一个添加 JSON-LD 语义结构的示例:
118+
119+
```yaml
120+
openapi: 3.0.3
121+
info:
122+
# 为简洁省略部分内容
123+
x-linkedData:
124+
"@context":
125+
schema: "https://schema.org/"
126+
hydra: "http://www.w3.org/ns/hydra/core#"
127+
vocab: "https://api.example.com/vocab#"
128+
"@type": "schema:WebAPI"
129+
"@id": "https://api.example.com/v1"
130+
"schema:name": "Enhanced Todo API"
131+
"schema:description": "一个提供待办管理、元数据和语义注释的综合 API"
132+
"schema:provider":
133+
"@type": "schema:Organization"
134+
"schema:name": "Example Organization"
135+
"schema:url": "https://example.com"
136+
"schema:dateModified": "2025-04-15"
137+
```
138+
139+
如果上述方法都无法满足你的需求,你还可以选择[扩展 OpenAPI 规范](https://swagger.io/docs/specification/v3_0/openapi-extensions/),添加你自己的自定义属性。例如,当你对路径的 `description` 或 `summary` 字段存在向后兼容性问题时,可以添加自定义字段以增强描述能力:
140+
141+
```yaml
142+
/todos:
143+
get:
144+
summary: 获取现有待办事项,用于上下文任务感知与规划
145+
description: 简要描述在此
146+
tags:
147+
- todos
148+
x-company-mcp:
149+
name: very-descriptive-name-here
150+
description: 更详细的描述信息
151+
```
152+
153+
## 转换为 MCP 工具
154+
155+
接下来我们要思考:如何将 OpenAPI 规范转换为 MCP 工具?我们可以用 `operationId` 作为工具的名称,但描述信息该如何处理?MCP 工具需要以“能力”为中心进行描述,并提供足够的上下文,让 AI 模型能够判断该使用哪个工具、在什么时机使用。
156+
157+
在将 OpenAPI 映射为 MCP 工具时,可以直接使用 `operation` 的描述信息和参数说明,也可以在映射过程中对这些内容进行增强。你甚至可以借助 JSON-LD 的 URI 来补全数据结构的语义信息。以下是一个典型的 MCP 工具响应示例:
158+
159+
```json
160+
{
161+
"jsonrpc": "2.0",
162+
"id": 123,
163+
"result": {
164+
"tools": [
165+
{
166+
"name": "listAllTodoTasks",
167+
"description": "允许客户端或 AI Agent 检索现有的待办事项列表,支持按完成状态过滤并支持分页参数限制。
168+
该能力有助于理解当前任务状态、识别未完成事项以及规划后续行动。适用于生产力追踪、个人助手或依赖实时上下文的自动化规划系统。",
169+
"inputSchema": {
170+
"type": "object",
171+
"properties": {
172+
"limit": {
173+
"type": "integer",
174+
"description": "返回的最大项数(1-100)",
175+
"minimum": 1,
176+
"maximum": 100,
177+
"default": 20
178+
},
179+
"completed": {
180+
"type": "boolean",
181+
"description": "按完成状态筛选"
182+
}
183+
}
184+
},
185+
"annotations": {
186+
"title": "增强版 Todo API",
187+
"readOnlyHint": true,
188+
"openWorldHint": false
189+
}
190+
}
191+
]
192+
}
193+
}
194+
```
195+
196+
将 OpenAPI 规范作为 API 的“**单一事实来源**”(Single Source of Truth)——包括其衍生物如 MCP shim——至关重要。如果忽视 OpenAPI 的质量和一致性,会在后续流程中造成严重问题,尤其是在与 AI Agent、LLM 或基于 MCP 的工具集成时。描述不清或结构不一致的规范可能导致服务间不匹配、MCP 工具生成困难、版本或后端兼容性问题,甚至会破坏 AI Agent 的工作流。
197+
198+
而对于 AI 模型而言,如果工具描述模糊或不完整,可能会导致错误的理解:选错工具、使用无效参数,或者误解意图(如应当查询却去创建数据)。这些问题不仅会降低 Agent 的行为质量,还可能导致“幻觉式”响应、偏离目标的操作,甚至彻底失败。
199+
200+
我们可以总结如下对照表:
201+
202+
| MCP 工具字段 | OpenAPI 对应字段 | 说明 |
203+
|--------------------|-------------------------------------------|----------------------------------------------------------|
204+
| 工具名称 | `operationId` | 唯一、便于机器识别;如无,可退回至 HTTP 方法+路径 |
205+
| 工具描述 | `summary` / `description` | 简洁用 `summary`,详细说明用 `description` |
206+
| 输入结构(参数) | `parameters`,`description` | 包括类型、约束的结构化输入 |
207+
| 输出结构(响应) | `responses` | 包括成功与错误响应的结构化输出 |
208+
| 调用细节 | `servers`, `path`, `method` | 包括 URL、HTTP 方法、服务器信息 |
209+
| 安全性 | `security`, `components.securitySchemes` | 用于描述需要鉴权的接口 |
210+
211+
### 关于安全的补充说明
212+
213+
**LLM 提示注入(prompt injection)** 是当前 AI 安全的一个重大风险(参见 [OWASP Top 10 for LLM 应用](https://owasp.org/www-project-top-10-for-large-language-model-applications/))。当工具的 `description` 或参数说明被恶意注入指令时,就可能发生所谓的 **工具投毒攻击(tool poisoning)**(详见 [Invariant Labs 的安全通告](https://invariantlabs.ai/blog/mcp-security-notification-tool-poisoning-attacks))。因此,务必要对 OpenAPI 规范进行审核和“清洗”。理想情况下,这应当在 API 治理流程中完成;但作为兜底方案,也可以在 OpenAPI 转换为 MCP 工具的过程中加入清洗流程。我将会在后续博客中深入探讨这个问题。
214+
215+
## 这种映射应当发生在哪里?
216+
217+
正如前文所述,虽然未来可能出现原生支持 MCP 的实现方案,但企业最终仍是要基于已有的 API 投资来暴露 MCP 工具。那么这种 **OpenAPI 到 MCP 的映射** 应该在哪里发生呢?
218+
219+
- 有可能会出现“AI 原生工具”来完成这类转换,它们会考虑到上面提到的语义因素;
220+
- 有可能你会使用支持将 REST API 暴露为 MCP 端点的 API Gateway;
221+
- 也可能你需要自行构建一些映射逻辑工具。

0 commit comments

Comments
 (0)