feat(server): KB prompt优化、字幕修复、S2S重连、助手配置API
- assistantProfileConfig: KB answer prompt改为分层策略(严格产品信息+灵活常识补充) - nativeVoiceGateway: S2S upstream自动重连(最多50次)、event 351字幕debounce(800ms取最长文本) - toolExecutor: 确定性query改写增强、KB查询传递session上下文 - contextKeywordTracker: 支持KB话题记忆优先enrichment - contentSafeGuard: 新增品牌安全内容过滤服务 - assistantProfileService: 新增助手配置CRUD服务 - routes/assistantProfile: 新增助手配置API路由 - knowledgeKeywords: 扩展KB关键词词典 - fastAsrCorrector: ASR纠错规则更新 - tests/: KB prompt测试、保护窗口测试、Viking性能测试 - docs/: 助手配置API文档、系统提示词目录
This commit is contained in:
400
test2/server/docs/assistant-profile-api.md
Normal file
400
test2/server/docs/assistant-profile-api.md
Normal file
@@ -0,0 +1,400 @@
|
||||
# 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`
|
||||
391
test2/server/docs/system-prompts-catalog.md
Normal file
391
test2/server/docs/system-prompts-catalog.md
Normal file
@@ -0,0 +1,391 @@
|
||||
# 大沃 AI 语音助手 — 系统人设提示词全览
|
||||
|
||||
> 最后更新:2026-03-23
|
||||
> 梳理范围:`test2/server/services/` 下所有涉及 AI 人设、系统指令、安全回复的文本
|
||||
|
||||
---
|
||||
|
||||
## 目录
|
||||
|
||||
1. [S2S 语音对话层(火山引擎)](#1-s2s-语音对话层火山引擎)
|
||||
2. [知识库检索层(方舟 API)](#2-知识库检索层方舟-api)
|
||||
3. [对话交接层(Handoff)](#3-对话交接层handoff)
|
||||
4. [内容安全层(SafeGuard)](#4-内容安全层safeguard)
|
||||
5. [高频热答案(HOT_ANSWERS)](#5-高频热答案hot_answers)
|
||||
6. [ASR 热词上下文](#6-asr-热词上下文)
|
||||
|
||||
---
|
||||
|
||||
## 1. S2S 语音对话层(火山引擎)
|
||||
|
||||
> 文件:`nativeVoiceGateway.js`
|
||||
> 作用:通过火山引擎 S2S WebSocket 进行实时语音对话,以下提示词直接发送给火山引擎模型
|
||||
|
||||
### 1.1 反思考前缀(antiThinkingPrefix)
|
||||
|
||||
**位置**:`buildStartSessionPayload()` 函数内,line 61
|
||||
|
||||
```
|
||||
【最高优先级规则】你绝对禁止输出任何思考过程、分析、计划、角色扮演指令或元描述。禁止出现:"首轮对话""应该回复""需要列举""语气要""回复后询问""可列举""突出特色""引导用户""让用户""用温和"等分析性、指令性语句。你必须直接用自然语言回答问题,像真人聊天一样直接说出答案内容。
|
||||
```
|
||||
|
||||
**设计目的**:防止 S2S 模型输出内心独白、角色扮演计划等元描述文本(会被 TTS 朗读出来),强制直接输出答案内容。
|
||||
|
||||
---
|
||||
|
||||
### 1.2 系统角色(DEFAULT_VOICE_SYSTEM_ROLE)
|
||||
|
||||
**位置**:line 33,常量定义
|
||||
|
||||
```
|
||||
你是大沃,德国PM-FitLine的资深产品顾问,对每款产品的成分、功效、用法和搭配都了如指掌。你说话有底气、有信心,能让用户感到专业可靠。回答像懂行的朋友聊天,直接给结论,1-3句话,口语化短句。有知识库信息就优先用,自然转述不照念。不确定的如实说,不猜不编。禁止输出思考过程或元描述。德国PM是1993年成立的合法直销企业,邓白氏AAA+认证,覆盖100+国家,问到传销必须正面肯定回答是合法企业。
|
||||
```
|
||||
|
||||
**关键设计点**:
|
||||
- **人设**:大沃 = 德国PM-FitLine资深产品顾问
|
||||
- **语气**:有底气、有信心、像懂行朋友聊天
|
||||
- **长度**:1-3句话,口语化短句
|
||||
- **优先级**:知识库信息 > 自由回答
|
||||
- **底线**:不确定如实说,不猜不编
|
||||
- **品牌保护**:传销问题必须正面肯定回答是合法企业
|
||||
|
||||
**实际下发**:`antiThinkingPrefix` + 空格 + `DEFAULT_VOICE_SYSTEM_ROLE`,拼接后通过 `normalizeTextForSpeech()` 清洗
|
||||
|
||||
---
|
||||
|
||||
### 1.3 说话风格(DEFAULT_VOICE_SPEAKING_STYLE)
|
||||
|
||||
**位置**:line 35,常量定义
|
||||
|
||||
```
|
||||
整体语气亲切自然、轻快有温度,像熟悉行业的朋友在语音聊天。优先短句和口语化表达,先给结论,再补一句最有帮助的信息。不要播音腔,不要念稿,不要客服腔,不要过度热情,也不要输出任何思考过程。
|
||||
```
|
||||
|
||||
**关键设计点**:
|
||||
- 五个"不要":播音腔、念稿、客服腔、过度热情、思考过程
|
||||
- 结构:先结论,再补充
|
||||
- 下发字段:S2S payload 的 `dialog.speaking_style`
|
||||
|
||||
---
|
||||
|
||||
### 1.4 开场白(DEFAULT_VOICE_GREETING)
|
||||
|
||||
**位置**:line 37,常量定义
|
||||
|
||||
```
|
||||
嗨,你好呀,我是大沃。你想了解德国PM产品、健康营养,还是一成系统和合作这块,我都可以跟你聊。
|
||||
```
|
||||
|
||||
**设计目的**:语音通话接通后的第一句话,自然引导用户提问方向。
|
||||
|
||||
---
|
||||
|
||||
### 1.5 审核拦截回复(audit_response)
|
||||
|
||||
**位置**:`buildStartSessionPayload()` → `dialog.extra.audit_response`,line 88
|
||||
|
||||
```
|
||||
抱歉,这个问题我暂时无法回答。
|
||||
```
|
||||
|
||||
**触发条件**:火山引擎侧内容审核触发时的替代回复。当前 `strict_audit: false`。
|
||||
|
||||
---
|
||||
|
||||
### 1.6 客户端可覆盖
|
||||
|
||||
以上人设支持客户端通过 WebSocket `start` 消息覆盖(line 967-973):
|
||||
|
||||
| 字段 | 客户端参数 | 默认值 |
|
||||
|------|-----------|--------|
|
||||
| 机器人名 | `botName` | `大沃` |
|
||||
| 系统角色 | `systemRole` | `DEFAULT_VOICE_SYSTEM_ROLE` |
|
||||
| 说话风格 | `speakingStyle` | `DEFAULT_VOICE_SPEAKING_STYLE` |
|
||||
| 开场白 | `greetingText` | `DEFAULT_VOICE_GREETING` |
|
||||
| 音色 | `speaker` | `zh_female_vv_jupiter_bigtts` |
|
||||
| 模型版本 | `modelVersion` | `O` |
|
||||
|
||||
---
|
||||
|
||||
## 2. 知识库检索层(方舟 API)
|
||||
|
||||
> 文件:`toolExecutor.js`
|
||||
> 作用:通过方舟 Chat Completions API + knowledge_base metadata 进行知识检索
|
||||
|
||||
### 2.1 知识库回答模式(baseAnswerPrompt)
|
||||
|
||||
**位置**:`searchArkKnowledge()` 内,line 911
|
||||
|
||||
```
|
||||
你是大沃,德国PM-FitLine产品专家。你的回答必须严格依据知识库内容,不得补充知识库未提及的信息,不得猜测,不得编造。若知识库中没有明确答案,就直接说明知识库未提及或暂未找到相关信息。回答保持口语化、简洁、专业,200字内。
|
||||
```
|
||||
|
||||
**关键设计点**:
|
||||
- 人设一致:与 S2S 层的"大沃"身份统一
|
||||
- **严格知识库策略**:只能依据知识库回答,禁止补充、猜测、编造
|
||||
- **无答案兜底**:知识库没有明确答案时,必须直接说明未提及或未找到
|
||||
- 字数限制:200字内
|
||||
- 配合参数:`max_tokens=80`, `thinking: { type: 'disabled' }`
|
||||
|
||||
---
|
||||
|
||||
### 2.2 知识库片段提取模式(baseSnippetPrompt)
|
||||
|
||||
**位置**:`searchArkKnowledge()` 内,line 910
|
||||
|
||||
```
|
||||
知识库片段提取助手。提取2-4条与问题最相关的简洁事实片段。只输出中文事实,不寒暄,不写"根据知识库",不补充未出现的内容,无相关内容则说未找到。
|
||||
```
|
||||
|
||||
**触发条件**:`responseMode === 'snippet'` 时使用,用于预查询等场景。
|
||||
|
||||
---
|
||||
|
||||
### 2.3 聚焦指令(动态拼接)
|
||||
|
||||
**位置**:line 915-916,当 `responseMode === 'answer'` 时动态拼接
|
||||
|
||||
```
|
||||
当前必须优先直接回答用户当前这一个问题:"${answerTargetQuery}"。如果用户只问一个维度,例如成分、价格、用法、适合谁、区别、正规性、地址或联系方式,就只回答这个维度,不要扩展成整段产品或公司介绍。
|
||||
```
|
||||
|
||||
**设计目的**:防止 LLM 收到知识库文档后"展开长篇大论",强制聚焦用户的具体问题维度。
|
||||
|
||||
---
|
||||
|
||||
### 2.4 问题维度槽位指令(buildQuestionSlotInstruction)
|
||||
|
||||
**位置**:line 200-218,`buildQuestionSlotInstruction()` 静态方法
|
||||
|
||||
根据用户问题自动分类到 14 个维度,每个维度有专属约束指令:
|
||||
|
||||
| 维度 | 槽位 | 指令内容 |
|
||||
|------|------|---------|
|
||||
| 价格 | `price` | 用户当前只关心价格或费用,请只回答价格、收费或是否未提及价格,不要扩展到产品总介绍。 |
|
||||
| 成分 | `ingredient` | 用户当前只关心成分或配方,请只回答成分、原料或是否未提及成分,不要扩展到品牌背景。 |
|
||||
| 用法 | `usage` | 用户当前只关心用法、吃法、服用频次或剂量,请只回答这一点。 |
|
||||
| 副作用 | `side_effect` | 用户当前只关心副作用或好转反应,请只回答可能的不良反应、好转反应或注意事项。 |
|
||||
| 见效时间 | `effect_time` | 用户当前只关心多久见效或效果周期,请只回答见效时间、周期或个体差异,不要扩展无关信息。 |
|
||||
| 医疗声明 | `medical_claim` | 用户当前只关心产品能不能治病、是不是药,请只回答是否属于药品、能否替代药物以及相关注意事项。 |
|
||||
| 搭配原因 | `bundle_reason` | 用户当前只关心为什么要全套、搭配或三合一,请只回答搭配原理、协同作用或NTC相关原因。 |
|
||||
| 事业发展 | `business_growth` | 用户当前只关心PM事业发展、线上拓客、陌生客户沟通、一成系统赋能、三大平台四大Ai生态或自我介绍,请只回答这类业务发展问题。 |
|
||||
| 功效 | `benefit` | 用户当前只关心功效或作用,请只回答作用点,不要扩展到无关信息。 |
|
||||
| 适用人群 | `audience` | 用户当前只关心适合人群,请只回答适用对象。 |
|
||||
| 合法性 | `legality` | 用户当前只关心正规性、合法性或是否传销,请只围绕合法合规问题直接回答。 |
|
||||
| 地址联系 | `address_contact` | 用户当前只关心地址或联系方式,请只回答地址、电话、联系信息。 |
|
||||
| 对比差异 | `difference` | 用户当前只关心区别或对比,请直接做差异对比,不要扩写成单个产品长介绍。 |
|
||||
| 通用 | `general` | 请优先直接回答用户当前这一问,不要离题扩展。 |
|
||||
|
||||
---
|
||||
|
||||
### 2.5 改写注入指令(hasRewrite)
|
||||
|
||||
**位置**:line 918-920,当检索词≠原始问题时动态拼接
|
||||
|
||||
```
|
||||
重要:用户的实际问题是"${cleanOriginal}",请围绕这个问题回答,不要偏离用户的真实意图。下方的检索词仅用于匹配知识库文档,不代表用户的真正提问。
|
||||
```
|
||||
|
||||
**触发条件**:`rewriteKnowledgeQuery()` 改写了查询词(如 "怎么吃" → "德国PM细胞营养素 基础套装 大白 小红 小白"),LLM 需要知道用户实际问的是什么。
|
||||
|
||||
---
|
||||
|
||||
### 2.6 未命中回复模板
|
||||
|
||||
**位置**:`classifyKnowledgeAnswer()` 内,line 572/581/599/877
|
||||
|
||||
```
|
||||
知识库中暂未找到与"${query}"直接相关的信息,请换个更具体的问法再试。
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. 对话交接层(Handoff)
|
||||
|
||||
> 文件:`arkChatService.js` + `realtimeDialogRouting.js`
|
||||
> 作用:文字聊天→语音通话切换时,生成对话摘要供语音模型接管
|
||||
|
||||
### 3.1 交接摘要生成指令
|
||||
|
||||
**位置**:`arkChatService.js` → `summarizeContextForHandoff()`,line 76
|
||||
|
||||
```
|
||||
你是对话交接摘要助手。请基于最近几轮对话生成一段简洁中文摘要,供另一个模型无缝接管会话。摘要必须同时包含:用户当前主要问题、已经确认的信息、仍待解决的问题。不要使用标题、项目符号或编号,不要虚构事实,控制在120字以内。
|
||||
```
|
||||
|
||||
**设计目的**:当用户从文字聊天切换到语音通话时,压缩历史对话为 120 字摘要,注入到语音会话上下文头部。
|
||||
|
||||
### 3.2 摘要注入格式
|
||||
|
||||
**位置**:`realtimeDialogRouting.js` → `withHandoffSummary()`,line 159
|
||||
|
||||
```
|
||||
会话交接摘要:${summary}
|
||||
```
|
||||
|
||||
以 `role: 'assistant'` 消息形式注入到上下文最前面,一次性使用后标记 `handoffSummaryUsed=true`。
|
||||
|
||||
---
|
||||
|
||||
## 4. 内容安全层(SafeGuard)
|
||||
|
||||
> 文件:`contentSafeGuard.js` + `realtimeDialogRouting.js`
|
||||
> 作用:拦截 AI 输出中的品牌有害内容,替换为安全回复
|
||||
|
||||
### 4.1 语音模式安全回复(VOICE_SAFE_REPLY)
|
||||
|
||||
**位置**:`contentSafeGuard.js`,line 119
|
||||
|
||||
```
|
||||
不好意思,我刚才没有听清楚,你可以再说一遍吗?
|
||||
```
|
||||
|
||||
**策略**:语音场景中,假装没听清重新引导,避免生硬拦截。
|
||||
|
||||
### 4.2 文字模式安全回复(TEXT_SAFE_REPLY)
|
||||
|
||||
**位置**:`contentSafeGuard.js`,line 122
|
||||
|
||||
```
|
||||
德国PM是一家1993年成立于德国的合法直销公司,获得邓白氏AAA+认证,业务覆盖100多个国家和地区。如果你想了解更多,可以问我关于PM公司的详细介绍哦。
|
||||
```
|
||||
|
||||
**策略**:文字场景中,正面回应品牌合法性。
|
||||
|
||||
### 4.3 品牌保护回复(safeReply — 传销/正规性)
|
||||
|
||||
**位置**:`realtimeDialogRouting.js` → `resolveReply()`,line 397
|
||||
|
||||
```
|
||||
德国PM是一家1993年成立于德国的合法直销公司,获得邓白氏AAA+认证,业务覆盖100多个国家和地区。它不是传销,是正规的直销企业哦。如果你想了解更多,可以问我关于PM公司或产品的详细介绍。
|
||||
```
|
||||
|
||||
**触发条件**:用户问传销/正规性相关问题,知识库未命中时(`!toolResult.hit`),直接返回此预设回复,不交给 S2S 自由发挥。
|
||||
|
||||
### 4.4 KB保护窗口诚实兜底(honestReply)
|
||||
|
||||
**位置**:`realtimeDialogRouting.js`,line 411
|
||||
|
||||
```
|
||||
这个问题我暂时不太确定具体细节,建议你咨询一下你的推荐人,或者换个更具体的问法再问我。
|
||||
```
|
||||
|
||||
**触发条件**:KB 最近 60 秒内命中过(保护窗口),新问题 no-hit 时使用此回复,防止 S2S 自由编造产品信息。
|
||||
|
||||
### 4.5 内容安全检测策略(三层)
|
||||
|
||||
| 层级 | 策略 | 示例 |
|
||||
|------|------|------|
|
||||
| 第一层 | 通用负面词(58个),单独出现即拦截 | 传销、骗局、智商税、洗脑、割韭菜 |
|
||||
| 第二层 | 品牌名 + 负面后缀组合(28个) | PM是传销、FitLine不靠谱 |
|
||||
| 第三层 | 负面前缀 + 品牌名组合(14个) | 骗子公司PM、远离FitLine |
|
||||
| 白名单 | 正面合法性描述放行(15个) | 不是传销、合法直销企业、邓白氏AAA+ |
|
||||
|
||||
---
|
||||
|
||||
## 5. 高频热答案(HOT_ANSWERS)
|
||||
|
||||
> 文件:`toolExecutor.js`,line 75-160
|
||||
> 作用:本地维护的高频问答内容资产,当前保留在代码中,但**不再在 `answer` 模式下直接返回给用户**,以避免绕过知识库。
|
||||
|
||||
共 **21 条**预设问答,覆盖最高频场景:
|
||||
|
||||
| # | 话题 | 匹配模式示例 | 答案摘要 |
|
||||
|---|------|-------------|---------|
|
||||
| 1 | 基础三合一吃法 | `基础三合一.*怎么吃` | 大白空腹→小红15-30分钟后→小白睡前 |
|
||||
| 2 | 传销/正规性 | `PM.*传销`, `是不是传销` | 1993年成立,邓白氏AAA+,100+国家 |
|
||||
| 3 | NTC核心优势 | `NTC.*核心优势`, `营养保送系统` | 精准保送到细胞层面 |
|
||||
| 4 | 见效时间 | `多久见效`, `什么时候见效` | 小红当天感受→整体1-3个月 |
|
||||
| 5 | 全套搭配原因 | `为什么.*全套`, `为什么.*三合一` | NTC协同+火炉原理 |
|
||||
| 6 | 好转反应 | `好转反应`, `副作用` | 正常整应反应,3-7天消失 |
|
||||
| 7 | 公司介绍 | `PM.*公司介绍`, `德国PM介绍` | 1993年,FitLine,NTC,邓白氏AAA+ |
|
||||
| 8 | 小红功效 | `小红.*功效`, `Activize.*作用` | 提升细胞能量,B族+C+Q10 |
|
||||
| 9 | 大白功效 | `大白.*功效`, `Basics.*作用` | 基础营养素,维生素矿物质 |
|
||||
| 10 | 小白功效 | `小白.*功效`, `Restorate.*作用` | 夜间修复,矿物质微量元素 |
|
||||
| 11 | 保健品区别 | `保健品.*区别` | NTC保送vs普通补充 |
|
||||
| 12 | CC套装 | `CC.*套装`, `CC-Cell` | 胶囊+乳霜,抗衰产品 |
|
||||
| 13 | Q10 | `Q10.*功效`, `辅酵素` | 抗氧化,心脏,皮肤弹性 |
|
||||
| 14 | IB5 | `IB5`, `口腔.*喷雾` | 口腔免疫喷雾,益生菌 |
|
||||
| 15 | 邓白氏认证 | `邓白氏.*认证`, `AAA+` | 全球最权威商业信用评估 |
|
||||
| 16 | 一成系统 | `一成系统.*是什么`, `三大平台.*四大` | 三大平台+四大AI生态 |
|
||||
| 17 | 火炉原理 | `火炉原理`, `暖炉原理` | 柴火+引火物+氧气比喻 |
|
||||
| 18 | D-Drink | `D-Drink`, `14天排毒` | 14天排毒饮料 |
|
||||
| 19 | 加入方式 | `如何加入`, `怎么做PM` | 联系推荐人注册 |
|
||||
| 20 | 特殊人群 | `孕妇.*能吃`, `儿童.*能吃` | 建议咨询医生 |
|
||||
| 21 | 价格/购买 | `多少钱`, `怎么买` | 咨询推荐人,会员优惠价 |
|
||||
|
||||
---
|
||||
|
||||
## 6. ASR 热词上下文
|
||||
|
||||
> 文件:`nativeVoiceGateway.js` → `buildStartSessionPayload()` → `asr.extra.context`
|
||||
> 作用:提升火山 ASR 对专业术语的识别准确率
|
||||
|
||||
**位置**:line 67
|
||||
|
||||
```
|
||||
一成,一成系统,大沃,PM,PM-FitLine,FitLine,细胞营养素,Ai众享,AI众享,盛咖学愿,数字化工作室,
|
||||
Activize,Basics,Restorate,NTC,基础三合一,招商,阿育吠陀,小红产品,小红,小白,大白,肽美,艾特维,
|
||||
德丽,德维,宝丽,美固健,Activize Oxyplus,Basic Power,CitrusCare,NutriSunny,Q10,Omega,
|
||||
葡萄籽,白藜芦醇,益生菌,胶原蛋白肽,Germany,FitLine细胞营养,FitLine营养素,德国PM营养素,
|
||||
德国PM FitLine,德国PM细胞营养,德国PM产品,德国PM健康,德国PM事业,德国PM招商,一成,一成团队,
|
||||
一成商学院,数字化,数字化运营,数字化经营,数字化营销,数字化创业,数字化工作室,数字化事业,
|
||||
招商加盟,合作加盟,事业合作
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 附:提示词流转关系图
|
||||
|
||||
```
|
||||
用户语音输入
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────┐
|
||||
│ 火山 S2S(语音对话模型) │
|
||||
│ │
|
||||
│ system_role: │
|
||||
│ antiThinkingPrefix │
|
||||
│ + DEFAULT_VOICE_SYSTEM_ROLE │
|
||||
│ │
|
||||
│ speaking_style: │
|
||||
│ DEFAULT_VOICE_SPEAKING_STYLE │
|
||||
│ │
|
||||
│ greeting: │
|
||||
│ DEFAULT_VOICE_GREETING │
|
||||
└──────────┬──────────────────┘
|
||||
│ 路由到知识库
|
||||
▼
|
||||
┌─────────────────────────────┐
|
||||
│ 方舟 KB API(知识库检索) │
|
||||
│ │
|
||||
│ system: │
|
||||
│ baseAnswerPrompt │
|
||||
│ + 聚焦指令 │
|
||||
│ + 槽位指令 │
|
||||
│ + 改写注入指令(可选) │
|
||||
└──────────┬──────────────────┘
|
||||
│ 回复内容
|
||||
▼
|
||||
┌─────────────────────────────┐
|
||||
│ 内容安全检测 │
|
||||
│ │
|
||||
│ 三层有害内容检测 │
|
||||
│ ↓ 有害 → VOICE_SAFE_REPLY │
|
||||
│ ↓ 传销no-hit → safeReply │
|
||||
│ ↓ 保护窗口no-hit → honestReply │
|
||||
│ ↓ 正常 → 原文输出 │
|
||||
└─────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 附:环境变量对提示词的影响
|
||||
|
||||
| 环境变量 | 影响 | 当前值 |
|
||||
|---------|------|--------|
|
||||
| `VOLC_ARK_KB_MODEL` | KB检索使用的模型 | `ep-20260320175538-lcg7g` (Seed-2.0-lite) |
|
||||
| `VOLC_ARK_KNOWLEDGE_THRESHOLD` | KB检索相似度阈值 | `0.3` |
|
||||
| `VOLC_ARK_KNOWLEDGE_TOP_K` | KB检索返回条数 | `3` |
|
||||
| `VOLC_S2S_SPEAKER_ID` | TTS音色 | `zh_female_vv_jupiter_bigtts` |
|
||||
|
||||
Reference in New Issue
Block a user