# 修复 Docker 环境 404 错误

## 问题诊断

### 日志分析

从 `assets/physics-correction.log` 中发现以下关键错误：

```
❌ HTTP Request: POST https://api.coze.cn/v1/chat/completions "HTTP/1.1 404 Not Found"
❌ HTTP Request: POST https://api.coze.cn/v1/loop/traces/ingest "HTTP/1.1 401 Unauthorized"
```

**日志明确提示**：
```
remote service error, authentication is invalid
[http_code=401 error_code=4100]
```

### 根本原因

1. **认证失败**：虽然端点已经正确添加了 `/v1/` 前缀，但由于认证失败导致返回 404 错误
2. **缺少必需环境变量**：
   - ❌ 没有 `COZE_WORKSPACE_ID`
   - ❌ 密钥被硬编码在 Dockerfile 中（不安全且配置混乱）

## 修复步骤

### 步骤 1：使用修复后的 Dockerfile

将 `assets/Dockerfile.fixed` 替换原来的 `Dockerfile`：

```bash
# 备份原文件
mv Dockerfile Dockerfile.backup

# 使用修复后的文件
mv Dockerfile.fixed Dockerfile
```

**关键修改**：
- ✅ 移除硬编码的 API_KEY 和密钥
- ✅ 添加 `COZE_INTEGRATION_CHAT_BASE_URL` 端点
- ✅ 保留 API 端点配置（`/v1` 前缀已正确）
- ✅ 添加健康检查

### 步骤 2：创建 docker-compose.yml

使用提供的 `assets/docker-compose.yml` 文件，确保包含以下环境变量：

```yaml
environment:
  # ✅ 从 JWT token 提取的值
  - COZE_API_KEY=Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6ImRmZmU2NmYxLTg0MDMtNDc5Ni05ZmRhLTViMmJjZWExM2ViOCJ9...
  # ✅ 从 token 的 sub 字段提取：spiffe://api.coze.cn/workload_identity/id:7622238752642957347
  - COZE_WORKSPACE_ID=7622238752642957347
```

### 步骤 3：验证环境变量

在重新构建之前，运行检查脚本：

```bash
# 在宿主机上（确保环境变量已设置）
python assets/check_env.py
```

应该看到类似输出：

```
✅ COZE_API_KEY: Bearer eyJhbGciOiJSUzI1...
✅ COZE_WORKSPACE_ID: 7622238752642957347
✅ COZE_INTEGRATION_BASE_URL: https://api.coze.cn/v1
✅ LLM_MODEL_NAME: doubao-seed-2-0-pro-260215
✅ Token 未过期
✅ API 端点包含 /v1 前缀
✅ 从 Token 提取的 Workspace ID: 7622238752642957347
```

### 步骤 4：重新构建并启动

```bash
# 停止旧容器
docker-compose down

# 重新构建镜像
docker-compose build --no-cache

# 启动服务
docker-compose up -d

# 查看日志
docker-compose logs -f
```

### 步骤 5：测试 LLM 调用

```bash
# 发送测试请求
curl -X POST http://localhost:8000/stream_run \
  -H "Content-Type: application/json" \
  -d '{
    "student_homework": [
      {
        "student_id": 1,
        "student_name": "测试学生",
        "homework_images": ["https://example.com/image.jpg"]
      }
    ],
    "answer_doc_url": "",
    "comment_max_length": 50,
    "max_concurrent": 1
  }'
```

## 验证修复成功的标志

### 日志应该显示：

```
✅ HTTP Request: POST https://api.coze.cn/v1/chat/completions "HTTP/1.1 200 OK"
✅ Workflow doc_extract started
✅ Node 'doc_extract_node' started
✅ LLM 调用成功
```

**不应该再出现**：
```
❌ 404 Not Found
❌ 401 Unauthorized
❌ authentication is invalid
```

## 环境变量说明

### 必需的环境变量

| 变量名 | 说明 | 示例值 |
|--------|------|--------|
| `COZE_API_KEY` | Coze API 认证密钥 | `Bearer eyJhbGci...` |
| `COZE_WORKSPACE_ID` | 工作区 ID | `7622238752642957347` |

### 可选的环境变量（已在 Dockerfile 中设置）

| 变量名 | 说明 | 默认值 |
|--------|------|--------|
| `COZE_INTEGRATION_BASE_URL` | API 基础 URL | `https://api.coze.cn/v1` |
| `COZE_INTEGRATION_MODEL_BASE_URL` | 模型 API 基础 URL | `https://api.coze.cn/v1` |
| `LLM_MODEL_NAME` | LLM 模型名称 | `doubao-seed-2-0-pro-260215` |

### 提取 Workspace ID 的方法

从 JWT Token 的 `sub` 字段提取：

```python
# Token 示例
token = "Bearer eyJhbGci..."

# 解码 JWT payload
import json, base64
payload = json.loads(base64.b64decode(token.split('.')[1]))

# sub 字段：spiffe://api.coze.cn/workload_identity/id:7622238752642957347
sub = payload['sub']
workspace_id = sub.split('workload_identity/id:')[-1]
print(workspace_id)  # 7622238752642957347
```

## 安全建议

### ✅ 推荐：使用环境变量文件

创建 `.env` 文件（不要提交到 Git）：

```bash
# .env
COZE_API_KEY=Bearer eyJhbGci...
COZE_WORKSPACE_ID=7622238752642957347
```

修改 `docker-compose.yml`：

```yaml
env_file:
  - .env
```

添加到 `.gitignore`：

```
.env
```

### ❌ 避免：硬编码密钥

**不要**在 Dockerfile 中硬编码密钥：
```dockerfile
# ❌ 错误示例
ENV COZE_API_KEY="Bearer eyJhbGci..."
```

## 故障排查

### 问题 1：仍然出现 401 错误

**检查**：
```bash
# 检查环境变量是否正确注入
docker exec -it math-grading-app env | grep COZE

# 应该看到 COZE_API_KEY 和 COZE_WORKSPACE_ID
```

**修复**：
```bash
# 重新启动容器
docker-compose down
docker-compose up -d
```

### 问题 2：仍然出现 404 错误

**检查**：
```bash
# 检查端点配置
docker exec -it math-grading-app env | grep BASE_URL

# 应该包含 /v1
# COZE_INTEGRATION_BASE_URL=https://api.coze.cn/v1
```

**修复**：
```bash
# 重新构建镜像（确保使用最新的 Dockerfile）
docker-compose build --no-cache
docker-compose up -d
```

### 问题 3：Token 过期

**检查**：
```bash
# 运行检查脚本
python assets/check_env.py
```

**修复**：
```bash
# 获取新的 Token
# 1. 登录 Coze 平台
# 2. 进入个人中心
# 3. 生成新的 API Key
# 4. 更新 docker-compose.yml 中的 COZE_API_KEY
```

## 总结

**关键修复点**：
1. ✅ 添加 `COZE_WORKSPACE_ID` 环境变量
2. ✅ 使用运行时环境变量注入密钥（不硬编码）
3. ✅ 确保 API 端点包含 `/v1` 前缀
4. ✅ 添加健康检查

**预期结果**：
- ✅ LLM 调用成功（200 OK）
- ✅ 不再出现 401/404 错误
- ✅ 工作流正常运行
