工具接入
本文档面向平台开发者,解释「插件」与「工具」的概念,并完成 OpenAPI、MCP、Agent 三类工具的导入与创建。同时给出每个字段的含义、取值范围、必填条件与限制,可作为配置时的参考手册。
1. 平台与核心概念
平台允许开发者把「外部能力」接入进来,封装成可被大模型自动调用的工具(Tool)。你只需要按规范描述「怎么连接你的服务」和「有哪些能力可以调用」,平台会自动生成符合 LLM function calling 规范的工具描述,并在对话过程中由模型按需调用。
1.1 插件与工具
平台的能力接入使用两层模型:
概念 | 定位 | 职责 | 通俗理解 |
插件 (Plugin) | 服务接入点 | 定义「怎么连」:基础地址、认证方式、协议、公共参数 | 一个外部服务 / 一个 API 域 |
工具 (Tool) | 能力单元 | 定义「调什么」:具体接口、入参、出参、调用方式 | 服务下的一个具体接口 / 一个能力 |
关系:一个插件包含一个或多个工具。插件负责连接层(URL、认证、协议),工具负责能力层(参数、返回值、调用逻辑)。
插件 Plugin(天气服务)
├── 工具 Tool(查询实时天气)
├── 工具 Tool(查询 7 天预报)
└── 工具 Tool(查询空气质量)1.2 编码规则
编码 | 唯一性范围 | 说明 |
插件 code | 全局唯一 | 新建插件时由系统自动生成,无需手动填写 |
工具 code | 插件内唯一 | 同一插件下不可重复;不同插件下可以重名 |
工具 unionCode | 全局唯一 | 命名形式为插件code和工具code,形如 |
1.3 生命周期
插件遵循「草稿 → 已发布」的生命周期:
草稿(DRAFT) ──────发布─────▶ 已发布(PUBLISHED)草稿(DRAFT):可自由编辑、调试。
已发布(PUBLISHED):已发布插件会进入锁定状态,暂不可修改,避免影响线上Skill
工具遵循「草稿 → 调试通过 → 已发布」的生命周期:
草稿(DRAFT) ──────调试通过(DEBUGGING_PASSED)── 发布───▶ 已发布(PUBLISHED)
▲ │
│ │
└─────── 更新 ◀────────────┘草稿(DRAFT):可自由编辑、调试。
调试通过(DEBUGGING_PASSED):工具调试通过一次状态自动更新;可自由编辑、调试。
已发布(PUBLISHED):已发布工具会进入锁定状态,暂不可修改,避免影响线上Skill
工具状态跟随插件状态联动,发布后同样锁定。
SKILL发布上线时,其引用的所有工具都必须处于已发布。
2. 三类工具总览
平台对外开放三类工具,覆盖不同的接入场景:
类型 | 适用场景 | 工具创建方式 |
OpenAPI | 你已有标准 HTTP RESTful API | 手动创建 / OpenAPI 文档导入,需配置方法、路径与参数 |
MCP | 你已有符合 Model Context Protocol 的 Server | 平台自动从 MCP Server 拉取工具列表 |
Agent | 你在百炼 / 扣子上已创建了 Agent 应用 | 配置 appId + apiKey 即可,工具自动生成 |
2.1 能力边界速查
维度 | OpenAPI | MCP | Agent |
基础地址 baseUrl | 必填 | 必填 | 由平台内置 |
认证方式 | 无认证 / Bearer Token / 自定义授权 | 无认证 / Bearer Token / 自定义授权 | API Key |
参数配置 | 手动配置位置与来源 | 自动解析(支持配置来源) | 无需配置(固定入参) |
入参 | 完全自定义 | 由 MCP Server 定义 | 固定单一 |
出参 | 自定义结构 | MCP 协议的固定框架 | 固定 |
超时 | 统一 3000ms | 统一 3000ms | 支持流式响应 |
流式(SSE) | 暂不支持 | 依协议 | 支持 |
Groovy 脚本 | 支持 | 不适用 | 不适用 |
3. 快速开始
HTTP API 最小步骤如下:
智能导入:选择智能导入,上传 Markdown 格式的 API 定义,等待平台解析
导入插件:将文档中定义的 API 接口转为工具导入开放平台
调试:在工具详情页试调用,确认返回正常。将其用于草稿SKILL,在沙箱/真机链路上调试
发布:调试通过后发布插件,工具即可用于线上SKILL。
MCP Server 最小步骤如下:
JSON导入:选择JSON导入,粘贴 MCP Server config,等待平台解析
导入插件:将 MCP Server 作为插件导入到开放平台
调试:在工具详情页试调用,确认返回正常。将其用于草稿SKILL,在沙箱/真机链路上调试
发布:调试通过后发布插件,工具即可用于线上SKILL。
Agent 最小步骤如下:
JSON导入:选择JSON导入,配置来自百炼、扣子平台的 appId、apiKey等信息,等待平台解析
导入插件:将agent 导入开放平台
调试:在工具详情页试调用,确认返回正常。将其用于草稿SKILL,在沙箱/真机链路上调试
发布:调试通过后发布插件,工具即可用于线上SKILL。
三类工具的通用流程一致:建插件 → 建/拉取工具 → 配置(如需)→ 调试 → 发布。
4. OpenAPI 工具
OpenAPI 工具用于将标准 RESTful API 封装为平台工具,是最常用、最灵活的接入方式。它支持精细的参数映射、认证签名与 Groovy 脚本处理。
4.1 创建 OpenAPI 插件
新建插件时需要填写以下字段:
字段 | 枚举/类型 | 必填 | 说明与限制 |
名称 name | String | 是 | 插件名称,建议 ≤ 16 字 |
描述 description | String | 是 | 插件能力描述,建议 ≤ 60 字 |
类型 | OpenAPI | 是 | 固定选择 OpenAPI 类型 |
工具包地址 baseUrl | String | 是 | API 服务基础地址,如 |
认证方式 | 无认证 / Bearer Token / 自定义授权 | 是 | 见 4.2 |
4.2 认证方式(AuthInfo)
认证配置作用于插件级别,插件下所有工具共享。
认证方式 | 说明 | 需要填写 |
无认证 | 不添加任何认证信息 | — |
Bearer Token | 每个请求 Header 自动添加 |
|
自定义授权 | 每个请求 Header / Query / Path 自动添加 Key: Value |
|
4.3 插件级公共参数与密钥参数
OpenAPI 插件支持两类插件级配置,均在插件的 config.openApi 下:
公共参数 publicParameters:所有工具共享的参数(如 appKey、时间戳、签名),会自动应用到该插件下每个工具的请求。
{
"config": {
"openApi": {
"publicParameters": [
{ "name": "app_key", "type": "string", "position": "query", "from": "constant", "defaultValue": "your-app-key" },
{ "name": "timestamp", "type": "string", "position": "query", "from": "gop_shortcut", "gopShortcut": "timestamp" },
{ "name": "nonce", "type": "string", "position": "query", "from": "gop_shortcut", "gopShortcut": "random_string32" }
]
}
}
}密钥参数 configParameters:仅参与签名计算、不会随请求发出的常量(如 appSecret)。以键值对形式配置,会以 config 入口传入 Groovy 脚本。
{
"config": {
"openApi": {
"configParameters": { "app_secret": "your-app-secret" }
}
}
}4.4 添加工具(基础信息)
在插件下添加具体接口,核心字段:
字段 | 类型 | 必填 | 说明与限制 |
toolCode | String | 是 | 工具编码,插件内唯一 |
name | String | 是 | 工具名称,含义清晰 |
description | String | 否 | 功能与适用场景描述(有助于模型判断何时调用) |
endpoint | String | 是 | 相对路径,以 |
method |
| 是 | HTTP 方法 |
requestParameters | List | 否 | 请求参数列表,见 4.5 |
responseParameter | Object | 否 | 响应参数定义,见 4.6 |
说明:stream(SSE 流式输出)字段暂不对外开放,OpenAPI 工具当前不支持流式响应。
4.5 配置请求参数(ToolParameter)
请求参数是 OpenAPI 工具的核心。每个参数由「类型 + 位置 + 来源」三要素定义。
4.5.1 参数字段一览
字段 | 说明 | 必填条件 |
name | 参数名 | 始终必填 |
type | 参数类型(见 4.5.2) | 始终必填 |
position | 参数位置(见 4.5.3) | 始终必填 |
from | 参数来源(见 4.5.4) | 叶子节点始终必填 |
required | 是否必填 | 可选 |
description | 参数描述 | 来源为「模型抽取」时必填 |
defaultValue | 默认值 | 来源为「常量」时必填 |
contextField | 上下文字段 | 来源为「系统上下文」时必填 |
gopShortcut | 内置语法糖 | 来源为「内置语法糖」时必填 |
script | 脚本配置 | 来源为「脚本生成」时必填 |
subParameters | 子参数列表 | 类型为「对象」或「列表」时必填 |
4.5.2 参数类型 type
类型 | 说明 |
字符串 string | 文本值 |
数字 number | 数值 |
布尔 boolean | true / false |
对象 object | 需配置 |
列表 array |
|
4.5.3 参数位置 position
位置 | 说明 |
查询参数(Query) | 拼接到 URL 查询串 |
请求头(Header) | 放入 HTTP 请求头 |
路径参数(Path) | 替换 URL 路径占位符 |
请求体(Body) | 放入请求体 |
4.5.4 参数来源 from(重点)
参数来源决定了每个参数的值从哪里获取,是配置的关键:
来源 | 含义 |
模型抽取 | 由大模型从用户输入中提取 |
常量 | 固定常量值 |
系统上下文 | 从运行环境自动注入 |
内置语法糖 | 系统内置动态量(时间戳/随机串等) |
脚本生成 | 用 Groovy 脚本动态计算(如签名) |
系统上下文字段的可选值:
上下文字段 | 备注 |
用户千问 ID | 千问账号ID 加密后的 openUserId (获取openId后的使用方式见下) |
眼镜设备 ID | 千问AI硬件设备 ID 加密后的 openUuid (获取openId后的使用方式见下) |
设备经度 | 千问AI硬件设备当前的经度,需用户授权地理位置 |
设备纬度 | 千问AI硬件设备当前的纬度,需用户授权地理位置 |
内置语法糖的可选值:
语法糖 | 说明 |
标准 UUID | UUID v4 格式 |
16 位随机字符串 | 长度 16 的随机串 |
32 位随机字符串 | 长度 32 的随机串 |
64 位随机字符串 | 长度 64 的随机串 |
当前时间戳 | 当前毫秒时间戳 |
格式化时间 |
|
格式化日期 |
|
参数来源选择决策树:
这个参数值需要签名或复杂派生计算吗?
→ 是:选择「脚本生成」
→ 否:
与用户/设备身份相关吗?(用户ID、设备UUID、经纬度)
→ 是:选择「系统上下文」
是时间戳 / 随机串等动态量吗?
→ 是:选择「内置语法糖」
是固定常量、不随请求变化吗?
→ 是:选择「常量」
需要由大模型从用户输入中提取吗?
→ 是:选择「模型抽取」4.5.5 请求参数示例
{
"requestParameters": [
{ "name": "city", "type": "string", "position": "query", "from": "model", "required": true, "description": "城市名称,如北京、上海" },
{ "name": "units", "type": "string", "position": "query", "from": "constant", "defaultValue": "metric" },
{ "name": "device_id", "type": "string", "position": "header", "from": "context", "contextField": "uuid" }
]
}嵌套对象/数组示例:
{
"name": "filters",
"type": "object",
"position": "body",
"subParameters": [
{ "name": "tags", "type": "array", "subParameters": [ { "name": "item", "type": "string", "from": "model", "description": "标签" } ] },
{ "name": "limit", "type": "number", "from": "constant", "defaultValue": "10" }
]
}复合类型(object/array)本身不需要 from,from 只在叶子节点必填。array 的 subParameters 只能有 1 个元素作为元素模板。
4.6 配置响应参数(ResponseParameter)
响应参数用于描述接口返回结构,帮助模型理解与使用返回值。结构为树形,支持嵌套:
字段 | 说明 |
name | 参数名 |
description | 参数描述 |
type | 类型: |
subParameters | 子参数(object/array 时使用) |
{
"responseParameter": {
"name": "result",
"type": "object",
"subParameters": [
{ "name": "temperature", "type": "number", "description": "当前温度(摄氏度)" },
{ "name": "weather", "type": "string", "description": "天气状况" }
]
}
}4.7 使用 Groovy 脚本处理签名
当参数值需要签名或复杂计算时,选择「脚本生成」来源。脚本运行在受限的沙箱环境中,并强制编译检查。
脚本编写规则:
规则 | 说明 |
必须实现 | 否则运行报错 |
package 固定 |
|
所有变量必须显式声明类型 | 不能使用 |
从 Map 取值必须用 | 不能用 |
返回值必须 JSON 可序列化 | String / Map / List / Number / Boolean |
类名建议加随机后缀 | 避免缓存冲突 |
脚本语言仅支持 Groovy | 不支持其他脚本语言 |
脚本可用入参(arguments: Map<String, Object>):
├── "path" → Map | null URL 路径参数
├── "query" → Map | null URL 查询参数
├── "header" → Map | null HTTP 请求头
├── "body" → Map | null 请求体
└── "config" → Map | null 密钥参数(configParameters)脚本采用两阶段执行:先解析所有非 script 参数,再把结果作为上下文传入脚本,因此脚本可读取其它已解析参数的值。
脚本骨架示例:
package com.alibaba.aicloud.mcp.service.mcp.caller.openapi
import java.util.*
import java.nio.charset.StandardCharsets
import javax.crypto.Mac
import javax.crypto.spec.SecretKeySpec
public class SignCalculator_K7mN2p implements GroovyParserService {
@Override
public Object parse(Map<String, Object> arguments) {
Map<String, Object> query = (Map<String, Object>) arguments.get("query")
Map<String, Object> config = (Map<String, Object>) arguments.get("config")
String appSecret = (String) config.get("app_secret")
TreeMap<String, Object> sorted = new TreeMap<>(query)
StringBuilder sb = new StringBuilder()
for (Map.Entry<String, Object> e : sorted.entrySet()) {
if (sb.length() > 0) sb.append("&")
sb.append(e.getKey()).append("=").append(String.valueOf(e.getValue()))
}
Mac mac = Mac.getInstance("HmacSHA1")
mac.init(new SecretKeySpec(appSecret.getBytes(StandardCharsets.UTF_8), "HmacSHA1"))
byte[] bytes = mac.doFinal(sb.toString().getBytes(StandardCharsets.UTF_8))
StringBuilder hex = new StringBuilder()
for (byte b : bytes) { hex.append(String.format("%02x", b & 0xff)) }
return hex.toString()
}
}5. MCP 工具
MCP 工具用于注册符合 Model Context Protocol 的远端 Server。与 OpenAPI 不同,MCP 工具无需手工配置参数 —— 平台会自动从 MCP Server 拉取工具列表并解析参数。
5.1 注册 MCP 插件
字段 | 枚举/类型 | 必填 | 说明 |
名称 name | String | 是 | MCP Server 名称 |
描述 description | String | 是 | 核心功能描述 |
类型 | MCP | 是 | 固定选择 MCP 类型 |
基础地址 baseUrl | String | 是 | MCP Server 地址 |
传输协议 | SSE / Streamable HTTP / 无状态 HTTP | 是 | 见 5.2 |
端口 | String | 是 | MCP 端点路径,如 |
认证方式 | 无认证 / Bearer Token / 自定义授权 | 是 | 与 OpenAPI 一致,但自定义授权时参数不允许在位于 |
自定义授权限制:MCP 的「自定义授权」认证参数位置仅支持「查询参数」或「请求头」,不支持「路径参数」。
5.2 传输协议 transport
协议 | 说明 |
SSE | 基于长连接实现服务端单向推送,客户端通过独立的 POST 通道发送请求 |
Streamable HTTP | 在单个 HTTP 通道上实现双向流式通信 |
无状态 HTTP | 无需预先建立连接,即可直接发起 Function Call 调用 |
5.3 创建与刷新工具
创建 MCP 插件时填写 baseUrl、传输协议、endpoint 与认证方式。
保存时平台会自动连接 MCP Server 并调用
tools/list,自动注册为本地工具(连接失败会报错,也可能由于授权方式填错导致连接成功但工具清单为空)。后续若 MCP Server 的工具有变更,可在列表页点击「刷新工具」重新拉取。
5.4 工具调用与参数特点
参数全部在
arguments中传递(遵循 MCP 协议),无需也不支持手工配置位置,可手动配置参数来源。参数的描述全部来自 MCP Server,无需也不支持在平台上修改;
认证方式继承自插件配置。
工具调用链路:
大模型 → MCP 调用请求 → 平台 MCP 网关 → 远端 MCP Server → 返回结果5.5 MCP JSON导入格式
MCP 服务支持通过 JSON 配置进行导入,配置的顶层字段为 mcpServers,其中每个键代表一个 MCP 服务的名称,值为该服务的具体配置。根据鉴权方式和导入数量的不同,配置格式略有差异,下面分别说明。
无鉴权的单MCP导入:
{
"mcpServers": {
"mcp-http-example": {
"type": "streamableHttp",
"description": "插件描述",
"url": "https://api.example.com/mcp"
}
}
}Bearer鉴权的单MCP导入:适用于使用标准 Bearer Token 鉴权的 MCP 服务,通过 headers 字段配置 Authorization。其中 ${Token} 需更换为真正的Token。
{
"mcpServers": {
"mcp-http-example": {
"type": "streamableHttp",
"description": "插件描述",
"url": "https://api.example.com/mcp",
"headers": {
"Authorization": "Bearer ${Token}"
}
}
}
}自定义鉴权的单MCP导入:当服务使用自定义鉴权方式时,支持在 query(URL 查询参数)或 headers(请求头)中放置自定义字段。以下示例通过 query 传递 apiKey:
{
"mcpServers": {
"mcp-http-example": {
"type": "streamableHttp",
"description": "插件描述",
"url": "https://api.example.com/mcp",
"query": {
"apiKey": "${API_KEY}"
}
}
}
}多MCP导入:mcpServers 内可包含多个 MCP 服务的配置,一次性完成批量导入。每个服务的键名需保持唯一。
{
"mcpServers": {
"mcp-http-example1": {
"type": "streamableHttp",
"description": "插件描述",
"url": "https://api.example.com/mcp1"
},
"mcp-http-example2": {
"type": "streamableHttp",
"description": "插件描述",
"url": "https://api.example.com/mcp2"
},
"mcp-http-example3": {
"type": "streamableHttp",
"description": "插件描述",
"url": "https://api.example.com/mcp3"
}
}
}6. Agent 工具
Agent 工具用于对接第三方智能体平台。你只需提供在平台上创建好的 Agent 应用的 appId 与 apiKey,平台会自动适配协议并生成一个工具。
6.1 支持的平台
平台 | 说明 |
百炼(通义百炼) | 阿里云百炼平台的 Agent |
扣子 | 字节跳动扣子平台的 Agent |
6.2 创建 Agent 插件
字段 | 类型 | 必填 | 说明 |
平台 platform | 百炼 / 扣子 | 是 | 智能体所在平台 |
智能体 ID appId | String | 是 | 三方平台的应用 App ID |
API Key apiKey | String | 是 | 三方平台的认证密钥 |
名称 name | String | 是 | 智能体名称 |
描述 description | String | 是 | 功能描述 |
Prompt 范围 prompt | String | 否 | 描述智能体接收什么样的 prompt,帮助模型判断何时调用 |
6.3 入参 / 出参约定(固定)
Agent 类型工具不支持自定义入参,工具入参固定为单个 query 字段:
{
"type": "object",
"required": ["query"],
"properties": {
"query": { "type": "string", "description": "用户 query,需要传递给 agent。" }
}
}出参固定为 {$: string} 格式。即大模型只需传递 query,平台自动路由到对应智能体并返回结果。
6.4 调用与流式响应
Agent 工具支持流式响应,通过 MCP 进度通知逐步返回结果:
用户输入 → 大模型提取 query → MCP 调用 → 平台路由
├→ DashScope(百炼)
└→ Coze(扣子)
↓
流式 SSE 返回 → 逐 chunk 推送7. 字段限制与校验汇总
7.1 插件级
字段 | 限制 / 校验 |
name | 必填,建议 ≤ 16 字 |
description | 必填,建议 ≤ 60 字 |
type | 必填,只能为 OpenAPI / MCP / Agent 类型 |
baseUrl | OpenAPI / MCP 必填 |
authInfo.bearerToken | 认证方式为「Bearer Token」时必填 |
authInfo.customAuth | 认证方式为「自定义授权」时必填;MCP 下位置仅允许「查询参数」或「请求头」 |
config.mcp.transport | MCP 必填 |
config.mcp.endpoint | MCP 必填 |
agent.platform/appId/apiKey | Agent 必填 |
timeout | 默认 3000ms(统一口径) |
7.2 OpenAPI 工具级
字段 | 限制 / 校验 |
toolCode | 必填,插件内唯一(重复报错) |
endpoint | 必填,以 |
method | 必填,只能为 GET/POST/PUT/DELETE(非法方法报错) |
参数 name / type / position | 始终必填 |
参数 from | 叶子节点必填(未填报“取值来源未填写”) |
来源「模型抽取」→ description | 必填 |
来源「常量」→ defaultValue | 必填 |
来源「系统上下文」→ contextField | 必填 |
来源「内置语法糖」→ gopShortcut | 必填 |
来源「脚本生成」→ script | 必填,且会预编译校验 |
object/array → subParameters | 必填;array 只能 1 个元素模板 |
summary(响应摘要) | 若配置,表达式会被预编译校验 |
7.3 通用规则
已发布的插件 / 工具不可修改,需删除后重建。
脚本在沙箱环境执行,强制编译检查,禁用危险方法。
调用超时统一 3000ms(工具级可覆盖插件级)。
8. 插件发布
插件创建后即可用于SKILL,但需「发布」才能用于正式版的 SKILL:
所有工具的调试状态为「调试通过」。
在插件详情页点击「发布」。
发布后锁定,如需修改需重建。
9. OpenId上下文参数使用
对接千问AI硬件 OpenSDK 消息推送等能力时,需要使用 OpenId, IdType, EncodeType, EncodeKey 这四个字段来唯一标识一名千问AI眼镜用户,或者一台千问AI眼镜设备。
{
"EnocdeType": "SKILL_ID",
"EncodeKey": "千问AI硬件开放平台 - 账号中心 - EncodeKey",
"IdType": "USER_ID",
"Id": "openUserId"
}{
"EnocdeType": "SKILL_ID",
"EncodeKey": "千问AI硬件开放平台 - 账号中心 - EncodeKey",
"IdType": "DEVICE_ID",
"Id": "openUserId"
}
10. 常见问题(FAQ)
Q1:插件与工具有什么区别?
A:插件是服务接入点(怎么连),工具是具体能力单元(调什么)。一个插件包含多个工具。
Q2:我应该选哪种工具类型?
A:已有 HTTP API 选 OpenAPI;已有 MCP Server 选 MCP;已在百炼/扣子创建了 Agent 应用选 Agent。
Q3:OpenAPI 工具支持流式(SSE)输出吗?
A:暂不支持。如需流式能力,可考虑使用 Agent 工具(支持流式响应)。
Q4:为什么我的参数未被模型正确抽取?
A:来源为「模型抽取」的参数请写清晰的 description,描述越具体,模型抽取越准确。
Q5:签名参数怎么配?
A:将密钥放入插件的 configParameters,在参数中选择「脚本生成」来源,编写 Groovy 脚本计算签名,脚本可从 config 读取密钥。目前仅OpenAPI的参数支持脚本计算。
Q6:发布后发现配置错了怎么办?
A:已发布不可修改,需重建。建议发布前充分调试。
Q7:Agent 工具能自定义入参吗?
A:不能。入参固定为单个 prompt,出参固定为 {$: string}。
技能平台