配置第三方机器人
功能概述
第三方机器人是WPS服务台的核心开放能力之一。在配置第三方机器人后,WPS服务台仅作为输出形象,由第三方机器人接管服务台用户咨询,用户消息由服务台转发至第三方机器人,回复由第三方机器人通过接口返回至服务台并展示。
实现步骤
- 进入 服务台管理后台-服务台设置-开放配置 中开启 第三方机器人 功能
- 按规则配置接收服务台请求的 URL 地址
- 按需要配置第三方接口Secret Key
协议类型
- 服务台支持两种协议类型:
- 自定义协议:自定义的流式/非流式协议
- OpenAI 协议:兼容 OpenAI Chat Completion API 的流式/非流式协议
一、自定义协议第三方机器人回调接口说明
接口概览
提供两种类型的回调接口:
- 流式接口:用于实时流式返回 AI 回答内容
- 非流式接口:用于一次性返回完整的 AI 回答内容
两种接口使用相同的签名方式和入参结构。
通用签名说明
签名生成过程
go
package main
import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"encoding/json"
"fmt"
)
// 通用请求体结构
type CallbackRequestBody struct {
HelpdeskId int64 `json:"helpdesk_id"`
SessionId string `json:"session_id"`
Question string `json:"question"`
UserId string `json:"user_id"`
}
// 生成签名的核心函数
func GenerateSignature(secretKey string, helpdeskId int64, sessionId, question string, userId string) (string, error) {
// 1. 构造请求体
body := &CallbackRequestBody{
HelpdeskId: helpdeskId,
SessionId: sessionId,
Question: question,
UserId: userId,
}
// 2. 序列化为 JSON
marshal, err := json.Marshal(body)
if err != nil {
return "", fmt.Errorf("JSON序列化失败: %v", err)
}
// 3. 计算 HMAC-SHA256 签名
hm := hmac.New(sha256.New, []byte(secretKey))
hm.Write(marshal)
signatureStr := hex.EncodeToString(hm.Sum(nil))
return signatureStr, nil
}请求头设置
将签名放入 HTTP Header 中:
http
signature: {生成的签名值}流式接口
基本信息
- 接口路径: POST
- 请求头: accept: text/event-stream
- 签名: 参考上文通用签名说明
请求参数
| 名称 | 位置 | 类型 | 是否必传 | 说明 |
|---|---|---|---|---|
| helpdesk_id | body | integer | 是 | 服务台id |
| session_id | body | string | 是 | 请求唯一id |
| question | body | string | 是 | 问题内容 |
| user_id | body | string | 否 | 当前设备登录用户,第三方联合id |
响应参数
响应采用 Server-Sent Events (SSE) 格式:
| 名称 | 位置 | 类型 | 是否必须 | 说明与示例 |
|---|---|---|---|---|
| session_id | body | string | 是 | 请求唯一id |
| start | body | object | 否 | 开始内容 |
| start.text | body | string | 是 | ai loading文本,例如:正在理解问题 |
| delta | body | object | 否 | 正文内容 |
| delta.text | body | string | 是 | 正文内容,连续传递会追加 |
| reference | body | object | 否 | 引用内容,限制5个 |
| reference.items | body | []object | 是 | 引用 |
| reference.items[].url | body | string | 是 | 引用链接 |
| reference.items[].name | body | string | 是 | 引用描述 |
| reference.desc | body | string | 是 | 描述 |
| finish | body | int64 | 否 | 结束标识,可以传当前时间戳,秒级别 |
| heartbeat | body | int64 | 否 | 心跳检测,可以传当前时间戳,秒级别。服务台会有心跳检测,每一段数据超过10s则会断开 |
流式输出示例
text
event:message
data:{"code": 0, "data": {"session_id": "1", "start": {"text": "正在理解问题"}}}
event:message
data:{"code": 0, "data": {"session_id": "1", "reference": {"items": [{"url": "http://www.kdocs.cn/xxx", "name": "文档"}], "desc": "参考文档"}}}
event:message
data:{"code": 0, "data": {"session_id": "1", "delta": {"text": "以下是问题答案:1.xxx"}}}
event:message
data:{"code": 0, "data": {"session_id": "1", "delta": {"text": "2.xxx"}}}
event:message
data:{"code": 0, "data": {"session_id": "1", "heartbeat": 123}}
event:message
data:{"code": 0, "data": {"session_id": "1", "finish": 123}}非流式接口
基本信息
- 接口路径: POST
- 请求头: Accept: application/json
- 签名: 参考上文通用签名说明
请求参数
| 名称 | 位置 | 类型 | 是否必传 | 说明 |
|---|---|---|---|---|
| helpdesk_id | body | integer | 是 | 服务台id |
| session_id | body | string | 是 | 请求唯一id |
| question | body | string | 是 | 问题内容 |
| user_id | body | string | 否 | 当前设备登录用户,第三方联合id |
响应参数
| 名称 | 位置 | 类型 | 是否必须 | 说明与示例 |
|---|---|---|---|---|
| session_id | body | string | 是 | 请求唯一id |
| text | body | string | 否 | 文本内容,支持markdown格式 |
非流式输出示例
json
{
"code": 0,
"data": {
"session_id": "123",
"text": "正在理解问题\n\n以下是问题答案:\n1. xxx\n2. yyy"
}
}二、兼容OpenAI协议第三方机器人回调接口说明
接口概览
兼容 OpenAI Chat Completion API 格式,支持:
- 流式接口:使用 SSE 流式返回
- 非流式接口:一次性返回完整回答
认证方式
采用 双重认证:
- Bearer Token:在请求头中设置
Authorization: Bearer {api_key} - 签名验证:使用与自定义协议相同的 HMAC-SHA256 签名机制
签名生成
go
package main
import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"encoding/json"
)
type Message struct {
Role string `json:"role"`
Content string `json:"content"`
}
type OpenAICallbackRequestBody struct {
Messages []Message `json:"messages"`
Stream bool `json:"stream"`
}
// 生成 OpenAI 协议签名
func GenerateOpenAISignature(secretKey string, messages []Message, stream bool) (string, error) {
// 1. 构造请求体
body := &OpenAICallbackRequestBody{
Messages: messages,
Stream: stream,
}
// 2. 序列化为 JSON
marshal, err := json.Marshal(body)
if err != nil {
return "", err
}
// 3. 计算 HMAC-SHA256 签名
hm := hmac.New(sha256.New, []byte(secretKey))
hm.Write(marshal)
return hex.EncodeToString(hm.Sum(nil)), nil
}请求头设置
http
Authorization: Bearer {api_key}
signature: {生成的签名值}
Content-Type: application/json
Accept: text/event-stream (流式接口)
Accept: application/json (非流式接口)流式接口
基本信息
- 接口路径: POST
- 请求头:
Authorization: Bearer {api_key}signature: {签名值}Accept: text/event-streamContent-Type: application/json
- 协议: 兼容 OpenAI Chat Completion API
请求参数
| 名称 | 位置 | 类型 | 是否必传 | 说明 |
|---|---|---|---|---|
| messages | body | []object | 是 | 消息历史数组,限制10条 |
| messages[].role | body | string | 是 | 角色:user/ assistant |
| messages[].content | body | string | 是 | 消息内容 |
| stream | body | boolean | 是 | 必须为 true |
请求示例:
json
{
"messages": [
{"role": "user", "content": "如何使用WPS文档?"},
{"role": "assistant", "content": "WPS文档是一款在线协作办公软件..."},
{"role": "user", "content": "如何协作编辑?"}
],
"stream": true
}响应参数
响应遵循 OpenAI Stream 格式:
| 名称 | 位置 | 类型 | 是否必须 | 说明 |
|---|---|---|---|---|
| id | body | string | 否 | 该对话的唯一标识符 |
| choices | body | []object | 是 | 选项数组 |
| choices[].delta | body | object | 是 | 增量内容 |
| choices[].delta.role | body | string | 否 | 角色 |
| choices[].delta.content | body | string | 否 | 增量文本内容 |
| choices[].delta.reasoning_content | body | string | 否 | 推理内容,用于 deepseek-reasoner 等模型 |
| choices[].delta.reference | body | object | 否 | 引用内容 |
| choices[].delta.reference.desc | body | string | 是 | 引用描述 |
| choices[].delta.reference.items | body | []object | 是 | 引用列表,限制5个 |
| choices[].delta.reference.items[].document | body | object | 是 | 文档信息 |
| choices[].delta.reference.items[].document.url | body | string | 是 | 文档链接 |
| choices[].delta.reference.items[].document.name | body | string | 是 | 文档名称 |
| choices[].finish_reason | body | string | 否 | 结束原因:stop等 |
流式输出示例
text
data: {"id":"chatcmpl-123","choices":[{"delta":{"role":"assistant","content":""}}]}
data: {"id":"chatcmpl-123","choices":[{"delta":{"content":"正在"}}]}
data: {"id":"chatcmpl-123","choices":[{"delta":{"content":"理解"}}]}
data: {"id":"chatcmpl-123","choices":[{"delta":{"reference":{"desc":"参考文档","items":[{"document":{"url":"http://www.kdocs.cn/xxx","name":"使用指南.docx"}}]}}}]}
data: {"id":"chatcmpl-123","choices":[{"delta":{"content":"以下是"}}]}
data: {"id":"chatcmpl-123","choices":[{"delta":{"content":"答案"}}]}
data: {"id":"chatcmpl-123","choices":[{"delta":{},"finish_reason":"stop"}]}
data: [DONE]非流式接口
基本信息
- 接口路径: POST
- 请求头:
Authorization: Bearer {api_key}signature: {签名值}Accept: application/jsonContent-Type: application/json
- 协议: 兼容 OpenAI Chat Completion API
请求参数
| 名称 | 位置 | 类型 | 是否必传 | 说明 |
|---|---|---|---|---|
| messages | body | []object | 是 | 消息历史数组,限制10条 |
| messages[].role | body | string | 是 | 角色:user / assistant |
| messages[].content | body | string | 是 | 消息内容 |
| stream | body | boolean | 是 | 必须为 false |
请求示例:
json
{
"messages": [
{"role": "user", "content": "如何使用WPS文档?"},
{"role": "assistant", "content": "WPS文档是一款在线协作办公软件..."},
{"role": "user", "content": "如何协作编辑?"}
],
"stream": false
}响应参数
| 名称 | 位置 | 类型 | 是否必须 | 说明 |
|---|---|---|---|---|
| id | body | string | 否 | 该对话的唯一标识符 |
| choices | body | []object | 是 | 选项数组 |
| choices[].message | body | object | 是 | 消息 |
| choices[].message.role | body | string | 是 | 角色 |
| choices[].message.content | body | string | 是 | 完整回答内容 |
| choices[].message.reasoning_content | body | string | 否 | 推理内容,用于 deepseek-reasoner 等模型 |
| choices[].finish_reason | body | string | 否 | 结束原因:stop等 |
非流式输出示例
json
{
"id": "chatcmpl-123",
"choices": [
{
"message": {
"role": "assistant",
"content": "正在理解问题\n\n以下是问题答案:\n1. WPS文档支持多人协作编辑\n2. 可以通过分享链接邀请协作者"
},
"finish_reason": "stop"
}
]
}注意事项
自定义协议限制
- 签名密钥:HMAC-SHA256签名需要的secret_key 从服务台页面获取
- 心跳机制:流式接口需要定期发送心跳,超过10秒无数据会断开连接
- 引用限制:流式接口的引用内容最多5个
- 消息限制:返回的消息整体限制在4000字符以内
OpenAI协议限制
- 消息限制:单个chunk不可大于1024B,返回的消息整体限制在4000字符以内
- 首条消息:必须包含 role
- 最后一条消息:finish_reason 非空或者[DONE]