feat: 优化模型配置管理 - 动态使用优先级最高的Provider
## 主要改进 ### 1. 数据库驱动的模型配置 - 新增 GetActiveProviderWithModel() 方法,从数据库获取优先级最高的 Provider 及其默认模型 - 支持多 Provider 配置,通过 priority 字段控制优先级 - 实现 5 分钟缓存机制,减少数据库查询 ### 2. 应用模型配置优化 - 移除应用层硬编码模型配置 - 应用自动使用优先级最高的 Provider 的默认模型 - 支持应用级模型覆盖(可选) ### 3. 工具脚本 - check-providers: 查询数据库中的 Provider 和应用配置 - fix-providers: 修复 Provider 配置(补全 config 和 models 字段) - clear-app-models: 清空应用硬编码模型配置 ### 4. 代码质量 - 删除未使用的 getProvider() 方法 - 修复 fmt.Println 冗余换行警告 - 统一代码格式 ## 技术细节 **降级策略**: 数据库 Provider (优先级) → 环境变量 Provider → 应用配置模型 **当前配置**: - 优先级 110: 本地LLM (qwen2.5-7b-instruct) - 优先级 100: 阿里云百炼 (qwen-plus) 所有 41 个应用现在自动使用本地模型,无需手动配置。
This commit is contained in:
+23
-10
@@ -116,12 +116,18 @@ func (m *Manager) LoadProvidersFromDB(ctx context.Context) error {
|
||||
|
||||
// GetActiveProvider 获取优先级最高的激活 provider
|
||||
func (m *Manager) GetActiveProvider(ctx context.Context) (Provider, error) {
|
||||
provider, _, err := m.GetActiveProviderWithModel(ctx)
|
||||
return provider, err
|
||||
}
|
||||
|
||||
// GetActiveProviderWithModel 获取优先级最高的激活 provider 及其默认模型
|
||||
func (m *Manager) GetActiveProviderWithModel(ctx context.Context) (Provider, string, error) {
|
||||
if m.pool == nil {
|
||||
// 如果没有数据库连接,使用注册的 fallback
|
||||
if p, ok := m.providers[m.fallback]; ok {
|
||||
return p, nil
|
||||
return p, "", nil // 降级时返回空模型名,使用应用配置
|
||||
}
|
||||
return nil, fmt.Errorf("no active provider")
|
||||
return nil, "", fmt.Errorf("no active provider")
|
||||
}
|
||||
|
||||
// 从数据库获取优先级最高的激活 provider
|
||||
@@ -135,21 +141,25 @@ func (m *Manager) GetActiveProvider(ctx context.Context) (Provider, error) {
|
||||
LIMIT 1
|
||||
`).Scan(&id, &baseURL, &apiKey, &configJSON)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("query active provider: %w", err)
|
||||
return nil, "", fmt.Errorf("query active provider: %w", err)
|
||||
}
|
||||
|
||||
// 检查缓存
|
||||
m.cacheMu.RLock()
|
||||
if entry, ok := m.cache[id]; ok && time.Since(entry.updatedAt) < m.cacheTTL {
|
||||
m.cacheMu.RUnlock()
|
||||
return entry.provider, nil
|
||||
// 从 config 中提取默认模型
|
||||
var config map[string]any
|
||||
json.Unmarshal(configJSON, &config)
|
||||
defaultModel, _ := config["default_model"].(string)
|
||||
return entry.provider, defaultModel, nil
|
||||
}
|
||||
m.cacheMu.RUnlock()
|
||||
|
||||
// 创建新的 provider
|
||||
var config map[string]any
|
||||
if err := json.Unmarshal(configJSON, &config); err != nil {
|
||||
return nil, fmt.Errorf("unmarshal config: %w", err)
|
||||
return nil, "", fmt.Errorf("unmarshal config: %w", err)
|
||||
}
|
||||
|
||||
providerType, _ := config["provider"].(string)
|
||||
@@ -157,6 +167,9 @@ func (m *Manager) GetActiveProvider(ctx context.Context) (Provider, error) {
|
||||
providerType = "openai"
|
||||
}
|
||||
|
||||
// 获取默认模型
|
||||
defaultModel, _ := config["default_model"].(string)
|
||||
|
||||
var provider Provider
|
||||
switch providerType {
|
||||
case "openai":
|
||||
@@ -164,7 +177,7 @@ func (m *Manager) GetActiveProvider(ctx context.Context) (Provider, error) {
|
||||
case "anthropic":
|
||||
provider = NewAnthropicProvider(apiKey, baseURL, "")
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported provider type: %s", providerType)
|
||||
return nil, "", fmt.Errorf("unsupported provider type: %s", providerType)
|
||||
}
|
||||
|
||||
// 更新缓存
|
||||
@@ -175,7 +188,7 @@ func (m *Manager) GetActiveProvider(ctx context.Context) (Provider, error) {
|
||||
}
|
||||
m.cacheMu.Unlock()
|
||||
|
||||
return provider, nil
|
||||
return provider, defaultModel, nil
|
||||
}
|
||||
|
||||
func (m *Manager) GetProvider(name string) (Provider, error) {
|
||||
@@ -208,9 +221,9 @@ type StreamEvent struct {
|
||||
}
|
||||
|
||||
type Usage struct {
|
||||
PromptTokens int `json:"prompt_tokens"`
|
||||
CompletionTokens int `json:"completion_tokens"`
|
||||
TotalTokens int `json:"total_tokens"`
|
||||
PromptTokens int `json:"prompt_tokens"`
|
||||
CompletionTokens int `json:"completion_tokens"`
|
||||
TotalTokens int `json:"total_tokens"`
|
||||
Model string `json:"model"`
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user