1777 字
约 5 分钟
5
S02-B10 · 从 OpenAPI 到可执行工具:API 描述如何变成插件

适用读者:要接 AI Agent / 低代码平台 / 内部工具市场的人;要设计"可被程序自动调用"的 API 的人。
前置:S02-B06(HTTP)、S02-B09(HTTP 与 RPC)。
实测环境:Python 3.12(内置 http.server + urllib);端到端 demo 为 2026-11-05 实测。
覆盖旧文:A-647(OpenAPI Schema:把 HTTP API 变成可执行插件工具,199 点)、A-649(从 toolId 到真实 HTTP 请求,56 点)= 255 点。
覆盖扩展:E-S02-019(OpenAPI 3.1 与 JSON Schema)、E-S02-020(function calling / MCP)。
上一篇:S02-B09 · HTTP 与 RPC:为什么 RPC 更快,又为什么仍要 HTTP
下一篇:S02-X01 · 面试问答速查(基础层附录)。


1. 一句话结论

一个 HTTP API 要变成"可被程序调用的工具",只需要三样东西:可机读的描述(schema)、可预测的地址(URL 模板)、可判定的结果(状态码 + 结构)。

OpenAPI 文档  ──抽取──►  工具描述(name / description / parameters)
                                │ 模型按描述生成参数 JSON
                                ▼
                        参数校验 → URL 拼接 → 发起请求 → 结果归一化

这四步里,最容易出事的是第一步和第四步:描述不严 → 模型乱填参数;结果不统一 → 上层无法判断成败。


2. 实测:从 spec 到真实请求

2.1 一份最小 OpenAPI 3.1 描述

{
  "openapi": "3.1.0",
  "info": { "title": "Demo Items API", "version": "1.0.0" },
  "servers": [{ "url": "http://127.0.0.1:19030" }],
  "paths": {
    "/items/{id}": {
      "get": {
        "operationId": "getItem",
        "summary": "按 ID 取条目",
        "parameters": [
          { "name": "id", "in": "path", "required": true,
            "schema": { "type": "string", "pattern": "^[0-9]{1,6}$" } },
          { "name": "verbose", "in": "query", "required": false,
            "schema": { "type": "boolean", "default": false } }
        ],
        "responses": { "200": { "description": "OK" } }
      }
    }
  }
}

2.2 按描述生成并发出真实请求

args = {"id": "42", "verbose": True}
for p in op["parameters"]:
    if p["required"] and p["name"] not in args:
        raise SystemExit(f"缺必填参数 {p['name']}")
url = base + "/items/{id}".replace("{id}", args["id"]) + ("?verbose=true" if args.get("verbose") else "")

实测输出:

工具描述 -> 实际 URL: http://127.0.0.1:19030/items/42?verbose=true
响应: {"id": "42", "name": "示例条目", "verbose": true}

这条链路就是"插件化"的全部本质:描述 → 参数 → URL → 结果。没有魔法。


3. 描述里的五个字段,缺一个就不可靠

字段 作用 缺了会怎样
operationId 工具唯一 ID(toolId) 无法稳定引用;重名/改名引用的调用全断
summary / description 给模型看的"什么时候该用它" 模型不知道何时调用,或乱调用
parameters[].required 必填校验 模型漏参数 → 请求构造失败
parameters[].schema.type/pattern 类型与格式约束 模型传 "abc" 给 ID → 后端 500
responses 结果结构 无法判断成败与提取数据

3.1 toolId 到请求的映射(旧文 A-649 的核心)

toolId HTTP 映射规则
getItem GET /items/{id} path 参数替换、query 参数拼接
createOrder POST /orders body 由 requestBody schema 生成,Content-Type 来自 spec
listOrders GET /orders?status= 可选参数缺省值由 default 决定

工程实践:toolId 一旦发布就不要改。要改就新增一个 toolId 并把旧的标记 deprecated——这是"工具契约"的版本兼容问题(A02 里讲的 API 治理同理)。


4. 四道安全闸门(旧文没讲,但必须有)

闸门 风险 做法
鉴权 工具被滥用 凭据由平台注入(不让模型看见 token)
参数校验 注入/越权 按 schema 校验(类型、范围、枚举、正则)
目标限制 SSRF:模型让你请求内网地址 白名单域名 + 禁止 169.254.169.254、127.0.0.1、私网段
副作用控制 误删/误扣款 写操作需二次确认;幂等键;限流

SSRF 那条尤其重要:如果工具描述里的 servers.url 或参数能被外部影响,攻击者可以让你的服务去访问云元数据接口(http://169.254.169.254/latest/meta-data/)拿到凭据。


5. 与 function calling / MCP 的关系(E-S02-020)

概念 是什么 与 OpenAPI 的关系
function calling 模型输出"我要调用 X,参数是 {...}" 工具的 schema 来自 OpenAPI 的精简版(name/description/parameters)
MCP(Model Context Protocol) 标准化的"模型 ↔ 工具/资源"协议 一个 MCP server 可以把多个 OpenAPI 接口包装成工具
OpenAPI 描述 HTTP 接口的行业标准 描述源头;工具市场多由它导入

实践结论:

  1. 先有干净的 OpenAPI,再有可靠的工具——描述质量决定工具质量。
  2. 不要直接把整个 OpenAPI 丢给模型:接口几十个时要做"工具筛选/分组",否则模型选择困难。
  3. 写操作必须走确认:读接口可以自动调,写接口(下单、删除、转账)必须人工确认或强幂等。

6. 一个"不合格的工具描述"长什么样

{ "name": "do", "description": "执行操作", "parameters": { "type": "object" } }
问题 后果
名字无意义 模型无法判断用途
描述模糊 该用的时候不用,不该用时乱用
参数无 schema 传什么都能构造请求,后端承担全部风险
无返回值定义 上层无法判断成功/失败

反面判据:如果一个描述不能让人(不看代码)正确调用它,模型也做不到。


7. 五个误区

误区 真相
"有了 OpenAPI 就能自动生成可靠工具" 描述质量决定一切;自动生成只解决"形式"
"工具越多越好" 选择成本上升,误调用率上升
"鉴权交给模型传 token" 凭据绝不应进入模型上下文
"写接口和读接口一样处理" 写接口必须幂等 + 确认
"MCP 会取代 OpenAPI" MCP 是"如何暴露给模型",OpenAPI 是"如何描述 HTTP";互补

8. 自检

  1. 工具描述里缺 required 会导致什么具体故障?
  2. 为什么 operationId 不能随意改?
  3. SSRF 在这个链路里的具体入口在哪?
  4. 读接口与写接口的处理差异是什么?为什么?
  5. 什么样的描述算"人能不看代码就正确调用"?

9. 下一篇

S02-X01 · 面试问答速查:操作系统 / 计算机网络 / 网络编程

基础层最后一篇是可查的附录:把 4 张大卡(2,232 个点位)压成"题干 + 一句话答案 + 正文小节链接",只做索引不重复正文。之后进入进阶层(TCP 排障、TLS 深水区、连接数工程)。


本篇属于系列《S02 · 计算机与网络基础》。旧文来源:A-647、A-649;扩展点 E-S02-019/020。OpenAPI → 请求端到端为 2026-11-05 实测。

S02-B10 · 从 OpenAPI 到可执行工具:API 描述如何变成插件
https://www.clxhxhhr.top/posts/5191/
作者
clxstart
发布于
2024-12-31
许可协议
CC BY-NC-SA 4.0
评论
0 条
还没有评论,先写一条吧。