// Package scheduler 消息发送调度器 // Phase 1 Step 3: 自适应消息节奏控制 package scheduler import ( "math" "math/rand" "time" "unicode/utf8" ) // MessageDisplayType 消息展示类型 type MessageDisplayType string const ( DisplayChat MessageDisplayType = "chat" DisplayAction MessageDisplayType = "action" DisplayThinking MessageDisplayType = "thinking" DisplayToolProgress MessageDisplayType = "tool_progress" DisplaySystemInfo MessageDisplayType = "system_info" ) // ScheduledMessage 待发送消息 type ScheduledMessage struct { Type MessageDisplayType Content string Priority int // 0=立即, 1=正常, 2=可延迟 Delay time.Duration // 相对上一条消息的延迟 } // Complexity 消息复杂度 type Complexity int const ( ComplexitySimple Complexity = iota // 问候、确认 ComplexityNormal // 日常对话 ComplexityComplex // 详细解答 ) // SchedulingRules 调度规则 type SchedulingRules struct { MinInterval time.Duration // 最小消息间隔 200ms MaxInterval time.Duration // 最大消息间隔 800ms MaxMessagesPerRound int // 每轮最多消息数 5 MaxActionsPerRound int // 每轮最多动作消息数 2 ChatBeforeAction bool // 聊天消息先于动作 AdaptiveRhythm bool // 自适应节奏 } // DefaultRules 默认调度规则 func DefaultRules() SchedulingRules { return SchedulingRules{ MinInterval: 200 * time.Millisecond, MaxInterval: 800 * time.Millisecond, MaxMessagesPerRound: 5, MaxActionsPerRound: 2, ChatBeforeAction: true, AdaptiveRhythm: true, } } // MessageScheduler 消息发送调度器 type MessageScheduler struct { rules SchedulingRules rng *rand.Rand } // NewMessageScheduler 创建调度器 func NewMessageScheduler(rules SchedulingRules) *MessageScheduler { return &MessageScheduler{ rules: rules, rng: rand.New(rand.NewSource(time.Now().UnixNano())), } } // Schedule 调度消息发送:计算每条消息的发送延迟 func (s *MessageScheduler) Schedule(messages []ScheduledMessage) []ScheduledMessage { if len(messages) == 0 { return nil } // 1. 限制总量 messages = s.enforceLimits(messages) // 2. 评估复杂度 complexity := s.assessComplexity(messages) // 3. 计算基础延迟 baseDelay := s.baseDelayForComplexity(complexity) // 4. 为每条消息分配延迟 for i := range messages { msg := &messages[i] // action 消息紧跟前面的 chat if msg.Type == DisplayAction { msg.Delay = 0 continue } // 第一条消息立即发送 if i == 0 { msg.Delay = 0 continue } // chat 消息使用带 jitter 的延迟 jitter := baseDelay * time.Duration(0.7+0.6*s.rng.Float64()) msg.Delay = jitter // 短消息适当加快 runeCount := utf8.RuneCountInString(msg.Content) if runeCount < 20 { msg.Delay = time.Duration(math.Max(float64(msg.Delay)*0.6, float64(s.rules.MinInterval))) } // 限制在 [MinInterval, MaxInterval] 范围内 if msg.Delay < s.rules.MinInterval { msg.Delay = s.rules.MinInterval } if msg.Delay > s.rules.MaxInterval { msg.Delay = s.rules.MaxInterval } } return messages } // enforceLimits 限制消息数量 func (s *MessageScheduler) enforceLimits(messages []ScheduledMessage) []ScheduledMessage { if len(messages) <= s.rules.MaxMessagesPerRound { return messages } var result []ScheduledMessage actionCount := 0 for _, msg := range messages { if msg.Type == DisplayAction { if actionCount >= s.rules.MaxActionsPerRound { continue } actionCount++ } result = append(result, msg) if len(result) >= s.rules.MaxMessagesPerRound { break } } return result } // assessComplexity 根据消息数量和总长度评估复杂度 func (s *MessageScheduler) assessComplexity(messages []ScheduledMessage) Complexity { if len(messages) <= 1 { return ComplexitySimple } var totalChars int for _, msg := range messages { totalChars += utf8.RuneCountInString(msg.Content) } if len(messages) <= 2 && totalChars < 60 { return ComplexitySimple } if len(messages) <= 3 && totalChars < 200 { return ComplexityNormal } return ComplexityComplex } // baseDelayForComplexity 根据复杂度返回基础延迟 func (s *MessageScheduler) baseDelayForComplexity(c Complexity) time.Duration { switch c { case ComplexitySimple: return 200 * time.Millisecond case ComplexityNormal: return 400 * time.Millisecond case ComplexityComplex: return 600 * time.Millisecond default: return 400 * time.Millisecond } }