fix: IoT多设备支持 + Review Pipeline审查消息 + 意图分析快速通道优化
- IoT Provider: 重写Execute()支持多设备命令批量执行,修复persona路径 - Intent Analyzer: 新增isStrongIoTCommand快速通道,跳过LLM分析节省2-3s - Orchestrator: parseReviewMessages()内联审查 + 快速通道扩展(chat/greeting跳过子会话) - Gateway: SSE review_messages解析→WebSocket结构化消息转发(action/chat) - Persona: 对话风格注入action格式指令(括号包裹动作描述) - Frontend: sessionStore历史消息msgType映射 - 新增E2E测试脚本 + 调试标准文档 + 第4轮修复报告 E2E验证: IoT设备操控✅ Review消息拆分✅ 快速通道✅ 响应时间~3.4s Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -42,6 +42,12 @@ func (a *IntentAnalyzer) Analyze(ctx context.Context, userMessage string) (*mode
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// 快速通道:强 IoT 关键词直接使用规则匹配,跳过 LLM 调用(节省 2-3s)
|
||||
if a.isStrongIoTCommand(userMessage) {
|
||||
log.Printf("[intent] 快速通道: 检测到 IoT 操控命令,跳过 LLM 分析")
|
||||
return a.keywordAnalyze(userMessage), nil
|
||||
}
|
||||
|
||||
// 如果 LLM 不可用,直接使用关键词匹配
|
||||
if !a.enabled || a.llmAdapter == nil {
|
||||
log.Printf("[intent] LLM 不可用,使用关键词规则分析意图")
|
||||
@@ -119,6 +125,33 @@ func (a *IntentAnalyzer) isSimpleGreeting(userMessage string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// isStrongIoTCommand 检测是否为明确的 IoT 操控命令,可直接跳过 LLM 意图分析
|
||||
func (a *IntentAnalyzer) isStrongIoTCommand(userMessage string) bool {
|
||||
msgLower := strings.TrimSpace(strings.ToLower(userMessage))
|
||||
|
||||
// 控制类关键词 + 设备类关键词组合出现,即可判断为 IoT 命令
|
||||
controlWords := []string{"打开", "关闭", "调到", "设置", "开关", "调节", "调高", "调低", "开一下", "关一下"}
|
||||
deviceWords := []string{"灯", "空调", "窗帘", "电视", "风扇", "加湿器", "插座", "门锁", "传感器"}
|
||||
|
||||
hasControl := false
|
||||
for _, w := range controlWords {
|
||||
if strings.Contains(msgLower, w) {
|
||||
hasControl = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
hasDevice := false
|
||||
for _, w := range deviceWords {
|
||||
if strings.Contains(msgLower, w) {
|
||||
hasDevice = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return hasControl && hasDevice
|
||||
}
|
||||
|
||||
// keywordAnalyze 基于关键词的意图分析(降级方案)
|
||||
func (a *IntentAnalyzer) keywordAnalyze(userMessage string) *model.IntentResult {
|
||||
result := &model.IntentResult{
|
||||
|
||||
@@ -133,9 +133,10 @@ func (o *Orchestrator) ProcessInput(
|
||||
|
||||
// 对于 simple greeting,跳过子会话分派,直接合成回复
|
||||
var resultCh <-chan model.SubSessionResult
|
||||
skipSubSessions := intent.Primary == "greeting"
|
||||
skipSubSessions := intent.Primary == "greeting" ||
|
||||
(intent.Primary == "chat" && !intent.NeedsIoT && !intent.NeedsMemory)
|
||||
if skipSubSessions {
|
||||
log.Printf("[orchestrator] 快速通道: 简单问候,跳过子会话分派")
|
||||
log.Printf("[orchestrator] 快速通道: 简单消息(primary=%s),跳过子会话分派", intent.Primary)
|
||||
// 创建一个已关闭的空通道
|
||||
emptyCh := make(chan model.SubSessionResult)
|
||||
close(emptyCh)
|
||||
@@ -212,7 +213,7 @@ func (o *Orchestrator) ProcessInput(
|
||||
// 子会话结果还没完成,先带着空上下文开始合成
|
||||
// 大部分情况下子会话结果会在 LLM 调用前完成
|
||||
// 等待一小段时间让快速子会话(如 IoT)完成
|
||||
timeout := time.After(500 * time.Millisecond)
|
||||
timeout := time.After(200 * time.Millisecond)
|
||||
select {
|
||||
case enriched := <-enrichedCh:
|
||||
synthParams.MemorySummary = enriched.memorySummary
|
||||
|
||||
Reference in New Issue
Block a user