跳到主要内容

分身中心:API

将你的 SecondMe AI 分身集成到任意第三方应用中 —— 飞书机器人、客服系统,或任何自定义应用。

概述

分身开放 API 提供统一的鉴权入口。鉴权通过后,你将使用与 SecondMe App 完全相同的接口 —— 无需学习额外 API。

你的应用 → /open/avatar/auth(API Key → visitor token)
→ 标准 SecondMe 接口(与 App 一致)
→ WebSocket 实时接收 AI 回复

你可以构建什么

  • 飞书 / 钉钉 / Slack 机器人 —— 用户通过即时通讯平台与你的分身对话
  • 网页聊天组件 —— 在你的网站中嵌入分身对话
  • 智能客服 —— 让分身 7×24 小时处理咨询
  • 任意自定义集成 —— 任何能发起 HTTP 请求并连接 WebSocket 的应用

工作原理

  1. 你在 SecondMe App 中为分身创建 API Key
  2. 你的应用调用 /auth 接口,使用 API Key 获取 visitor token
  3. 你的应用使用 visitor token 调用标准 SecondMe 接口
  4. AI 回复通过 WebSocket 实时推送
  5. 你(分身所有者)可以在 App 中查看所有对话并随时接管

前提条件

  1. 拥有 SecondMe 账号并已创建至少一个分身
  2. 在分身中心 → 分身详情 → API Key 管理中创建 API Key
  3. 保存好你的 API Key(以 sk- 开头,创建时仅显示一次 —— 请妥善保管)

环境

环境Base URL
生产环境https://mindos.mindverse.ai/gate/in
预发环境https://mindos-prek8s.mindverse.ai/gate/in

快速开始

第 0 步:鉴权

用 API Key 换取 visitor token。每个终端用户需要一个唯一的 visitorId

visitorId 格式{platform}_{uuid}

示例:feishu_550e8400-e29b-41d4-a716-446655440000web_6ba7b810-9dad-11d1-80b4-00c04fd430c8

提示

为每个终端用户生成唯一的 visitorId 并持久化保存。相同的 visitorId = 同一个访客 = 可以复用已有会话。

curl -X POST $BASE_URL/rest/open/avatar/auth \
-H "Authorization: Bearer sk-your-api-key" \
-H "Content-Type: application/json" \
-d '{
"visitorId": "feishu_550e8400-e29b-41d4-a716-446655440000",
"visitorName": "John Doe",
"channel": "feishu"
}'
字段必填说明
visitorId格式:{platform}_{uuid}
visitorName显示名称,展示给分身所有者。例如 "张三"
channel渠道标识,附加在名称后显示为 "张三(feishu)"。例如 "feishu"、"dingtalk"、"web"

响应:

{
"code": 0,
"data": {
"visitorToken": "bb857435f640c8b2...",
"visitorUserId": "del3p",
"visitorMindId": "487569763543990272",
"avatarShareCode": "ebe251793d69",
"avatarName": "My Assistant",
"ownerUserId": "de4fh"
}
}
字段说明用于
visitorToken后续所有请求的鉴权 tokentoken 请求头
visitorUserId编码后的访客用户 IDws/createmessage/send
visitorMindId访客的 mind ID(数字型)session/create
avatarShareCode分身的分享码chat/init
ownerUserId分身所有者的编码 IDsession/create 的 memberUserIds
警告

后续所有请求需要携带两个请求头:

  • token: {visitorToken}
  • Fp: {visitorId}

第 1 步:初始化对话

将分身的上下文(人设、素材)加载到缓存中。10 分钟后过期。

curl -X POST $BASE_URL/rest/os/avatar/chat/init \
-H "token: $VISITOR_TOKEN" \
-H "Fp: $VISITOR_ID" \
-H "Content-Type: application/json" \
-d '{"shareCode": "ebe251793d69"}'

响应:

{
"code": 0,
"data": {
"mindId": "3m24e99h3mbp",
"avatarName": "My Assistant",
"ownerUserId": "de4fh",
"opening": "Hello! 👋"
}
}
提示

保存此响应中的 mindId —— 你将在第 6 步(发送消息)中使用它。这是一个编码字符串(不是第 0 步中的数字型 visitorMindId)。

第 2 步:创建 WebSocket

curl -X POST $BASE_URL/rest/general/ws/create \
-H "token: $VISITOR_TOKEN" \
-H "Fp: $VISITOR_ID" \
-H "Content-Type: application/json" \
-d '{
"userId": "del3p",
"channel": ["ALL"],
"apiVersion": "1.3.0",
"sdkVersion": "1.0.0"
}'

返回 WebSocket 地址。必须在 60 秒内连接。

第 3 步:创建会话

curl -X POST $BASE_URL/rest/general/session/create \
-H "token: $VISITOR_TOKEN" \
-H "Fp: $VISITOR_ID" \
-H "Content-Type: application/json" \
-d '{
"mindId": 487569763543990272,
"mindType": "shadow",
"mode": "PERSONAL",
"sessionType": "SHARE",
"memberUserIds": ["de4fh"]
}'
关键参数

mindIdmemberUserIds 都是必填的。缺少它们会导致:

  • AI 无法识别分身的人设
  • 分身所有者无法在 App 中回复("not a member" 错误)
参数来源
mindId数字型 ID第 0 步 visitorMindId
memberUserIds["ownerUserId"]第 0 步 ownerUserId
sessionType"SHARE"固定值

第 4 步:绑定会话到分身

使对话在分身所有者的分身中心中可见。

# 首先,获取分身的数字型 ID
curl -X GET "$BASE_URL/rest/os/avatar/public/ebe251793d69" \
-H "token: $VISITOR_TOKEN"
# 响应:data.id = avatarId(例如 67)

# 然后绑定
curl -X POST $BASE_URL/rest/os/avatar/chat/start \
-H "token: $VISITOR_TOKEN" \
-H "Fp: $VISITOR_ID" \
-H "Content-Type: application/json" \
-d '{"avatarId": 67, "sessionId": "your-session-id"}'

第 5 步:连接 WebSocket

连接到第 2 步获取的地址。每 15 秒发送一次心跳。

const ws = new WebSocket(address);

// 每 15 秒发送心跳
setInterval(() => {
ws.send(JSON.stringify({ type: 'ping', wsId: wsId }));
}, 15000);

第 6 步:发送消息

消息通过 HTTP 发送,AI 回复通过 WebSocket 推送。

curl -X POST $BASE_URL/rest/general/message/send \
-H "token: $VISITOR_TOKEN" \
-H "Fp: $VISITOR_ID" \
-H "Content-Type: application/json" \
-d '{
"timestamp": 1774580000000,
"seqId": "12345_____1774580000000",
"sessionId": "your-session-id",
"userId": "del3p",
"messageId": "12345_____1774580000000",
"mindId": "3m24e99h3mbp",
"index": 0,
"sendUserId": "del3p",
"dataType": "text",
"sender": "client",
"type": "msg",
"wsId": "ws:260327...",
"data": {"content": "你好,介绍一下你自己"}
}'
参数来源
timestamp当前时间戳(毫秒)Date.now()
seqId{random}_____${timestamp}每条消息唯一
sessionId会话 ID第 3 步响应
userId访客编码 ID第 0 步 visitorUserId
messageId与 seqId 相同
mindId编码字符串(非数字型)第 1 步响应的 mindId
sendUserId与 userId 相同
wsIdWebSocket ID第 2 步响应的 wsId
data.content消息文本
mindId 易混淆

第 6 步使用的是第 1 步返回的编码字符串 mindId(例如 "3m24e99h3mbp")。 这与第 0 步中的数字型 visitorMindId(例如 "487569763543990272",用于第 3 步)不同

WebSocket 消息

AI 回复

{
"sender": "umm",
"multipleData": [{ "modal": { "answer": "Hello! I'm..." } }]
}

所有者接管回复

当分身所有者在 SecondMe App 中手动回复时:

{
"sender": "client",
"sendUserId": "de4fh",
"multipleData": [{ "modal": { "answer": "你好,这是真人回复..." } }]
}

区分消息类型

sendersendUserId含义
ummAI 分身回复
client等于你的 visitorUserId你自己发送消息的回显(忽略)
client不等于你的 visitorUserId所有者接管回复

错误码

错误码说明
open.api.unauthorized缺少 Authorization 请求头
open.api.key.not.found无效的 API Key
open.api.key.disabledAPI Key 已禁用
open.api.rate.limited超出频率限制(每个 Key 每分钟 60 次)
open.api.avatar.not.found分身未找到
open.api.invalid.visitor.id无效的 visitorId 格式
session.not.member非会话成员(检查 memberUserIds)

注意事项

  1. 上下文缓存 10 分钟后过期 —— 请在第 1 步完成后 10 分钟内完成第 3 步
  2. WebSocket 地址 60 秒后过期 —— 获取后请立即连接
  3. 必须发送心跳 —— 每 15 秒发送一次 ping,否则连接将断开
  4. 消息通过 HTTP 发送,回复通过 WebSocket 推送 —— 这是设计如此,与 App 行为一致
  5. 一个 visitorId 可以有多个会话 —— 每次调用 session/create 都会创建新的对话
  6. 频率限制 —— 每个 API Key 每分钟 60 次请求