# 项目部署指南

本文档帮助你将初中物理作业批改工作流导出到自己的服务器上运行。

## 📋 目录
- [前置要求](#前置要求)
- [快速部署](#快速部署)
- [详细配置](#详细配置)
- [启动方式](#启动方式)
- [常见问题](#常见问题)

---

## 前置要求

### 1. 系统要求
- **操作系统**: Linux / macOS / Windows (推荐 Linux)
- **Python版本**: Python 3.10 或以上
- **内存**: 建议 4GB 以上
- **磁盘空间**: 建议 10GB 以上

### 2. 必需的第三方服务

本项目依赖以下第三方服务，**必须提前准备好**：

#### 大语言模型 API
- **推荐**: 火山引擎豆包大模型（本项目使用 `doubao-seed-2-0-pro-260215`）
- **替代方案**: 
  - OpenAI API
  - 其他兼容 OpenAI 格式的 API（如 DeepSeek、Kimi）
- **获取方式**: 
  - 火山引擎: https://console.volcengine.com/ark
  - OpenAI: https://platform.openai.com/

**注意**：
- ✅ **不需要配置对象存储**（S3/TOS/OSS 等）
- ✅ 图片直接使用原始URL，不上传存储
- ✅ Word文档使用 requests 直接下载，不涉及对象存储

---

## 快速部署

### 步骤 1: 导出项目代码

**方式一：从 Coze 平台下载**
```bash
# 在 Coze Coding 平台点击"导出项目"按钮
# 下载后解压到服务器
```

**方式二：使用 Git 克隆（如果有仓库地址）**
```bash
git clone <your-repo-url>
cd <project-directory>
```

### 步骤 2: 安装依赖

```bash
# 创建虚拟环境（推荐）
python3 -m venv venv
source venv/bin/activate  # Linux/macOS
# 或 venv\Scripts\activate  # Windows

# 安装依赖
pip install -r requirements.txt
```

### 步骤 3: 配置环境变量

创建 `.env` 文件（或在服务器环境变量中配置）：

```bash
# 必需环境变量（只需配置大模型API）
export LLM_API_KEY="your-api-key-here"
export LLM_BASE_URL="https://ark.cn-beijing.volces.com/api/v3"
export LLM_MODEL_NAME="doubao-seed-2-0-pro-260215"

# 可选：日志级别
export LOG_LEVEL="INFO"

# 注意：不需要配置对象存储（S3/TOS等）
```

### 步骤 4: 启动服务

```bash
# 方式1: 使用启动脚本（推荐）
bash scripts/http_run.sh -p 8000

# 方式2: 直接运行
python src/main.py -m http -p 8000
```

服务启动后，访问：
- 健康检查: `http://localhost:8000/health`
- API 文档: `http://localhost:8000/docs`（FastAPI 自动生成）

---

## 详细配置

### 1. 大语言模型配置

#### 方式一：使用火山引擎豆包大模型（推荐）

```bash
# 环境变量
export LLM_API_KEY="your-ark-api-key"
export LLM_BASE_URL="https://ark.cn-beijing.volces.com/api/v3"
export LLM_MODEL_NAME="doubao-seed-2-0-pro-260215"
```

**获取方式**：
1. 访问火山引擎控制台: https://console.volcengine.com/ark
2. 创建推理接入点
3. 获取 API Key

#### 方式二：使用 OpenAI API

需要修改代码中的模型配置文件（`config/*.json`），将 `model` 字段改为 OpenAI 模型：

```json
{
  "config": {
    "model": "gpt-4o",
    "temperature": 0.0
  }
}
```

环境变量：
```bash
export LLM_API_KEY="your-openai-api-key"
export LLM_BASE_URL="https://api.openai.com/v1"
export LLM_MODEL_NAME="gpt-4o"
```

### 2. ~~对象存储配置~~（已移除）

**重要更新（2026-03-27）**：
- ❌ 不需要配置对象存储
- ✅ 图片直接使用原始URL，不上传
- ✅ Word文档直接下载，不存储

**架构优化原因**：
1. AI模型足够强大，可以直接访问原始图片URL
2. 使用相对坐标系统（0-1000），自动适配任意尺寸
3. 减少存储成本和上传时间，处理速度更快

### 3. 修改代码适配自己的环境

#### 修改 LLM 调用逻辑

项目使用了 `coze-coding-dev-sdk`，需要修改为直接调用 OpenAI API：

**修改文件**: `src/graphs/nodes/doc_extract_node.py`、`src/graphs/nodes/recognize_and_correct_node.py`

**原代码**（使用 coze-coding-dev-sdk）：
```python
from coze_coding_dev_sdk import LLM

llm = LLM()
response = llm.invoke(messages)
```

**修改为**（直接使用 OpenAI SDK）：
```python
import os
from openai import OpenAI

client = OpenAI(
    api_key=os.getenv("LLM_API_KEY"),
    base_url=os.getenv("LLM_BASE_URL")
)

response = client.chat.completions.create(
    model=os.getenv("LLM_MODEL_NAME"),
    messages=messages
)
```

#### ~~修改对象存储逻辑~~（不需要）

**已移除**：2026-03-27 优化后，不再使用对象存储
- 图片直接使用原始URL
- Word文档使用 requests 下载
- 无需修改任何存储相关代码

### 4. 缓存配置（可选）

项目使用文件缓存来存储解析结果，默认缓存目录为 `/tmp/cache`。

如需修改缓存目录：
```bash
export CACHE_DIR="/your/custom/cache/dir"
```

---

## 启动方式

### 1. HTTP 服务模式（推荐生产环境）

```bash
# 使用启动脚本
bash scripts/http_run.sh -p 8000

# 或直接运行
python src/main.py -m http -p 8000
```

**特点**：
- 提供 REST API 接口
- 支持流式响应（SSE）
- 支持超时控制
- 支持任务取消

**API 接口**：
- `POST /run` - 同步运行工作流
- `POST /stream_run` - 流式运行工作流（SSE）
- `POST /cancel/{run_id}` - 取消运行
- `GET /health` - 健康检查
- `GET /graph_parameter` - 查看工作流参数

### 2. 命令行模式（本地测试）

```bash
# 运行整个工作流
python src/main.py -m flow -i '{"student_homework": [...], "answer_doc_url": "..."}'

# 运行单个节点
python src/main.py -m node -n doc_extract -i '{"answer_doc_url": "..."}'
```

### 3. Docker 部署（推荐）

创建 `Dockerfile`：

```dockerfile
FROM python:3.10-slim

WORKDIR /app

# 安装系统依赖
RUN apt-get update && apt-get install -y \
    gcc \
    && rm -rf /var/lib/apt/lists/*

# 复制依赖文件
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# 复制项目文件
COPY . .

# 暴露端口
EXPOSE 8000

# 启动命令
CMD ["python", "src/main.py", "-m", "http", "-p", "8000"]
```

构建和运行：
```bash
# 构建镜像
docker build -t homework-correction:v1 .

# 运行容器
docker run -d \
  --name homework-correction \
  -p 8000:8000 \
  -e LLM_API_KEY="your-api-key" \
  -e LLM_BASE_URL="https://ark.cn-beijing.volces.com/api/v3" \
  -e LLM_MODEL_NAME="doubao-seed-2-0-pro-260215" \
  homework-correction:v1
```

### 4. 使用 Docker Compose

创建 `docker-compose.yml`：

```yaml
version: '3.8'

services:
  homework-correction:
    build: .
    ports:
      - "8000:8000"
    environment:
      - LLM_API_KEY=${LLM_API_KEY}
      - LLM_BASE_URL=${LLM_BASE_URL}
      - LLM_MODEL_NAME=${LLM_MODEL_NAME}
    restart: unless-stopped
    volumes:
      - ./cache:/tmp/cache  # 持久化缓存
```

运行：
```bash
docker-compose up -d
```

---

## 常见问题

### Q1: 如何验证环境变量是否正确配置？

```bash
# 检查环境变量
echo $LLM_API_KEY
echo $LLM_BASE_URL
echo $S3_ACCESS_KEY

# 或在代码中打印
python -c "import os; print(os.getenv('LLM_API_KEY'))"
```

### Q2: 启动时报错 "ModuleNotFoundError: No module named 'xxx'"

**解决方案**：
```bash
# 确保在虚拟环境中
source venv/bin/activate

# 重新安装依赖
pip install -r requirements.txt
```

### Q3: LLM 调用失败，报错 "API key not found"

**原因**: 环境变量未正确设置

**解决方案**：
```bash
# 方式1: 在 .env 文件中配置
echo "export LLM_API_KEY='your-api-key'" >> ~/.bashrc
source ~/.bashrc

# 方式2: 在启动命令前设置
LLM_API_KEY="your-api-key" python src/main.py -m http -p 8000
```

### Q4: 如何测试工作流是否正常？

使用 curl 发送测试请求：

```bash
curl -X POST http://localhost:8000/run \
  -H "Content-Type: application/json" \
  -d '{
    "student_homework": [
      {
        "student_id": 0,
        "student_name": "测试学生",
        "homework_images": ["https://example.com/homework.jpg"]
      }
    ],
    "answer_doc_url": "https://example.com/answer.docx"
  }'
```

### Q5: 如何查看运行日志？

```bash
# 实时查看日志
tail -f /app/work/logs/bypass/app.log

# 或使用 Docker logs
docker logs -f homework-correction
```

### Q6: 性能优化建议

1. **并发控制**: 调整 `max_concurrent` 参数（默认10）
2. **超时设置**: 修改 `SINGLE_IMAGE_TIMEOUT` 常量（默认120秒）
3. **缓存优化**: 定期清理 `/tmp/cache` 目录
4. **资源监控**: 使用 `htop` 或 `docker stats` 监控资源使用

### Q7: 如何替换为其他 LLM 模型？

1. 修改环境变量：
```bash
export LLM_API_KEY="your-other-llm-api-key"
export LLM_BASE_URL="https://api.other-llm.com/v1"
export LLM_MODEL_NAME="other-model-id"
```

2. 修改配置文件（`config/*.json`）中的 `model` 字段

3. 测试调用是否正常

---

## 项目文件说明

```
├── src/
│   ├── main.py                    # 主入口
│   ├── graphs/
│   │   ├── graph.py               # 主工作流编排
│   │   ├── loop_graph.py          # 子图定义
│   │   ├── state.py               # 状态定义
│   │   └── nodes/                 # 节点实现
│   │       ├── doc_extract_node.py
│   │       ├── process_images_node.py
│   │       ├── recognize_and_correct_node.py
│   │       └── ...
│   └── utils/                     # 工具函数
│       ├── file/file.py           # 文件处理
│       └── cache_manager.py       # 缓存管理
├── config/                        # LLM 配置文件
│   ├── doc_extract_llm_cfg.json
│   ├── homework_correction_cfg.json
│   └── ...
├── scripts/                       # 启动脚本
│   ├── http_run.sh
│   └── local_run.sh
├── requirements.txt               # Python 依赖
└── README.md                      # 项目说明
```

---

## 技术支持

如遇到问题，请检查：
1. ✅ 环境变量是否正确配置
2. ✅ 依赖是否完整安装
3. ✅ 第三方服务（LLM、存储）是否可用
4. ✅ 日志文件中的错误信息

---

## 更新日志

- 2026-03-28: 添加缓存学科隔离，修复等级评定逻辑
- 2026-03-27: 移除图片上传，直接使用原始URL
- 2026-03-26: 优化坐标定位，修复识别问题
- 2026-03-25: 支持多学生多图片并行处理
