本次提交对项目进行了大规模重构,主要调整了服务层架构,以实现更清晰的职责划分和更好的可维护性。 具体变更包括: - 移除 `src/api/llm.js` 文件,相关 API 密钥管理逻辑已迁移到 `src/services/model/manager.js` 中。 - 移除 `src/config/llm.js` 文件,LLM 配置逻辑已迁移到 `src/services/model/manager.js` 和 `src/services/llm/service.js` 中。 - 移除 `src/services/llm.js` 文件,LLM 服务逻辑已迁移到 `src/services/llm/service.js` 中。 - 移除 `src/services/promptManager.js` 文件,提示词模板管理逻辑已迁移到 `src/services/prompt/service.js` 中,历史记录管理已迁移到 `src/services/history/manager.js` 中。 - 重构 `src/components/ModelManager.vue` 组件,使用新的模型管理服务。 - 重构 `src/App.vue` 组件,使用新的服务层架构。 - 修改 `tests/unit/services/llm.test.js` 文件,适应新的服务层架构。 - 修改 `tests/integration/services/llm/common.test.js`, `tests/integration/services/llm/custom.test.js`, `tests/integration/services/llm/deepseek.test.js`, `tests/integration/services/llm/gemini.test.js` 文件,适应新的服务层架构。 - 修改 `tests/unit/App.test.js` 文件,适应新的服务层架构。 - 修改 `src/components/OutputPanel.vue` 组件,添加复制选中内容功能。 - 更新 `experience.md`,记录重构经验。 - 更新 `scratchpad.md`,添加重构计划和日志。 本次重构的主要目标是: - 更清晰的职责划分:将模型管理、LLM 服务、提示词模板管理和历史记录管理分离到独立的模块中。 - 更好的可维护性:通过模块化设计,降低代码耦合度,提高代码可读性和可维护性。 - 更高的可扩展性:新的架构更易于添加新的模型和功能。 本次重构对现有功能没有影响,所有测试均已通过。
4.8 KiB
4.8 KiB
项目经验总结(优化版)
📋 快速索引
架构设计
API集成规范
-
配置分离
- 业务逻辑与API配置解耦
- 统一接口格式(OpenAI兼容)
- 独立管理提示词模板
// 配置示例 export default { baseURL: "https://api.openai.com/v1", models: ["gpt-4", "gpt-3.5"] } -
模块化结构
├─ api/ # API封装 ├─ services/ # 业务逻辑 ├─ config/ # 全局配置 ├─ components/# UI组件 └─ prompts/ # 提示模板库
LLM服务架构
| 设计要点 | 实现方案 |
|---|---|
| 接口标准化 | 统一使用OpenAI格式 |
| 多服务商兼容 | Provider标识区分(如Gemini) |
| 动态配置更新 | 支持热加载配置 |
| 敏感信息管理 | 环境变量+本地加密存储 |
错误处理
典型问题与修复
| 问题场景 | 解决方案 | 发生日期 |
|---|---|---|
| 模板ID与模型Key混淆 | 明确功能ID与API Key分离 | 2024-03-22 |
| 状态同步异常 | 增加状态同步处理函数 | 2024-03-22 |
| 全局currentProvider污染 | 显式传递模型参数 | 2024-03-22 |
处理原则
- 开发环境:保留完整错误堆栈
- 生产环境:友好提示+日志记录
- 通用规则:
try { await apiCall(); } catch (err) { console.error("[API Error]", err.context); throw new Error("服务调用失败,请检查配置"); }
测试规范
核心要点
-
环境变量
// Vite项目必须使用import.meta.env const apiKey = import.meta.env.VITE_GEMINI_KEY; -
测试架构
- 集中管理多服务商配置
- 独立测试数据库
- 模拟异常场景(网络错误/无效Token)
-
用例设计
describe("API测试", () => { it("应正确处理多轮对话", async () => { const response = await sendRequest(messages); expect(response.content).toMatch(/优化建议/); }); });
Vue开发
组件规范
-
Composable使用
// 正确用法 const { data } = useFetch(); // 错误用法 onMounted(() => { const { data } = useFetch(); // 禁止在生命周期内调用 }); -
状态同步方案
<!-- 父组件 --> <ModelManager @update="handleModelUpdate" /> <!-- 子组件 --> <script setup> const emit = defineEmits(['update']); const updateModel = () => { emit('update', newModels); } </script>
UI设计准则
| 分类 | 规范 |
|---|---|
| 布局系统 | 基于Tailwind的响应式网格 |
| 主题管理 | CSS变量+透明度层级控制 |
| 交互反馈 | 加载状态/禁用状态/过渡动画 |
工具与配置
NPM管理
# 常用命令
npm outdated # 检查可更新包
ncu -u "eslint*" # 安全更新指定包
版本策略
| 符号 | 含义 | 示例 |
|---|---|---|
| ^ | 允许小版本更新 | ^1.2.3 → 1.3.0 |
| ~ | 仅允许补丁更新 | ~1.2.3 → 1.2.4 |
YAML处理
-
常见错误
# 错误示例 -invalid: 缺少空格 tags: -test # 列表格式错误 -
修复方案
# 正确格式 valid_key: "值" tags: - test - template
关键重构经验
服务层优化(2024-03-19)
-
类型安全
interface ModelConfig { name: string; baseURL: string; // 非可选字段 models: string[]; } -
错误处理改进
- 统一继承自
LLMError基类 - 批量验证错误收集
class ValidationError extends LLMError { constructor(errors: string[]) { super(`配置验证失败: ${errors.join(', ')}`); } } - 统一继承自
配置管理(2024-03-21)
-
模型启用验证
function validateConfig(config) { if (!config.apiKey) { throw new Error("API Key为必填项"); } } -
环境变量处理
/// <reference types="vite/client" /> interface ImportMetaEnv { VITE_GEMINI_KEY: string; }