# 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 ` 方式发送 - `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_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`