package intent import ( "context" "fmt" "strings" ) var planConnectors = []string{",然后", ",然后", ",并", ",并", ",接着", ",接着", ";再", ";再"} // splitOnPlanConnectors 按有限连接词拆分多意图输入 func splitOnPlanConnectors(input string) []string { for _, sep := range planConnectors { if idx := strings.Index(input, sep); idx > 0 { left := strings.TrimSpace(input[:idx]) right := strings.TrimSpace(input[idx+len(sep):]) if left != "" && right != "" { return []string{left, right} } } } return nil } // buildLimitedIntentPlan 构建有限多意图计划(仅 query+query / query+generate 等安全组合) func buildLimitedIntentPlan(ctx context.Context, r *RuleBasedRecognizer, input string, snap *ContextSnapshot, primary *IntentRecognitionResult) *IntentPlan { if !CurrentFeatureFlags().MultiIntentEnabled { return nil } parts := splitOnPlanConnectors(input) if len(parts) < 2 { return nil } var steps []IntentPlanStep for i, part := range parts { subRes, err := r.Recognize(ctx, part, snap) if err != nil || subRes == nil || subRes.TopIntent == nil { return nil } frame := BuildIntentFrameV2(subRes, DefaultRegistry()) if frame == nil { return nil } // 高风险写动作组合初期不支持 if isWriteIntent(subRes.TopIntent.Intent) { return nil } stepID := fmt.Sprintf("%d", i+1) var depends []string if i > 0 { depends = []string{fmt.Sprintf("%d", i)} } steps = append(steps, IntentPlanStep{ StepID: stepID, Frame: *frame, DependsOn: depends, OnFailure: "abort", }) } if len(steps) < 2 { return nil } // 至少一个查询步骤 hasQuery := false for _, s := range steps { if s.Frame.Goal == GoalQuery || isQueryIntent(s.Frame.LegacyIntent) { hasQuery = true break } } if !hasQuery { return nil } if primary != nil && primary.IntentFrameV2 != nil { primary.IntentFrameV2.Relation = RelationExpectationPlusNew } return &IntentPlan{ Steps: steps, Atomicity: "sequential", NeedsConfirm: false, FailureMode: "stop_on_first_failure", } } func inferSupplementSubtype(input string, slots map[string]string) string { if strings.Contains(input, "附件") || strings.Contains(input, "材料") || strings.Contains(input, "上传") { return "attach" } if strings.Contains(input, "纠正") || strings.Contains(input, "更正") || (strings.Contains(input, "改为") && strings.Contains(input, "原来")) { return "correct" } if strings.Contains(input, "修改为") || strings.Contains(input, "改为") || strings.Contains(input, "改成") { if slots[SlotFactKey] != "" { return "correct" } } return "add" }