refactor(server): optimize KB retrieval and voice context
This commit is contained in:
@@ -139,6 +139,13 @@ function isKnowledgeFollowUp(text) {
|
||||
return subjectActionRegex.test(normalized);
|
||||
}
|
||||
|
||||
// KB-First: 纯闲聊/告别白名单,匹配则跳过KB直接交给S2S
|
||||
function isPureChitchat(text) {
|
||||
const t = (text || '').trim();
|
||||
if (!t) return true;
|
||||
return /^(喂|你好|您好|嗨|哈喽|hello|hi|在吗|在不在|早上好|中午好|下午好|晚上好|早安|晚安|谢谢|谢谢你|谢谢啦|多谢|感谢|再见|拜拜|拜|好的|嗯|哦|行|对|是的|没有了|没事了|不用了|可以了|好的谢谢|没问题|知道了|明白了|了解了|好嘞|好吧|行吧|ok|okay)[,,。!??~~\s]*[啊呀吧呢哦嗯嘛哈的了]*[!。??~~]*$/i.test(t);
|
||||
}
|
||||
|
||||
function shouldForceKnowledgeRoute(userText, context = []) {
|
||||
const text = (userText || '').trim();
|
||||
if (!text) return false;
|
||||
@@ -271,7 +278,7 @@ async function resolveReply(sessionId, session, text) {
|
||||
const ragItems = fastResult.hit && Array.isArray(fastResult.results)
|
||||
? fastResult.results.filter(i => i && i.content).map(i => ({ title: i.title || '知识库结果', content: i.content }))
|
||||
: [];
|
||||
console.log(`[resolveReply] fast-path hit in ${Date.now() - _resolveStart}ms session=${sessionId} source=${fastResult.hot_answer ? 'hot_answer' : (fastResult.cache_hit ? 'cache' : 'direct')} mode=${fastResult.retrieval_mode || 'answer'}`);
|
||||
console.log(`[resolveReply] fast-path hit in ${Date.now() - _resolveStart}ms session=${sessionId} source=${fastResult.cache_hit ? 'cache' : 'direct'} mode=${fastResult.retrieval_mode || 'answer'}`);
|
||||
if (ragItems.length > 0) {
|
||||
session.handoffSummaryUsed = true;
|
||||
// raw 模式:ragItems 已包含上下文 + 多个 KB 片段,直接透传
|
||||
@@ -324,18 +331,10 @@ async function resolveReply(sessionId, session, text) {
|
||||
.map((item) => ({ role: item.role, content: item.content }));
|
||||
const context = withHandoffSummary(session, baseContext);
|
||||
let routeDecision = getRuleBasedDirectRouteDecision(originalText);
|
||||
if (routeDecision.route === 'chat' && shouldForceKnowledgeRoute(originalText, context)) {
|
||||
// KB-First: 所有非闲聊查询强制先走知识库,KB不命中再交给S2S自由回答
|
||||
if (routeDecision.route === 'chat' && !isPureChitchat(originalText)) {
|
||||
routeDecision = { route: 'search_knowledge', args: { query: originalText } };
|
||||
}
|
||||
// KB保护窗口:60秒内有KB命中,当前非纯闲聊,强制走KB搜索
|
||||
// 防止追问(如"它需要漱口吗")绕过KB走S2S自由编造
|
||||
const KB_PROTECTION_WINDOW_MS = 60000;
|
||||
if (routeDecision.route === 'chat' && session?._lastKbHitAt && (Date.now() - session._lastKbHitAt < KB_PROTECTION_WINDOW_MS)) {
|
||||
const isPureChitchat = /^(喂|你好|嗨|hi|hello|谢谢|谢谢你|谢谢啦|多谢|感谢|再见|拜拜|拜|好的|嗯|哦|行|没事了|不用了|可以了|好的谢谢|没问题|知道了|明白了|了解了|好嘞|好吧|行吧|ok|okay)[,,。!?~\s]*$/i.test(originalText);
|
||||
if (!isPureChitchat) {
|
||||
routeDecision = { route: 'search_knowledge', args: { query: originalText } };
|
||||
console.log(`[resolveReply] KB protection window active, forcing KB route session=${sessionId} lastKbHit=${Math.round((Date.now() - session._lastKbHitAt) / 1000)}s ago`);
|
||||
}
|
||||
console.log(`[resolveReply] KB-First: forcing KB route for non-chitchat session=${sessionId}`);
|
||||
}
|
||||
let replyText = '';
|
||||
let source = 'voice_bot';
|
||||
@@ -476,5 +475,6 @@ module.exports = {
|
||||
splitTextForSpeech,
|
||||
estimateSpeechDurationMs,
|
||||
shouldForceKnowledgeRoute,
|
||||
isPureChitchat,
|
||||
resolveReply,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user