从创建应用到首次调用
创建应用、勾选能力、运行 Demo,并使用 Java 或 Node.js 调用 JSON 和 SSE。
调用链路
创建应用 → 勾选分组下的能力 → 保存应用 → Demo 选择应用和能力 → 服务端校验应用及权限 → 转发业务上游 → 返回 JSON 或 SSE。
1. 准备能力
运营人员在「能力管理」配置能力分组、能力标识、上游接口地址、请求路径及上游密钥,并启用能力。上游密钥加密保存在平台数据库,由网关调用时读取、解密,不返回给应用创建页面。
能力列表来自后台配置。调用方只需选择平台能力标识,业务输入按能力文档准备,上游配置由平台内部维护。
2. 创建应用并勾选能力
进入控制台「应用管理」,点击「创建应用」。在右侧 Drawer 填写应用名称和可选描述,在关联能力目录树中展开分组,勾选需要调用的能力。
勾选分组可选择全部子能力;部分子项选中时分组显示半选。一个应用可以关联多个能力,不勾选则没有能力调用权限。点击右上角「确认创建」,保存生成的 Access Key。后续可在应用详情查看、复制 Key,编辑应用可调整绑定。
应用需处于启用状态。也可从开放能力卡片「关联应用」为已有应用授予权限;已绑定应用无需重复关联。
3. 使用内置 Demo 验证
在项目根目录运行:
pnpm dev:server-api
# 在另一个终端启动演示页面
pnpm demo:gateway打开 http://127.0.0.1:4100:
- 从下拉框选择刚创建的应用,无需输入 Key。
- 选择已勾选的能力,填写请求内容。
- 点击「普通 JSON」查看状态码及原始响应,或对支持流式输出的能力点击「SSE 流式输出」。
需要 Node.js / Java 调用代码时,参见下方「在业务服务端调用」。
Demo 浏览器仅向 /api/invoke/ 发送应用 ID、model 和业务数据;Demo 服务端读取应用密钥后,通过 HTTP 请求 server-api 的 /openapi/v1/ 接口,由平台统一鉴权、转发及采集统计。真实上游配置来自当前数据库,不是固定模拟响应。停用应用由平台拒绝;没有可恢复密钥的应用无法通过 Demo 发起调用。
Demo 仅监听本机,列出当前数据库应用供联调使用,没有业务用户授权体系,不应直接公开部署。正式业务服务端必须校验用户身份及应用归属,不能允许任意用户通过应用 ID 代调接口。
4. 在业务服务端调用
配置环境变量 THINKWHEEL_GATEWAY_ORIGIN(开放平台网关地址)和 THINKWHEEL_ACCESS_KEY(该应用的 Key)。本地网关使用 http://127.0.0.1:4000(4100 仅为演示页面端口);生产使用实际 HTTPS 域名。不要把 Key 写到浏览器、URL 或源码中。
以下示例使用 deepseekV4Pro。查询参数 model 选择平台能力。无需提供上游模型、路径或密钥,平台在鉴权通过后自动注入内部配置。应用 ID 不需要传给开放接口,Authorization: Bearer <Access Key> 请求头已确定应用身份。
// Node.js 20+;保存为 invoke.mjs,执行 node invoke.mjs
const base = process.env.THINKWHEEL_GATEWAY_ORIGIN;
const key = process.env.THINKWHEEL_ACCESS_KEY;
if (!base || !key) throw new Error('请设置网关地址和应用 Access Key');
const response = await fetch(new URL('/openapi/v1/?model=deepseekV4Pro', base), {
method: 'POST',
headers: { 'Content-Type': 'application/json', Authorization: 'Bearer ' + key },
body: '{"messages":[{"role":"system","content":"你是人工智能助手."},{"role":"user","content":"你好"}],"stream":false}',
});
if (!response.ok) throw new Error('HTTP ' + response.status + ': ' + (await response.text()));
console.log(await response.text());运行 node invoke.mjs,要求 Node.js 20+。
5. SSE 与权限验收
对于聊天上游,将请求体 stream 改为 true。Node.js 用下面的读取方式替换 response.text();Java 示例已按字节持续读取并刷新输出,可直接使用。
for await (const chunk of response.body) process.stdout.write(chunk);这是原样输出 SSE,不把网络分块当作完整事件。如果需要解析事件,应按空行分隔并保留跨块残留数据。其他能力的请求字段和流式路径以该能力约定为准,Demo 的通用 message / stream 路径不适用于所有业务接口。
| 场景 | 预期 |
|---|---|
| 应用启用、能力已绑定、上游可用 | 返回上游 JSON 或持续输出 SSE |
| 应用未绑定所选能力 | 网关拒绝,返回 403 |
| 直接调用开放接口缺少或使用无效 Key | 返回 401 |
| Demo 未选择应用 | 页面提示选择应用 |
| Demo 选择的应用被停用或密钥不可恢复 | Demo 拒绝,返回 403 |
| 能力或上游配置不可用 | 根据原因返回错误;未配置上游返回 503 |