# ADR-0002: AI 能力通过外部 API 调用实现 > **状态**: 已决议(2026-05-21 修订) > **日期**: 2026-05-20 > **修订**: 2026-05-21 > **父决策**: ADR-0001(整体技术栈) > **决策者**: 架构评审 --- ## 上下文 平台需要 AI 能力支撑四大核心模块:配方指标预测、NL 搜索、配方生成/推演、颜色推荐。考虑两种实现路径: - **方案 A**:自建 Python AI 微服务(FastAPI + 自训练模型) - **方案 B**:通过外部 AI API 调用实现(LLM API + Prompt Engineering) --- ## 决策 **选择方案 B**:所有 AI 能力通过调用外部 LLM API 实现。 --- ## 理由 ### 方案 B 优势 | 维度 | 方案 A(自建) | 方案 B(外部 API) | | :--- | :--- | :--- | | **开发成本** | 需要 ML 工程师训练模型;数据清洗和标注投入大 | Prompt Engineering 即可;无需 ML 专业背景 | | **运维成本** | GPU 服务器(至少 1 台 A100)+ 模型部署和监控 | 零运维,按调用量付费 | | **迭代速度** | 重新训练需数天到数周 | 调整 Prompt 即时生效 | | **模型能力** | 受限于自有数据量和训练资源 | 持续获得最新大模型能力升级 | | **部署复杂度** | 增加 1 个微服务 + GPU 依赖 + gRPC | 仅 BFF 层 HTTP 调用 | | **冷启动** | 模型加载需数分钟 | 即用即走 | ### 化妆品配方场景的特殊适配 配方研发的 AI 需求特点: 1. **推理为主,非训练密集型**:预测肤感/稳定性本质是"基于成分知识的推理",LLM 的常识推理 + few-shot learning 可以胜任 2. **数据量小**:企业内部配方数据通常是千到万级,不足以训练专用深度学习模型 3. **领域知识密集**:LLM 已具备化学/化妆品基础知识,通过 Prompt 注入成分数据库即可精准推理 4. **需求多变**:配方推演的约束条件千变万化,API 调用的灵活性远胜固定模型 --- ## AI Service 架构 ``` Route Layer (modules/ai/ai.route.ts) │ ▼ AIService (services/ai/index.ts) ├── Provider 抽象层 │ ├── createOpenAIProvider (GPT-4o, base: api.openai.com/v1) │ └── createDeepSeekProvider (deepseek-chat, base: api.deepseek.com/v1) ├── LRUCache (200 条, 带 TTL) ├── RateLimiter (10 req/s, token bucket) ├── 重试策略 (指数退避, 最多 3 次) ├── Fallback → Mock 模式 (AI_MOCK=true 时返回预设数据) └── Audit Log → ai_audit_logs 表 (capability, model, tokens, duration) ``` > **修订(2026-05-21)**:AI Service 重构为实例属性管理配置(openaiKey/deepseekKey),不再依赖 `process.env` 直读。Provider 通过 `reload(updates)` 热更新。 --- ## AI 能力清单 | Prompt 模板 | 能力 | System Prompt 角色 | 输出格式 | |-------------|------|--------------------|----------| | `predictMetricsPrompt` | 预测配方指标 | 资深化妆品配方工程师 | `{sensoryIndex, stabilityScore, costEstimate, confidence, reasoning}` | | `parseNLQueryPrompt` | 自然语言搜索 | 查询解析器 | `{filters, keywords, vectorQuery}` | | `generateFormulaPrompt` | 配方推演 | 资深化妆品配方工程师 | `[{name, changes, predictedMetrics, reasoning}]` | | `recommendColorantsPrompt` | 配色推荐 | 化妆品色彩专家 | `{recommendations: [{colorants, predictedDeltaE, confidence}]}` | | `extractFormulaPrompt` | 配方文本提取 | 数据结构化提取 | `{ingredients: [{inciName, chineseName, percentage, phase, processNotes}]}` | --- ## 配置管理 | 配置项 | 存储位置 | 说明 | |--------|----------|------| | `AI_MOCK` | `runtime/config.json` | Mock 模式开关(开发环境默认 true) | | `OPENAI_API_KEY` | `runtime/config.json` | 服务器端持久化,客户端不透传 | | `DEEPSEEK_API_KEY` | `runtime/config.json` | 同上 | | `OPENAI_BASE_URL` | `runtime/config.json` | 自定义 endpoint(如 API 代理) | | `DEEPSEEK_BASE_URL` | `runtime/config.json` | 同上 | > **修订(2026-05-21)**:API Key 从 localStorage 传输改为服务器端文件持久化。前端 SettingsPage 仅显示"已配置/未配置"状态,不展示 Key 内容。 --- ## 后果 - 依赖外部 API 服务可用性(OpenAI / DeepSeek),API 不可用时自动降级为 Mock 模式 - AI 响应格式严格约束为 JSON,前端不解析自然语言输出 - 每次 AI 调用记录审计日志,用于成本核算和问题排查 - 新增 AI Provider 只需实现 `AIProvider` 接口(`chat` + `chatStream`)