Skip to content

Commit bb28212

Browse files
authored
fix: system config model provider issues (#187)
1 parent b547023 commit bb28212

130 files changed

Lines changed: 1380 additions & 1212 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

MODEL_DELETION_FIX_REPORT.md

Lines changed: 336 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,336 @@
1+
# 模型删除同步问题分析与解决方案
2+
3+
## 问题现象
4+
5+
用户反馈:在系统配置管理中删除模型后,模型列表和Agent选择器仍然显示已删除的模型。
6+
7+
## 问题分析
8+
9+
### 数据流向
10+
11+
系统涉及三层数据存储:
12+
13+
1. **配置文件层** (`~/.derisk/derisk.json`)
14+
- 存储完整的 agent_llm 配置
15+
- 包括 providers 和 models 列表
16+
17+
2. **内存配置层** (`SystemApp.config`)
18+
- 运行时配置对象
19+
- 通过 `system_app.config.set("agent.llm", config)` 同步
20+
21+
3. **模型缓存层** (`ModelConfigCache`)
22+
- 单例模式的全局缓存
23+
- 存储模型配置用于快速查找
24+
25+
### API接口依赖
26+
27+
| 功能模块 | API接口 | 数据源 |
28+
|---------|---------|--------|
29+
| 模型管理页面 | `/api/v2/serve/model/models` | SystemApp.config + ModelConfigCache |
30+
| Agent选择器 | `/api/v1/model/types` | SystemApp.config |
31+
| 模型创建页面 | `/api/v2/serve/model/model-types` | SystemApp.config |
32+
33+
### 核心问题
34+
35+
1. **SystemApp导入缺失** (已修复)
36+
- `/api/v1/model/types` 接口缺少 `SystemApp` 导入
37+
- 导致接口报错:`name 'SystemApp' is not defined`
38+
39+
2. **reset_config同步缺失** (已修复)
40+
- `/api/v1/config/reset` 接口缺少配置同步
41+
- 重置配置后内存缓存不更新
42+
43+
## 解决方案
44+
45+
### 修复内容
46+
47+
#### 1. 修复 SystemApp 导入问题
48+
49+
**文件**: `packages/derisk-app/src/derisk_app/openapi/api_v1/api_v1.py`
50+
51+
```python
52+
# 第16行
53+
from derisk.component import ComponentType, SystemApp
54+
```
55+
56+
#### 2. 修复 reset_config 接口
57+
58+
**文件**: `packages/derisk-app/src/derisk_app/openapi/api_v1/config_api.py`
59+
60+
```python
61+
@router.post("/reset")
62+
async def reset_config():
63+
"""重置为默认配置"""
64+
try:
65+
from derisk_core.config import AppConfig
66+
67+
manager = get_config_manager()
68+
config = AppConfig()
69+
manager._config = config
70+
71+
saved = save_config_with_error_handling(manager, "默认配置")
72+
73+
# 新增:同步配置和刷新缓存
74+
sync_status = _sync_config_to_system_app(config)
75+
models_registered = _refresh_model_config_cache(config)
76+
77+
return JSONResponse(
78+
content={
79+
"success": True,
80+
"message": "配置已重置为默认值",
81+
"data": config.model_dump(mode="json"),
82+
"saved_to_file": saved,
83+
"models_registered": models_registered,
84+
"sync_status": sync_status,
85+
}
86+
)
87+
except Exception as e:
88+
raise HTTPException(status_code=500, detail=str(e))
89+
```
90+
91+
### 删除模型完整流程
92+
93+
当用户在前端删除模型时,流程如下:
94+
95+
```mermaid
96+
sequenceDiagram
97+
participant User as 用户
98+
participant Frontend as 前端
99+
participant ConfigAPI as /api/v1/config/import
100+
participant ConfigFile as 配置文件
101+
participant SystemApp as SystemApp.config
102+
participant Cache as ModelConfigCache
103+
participant ModelAPI as 模型列表API
104+
105+
User->>Frontend: 删除模型
106+
Frontend->>Frontend: 更新表单数据
107+
Frontend->>ConfigAPI: POST /api/v1/config/import
108+
ConfigAPI->>ConfigFile: 保存新配置
109+
ConfigAPI->>SystemApp: _sync_config_to_system_app()
110+
ConfigAPI->>Cache: _refresh_model_config_cache()
111+
Note over Cache: 清空旧缓存<br/>注册新模型
112+
ConfigAPI->>Frontend: 返回成功响应
113+
Frontend->>Frontend: 刷新页面数据
114+
Frontend->>ModelAPI: GET /api/v2/serve/model/models
115+
ModelAPI->>SystemApp: 读取 agent.llm 配置
116+
ModelAPI->>Cache: 读取缓存模型
117+
ModelAPI->>Frontend: 返回更新后的模型列表
118+
```
119+
120+
## 测试验证
121+
122+
### 测试脚本
123+
124+
创建了 `test_model_deletion.py` 脚本进行自动化测试。
125+
126+
### 测试结果
127+
128+
```
129+
============================================================
130+
测试模型删除流程
131+
============================================================
132+
133+
1. 获取当前配置
134+
当前 Provider 数量: 1
135+
Provider: openai
136+
Models: ['glm-4.7', 'kimi-k2.5', 'qwen3.5-plus', 'glm-5']
137+
138+
2. 删除模型 'glm-5'
139+
140+
3. 导入新配置
141+
更新结果: True
142+
消息: 配置已导入并保存
143+
注册的模型数: 3
144+
145+
4. 检查内存缓存
146+
缓存的模型: ['glm-4.7', 'kimi-k2.5', 'qwen3.5-plus']
147+
✅ 成功: glm-5 已从缓存中删除
148+
149+
5. 检查模型列表API (模型管理页面)
150+
模型列表: ['glm-4.7', 'kimi-k2.5', 'qwen3.5-plus']
151+
✅ 成功: glm-5 已从模型列表中删除
152+
153+
6. 检查Agent选择器API
154+
模型类型: ['qwen3.5-plus', 'glm-4.7', 'kimi-k2.5']
155+
✅ 成功: glm-5 已从Agent选择器中删除
156+
157+
============================================================
158+
测试完成
159+
============================================================
160+
```
161+
162+
**结论**: 删除模型后,所有API都能正确返回更新后的数据。
163+
164+
## 使用说明
165+
166+
### 前端操作
167+
168+
在系统配置页面删除模型:
169+
170+
1. 进入 **系统设置 → 配置管理**
171+
2.**模型提供商配置** 区域,找到要删除的模型
172+
3. 点击模型旁边的 **删除按钮**(垃圾桶图标)
173+
4. 系统会弹出确认对话框
174+
5. 确认后,点击 **保存** 按钮
175+
6. 系统会自动:
176+
- 更新配置文件
177+
- 同步内存配置
178+
- 刷新模型缓存
179+
- 显示成功消息
180+
181+
### 后端验证
182+
183+
删除后可以通过API验证:
184+
185+
```bash
186+
# 查看配置文件中的模型
187+
cat ~/.derisk/derisk.json | grep -A 10 '"models"'
188+
189+
# 查看内存缓存中的模型
190+
curl -s "http://localhost:7777/api/v1/config/model-cache/models" | jq '.data.models'
191+
192+
# 查看模型管理页面的模型列表
193+
curl -s "http://localhost:7777/api/v2/serve/model/models" | jq '.data[].model_name'
194+
195+
# 查看Agent选择器的模型列表
196+
curl -s "http://localhost:7777/api/v1/model/types" | jq '.data'
197+
```
198+
199+
## 特殊情况说明
200+
201+
### SystemApp 同步状态
202+
203+
在某些情况下,`sync_status.agent_llm` 可能显示为 `False`,这是因为:
204+
205+
- SystemApp 是在 uvicorn worker 进程中创建的
206+
- 在某些部署模式下,`SystemApp.get_instance()` 可能返回 None
207+
- 但这不影响核心功能,因为:
208+
- 配置文件已正确保存 ✓
209+
- ModelConfigCache 已正确刷新 ✓
210+
- API接口能正确读取配置 ✓
211+
212+
### 重启服务
213+
214+
如果删除模型后发现某些功能异常,可以重启服务:
215+
216+
```bash
217+
# 停止服务
218+
pkill -f "derisk start"
219+
220+
# 启动服务
221+
derisk start
222+
```
223+
224+
重启后:
225+
- 配置文件重新加载 ✓
226+
- SystemApp 完整初始化 ✓
227+
- ModelConfigCache 正确刷新 ✓
228+
229+
## 技术细节
230+
231+
### 关键函数
232+
233+
#### `_sync_config_to_system_app()`
234+
235+
```python
236+
def _sync_config_to_system_app(config: AppConfig) -> Dict[str, bool]:
237+
"""同步配置到 SystemApp
238+
239+
步骤:
240+
1. agent_llm → agent.llm
241+
2. default_model → agent.default_model
242+
3. agents → agent.agents
243+
4. sandbox → sandbox
244+
5. app_config → configs dict
245+
"""
246+
```
247+
248+
#### `_refresh_model_config_cache()`
249+
250+
```python
251+
def _refresh_model_config_cache(config: AppConfig) -> int:
252+
"""刷新模型缓存
253+
254+
步骤:
255+
1. 清空 ModelConfigCache
256+
2. 解析 agent_llm 配置
257+
3. 注册新模型到缓存
258+
259+
返回:注册的模型数量
260+
"""
261+
```
262+
263+
### 数据结构
264+
265+
**前端格式 (agent_llm)**:
266+
```json
267+
{
268+
"temperature": 0.5,
269+
"providers": [
270+
{
271+
"provider": "openai",
272+
"api_base": "https://...",
273+
"api_key_ref": "${secrets.openai_api_key}",
274+
"models": [
275+
{
276+
"name": "glm-4.7",
277+
"temperature": 0.7,
278+
"max_new_tokens": 4096,
279+
"is_multimodal": false,
280+
"is_default": true
281+
}
282+
]
283+
}
284+
]
285+
}
286+
```
287+
288+
**后端格式 (agent.llm)**:
289+
```json
290+
{
291+
"temperature": 0.5,
292+
"provider": [
293+
{
294+
"provider": "openai",
295+
"api_base": "https://...",
296+
"api_key_ref": "${secrets.openai_api_key}",
297+
"model": [
298+
{
299+
"name": "glm-4.7",
300+
"temperature": 0.7,
301+
"max_new_tokens": 4096,
302+
"is_multimodal": false,
303+
"is_default": true
304+
}
305+
]
306+
}
307+
]
308+
}
309+
```
310+
311+
注意:前端使用 `providers``models`,后端使用 `provider``model`
312+
313+
## 总结
314+
315+
### 修复成果
316+
317+
✅ 修复 SystemApp 导入问题
318+
✅ 修复 reset_config 接口同步缺失
319+
✅ 确保删除模型后所有API立即更新
320+
✅ 测试验证流程正确性
321+
322+
### 使用建议
323+
324+
1. 在系统配置页面删除模型后,**务必点击保存按钮**
325+
2. 系统会自动刷新所有相关数据
326+
3. 如果发现问题,可调用 `/api/v1/config/refresh-model-cache` 手动刷新
327+
4. 重启服务可确保所有配置完全生效
328+
329+
### 后续优化
330+
331+
可考虑的优化方向:
332+
333+
1. 增强 SystemApp 初始化稳定性
334+
2. 添加配置变更事件通知机制
335+
3. 前端实时刷新机制(WebSocket/SSE)
336+
4. 配置版本控制和回滚功能

assets/schema/derisk.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use derisk;
99
-- MySQL DDL Script for Derisk
1010
-- Version: 0.3.0
1111
-- Generated from SQLAlchemy ORM Models
12-
-- Generated: 2026-03-30 19:52:29
12+
-- Generated: 2026-03-30 22:06:22
1313
-- ============================================================
1414

1515
SET NAMES utf8mb4;

0 commit comments

Comments
 (0)