Stream 执行流式请求,支持自动降级
( ctx context.Context, messages []types.Message, opts *provider.StreamOptions, )
| 163 | |
| 164 | // Stream 执行流式请求,支持自动降级 |
| 165 | func (m *ModelFallbackManager) Stream( |
| 166 | ctx context.Context, |
| 167 | messages []types.Message, |
| 168 | opts *provider.StreamOptions, |
| 169 | ) (<-chan provider.StreamChunk, error) { |
| 170 | m.stats.TotalRequests++ |
| 171 | |
| 172 | var lastErr error |
| 173 | |
| 174 | // 遍历所有启用的模型 |
| 175 | for i, fb := range m.fallbacks { |
| 176 | if !fb.Enabled { |
| 177 | continue |
| 178 | } |
| 179 | |
| 180 | modelKey := fmt.Sprintf("%s/%s", fb.Config.Provider, fb.Config.Model) |
| 181 | |
| 182 | // 尝试执行,支持重试 |
| 183 | for retry := 0; retry <= fb.MaxRetries; retry++ { |
| 184 | if retry > 0 { |
| 185 | fallbackLog.Debug(ctx, "retrying model (stream)", map[string]any{"retry": retry, "max_retries": fb.MaxRetries, "model": modelKey}) |
| 186 | |
| 187 | // 重试前等待一小段时间 |
| 188 | backoff := time.Duration(retry) * 500 * time.Millisecond |
| 189 | select { |
| 190 | case <-ctx.Done(): |
| 191 | return nil, ctx.Err() |
| 192 | case <-time.After(backoff): |
| 193 | } |
| 194 | } |
| 195 | |
| 196 | // 执行流式请求 |
| 197 | stream, err := fb.provider.Stream(ctx, messages, opts) |
| 198 | if err == nil { |
| 199 | // 成功 |
| 200 | m.stats.SuccessRequests++ |
| 201 | m.stats.ModelUsageCount[modelKey]++ |
| 202 | m.currentIndex = i |
| 203 | |
| 204 | fallbackLog.Debug(ctx, "success with model (stream)", map[string]any{"model": modelKey, "retry": retry}) |
| 205 | return stream, nil |
| 206 | } |
| 207 | |
| 208 | lastErr = err |
| 209 | fallbackLog.Warn(ctx, "error with model (stream)", map[string]any{"model": modelKey, "retry": retry, "max_retries": fb.MaxRetries, "error": err}) |
| 210 | } |
| 211 | |
| 212 | // 所有重试都失败,尝试下一个模型 |
| 213 | if i < len(m.fallbacks)-1 { |
| 214 | m.stats.FallbackCount++ |
| 215 | m.stats.LastFallbackTime = time.Now() |
| 216 | fallbackLog.Info(ctx, "falling back to next model (stream)", map[string]any{"from_model": modelKey}) |
| 217 | } |
| 218 | } |
| 219 | |
| 220 | // 所有模型都失败 |
| 221 | m.stats.FailedRequests++ |
| 222 | return nil, fmt.Errorf("all models failed (stream), last error: %w", lastErr) |