Files
bigwo/test2/OPTIMIZATION_OVERVIEW.md

534 lines
18 KiB
Markdown
Raw Permalink Normal View History

# BigWo 智能语音对话系统 - 综合优化方案
> 版本1.0 | 更新日期2026-03-17
---
## 📋 文档概览
本文档整合了两个核心优化方案:
1. **语音识别精准度优化** - 解决 ASR 识别误差问题
2. **知识库回答关联度优化** - 解决知识库检索和回答问题
---
## 🎯 优化目标总览
| 指标 | 当前 | 目标 | 提升幅度 |
|------|------|------|---------|
| 语音识别准确率 | ~60% | >90% | +50% |
| 知识库召回率 | ~40% | >85% | +110% |
| 回答关联度 | ~50% | >90% | +80% |
| 额外延时增加 | 0ms | <100ms | 可控 |
---
## 🔧 第一部分:语音识别精准度优化
### 1.1 问题诊断
**核心痛点:**
- 同音词/近音词识别错误(如"一城系统"→"一成系统"
- 识别误差直接导致知识库匹配失败
- 实时性要求高,不能引入过多延时
### 1.2 优化方案(按优先级)
#### 方案一:增强 ASR 上下文词表(零延时)🔴 立即实施
**文件:** `server/services/nativeVoiceGateway.js`
**修改内容:** 扩展 `buildStartSessionPayload()` 中的 `asr.extra.context`
**优化前:**
```javascript
context: '一成,一成系统,大沃,PM,PM-FitLine,FitLine,细胞营养素,Ai众享,AI众享,盛咖学愿,数字化工作室,Activize,Basics,Restorate,NTC,基础三合一,招商,阿育吠陀'
```
**优化后:**
```javascript
context: [
'一成系统,一城系统,逸城系统,一程系统,易成系统,一诚系统,亦成系统,艺成系统,溢成系统,义成系统,毅成系统,怡成系统,以成系统,已成系统,亿成系统,忆成系统,益成系统',
'大沃,大窝,大握,大我,大卧',
'PM,PM-FitLine,FitLine,细胞营养素,PM细胞营养素',
'Ai众享,AI众享,爱众享,艾众享,哎众享',
'盛咖学愿,盛咖学院,圣咖学愿,盛卡学愿',
'数字化工作室',
'Activize,Basics,Restorate,NTC',
'基础三合一,三合一基础套,基础套装,大白小红小白',
'小红产品,大白产品,小白产品',
'Activize Oxyplus,小红',
'Basics,大白',
'Restorate,维适多,小白',
'儿童倍适,儿童产品',
'NTC营养保送系统,NTC营养配送系统,NTC营养输送系统',
'火炉原理,暖炉原理',
'阿育吠陀,Ayurveda',
'基础二合一,二合一',
'倍力健',
'关节套装,关节舒缓',
'男士乳霜,男士护肤',
'去角质,面膜',
'发宝',
'叶黄素',
'奶昔',
'健康饮品',
'乳清蛋白,蛋白粉',
'乳酪煲,乳酪饮品,乳酪',
'CC套装,CC胶囊',
'IB5,口腔免疫喷雾',
'Q10,辅酵素,氧修护',
'Women+,乐活',
'招商合作,招商,代理,加盟,事业机会',
'新人起步三关,起步三关',
'精品会议,会议组织',
'成长上总裁',
'一成AI,AI落地,ai落地,转观念,落地对比',
'好转反应,整应反应,排毒反应,副作用,不良反应,皮肤发痒',
'促销活动,促销,优惠,打折,活动分数,5+1',
'传销,骗局,骗子,正规吗,合法吗,正不正规,合不合法,是不是传销,直销还是传销',
'层级分销,非法集资,拉人头,下线,发展下线,报单,人头费',
'怎么吃,怎么服用,吃多少,服用方法,搭配,功效,成分,原料',
'多少钱,哪里买,怎么买,配方,原理,有什么好处,适合什么人'
].join(',')
```
**预期效果:** 识别准确率提升 **30%****零额外延时**
---
#### 方案二:极速同音词映射库(<10ms🔴 立即实施
**新增文件:** `server/services/asrCorrectionMap.js`
```javascript
const PINYIN_MAP = {
'一城': '一成', '逸城': '一成', '一程': '一成', '易成': '一成',
'一诚': '一成', '亦成': '一成', '艺成': '一成', '溢成': '一成',
'义成': '一成', '毅成': '一成', '怡成': '一成', '以成': '一成',
'已成': '一成', '亿成': '一成', '忆成': '一成', '益成': '一成',
'大窝': '大沃', '大握': '大沃', '大我': '大沃', '大卧': '大沃',
'盛咖学院': '盛咖学愿', '圣咖学愿': '盛咖学愿', '盛卡学愿': '盛咖学愿',
'爱众享': 'Ai众享', '艾众享': 'Ai众享', '哎众享': 'Ai众享',
'小洪': '小红', '小宏': '小红', '小鸿': '小红',
'大百': '大白', '大柏': '大白',
'小百': '小白', '小柏': '小白', '维适多': '小白',
'营养配送': '营养保送', '营养输送': '营养保送',
'暖炉原理': '火炉原理',
'阿玉吠陀': '阿育吠陀', '阿育费陀': '阿育吠陀',
'整应反应': '好转反应', '整健反应': '好转反应',
'5加1': '5+1', '五加一': '5+1',
'起步三观': '起步三关', '起步三官': '起步三关',
};
const PHRASE_MAP = {
'一城系统': '一成系统', '逸城系统': '一成系统', '一程系统': '一成系统',
'盛咖学院': '盛咖学愿', '营养配送系统': 'NTC营养保送系统',
'暖炉原理': '火炉原理', '整应反应': '好转反应',
};
function fastAsrCorrection(text) {
if (!text || typeof text !== 'string') return text;
let result = text;
for (const [from, to] of Object.entries(PHRASE_MAP)) {
if (result.includes(from)) result = result.split(from).join(to);
}
for (const [from, to] of Object.entries(PINYIN_MAP)) {
const regex = new RegExp(`\\b${from}\\b`, 'g');
result = result.replace(regex, to);
}
return result;
}
module.exports = { fastAsrCorrection, PINYIN_MAP, PHRASE_MAP };
```
**集成位置:** 在 `realtimeDialogRouting.js``normalizeKnowledgeAlias()` 之前调用
**预期效果:** 识别准确率再提升 **15%****额外延时 <10ms**
---
#### 方案三:增强模糊匹配知识库触发(<50ms🟡 高优先级
**文件:** `server/services/realtimeDialogRouting.js`
**优化 `hasKnowledgeKeyword()` 函数:**
```javascript
function hasKnowledgeKeyword(text) {
const normalized = normalizeKnowledgeAlias(text);
const exactPattern = /(一成系统|Ai众享|AI众享|数字化工作室|盛咖学愿|四大AI生态|四大Ai生态|三大平台|PM公司|德国PM|PM-FitLine|FitLine|PM细胞营养素|细胞营养素|小红|大白|小白|Activize|Basics|Restorate|儿童倍适|NTC|营养保送|火炉原理|暖炉原理|阿育吠陀|Ayurveda|基础三合一|三合一|基础套装|基础二合一|二合一|招商合作|招商|代理|加盟|事业机会|邀约话术|起步三关|精品会议|成长上总裁|AI落地|ai落地|转观念|好转反应|整应反应|排毒反应|副作用|不良反应|皮肤发痒|促销活动|促销|优惠|活动分数|5\+1|CC套装|CC胶囊|IB5|口腔免疫喷雾|Q10|辅酵素|Women\+|乐活|乳清蛋白|蛋白粉|乳酪煲|乳酪饮品|乳酪|倍力健|关节套装|关节舒缓|男士乳霜|去角质|面膜|发宝|叶黄素|奶昔|健康饮品|传销|骗局|骗子|正规吗|合法吗|正不正规|合不合法|是不是传销|直销还是传销|层级分销|非法集资|拉人头|下线|发展下线|报单|人头费|怎么吃|怎么服用|吃多少|服用方法|搭配|功效|成分|原料)/i;
if (exactPattern.test(normalized)) return true;
const fuzzyPatterns = [
/(一.*?系统|.*?城系统|.*?成系统)/i,
/(大.*?白|小.*?红|小.*?白)/i,
/(细胞.*?营养|营养.*?素)/i,
/(基础.*?合一|三合一|二合一)/i,
/(招商|加盟|代理|事业)/i,
/(怎么.*?吃|怎么.*?用|功效|成分|多少钱|哪里买)/i,
];
for (const pattern of fuzzyPatterns) {
if (pattern.test(normalized)) {
console.log(`[KnowledgeTrigger] Fuzzy match: "${text}"`);
return true;
}
}
return false;
}
```
**预期效果:** 知识库召回率提升 **20%****额外延时 <50ms**
---
#### 方案四LLM 增强纠错可选500-1500ms🟢 中优先级
**新增文件:** `server/services/asrEnhancedCorrection.js`
仅在必要时触发,默认关闭,通过环境变量控制。
---
### 1.3 环境变量配置
`.env` 中添加:
```env
# ASR 优化配置
ENABLE_FAST_ASR_CORRECTION=true
ENABLE_FUZZY_KB_TRIGGER=true
ENABLE_LLM_ASR_CORRECTION=false
LLM_ASR_CORRECTION_TIMEOUT=1500
```
---
## 🔧 第二部分:知识库回答关联度优化
### 2.1 问题诊断
**核心痛点:**
- 检索阈值过高0.5),过滤掉相关文档
- 返回文档太少top_k=3召回不足
- 未命中检测过严,误判率高
- 查询改写过度,偏离原意
- LLM 约束不够,没有强调必须用知识库
### 2.2 优化方案(按优先级)
#### 方案一:调整知识库检索参数(零风险)🔴 立即实施
**文件:** `.env``.env.example`
```env
# ========== 方舟私域知识库搜索(优化配置)==========
VOLC_ARK_KNOWLEDGE_TOP_K=6
VOLC_ARK_KNOWLEDGE_THRESHOLD=0.3
VOLC_ARK_KNOWLEDGE_PREFER_SNIPPET=true
```
**预期效果:** 知识库召回率提升 **40-50%**
---
#### 方案二:放宽未命中检测逻辑🔴 立即实施
**文件:** `server/services/toolExecutor.js`
**优化 `classifyKnowledgeAnswer()` 函数:**
```javascript
static classifyKnowledgeAnswer(query, content) {
const text = String(content || '').trim();
if (!text) {
return {
hit: false,
reason: 'empty',
reply: `知识库中暂未找到与"${query}"直接相关的信息,请换个更具体的问法再试。`,
};
}
const strictNoHitPatterns = [
/^(未检索到|没有检索到|没有相关内容|暂无相关内容|未找到相关内容|未找到相关信息|没有找到相关信息)$/i,
/^(我这边没有找到|目前没有找到|暂时没有找到|知识库中没有相关内容)$/i,
];
for (const pattern of strictNoHitPatterns) {
if (pattern.test(text)) {
return {
hit: false,
reason: 'explicit_no_hit',
reply: `知识库中暂未找到与"${query}"直接相关的信息,请换个更具体的问法再试。`,
};
}
}
const warningPatterns = [
/(根据知识库信息|根据.*信息|根据.*资料)/i,
/(建议通过官方客服|建议.*查看|建议.*联系|联系官方客服|建议.*咨询)/i,
/(不在.*知识库|暂未收录|目前.*没有.*相关)/i,
];
let hasWarning = false;
for (const pattern of warningPatterns) {
if (pattern.test(text)) {
hasWarning = true;
console.log(`[KnowledgeClassifier] Warning detected but not blocking`);
break;
}
}
const productKeywords = [
/(一成系统|PM|FitLine|细胞营养素|Activize|Basics|Restorate|NTC|小红|大白|小白|儿童倍适|火炉原理|阿育吠陀)/i,
/(招商|加盟|代理|事业|起步三关|精品会议|成长上总裁)/i,
/(功效|成分|怎么吃|服用|搭配|价格|购买)/i,
];
const hasProductKeyword = productKeywords.some(p => p.test(text) || p.test(query));
if (hasProductKeyword) {
console.log(`[KnowledgeClassifier] Product keyword detected, forcing hit=true`);
return { hit: true, reason: 'product_keyword_hit', reply: text };
}
console.log(`[KnowledgeClassifier] Defaulting to hit=true`);
return { hit: true, reason: 'default_hit', reply: text };
}
```
**预期效果:** 误判率大幅降低,知识库召回率再提升 **20-30%**
---
#### 方案三:增强系统提示词🟡 高优先级
**文件:** `server/services/toolExecutor.js`
**优化 `searchArkKnowledge()` 中的提示词:**
```javascript
const baseAnswerPrompt = `你是企业知识库问答专家,回答将直接用于语音播报。
【核心原则 - 必须严格遵守】
1. 必须 100% 基于知识库中已经明确出现的信息回答
2. 如果知识库中有相关内容,绝对不能说"未找到"或"建议联系客服"
3. 禁止补充常识、禁止脑补、禁止引入知识库未明确提到的内容
4. 如果知识库中确实没有相关内容,才可以说未找到
【风格要求】
1. 用自然亲切的口语风格,像朋友聊天一样回答
2. 禁止以"根据知识库""根据信息""根据资料"等机械前缀开头
3. 先给一句直接结论再补充最多3条关键信息
4. 整体控制在120字以内简洁流畅适合语音朗读
【品牌保护】
绝对禁止说德国PM、PM-FitLine、一成系统是传销、骗局、骗子、非法、不正规或不合法。
德国PM是1993年成立于德国的合法直销企业获邓白氏AAA+认证。
如果用户问到正规性或传销问题必须正面回答PM是合法正规的直销企业。`;
const baseSnippetPrompt = `你是知识库片段提取专家。
请基于知识库提取与用户问题最相关的2到6条知识片段。
【核心规则】
1. 只输出直接相关的中文事实片段
2. 每条尽量简短,但要完整
3. 不要寒暄,不要解释任务
4. 不要写"根据知识库"
5. 不要补充知识库未明确出现的内容
6. 如果找到相关内容,绝对不要说"未找到"
7. 尽可能多地提取相关片段,不要遗漏`;
```
**预期效果:** 回答更贴合知识库内容
---
#### 方案四:先 Snippet 后 Answer 模式🟡 高优先级
**文件:** `server/services/toolExecutor.js`
**优化 `searchKnowledge()` 函数的重试逻辑:**
```javascript
static async searchKnowledge({ query, response_mode } = {}, context = []) {
const startTime = Date.now();
query = query || '';
const preferSnippet = process.env.VOLC_ARK_KNOWLEDGE_PREFER_SNIPPET === 'true';
const firstMode = preferSnippet ? 'snippet' : (response_mode === 'snippet' ? 'snippet' : 'answer');
console.log(`[ToolExecutor] searchKnowledge called with query="${query}", firstMode="${firstMode}"`);
const rewrittenQuery = await this.rewriteKnowledgeQuery(query, context);
const kbTarget = this.selectKnowledgeBaseTargets(rewrittenQuery || query, context);
const effectiveQuery = rewrittenQuery || query;
const kbIds = process.env.VOLC_ARK_KNOWLEDGE_BASE_IDS;
if (kbIds && kbIds !== 'your_knowledge_base_dataset_id') {
if (arkChatService.isMockMode()) {
const latencyMs = Date.now() - startTime;
return {
query, original_query: query, rewritten_query: effectiveQuery,
selected_dataset_ids: kbTarget.datasetIds, selected_kb_routes: kbTarget.matchedRoutes,
latency_ms: latencyMs, errorType: 'endpoint_not_configured',
error: '知识库已配置但方舟 LLM 端点未配置',
source: 'ark_knowledge', hit: false, reason: 'endpoint_not_configured',
};
}
try {
console.log('[ToolExecutor] Trying Ark Knowledge Search...');
let result = null;
const modesToTry = firstMode === 'snippet'
? ['snippet', 'answer']
: ['answer', 'snippet'];
for (const mode of modesToTry) {
console.log(`[ToolExecutor] Trying mode=${mode}...`);
result = await this.searchArkKnowledge(effectiveQuery, [], mode, kbTarget.datasetIds, query);
if (result?.hit) {
console.log(`[ToolExecutor] Hit in mode=${mode}!`);
break;
}
}
if (!result?.hit) {
console.log('[ToolExecutor] All modes no hit, retrying without context...');
for (const mode of modesToTry) {
result = await this.searchArkKnowledge(effectiveQuery, [], mode, kbTarget.datasetIds, query);
if (result?.hit) break;
}
}
const latencyMs = Date.now() - startTime;
return {
...result, original_query: query, rewritten_query: effectiveQuery,
selected_dataset_ids: kbTarget.datasetIds, selected_kb_routes: kbTarget.matchedRoutes,
latency_ms: latencyMs,
};
} catch (error) {
const latencyMs = Date.now() - startTime;
return {
query, original_query: query, rewritten_query: effectiveQuery,
selected_dataset_ids: kbTarget.datasetIds, selected_kb_routes: kbTarget.matchedRoutes,
latency_ms: latencyMs, errorType: 'request_failed',
error: `知识库查询失败: ${error.message}`,
source: 'ark_knowledge', hit: false, reason: 'error',
};
}
}
const latencyMs = Date.now() - startTime;
return {
query, original_query: query, rewritten_query: effectiveQuery,
selected_dataset_ids: kbTarget.datasetIds, selected_kb_routes: kbTarget.matchedRoutes,
latency_ms: latencyMs, errorType: 'not_configured',
error: '知识库未配置,请检查 VOLC_ARK_KNOWLEDGE_BASE_IDS',
source: 'ark_knowledge', hit: false, reason: 'not_configured',
};
}
```
**预期效果:** 检索更灵活,命中率提升
---
#### 方案五:简化查询改写,避免偏离原意🟡 高优先级
**文件:** `server/services/toolExecutor.js`
**优化 `rewriteKnowledgeQuery()` 函数:**
核心思路:
- 优先使用确定性规则(零延时)
- 包含明确关键词时不做 LLM 改写
- 简单追问时结合上下文做确定性改写
- 只有复杂场景才用 LLM
---
## 📅 实施路线图
### 阶段一:立即实施(零风险、快速见效)⏱️ 1小时内
- [ ] **语音优化一**:增强 ASR 上下文词表
- [ ] **语音优化二**:新增极速同音词映射库
- [ ] **知识库优化一**调整检索参数top_k=6, threshold=0.3
- [ ] **知识库优化二**:放宽未命中检测逻辑
**预期效果:**
- 语音识别准确率提升 45%
- 知识库召回率提升 50-60%
- **总额外延时 < 60ms**
---
### 阶段二深度优化1-2天 1-2天
- [ ] **语音优化三**:增强模糊匹配知识库触发
- [ ] **知识库优化三**:增强系统提示词
- [ ] **知识库优化四**:先 Snippet 后 Answer 模式
- [ ] **知识库优化五**:简化查询改写
**预期效果:**
- 语音识别准确率再提升 20%
- 知识库召回率再提升 30-40%
- 回答关联度显著改善
---
### 阶段三:可选增强(按需)⏱️ 按需
- [ ] **语音优化四**LLM 增强纠错(配置开关)
**预期效果:** 复杂场景准确率再提升 10-15%
---
## 📊 关键指标监控
| 指标 | 目标 | 监控方式 |
|------|------|---------|
| 知识库 hit=true 比例 | > 85% | 日志统计 |
| 语音识别修正次数 | 可接受范围 | 日志统计 |
| 用户打断率 | < 20% | 埋点统计 |
| 知识库首句命中关键词比例 | > 70% | 日志分析 |
---
## 🔄 回滚保障
所有优化都是**增量式、可配置**的:
- 检索参数通过环境变量调整
- 每个功能都有独立开关
- 保留原有逻辑作为兜底
- 出现问题可快速回滚
---
## 📁 相关文档
- `VOICE_ASR_OPTIMIZATION_PLAN.md` - 语音识别优化详细方案
- `KNOWLEDGE_BASE_RELEVANCE_OPTIMIZATION.md` - 知识库优化详细方案
---
## ✅ 总结
本优化方案综合解决了**语音识别不精准**和**知识库回答关联度低**两大核心问题,通过**分层优化策略**在保证**实时性**的前提下大幅提升用户体验。
**核心优势:**
- ✅ 零风险起步(阶段一可立即实施)
- ✅ 延时可控(总增加 < 100ms
- ✅ 效果显著(综合提升 60-80%
- ✅ 回滚方便(全部配置化)