401 lines
7.8 KiB
Markdown
401 lines
7.8 KiB
Markdown
|
|
# test2 外接助手资料接口接入文档
|
|||
|
|
|
|||
|
|
## 1. 文档目的
|
|||
|
|
|
|||
|
|
本文档用于说明 `test2` 项目如何接入外部助手资料接口,并说明本地查询接口、外部接口要求、环境变量配置、缓存与降级策略,以及业务侧如何传入 `userId` 让语音链路和知识库链路使用同一份资料。
|
|||
|
|
|
|||
|
|
该能力用于统一管理以下助手资料字段,避免在代码中硬编码:
|
|||
|
|
|
|||
|
|
- `documents`
|
|||
|
|
- `email`
|
|||
|
|
- `nickname`
|
|||
|
|
- `wxl`
|
|||
|
|
- `mobile`
|
|||
|
|
- `wx_code`
|
|||
|
|
- `intro`
|
|||
|
|
- `sign`
|
|||
|
|
- `story`
|
|||
|
|
|
|||
|
|
## 2. 生效范围
|
|||
|
|
|
|||
|
|
外接助手资料接入后,会影响以下链路:
|
|||
|
|
|
|||
|
|
- `WebSocket 语音链路`
|
|||
|
|
- 文件:`server/services/nativeVoiceGateway.js`
|
|||
|
|
- 在 `start` 消息阶段按 `userId` 拉取外部资料
|
|||
|
|
|
|||
|
|
- `知识库回答链路`
|
|||
|
|
- 文件:`server/services/toolExecutor.js`
|
|||
|
|
- 查询知识库前优先按 `_session.profileUserId`,其次按 `_session.userId` 拉取资料
|
|||
|
|
|
|||
|
|
- `HTTP 文字对话链路`
|
|||
|
|
- 文件:`server/routes/chat.js`
|
|||
|
|
- 会透传 `userId` / `profileUserId` 到知识库查询逻辑
|
|||
|
|
|
|||
|
|
- `本地调试查询接口`
|
|||
|
|
- 文件:`server/routes/assistantProfile.js`
|
|||
|
|
- 已挂载到 `app.js`
|
|||
|
|
- 路径前缀:`/api/assistant-profile`
|
|||
|
|
|
|||
|
|
## 3. 环境变量配置
|
|||
|
|
|
|||
|
|
在 `test2/server/.env` 中增加以下配置:
|
|||
|
|
|
|||
|
|
```env
|
|||
|
|
ASSISTANT_PROFILE_API_URL=https://your-domain/api/profile
|
|||
|
|
ASSISTANT_PROFILE_API_METHOD=GET
|
|||
|
|
ASSISTANT_PROFILE_API_TOKEN=
|
|||
|
|
ASSISTANT_PROFILE_API_HEADERS={"X-App-Key":"demo"}
|
|||
|
|
ASSISTANT_PROFILE_API_TIMEOUT_MS=5000
|
|||
|
|
ASSISTANT_PROFILE_CACHE_TTL_MS=60000
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 参数说明
|
|||
|
|
|
|||
|
|
- `ASSISTANT_PROFILE_API_URL`
|
|||
|
|
- 外部资料接口地址
|
|||
|
|
- 未配置时,系统直接回退到默认助手资料
|
|||
|
|
|
|||
|
|
- `ASSISTANT_PROFILE_API_METHOD`
|
|||
|
|
- 支持 `GET` 或 `POST`
|
|||
|
|
- 其他值会按 `GET` 处理
|
|||
|
|
|
|||
|
|
- `ASSISTANT_PROFILE_API_TOKEN`
|
|||
|
|
- 可选
|
|||
|
|
- 配置后会自动以 `Authorization: Bearer <token>` 方式发送
|
|||
|
|
|
|||
|
|
- `ASSISTANT_PROFILE_API_HEADERS`
|
|||
|
|
- 可选
|
|||
|
|
- JSON 字符串格式
|
|||
|
|
- 例如:`{"X-App-Key":"demo"}`
|
|||
|
|
|
|||
|
|
- `ASSISTANT_PROFILE_API_TIMEOUT_MS`
|
|||
|
|
- 可选
|
|||
|
|
- 外部接口超时时间,默认 `5000`
|
|||
|
|
|
|||
|
|
- `ASSISTANT_PROFILE_CACHE_TTL_MS`
|
|||
|
|
- 可选
|
|||
|
|
- 资料缓存时长,默认 `60000`
|
|||
|
|
|
|||
|
|
## 4. 外部接口调用规则
|
|||
|
|
|
|||
|
|
`test2` 服务端不会直接把前端传来的资料写死到配置中,而是通过 `assistantProfileService` 统一向外部接口拉取。
|
|||
|
|
|
|||
|
|
### 4.1 当配置为 GET 时
|
|||
|
|
|
|||
|
|
请求方式:`GET`
|
|||
|
|
|
|||
|
|
请求参数:
|
|||
|
|
|
|||
|
|
- 有 `userId` 时,追加查询参数 `?userId=xxx`
|
|||
|
|
- 无 `userId` 时,不带该参数
|
|||
|
|
|
|||
|
|
默认请求头:
|
|||
|
|
|
|||
|
|
```http
|
|||
|
|
Accept: application/json
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
如果配置了 Token,还会带:
|
|||
|
|
|
|||
|
|
```http
|
|||
|
|
Authorization: Bearer <ASSISTANT_PROFILE_API_TOKEN>
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
如果配置了 `ASSISTANT_PROFILE_API_HEADERS`,会一并追加到请求头中。
|
|||
|
|
|
|||
|
|
### 4.2 当配置为 POST 时
|
|||
|
|
|
|||
|
|
请求方式:`POST`
|
|||
|
|
|
|||
|
|
请求体:
|
|||
|
|
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"userId": "abc123"
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
如果当前没有 `userId`,则请求体会是空对象:
|
|||
|
|
|
|||
|
|
```json
|
|||
|
|
{}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
默认请求头同上。
|
|||
|
|
|
|||
|
|
## 5. 外部接口返回格式要求
|
|||
|
|
|
|||
|
|
服务端支持以下任一返回结构。
|
|||
|
|
|
|||
|
|
### 5.1 结构一
|
|||
|
|
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"profile": {
|
|||
|
|
"nickname": "大沃",
|
|||
|
|
"mobile": "13800000000"
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 5.2 结构二
|
|||
|
|
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"assistantProfile": {
|
|||
|
|
"nickname": "大沃",
|
|||
|
|
"intro": "你好,我是大沃。"
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 5.3 结构三
|
|||
|
|
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"data": {
|
|||
|
|
"profile": {
|
|||
|
|
"nickname": "大沃"
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 5.4 结构四
|
|||
|
|
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"data": {
|
|||
|
|
"assistantProfile": {
|
|||
|
|
"nickname": "大沃"
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 5.5 结构五
|
|||
|
|
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"nickname": "大沃",
|
|||
|
|
"mobile": "13800000000"
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 6. 服务端识别的资料字段
|
|||
|
|
|
|||
|
|
服务端只会提取以下字段,其余字段会被忽略:
|
|||
|
|
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"documents": "",
|
|||
|
|
"email": "",
|
|||
|
|
"nickname": "",
|
|||
|
|
"wxl": "",
|
|||
|
|
"mobile": "",
|
|||
|
|
"wx_code": "",
|
|||
|
|
"intro": "",
|
|||
|
|
"sign": "",
|
|||
|
|
"story": ""
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
建议外部接口只返回上述字段,避免无关数据混入。
|
|||
|
|
|
|||
|
|
## 7. 本地查询接口
|
|||
|
|
|
|||
|
|
该接口用于联调和排查当前生效的助手资料。
|
|||
|
|
|
|||
|
|
### 7.1 查询当前资料
|
|||
|
|
|
|||
|
|
- `GET /api/assistant-profile`
|
|||
|
|
|
|||
|
|
查询参数:
|
|||
|
|
|
|||
|
|
- `userId`:可选
|
|||
|
|
- `forceRefresh`:可选,传 `true` 时强制拉取远端接口,跳过本地缓存
|
|||
|
|
|
|||
|
|
示例:
|
|||
|
|
|
|||
|
|
```http
|
|||
|
|
GET /api/assistant-profile?userId=abc123
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
```http
|
|||
|
|
GET /api/assistant-profile?userId=abc123&forceRefresh=true
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
成功响应示例:
|
|||
|
|
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"code": 0,
|
|||
|
|
"message": "success",
|
|||
|
|
"success": true,
|
|||
|
|
"data": {
|
|||
|
|
"userId": "abc123",
|
|||
|
|
"profile": {
|
|||
|
|
"documents": "",
|
|||
|
|
"email": "",
|
|||
|
|
"nickname": "大沃",
|
|||
|
|
"wxl": "wx_demo",
|
|||
|
|
"mobile": "13800000000",
|
|||
|
|
"wx_code": "",
|
|||
|
|
"intro": "你好,我是大沃。",
|
|||
|
|
"sign": "",
|
|||
|
|
"story": ""
|
|||
|
|
},
|
|||
|
|
"source": "remote_api",
|
|||
|
|
"cached": false,
|
|||
|
|
"fetchedAt": 1742710000000,
|
|||
|
|
"configured": true,
|
|||
|
|
"error": null
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
失败响应示例:
|
|||
|
|
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"code": 500,
|
|||
|
|
"message": "request timeout",
|
|||
|
|
"success": false,
|
|||
|
|
"error": "request timeout"
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 7.2 强制刷新缓存
|
|||
|
|
|
|||
|
|
- `POST /api/assistant-profile/refresh`
|
|||
|
|
|
|||
|
|
请求体:
|
|||
|
|
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"userId": "abc123"
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
成功响应结构与查询接口一致。
|
|||
|
|
|
|||
|
|
## 8. source 字段说明
|
|||
|
|
|
|||
|
|
本地查询接口返回的 `data.source` 可用于判断当前资料来源:
|
|||
|
|
|
|||
|
|
- `remote_api`
|
|||
|
|
- 本次成功从外部接口获取
|
|||
|
|
|
|||
|
|
- `default`
|
|||
|
|
- 未配置 `ASSISTANT_PROFILE_API_URL`
|
|||
|
|
- 使用系统默认助手资料
|
|||
|
|
|
|||
|
|
- `cache_fallback`
|
|||
|
|
- 外部接口调用失败
|
|||
|
|
- 回退到历史缓存资料
|
|||
|
|
|
|||
|
|
- `default_fallback`
|
|||
|
|
- 外部接口调用失败,且没有缓存
|
|||
|
|
- 回退到默认助手资料
|
|||
|
|
|
|||
|
|
## 9. 缓存与降级策略
|
|||
|
|
|
|||
|
|
### 9.1 缓存规则
|
|||
|
|
|
|||
|
|
- 缓存按 `userId` 隔离
|
|||
|
|
- 未传 `userId` 时,使用全局缓存槽位
|
|||
|
|
- 默认缓存时长为 `60000ms`
|
|||
|
|
- 在缓存有效期内重复请求时,会直接返回缓存结果
|
|||
|
|
|
|||
|
|
### 9.2 降级规则
|
|||
|
|
|
|||
|
|
当外部接口异常、超时或返回不可解析内容时:
|
|||
|
|
|
|||
|
|
- 若当前 `userId` 已有缓存,则回退到缓存资料
|
|||
|
|
- 若没有缓存,则回退到系统默认资料
|
|||
|
|
- 响应中会保留 `error` 字段,便于排查
|
|||
|
|
|
|||
|
|
## 10. 业务侧如何传 userId
|
|||
|
|
|
|||
|
|
为了让语音链路和知识库链路命中同一份资料,业务侧应尽量传入稳定的业务用户标识。
|
|||
|
|
|
|||
|
|
### 10.1 WebSocket 语音链路
|
|||
|
|
|
|||
|
|
在 `start` 消息中传入:
|
|||
|
|
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"type": "start",
|
|||
|
|
"userId": "abc123"
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 10.2 HTTP 文字对话链路
|
|||
|
|
|
|||
|
|
在聊天相关请求中传入:
|
|||
|
|
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"sessionId": "session_xxx",
|
|||
|
|
"message": "介绍一下你自己",
|
|||
|
|
"userId": "abc123"
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
系统会把该 `userId` 同步为 `profileUserId`,知识库查询时优先使用它拉取资料。
|
|||
|
|
|
|||
|
|
## 11. 推荐联调步骤
|
|||
|
|
|
|||
|
|
### 步骤 1
|
|||
|
|
|
|||
|
|
在 `server/.env` 中配置外部资料接口地址和认证信息。
|
|||
|
|
|
|||
|
|
### 步骤 2
|
|||
|
|
|
|||
|
|
启动 `test2/server`。
|
|||
|
|
|
|||
|
|
### 步骤 3
|
|||
|
|
|
|||
|
|
请求本地查询接口验证配置是否生效:
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
curl "http://localhost:3001/api/assistant-profile?userId=abc123"
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 步骤 4
|
|||
|
|
|
|||
|
|
观察返回中的以下字段:
|
|||
|
|
|
|||
|
|
- `data.source`
|
|||
|
|
- `data.cached`
|
|||
|
|
- `data.configured`
|
|||
|
|
- `data.error`
|
|||
|
|
|
|||
|
|
### 步骤 5
|
|||
|
|
|
|||
|
|
再分别验证:
|
|||
|
|
|
|||
|
|
- 语音 `start` 是否按 `userId` 生效
|
|||
|
|
- 文字聊天是否按 `userId` 生效
|
|||
|
|
- 知识库回答是否使用同一份助手资料
|
|||
|
|
|
|||
|
|
## 12. 接入注意事项
|
|||
|
|
|
|||
|
|
- 不要把外部接口 Token 写死到前端代码中
|
|||
|
|
- 建议外部接口返回稳定 JSON 对象,不要返回数组
|
|||
|
|
- 建议外部接口响应时间控制在 `5s` 内
|
|||
|
|
- 若业务侧有多租户或多用户资料,必须传稳定的 `userId`
|
|||
|
|
- 如果只是排查当前资料,优先使用 `GET /api/assistant-profile`
|
|||
|
|
- 如果远端已更新但本地仍旧值,调用 `POST /api/assistant-profile/refresh`
|
|||
|
|
|
|||
|
|
## 13. 相关代码位置
|
|||
|
|
|
|||
|
|
- 路由注册:`server/app.js`
|
|||
|
|
- 本地查询接口:`server/routes/assistantProfile.js`
|
|||
|
|
- 外部拉取与缓存:`server/services/assistantProfileService.js`
|
|||
|
|
- 语音链路接入:`server/services/nativeVoiceGateway.js`
|
|||
|
|
- 知识库链路接入:`server/services/toolExecutor.js`
|
|||
|
|
- 聊天链路透传:`server/routes/chat.js`
|
|||
|
|
- 环境变量示例:`server/.env.example`
|