# LLM 模型配置表格设计 ## 1. 概述 重新设计 Settings 页面的 LLM 模型配置 UI,将原有的卡片列表改为表格行内编辑形式,简化交互、减少页面长度,同时支持多模型配置。 ## 2. 需求 - **chat**: 必填,多个(子智能体可选不同模型) - **vlm**: 选填,多个 - **embedding**: 必填,1 个(知识库专用) - **rerank**: 必填,1 个(知识库专用) ## 3. UI 设计 ### 3.1 整体布局 每种 LLM 类型(chat/vlm/embedding/rerank)独立成区,区头部显示类型名称和必填/选填标识,右上角有 [+] 添加按钮。 ``` ┌─────────────────────────────────────────────────────────────┐ │ // LLM CONFIGURATION │ ├─────────────────────────────────────────────────────────────┤ │ ┌─ CHAT ─────────────────────────────────────────────── [+] │ │ │ 名称 │ Provider │ 模型 │ 状态 │ 操作 │ │ ├─────────────────────────────────────────────────────────┤ │ │ │ Agent-Chat │ OpenAI │ gpt-4o │ ● 可用 │ ▶ ✕ │ │ └─────────────────────────────────────────────────────────┘ │ │ ... (vlm, embedding, rerank 同理) │ └─────────────────────────────────────────────────────────────┘ ``` ### 3.2 表格列(精简版) | 列 | 说明 | |----|------| | 名称 | 模型名称,支持输入编辑 | | Provider | 下拉选择:OpenAI / Claude / Ollama / DeepSeek / Custom | | 模型 | 模型名称,支持输入编辑 | | 状态 | ● 可用(绿色)/ ○ 不可用(灰色)/ ⚠ 必填未填(红色) | | 操作 | 展开详情按钮 ▶ / 删除按钮 ✕ | ### 3.3 行内展开详情面板 点击任意行,行下方展开详情表单: ``` │ ▼ Agent-Chat │ OpenAI │ gpt-4o │ ● 可用 │ ▶ ✕ │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ │ │ │ │ Provider: [OpenAI ▼] Model: [gpt-4o ] │ │ │ │ Base URL: [https://api.openai.com/v1 ] │ │ │ │ API Key: [sk-•••••••••••••••• ] 👁 │ │ │ │ │ │ │ │ [▶ 测试连接] [保存] [取消] │ │ │ └─────────────────────────────────────────────────────────┘ │ ``` ### 3.4 状态说明 | 状态 | 颜色 | 含义 | |------|------|------| | ● 可用 | 绿色 | 测试通过 | | ○ 不可用 | 灰色 | 未测试或测试失败 | | ⚠ 必填未填 | 红色 | chat/embedding/rerank 未配置 | ### 3.5 警告提示 当 chat/embedding/rerank 任一类型为空时,表格顶部显示红色警告条: ``` ┌─────────────────────────────────────────────────────────────┐ │ ⚠ chat / embedding / rerank 为知识库必填,请确保已配置 │ └─────────────────────────────────────────────────────────────┘ ``` ## 4. 交互规则 | 动作 | 行为 | |------|------| | 添加模型 | 点击 [+] 在对应类型底部添加新行,状态默认为 ○ 不可用 | | 展开编辑 | 点击任意行,行内展开详情面板,同时收起其他已展开的行 | | 测试连接 | 点击"测试连接",调用后端 API,测试通过则状态变 ● 可用,失败显示错误 Toast | | 保存 | 只有测试通过的模型才能保存,保存后更新 originalLlmConfig | | 删除 | 点击 ✕ 删除该模型(embedding/rerank 至少保留 1 个) | | 取消编辑 | 点击"取消"或再次点击展开按钮,收起详情面板,表单数据恢复原值 | | Provider 变化 | 自动填充对应 Provider 的默认 Base URL | ## 5. 数据模型 ```typescript interface LLMModelConfig { name: string // 模型名称 provider: 'openai' | 'claude' | 'ollama' | 'deepseek' | 'custom' model: string // 模型名称 base_url: string // API Base URL api_key: string // API Key enabled: boolean // 是否启用 } interface LLMConfig { chat: LLMModelConfig[] // 必填,多个 vlm: LLMModelConfig[] // 选填,多个 embedding: LLMModelConfig[] // 必填,1个 rerank: LLMModelConfig[] // 必填,1个 } ``` ## 6. 后端 API ### 6.1 保存策略 `saveModel(type, index)` 发送完整 `LLMConfig` 对象到后端,后端整体替换该类型的模型列表。 - chat/vlm: 列表直接替换 - embedding/rerank: 列表直接替换(限制最多 1 个) ### 6.2 测试连接 API ```typescript POST /api/settings/llm/test { "type": "chat" | "vlm" | "embedding" | "rerank", "provider": "openai" | "claude" | "ollama" | "deepseek" | "custom", "model": "gpt-4o", "base_url": "https://api.openai.com/v1", "api_key": "sk-..." } ``` 返回: ```typescript { "success": true, "message": "连接成功" } { "success": false, "error": "错误信息" } ``` ## 7. 组件结构 ``` SettingsView.vue ├── LLMConfigSection (chat/vlm/embedding/rerank 四区) │ ├── LLMTypeCard (每个类型一个卡片) │ │ ├── LLMTable (表格头部 + 列表) │ │ │ ├── LLMTableRow (每行模型) │ │ │ └── LLMExpandPanel (展开的详情面板) │ │ └── LLMEmptyState (空状态 + 添加按钮) │ └── LLMWarning (必填警告条) ``` ## 8. 实现要点 1. **单行展开**: 点击行时收起其他已展开行,保持 UI 简洁 2. **测试通过才可保存**: 保存按钮仅在 `model.enabled === true` 时可用 3. **API Key 脱敏**: 列表中不显示 API Key,详情面板中默认隐藏(显示为 ••••) 4. **Provider 默认 URL**: `onProviderChange` 自动填充默认值 5. **深拷贝比较**: `isModelDirty` 使用 `JSON.stringify` 深拷贝比较 6. **originalLlmConfig 同步**: 每次保存成功后更新原始配置副本