backend/ai-service/README.zh.md
AI Service 是一个基于 FastAPI 构建的综合性智能服务平台,集成了多种 AI 能力和完整的积分管理系统。平台提供了聊天对话、OCR 文字识别、验证码识别等核心功能,并通过积分机制实现服务使用的精细化管理。
/v1/chat/completions)/v1/models)/ocr/general)/jfbym/customApi)/admin)| 组件 | 技术选型 | 版本要求 |
|---|---|---|
| 后端框架 | FastAPI | >=0.115.12 |
| Python | Python | >=3.13 |
| 数据库 | MySQL + SQLAlchemy | >=2.0.41 |
| 缓存 | Redis | >=6.1.0 |
| 异步支持 | asyncio + aiomysql | >=0.2.0 |
| 配置管理 | Pydantic Settings | >=2.9.1 |
| 容器化 | Docker + Docker Compose | - |
| 测试框架 | pytest + pytest-asyncio | >=8.3.5 |
| 代码质量 | Ruff | >=0.11.11 |
| 加密支持 | bcrypt + cryptography | >=4.3.0 |
ai-service/
├── app/ # 应用主目录
│ ├── main.py # FastAPI 应用入口
│ ├── config.py # 配置管理
│ ├── database.py # 数据库连接和会话管理
│ ├── redis_op.py # Redis 连接池管理
│ ├── logger.py # 日志配置
│ ├── dependencies/ # 依赖注入模块
│ │ ├── __init__.py # 通用依赖
│ │ └── points.py # 积分相关依赖
│ ├── models/ # 数据模型
│ │ ├── __init__.py
│ │ └── point.py # 积分相关模型
│ ├── schemas/ # Pydantic 数据模式
│ │ ├── chat.py # 聊天接口模式
│ │ ├── ocr.py # OCR 接口模式
│ │ └── jfbym.py # 验证码接口模式
│ ├── routers/ # API 路由
│ │ ├── ocr.py # OCR 路由
│ │ ├── jfbym.py # 验证码路由
│ │ └── v1/
│ │ ├── chat.py # 聊天路由
│ │ └── models.py # 模型管理路由
│ ├── services/ # 业务逻辑服务
│ │ └── point.py # 积分管理服务
│ ├── utils/ # 工具函数
│ │ ├── ocr.py # OCR 工具
│ │ └── jfbym.py # 验证码工具
│ ├── middlewares/ # 中间件
│ │ └── tracing.py # 请求追踪中间件
│ └── internal/ # 内部管理接口
│ └── admin.py # 管理员接口
├── tests/ # 测试代码
│ ├── conftest.py # 测试配置
│ ├── test_main.py # 主应用测试
│ └── routers/ # 路由测试
├── logs/ # 日志目录(如 app.log)
├── docker-compose.yml # 生产环境 Docker Compose
├── docker-compose.test.yaml # 测试环境 Docker Compose
├── Dockerfile # Docker 镜像构建
├── pyproject.toml # 项目依赖配置
├── uv.lock # uv 依赖锁定文件
└── README.md # 项目说明文档
git clone <repository-url>
cd ai-service
# 使用 pip 安装
pip install -e .
# 或使用 uv (推荐)
uv sync
推荐使用 uv 进行依赖管理,
uv.lock文件已锁定依赖版本,确保环境一致性。
编辑 .env 文件,配置必要的环境变量:
# 数据库配置
DATABASE_URL=mysql+aiomysql://username:password@localhost:3306/ai_service
DATABASE_USERNAME=your_db_username
DATABASE_PASSWORD=your_db_password
# Redis 配置
REDIS_URL=redis://localhost:6379/0
# AI 聊天服务配置
AICHAT_BASE_URL=https://api.deepseek.com/v1/
AICHAT_API_KEY=your_deepseek_api_key
# 讯飞 OCR 配置
XFYUN_APP_ID=your_xfyun_app_id
XFYUN_API_SECRET=your_xfyun_api_secret
XFYUN_API_KEY=your_xfyun_api_key
# 云码验证码配置
JFBYM_API_TOKEN=your_jfbym_token
# 积分策略配置,这个也可以不配置,使用默认的 .env.default
MONTHLY_GRANT_AMOUNT=100000
AICHAT_POINTS_COST=100
OCR_GENERAL_POINTS_COST=50
JFBYM_POINTS_COST=10
uv run python run.py dev
访问 http://localhost:8010/docs 查看 API 文档。
配置环境变量
创建 .env 文件并配置相关环境变量。
启动服务
docker-compose up -d
查看服务状态
docker-compose ps
docker-compose logs -f app
启动测试依赖服务
docker-compose -f docker-compose.test.yaml up -d
运行测试
pytest
所有 API 请求需要在请求头中包含用户 ID:
X-User-Id: 123
# 或
user_id: 123
POST /v1/chat/completions
{
"model": "deepseek-chat",
"messages": [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Hello!"}
],
"stream": false,
"temperature": 0.7,
"max_tokens": 4096
}
POST /ocr/general
{
"image": "base64_encoded_image_string",
"encoding": "jpg",
"status": 3
}
POST /jfbym/customApi
{
"type": "验证码类型",
"image": "base64_encoded_image_string"
}
响应格式:
{
"code": 10000,
"message": "success",
"data": {
"code": 0,
"data": "识别结果"
}
}
错误响应:
{
"code": 400,
"message": "云码验证码处理失败: 具体错误信息",
"data": null
}
GET /admin/user/points?user_id=123
POST /admin/user/points?user_id=123&amount=1000
| 配置项 | 默认值 | 说明 |
|---|---|---|
MONTHLY_GRANT_AMOUNT | 100000 | 月度自动发放积分数量 |
AICHAT_POINTS_COST | 100 | AI 聊天每次请求消耗积分 |
OCR_GENERAL_POINTS_COST | 50 | OCR 识别每次消耗积分 |
JFBYM_POINTS_COST | 10 | 验证码识别每次消耗积分 |
| 配置项 | 默认值 | 说明 |
|---|---|---|
LOG_LEVEL | INFO | 日志级别(DEBUG, INFO, WARNING, ERROR) |
LOG_DIR | /var/log/ai_service | 日志文件存储目录 |
# 启动测试数据库
docker-compose -f docker-compose.test.yaml up -d
# 运行所有测试
pytest
# 运行特定测试文件
pytest tests/routers/test_chat.py
# 运行测试并显示覆盖率
pytest --cov=app
# 格式化代码
ruff format
# 检查代码质量
ruff check
# 修复可自动修复的问题
ruff check --fix
# 实时查看应用日志
tail -f logs/app.log
app/routers/ 下创建新的路由文件app/schemas/ 下定义数据模式app/utils/ 下实现具体逻辑app/main.py 中注册路由app/models/point.py 中的 PointTransactionType 枚举添加新类型PointChecker 依赖注入进行积分检查和扣除注意:添加新的积分类型后,需要手动升级数据库,生产环境不建议这么做。
LOG_LEVEL 环境变量配置(默认:INFO)LOG_DIR 环境变量配置(默认:/var/log/ai_service)每个请求都会分配唯一的 Request ID,便于问题排查:
2025-06-03 10:30:15 - app.main - [abc-123-def] - INFO - Root endpoint accessed!
A: 可以通过管理员接口手动扣除用户当前所有积分,然后重新添加:
# 1. 查询用户当前积分
curl -X GET "http://localhost:8010/admin/user/points?user_id=123"
# 2. 扣除所有积分
curl -X POST "http://localhost:8010/admin/user/points/deduct?user_id=123&amount=当前积分数"
# 3. 添加新的积分
curl -X POST "http://localhost:8010/admin/user/points?user_id=123&amount=新积分数"
A: 系统会自动检查用户积分,如果不足会返回 403 状态码。用户需要联系管理员添加积分或等待月度自动发放。
A: 可以通过以下方式监控:
/ 检查服务是否正常响应A:
备份:
# 备份 MySQL 数据
docker exec mysql_container mysqldump -u root -p ai_service > backup.sql
# 备份 Redis 数据
docker exec redis_container redis-cli BGSAVE
恢复:
# 恢复 MySQL 数据
docker exec -i mysql_container mysql -u root -p ai_service < backup.sql
A: 验证码识别失败时,系统会返回详细的错误信息:
所有错误信息都是中文,便于用户理解。
A: 确保:
RequestTracingMiddleware 中间件RequestIdFilter%(request_id)s如果仍有问题,可以检查日志配置和中间件是否正确加载。