Skip to main content
Glama

AutoDev Codebase MCP Server

by anrgct
250702-config-refactor-experience.md11.8 kB
# 配置重构经验总结 **日期**: 2025-07-02 **重构目标**: 统一embedding模型配置结构,解决混乱的配置字段问题 ## 问题背景 ### 原有配置结构的问题 1. **混乱的顶级字段** ```typescript interface CodeIndexConfig { embedderProvider: EmbedderProvider modelId?: string // 通用字段,但实际用法混乱 openAiOptions?: ApiHandlerOptions ollamaOptions?: ApiHandlerOptions openAiCompatibleOptions?: { baseUrl: string; apiKey: string; modelDimension?: number } } ``` 2. **字段命名不一致** - Ollama: `ollamaOptions.ollamaBaseUrl` - OpenAI Compatible: `openAiCompatibleOptions.baseUrl` - 字段名重复前缀,如 `ollamaOptions.ollamaBaseUrl` 3. **配置传递复杂** - `service-factory.ts` 需要手动解构不同provider的配置 - 每个embedder构造函数参数不统一 4. **维度配置混乱** - 配置文件中同时存在 `ollamaModel` 和 `modelId` - `modelDimension` 字段位置不统一 ## 重构方案 ### 新的配置结构 ```typescript // 基础配置 interface BaseConfig { isEnabled: boolean isConfigured: boolean qdrantUrl?: string qdrantApiKey?: string searchMinScore?: number } // 各Provider专用配置 interface OllamaConfig { provider: "ollama" baseUrl: string model: string dimension: number } interface OpenAIConfig { provider: "openai" apiKey: string model: string dimension: number } interface OpenAICompatibleConfig { provider: "openai-compatible" baseUrl: string apiKey: string model: string dimension: number } // 统一配置类型 interface CodeIndexConfig extends BaseConfig { embedder: OllamaConfig | OpenAIConfig | OpenAICompatibleConfig } ``` ### 配置文件示例 **新结构 (Ollama):** ```json { "isEnabled": true, "isConfigured": true, "embedder": { "provider": "ollama", "baseUrl": "http://localhost:11434", "model": "dengcao/Qwen3-Embedding-0.6B:f16", "dimension": 1024 }, "qdrantUrl": "http://localhost:6333" } ``` ## 实施过程 ### 1. 更新接口定义 文件: `src/code-index/interfaces/config.ts` - 定义了新的联合类型 `EmbedderConfig` - 更新了 `CodeIndexConfig` 接口 - 保持向前兼容的快照类型 ### 2. 更新配置加载器 文件: `src/adapters/nodejs/config.ts` - 更新了 `isConfigured()` 验证方法 - 提供向后兼容的 `getEmbedderConfig()` 方法 ### 3. 更新服务工厂 文件: `src/code-index/service-factory.ts` - 简化了 embedder 创建逻辑 - 直接从 `config.embedder.dimension` 获取维度 - 统一了所有 provider 的参数传递 ### 4. 更新配置管理器 文件: `src/code-index/config-manager.ts` - 更新了 `getConfig()` 方法来构造新格式 - 保持内部状态与新配置结构的兼容 ## 关键技术点 ### 1. 向后兼容策略 ```typescript // 自动迁移旧配置格式 if (fileConfig.embedderProvider && !fileConfig.embedder) { fileConfig.embedder = this.migrateLegacyConfig(fileConfig) } // 字段映射 if (fileConfig.ollamaModel && !fileConfig.modelId) { fileConfig.modelId = fileConfig.ollamaModel delete fileConfig.ollamaModel } ``` ### 2. 类型安全的联合类型 ```typescript export type EmbedderConfig = | OllamaEmbedderConfig | OpenAIEmbedderConfig | OpenAICompatibleEmbedderConfig ``` ### 3. 配置验证增强 ```typescript private isConfigured(): boolean { const { embedder, qdrantUrl } = this.config switch (embedder.provider) { case "ollama": return !!(embedder.baseUrl && embedder.model && embedder.dimension > 0 && qdrantUrl) case "openai": return !!(embedder.apiKey && embedder.model && embedder.dimension > 0 && qdrantUrl) // ... } } ``` ## 遇到的问题和解决方案 ### 1. 维度配置问题 **问题**: Qdrant 要求创建 collection 时必须指定准确的向量维度 **解决**: - 配置中强制要求手动指定 `dimension` - 添加维度验证逻辑 - 错误信息提示用户检查维度配置 ### 2. 配置架构分层问题 **问题**: ConfigManager 使用旧配置结构,但 ServiceFactory 期望新结构 **解决**: - ConfigManager 的 `getConfig()` 方法构造新格式配置 - 保持 ConfigManager 内部状态不变 - 在接口层面进行格式转换 ### 3. 类型导入冲突 **问题**: 新旧配置接口中都有 `EmbedderConfig` 类型 **解决**: ```typescript import { EmbedderConfig as NewEmbedderConfig } from "./interfaces/config" ``` ### 4. 维度不匹配错误 **问题**: Qdrant collection 期望 768 维但收到 1024 维向量 **原因**: ConfigManager 使用默认维度而不是配置中的实际维度 **解决**: 确保 ConfigManager 正确传递配置中的 dimension 值 ## 测试验证 ### 成功指标 1. ✅ **配置文件正确解析** ```bash Config file content: { "embedder": { "provider": "ollama", "model": "dengcao/Qwen3-Embedding-0.6B:f16", "dimension": 1024 } } ``` 2. ✅ **配置验证通过** ```bash Validation result: { "isValid": true, "errors": [] } ``` 3. ✅ **向后兼容正常** ```bash Embedder config: { "provider": "ollama", "modelId": "dengcao/Qwen3-Embedding-0.6B:f16", "ollamaOptions": { "ollamaBaseUrl": "http://localhost:11434" } } ``` 4. ✅ **Manager 初始化成功** ```bash isFeatureEnabled: true isFeatureConfigured: true isInitialized: true ``` ## 优势 ### 1. 清晰分离 - 每个 provider 配置独立,不会混乱 - 字段命名统一,易于理解 ### 2. 类型安全 - TypeScript 联合类型确保配置正确 - 编译时捕获配置错误 ### 3. 易于扩展 - 新增 provider 只需添加新的配置类型 - 不影响现有 provider ### 4. 统一接口 - 所有 embedder 构造函数参数统一 - 简化了服务工厂逻辑 ## 最佳实践总结 ### 1. 重构策略 - **渐进式重构**: 先更新接口,再更新实现 - **向后兼容**: 提供迁移逻辑,不破坏现有配置 - **类型优先**: 利用 TypeScript 类型系统保证正确性 ### 2. 配置设计原则 - **单一职责**: 每个配置对象只负责一个 provider - **明确性**: 字段名称明确,避免歧义 - **验证完整**: 提供完整的配置验证逻辑 ### 3. 测试方法 - **分层测试**: 配置加载 → 验证 → 服务创建 → 完整流程 - **边界测试**: 测试配置缺失、格式错误等边界情况 - **兼容性测试**: 确保旧配置能正常迁移 ## 深度调试与最终解决方案 ### 问题深入分析 在完成基本重构后,遇到了一个隐蔽的问题: **现象**: 配置文件格式正确,但仍然出现 "Cannot create services: Code indexing is not properly configured" 错误 **调试过程**: 1. **添加调试日志确认问题** ```typescript console.log('Debug isConfigured check:', { embedderProvider: this.embedderProvider, ollamaOptions: this.ollamaOptions, qdrantUrl: this.qdrantUrl }) ``` 2. **发现异常状态** ```bash Debug isConfigured check: { embedderProvider: 'openai', // 错误!应该是 ollama ollamaOptions: undefined, // 错误!应该有值 qdrantUrl: 'http://localhost:6333' // 正确 } ``` 3. **追踪配置加载过程** 发现 `NodeConfigProvider.getConfig()` 返回的配置同时包含新旧格式: ```json { "embedder": { "provider": "ollama", // 新格式正确 "model": "dengcao/Qwen3-Embedding-0.6B:f16", "dimension": 1024 }, "embedderProvider": "ollama", // 旧格式字段 "ollamaOptions": { ... } // 旧格式字段 } ``` ### 根本原因发现 通过深入调试发现,问题出现在 **TUI runner 的默认配置**: ```typescript // src/cli/tui-runner.ts - 问题根源 configOptions: { defaultConfig: { embedderProvider: "ollama", // 旧格式! ollamaOptions: { ollamaBaseUrl: options.ollamaUrl } } } ``` **问题机制**: 1. 配置文件使用新格式 `embedder` 对象 2. TUI runner 的 `defaultConfig` 使用旧格式字段 3. 配置合并时,新旧格式字段同时存在 4. ConfigManager 的 `_loadAndSetConfiguration()` 正确读取新格式 5. 但由于配置中仍有旧格式字段,导致状态不一致 ### 最终解决方案 **更新 TUI runner 使用新配置格式**: ```typescript // 修复前(旧格式) defaultConfig: { embedderProvider: "ollama", modelId: options.model, ollamaOptions: { ollamaBaseUrl: options.ollamaUrl, apiKey: '', } } // 修复后(新格式) defaultConfig: { embedder: { provider: "ollama" as const, baseUrl: options.ollamaUrl, model: options.model || "nomic-embed-text", dimension: 768 } } ``` **需要修复的文件**: - `src/cli/tui-runner.ts` (两个位置的 defaultConfig) ### 验证结果 修复后测试验证: ```bash timeout 30 npx tsx src/index.ts --demo # ✅ 不再有 "Cannot create services" 错误 # ✅ TUI 成功启动并进入初始化阶段 # ✅ 配置验证通过 ``` ## 关键经验总结 ### 1. 调试策略 - **逐层调试**: 从错误信息开始,逐层深入到配置加载、状态检查 - **状态日志**: 在关键检查点添加状态日志,确认实际值 - **配置追踪**: 追踪配置从文件加载到最终使用的完整路径 ### 2. 隐蔽问题识别 - **配置合并问题**: 注意新旧格式混合导致的状态不一致 - **默认配置影响**: 检查所有设置默认配置的位置 - **多层抽象**: 在多层抽象系统中,问题可能出现在任何一层 ### 3. 重构完整性检查 - **全局搜索**: 确保所有相关代码都更新到新格式 - **边界验证**: 检查配置的边界(默认值、合并逻辑) - **端到端测试**: 从配置文件到最终服务创建的完整流程测试 ## 后续优化建议 ### 1. 自动维度检测 ```typescript // 可以提供一个检测命令 // npm run detect-model-dimension model-name ``` ### 2. 配置模板 ```typescript // 提供常见模型的配置模板 const PRESET_CONFIGS = { "nomic-embed-text": { provider: "ollama", dimension: 768 }, "text-embedding-3-small": { provider: "openai", dimension: 1536 } } ``` ### 3. 配置校验增强 - 添加模型可用性检测 - 网络连接验证 - 维度自动验证 - 配置格式一致性检查 ### 4. 防止回归的措施 - 添加配置格式的单元测试 - 在 CI/CD 中加入配置验证检查 - 文档中明确新旧格式的迁移指导 ## 总结 这次配置重构成功解决了原有配置结构混乱的问题,建立了清晰、类型安全、易于扩展的配置体系。通过渐进式重构和向后兼容策略,确保了平滑过渡。 **重构的核心价值**: - **简化配置**: 用户只需关注所选 provider 的配置 - **减少错误**: 类型系统和验证逻辑减少配置错误 - **提升维护性**: 清晰的结构便于后续维护和扩展 **调试过程的核心价值**: - **深入调试技巧**: 展示了如何在复杂系统中定位隐蔽问题 - **配置合并陷阱**: 揭示了新旧格式混合时的常见问题 - **完整性验证**: 强调了重构时需要检查所有相关代码的重要性 这次经验展示了在复杂系统中进行配置重构的最佳实践,特别是如何处理新旧格式过渡期间的隐蔽问题,值得在类似项目中借鉴。 # memory - 通过`timeout 30 npx tsx src/index.ts --demo`验证配置重构成功 - 核心问题:TUI runner 默认配置使用旧格式,导致新旧格式混合 - 解决方案:更新 `src/cli/tui-runner.ts` 中的两个 defaultConfig 为新格式 - 调试技巧:逐层添加日志,追踪配置从加载到使用的完整路径

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/anrgct/autodev-codebase'

If you have feedback or need assistance with the MCP directory API, please join our Discord server