# Dify API Keys 配置管理经验

## 📅 更新时间
2025-10-16

## 🎯 经验背景

在全链路联调阶段，发现代码中存在多处硬编码的 Dify API Keys，不利于维护和安全管理。本文档总结了统一配置管理的实施经验。

## ✅ 问题发现

### 硬编码问题

**发现位置**：`app/api/v1/exam.py`

```python
# ❌ 硬编码的 API Key
headers = {
    "Authorization": "Bearer app-tDlrmXyS9NtWCShsOx5FH49L",
    "Content-Type": "application/json",
}
```

**问题影响**：
1. 更换 API Key 需要搜索全部代码
2. 敏感信息暴露在代码中
3. 不同环境无法灵活配置
4. 版本控制中包含敏感信息

## 🔧 解决方案

### 1. 配置文件集中管理

**文件**：`app/core/config.py`

```python
class Settings(BaseSettings):
    # Dify API 基础配置
    DIFY_API_BASE: Optional[str] = Field(default="http://dify.ireborn.com.cn/v1")
    
    # 各工作流 API Keys
    DIFY_API_KEY: Optional[str] = Field(default="app-LZhZcMO6CiriLMOLB2PwUGHx")  # 上传知识库
    DIFY_EXAM_GENERATOR_API_KEY: str = Field(default="app-tDlrmXyS9NtWCShsOx5FH49L")  # 试题生成器
    DIFY_ANSWER_JUDGE_API_KEY: str = Field(default="app-FvMdrvbRBz547DVZEorgO1WT")  # 答案判断器
    DIFY_PRACTICE_API_KEY: Optional[str] = Field(default="app-rYP6LNM4iPmNjIHns12zFeJp")  # 陪练场景提取
    DIFY_PRACTICE_ANALYSIS_API_KEY: str = Field(default="app-9MWaCEiRegpYGQLov4S9oQjh")  # 陪练分析报告
    DIFY_COURSE_CHAT_API_KEY: str = Field(default="app-lJzD6COkL8z7Eez8t6ZrYoJS")  # 与课程对话
    DIFY_YANJI_ANALYSIS_API_KEY: str = Field(default="app-g0I5UT8lBB0fvuxGDOqrG8Zj")  # 智能工牌分析
```

### 2. 代码重构

**重构前**：
```python
headers = {
    "Authorization": "Bearer app-tDlrmXyS9NtWCShsOx5FH49L",
    "Content-Type": "application/json",
}
```

**重构后**：
```python
from app.core.config import settings

headers = {
    "Authorization": f"Bearer {settings.DIFY_EXAM_GENERATOR_API_KEY}",
    "Content-Type": "application/json",
}
```

### 3. 配置验证脚本

创建验证脚本 `verify_dify_config.py`：

```python
from app.core.config import settings

def verify_dify_config():
    """验证所有 Dify 配置"""
    configs = [
        ("API Base URL", "DIFY_API_BASE", settings.DIFY_API_BASE),
        ("上传知识库", "DIFY_API_KEY", settings.DIFY_API_KEY),
        ("试题生成器", "DIFY_EXAM_GENERATOR_API_KEY", settings.DIFY_EXAM_GENERATOR_API_KEY),
        # ... 其他配置项
    ]
    
    all_valid = True
    for name, var_name, value in configs:
        if not value:
            print(f"❌ {name}: 配置缺失")
            all_valid = False
        else:
            print(f"✅ {name}: 已配置")
    
    return all_valid
```

## 📋 完整工作流清单

| 工作流名称 | 配置变量 | API Key |
|-----------|---------|---------|
| 上传知识库 | `DIFY_API_KEY` | `app-LZhZcMO6CiriLMOLB2PwUGHx` |
| 试题生成器 | `DIFY_EXAM_GENERATOR_API_KEY` | `app-tDlrmXyS9NtWCShsOx5FH49L` |
| 答案判断器 | `DIFY_ANSWER_JUDGE_API_KEY` | `app-FvMdrvbRBz547DVZEorgO1WT` |
| 陪练场景提取 | `DIFY_PRACTICE_API_KEY` | `app-rYP6LNM4iPmNjIHns12zFeJp` |
| 陪练分析报告 | `DIFY_PRACTICE_ANALYSIS_API_KEY` | `app-9MWaCEiRegpYGQLov4S9oQjh` |
| 与课程对话 | `DIFY_COURSE_CHAT_API_KEY` | `app-lJzD6COkL8z7Eez8t6ZrYoJS` |
| 智能工牌分析 | `DIFY_YANJI_ANALYSIS_API_KEY` | `app-g0I5UT8lBB0fvuxGDOqrG8Zj` |

## 💡 最佳实践

### 1. 命名规范
- 统一前缀：`DIFY_`
- 功能描述：`EXAM_GENERATOR`、`ANSWER_JUDGE`
- 后缀：`_API_KEY`
- 示例：`DIFY_EXAM_GENERATOR_API_KEY`

### 2. 类型注解
```python
# ✅ 推荐：使用明确的类型注解
DIFY_EXAM_GENERATOR_API_KEY: str = Field(default="app-xxx")

# ⚠️ 可选配置使用 Optional
DIFY_API_KEY: Optional[str] = Field(default="app-xxx")
```

### 3. 环境变量覆盖
```bash
# .env 文件
DIFY_EXAM_GENERATOR_API_KEY=app-new-key-for-dev
DIFY_ANSWER_JUDGE_API_KEY=app-new-key-for-dev
```

### 4. 安全管理
```gitignore
# .gitignore 必须包含
.env
.env.local
.env.*.local
```

## 🔍 排查经验

### 1. 查找硬编码 API Keys

```bash
# 搜索所有 app- 开头的字符串
grep -r "app-[A-Za-z0-9]" --include="*.py" app/

# 搜索 Bearer 后跟 app-
grep -r "Bearer app-" --include="*.py" app/
```

### 2. 验证配置生效

```bash
# 运行验证脚本
python verify_dify_config.py

# 预期输出
✅ 所有 Dify 配置验证通过！
```

### 3. 调试配置加载

```python
# 临时添加调试日志
import logging
logger = logging.getLogger(__name__)

logger.debug(f"DIFY_EXAM_GENERATOR_API_KEY: {settings.DIFY_EXAM_GENERATOR_API_KEY[:20]}...")
```

## ⚠️ 注意事项

### 1. 不要提交敏感信息
```bash
# 检查暂存区
git diff --cached | grep -i "app-"

# 如果误提交，使用 git filter-branch 清理历史
```

### 2. 环境隔离
- 开发环境：使用测试 API Keys
- 生产环境：使用正式 API Keys
- 通过环境变量区分

### 3. API Key 轮换
定期轮换 API Keys，步骤：
1. 在 Dify 平台生成新 Key
2. 更新配置文件
3. 重启服务验证
4. 废弃旧 Key

### 4. 权限最小化
- 每个工作流使用独立 API Key
- 便于权限管理和问题追踪
- 避免一个 Key 的泄露影响所有功能

## 📊 实施效果

### 改进前
- ❌ 3 处硬编码 API Keys
- ❌ 修改需要搜索全部代码
- ❌ 无法按环境区分配置
- ❌ 安全风险高

### 改进后
- ✅ 统一在配置文件管理
- ✅ 一处修改全局生效
- ✅ 支持环境变量覆盖
- ✅ 提供验证脚本
- ✅ 完善的文档说明

## 🔗 相关文档

- [Dify API Keys 配置说明](/root/aiedu/kaopeilian-backend/docs/dify_api_keys.md)
- [Dify 系统对接分析报告](/root/aiedu/Dify系统对接分析报告.md)
- [配置更新总结](/root/aiedu/DIFY_API_KEYS_UPDATE_SUMMARY.md)

## 📝 更新日志

| 日期 | 变更内容 | 影响范围 |
|------|---------|---------|
| 2025-10-16 | 添加试题生成器和答案判断器 API Keys | `app/api/v1/exam.py` |
| 2025-10-16 | 移除硬编码，统一使用配置变量 | `app/api/v1/exam.py` |
| 2025-10-16 | 创建配置验证脚本 | 新增 `verify_dify_config.py` |
| 2025-10-16 | 创建配置文档 | 新增 `docs/dify_api_keys.md` |

## 🎓 经验总结

1. **早期规划很重要**：在项目初期就应该统一配置管理规范
2. **代码审查必不可少**：定期检查是否有新的硬编码出现
3. **自动化验证**：使用脚本自动验证配置完整性
4. **文档同步更新**：配置变更时必须同步更新文档
5. **安全意识**：敏感信息绝不提交到版本控制

## 🚀 后续优化建议

1. **CI/CD 集成**：
   - 在部署流程中添加配置验证步骤
   - 配置缺失时阻止部署

2. **密钥管理服务**：
   - 考虑使用 AWS Secrets Manager 或 HashiCorp Vault
   - 实现动态密钥轮换

3. **监控告警**：
   - API Key 即将过期时发送告警
   - API 调用失败时检查 Key 是否有效

4. **权限审计**：
   - 定期审计 API Key 使用情况
   - 发现异常调用及时处理

