121 lines
7.5 KiB
Markdown
121 lines
7.5 KiB
Markdown
---
|
||
inclusion: manual
|
||
---
|
||
|
||
# OfferPie Python AI 项目结构说明
|
||
|
||
## 1️⃣ 项目整体层次
|
||
```
|
||
offerpie_python_ai/
|
||
│
|
||
├─ .env / .env.test / .env.prod # 环境变量配置(dev/test/prod)
|
||
├─ requirements.txt # Python 依赖清单
|
||
│
|
||
└─ app/ # 应用主目录
|
||
├─ main.py # FastAPI 应用入口(注册异常处理、中间件、CORS、路由)
|
||
├─ banner.txt # 启动 Banner
|
||
│
|
||
├─ config/ # **配置层**
|
||
│ └─ settings.py # Pydantic Settings 统一配置(环境、数据库、Redis、LLM供应商、JWT、CORS、日志等)
|
||
│
|
||
├─ core/ # **核心基础设施层**
|
||
│ ├─ auth.py # 权限校验依赖(require_login、func_permission 装饰器)
|
||
│ ├─ context.py # 请求上下文变量(RequestContext:request_id、user_id)
|
||
│ ├─ database.py # SQLAlchemy 异步引擎 + 会话工厂(init_db、close_db、get_db)
|
||
│ ├─ redis.py # Redis 异步连接池(init_redis、close_redis、get_redis)
|
||
│ ├─ lifespan.py # FastAPI 生命周期管理(启动初始化 DB/Redis,关闭释放资源)
|
||
│ ├─ logger.py # Loguru 日志配置(控制台+文件,自动注入 request_id/user_id)
|
||
│ ├─ middleware.py # 中间件注册(RequestID、JWT鉴权、登录拦截、请求日志、响应统一包装)
|
||
│ ├─ exceptions.py # 全局异常处理器(HTTP异常、验证异常、断言异常、未知异常)
|
||
│ └─ schemas/
|
||
│ └─ responses.py # 统一响应模型 StandardResponse(code/msg/data/timestamp/uuid)
|
||
│
|
||
├─ ai/ # **AI 能力层**
|
||
│ └─ models.py # LLM 模型枚举(LLM.DOUBAO_PRO_256K、DEEPSEEK_V3、GPT_4O 等),基于 LangChain ChatOpenAI
|
||
│
|
||
├─ api/ # **路由层**(REST API 接口)
|
||
│ └─ health.py # 健康检查接口 GET /health/
|
||
│
|
||
├─ models/ # **ORM 模型层**(SQLAlchemy 声明式映射)
|
||
│ ├─ func_permission.py # 功能权限定义表(bg_func_permission)
|
||
│ ├─ user_func_permission_stock.py # 用户功能权限库存表(bg_user_func_permission_stock)
|
||
│ └─ user_func_usage_log.py # 用户功能使用记录表(bg_user_func_usage_log)
|
||
│
|
||
├─ tool/ # **工具层**(无状态、无业务依赖的通用工具)
|
||
│ └─ file_parser.py # 文件解析工具(PDF/Word/TXT → 纯文本,parse_to_text 入口方法)
|
||
│
|
||
└─ services/ # **业务逻辑层**
|
||
└─ func_permission_service.py # 功能权限服务(校验+扣减+回退,逻辑与Java端一致)
|
||
```
|
||
|
||
## 2️⃣ 各层模块职责
|
||
| 层级 | 主要职责 | 关键类/文件 |
|
||
|------|----------|-------------|
|
||
| **config** | 统一配置管理,基于 Pydantic Settings,支持 .env 文件加载 | `Settings`(数据库、Redis、LLM供应商、JWT、CORS、日志等全部配置项) |
|
||
| **core** | 核心基础设施:数据库连接、Redis连接、鉴权、日志、中间件、异常处理、统一响应 | `database.py`、`redis.py`、`auth.py`、`middleware.py`、`exceptions.py`、`logger.py`、`StandardResponse` |
|
||
| **ai** | AI 模型管理,封装多供应商 LLM 实例创建,基于 LangChain ChatOpenAI | `LLM` 枚举(火山引擎:doubao/deepseek,心缘:gpt-4o/claude) |
|
||
| **api** | REST API 路由定义 | `health.py`(健康检查) |
|
||
| **models** | SQLAlchemy ORM 模型,与 Java 端共享同一数据库 | `FuncPermission`、`UserFuncPermissionStock`、`UserFuncUsageLog` |
|
||
| **tool** | 无状态通用工具,不依赖数据库/Redis/用户上下文 | `file_parser.py`(PDF/Word/TXT 文件解析为纯文本) |
|
||
| **services** | 业务逻辑实现 | `FuncPermissionService`(功能权限校验、扣减、回退) |
|
||
|
||
## 3️⃣ 技术栈
|
||
| 类别 | 技术选型 | 说明 |
|
||
|------|----------|------|
|
||
| **Web 框架** | FastAPI + Uvicorn + Gunicorn | 异步 ASGI 框架 |
|
||
| **ORM** | SQLAlchemy 2.0 (asyncio) + asyncmy | 异步 MySQL 驱动 |
|
||
| **缓存** | redis-py (asyncio) | 异步 Redis 客户端 |
|
||
| **AI/LLM** | LangChain + LangChain-OpenAI + LangGraph | AI 编排框架,兼容 OpenAI 协议的多供应商接入 |
|
||
| **配置** | Pydantic Settings + python-dotenv | 类型安全的环境变量管理 |
|
||
| **日志** | Loguru | 结构化日志,自动注入请求上下文 |
|
||
| **鉴权** | PyJWT | JWT 解析,与 Java 端共享同一 jwt_secret |
|
||
| **数据处理** | Pandas + NumPy | 数据分析与处理 |
|
||
| **HTTP** | httpx | 异步 HTTP 客户端 |
|
||
| **文件解析** | pdfplumber + python-docx | PDF 和 Word 文件内容提取 |
|
||
|
||
## 4️⃣ 中间件执行链(由外到内)
|
||
| 顺序 | 中间件 | 职责 |
|
||
|------|--------|------|
|
||
| 1 | `RequestIDMiddleware` | 生成 ShortUUID 请求ID,写入响应头 X-Request-ID |
|
||
| 2 | `JwtAuthMiddleware` | 从 Cookie/Header 解析 JWT,校验 Redis 登录信息,续期,写入 RequestContext.user_id |
|
||
| 3 | `AuthRequiredMiddleware` | 非白名单路径必须有 user_id,否则返回 401 |
|
||
| 4 | `RequestLogMiddleware` | 记录请求方法、URL、参数、响应状态码和耗时 |
|
||
| 5 | `ResponseWrapMiddleware` | 将业务路由的 JSON 响应统一包装为 StandardResponse 格式 |
|
||
|
||
## 5️⃣ 鉴权体系
|
||
- 与 Java 端共享同一 JWT Secret 和 Redis 登录信息
|
||
- Token 来源:优先 Cookie `Token`,其次 Header `Token`
|
||
- 白名单路径(`/health/**`、`/docs/**`、`/redoc/**`、`/openapi.json`)跳过鉴权
|
||
- 功能权限校验通过 `func_permission(func_code)` 依赖注入实现,逻辑与 Java 端 `FuncPermissionAspect` 完全一致:
|
||
1. 校验每日免费额度
|
||
2. 查付费库存(时间+次数维度)
|
||
3. SQL 原子扣减
|
||
4. 业务异常自动回退
|
||
|
||
## 6️⃣ AI 模型配置
|
||
| 供应商 | 模型 | 枚举值 |
|
||
|--------|------|--------|
|
||
| 火山引擎 | doubao-pro-256k | `LLM.DOUBAO_PRO_256K` |
|
||
| 火山引擎 | doubao-pro-32k | `LLM.DOUBAO_PRO_32K` |
|
||
| 火山引擎 | doubao-lite-128k | `LLM.DOUBAO_LITE_128K` |
|
||
| 火山引擎 | deepseek-v3-250324 | `LLM.DEEPSEEK_V3` |
|
||
| 火山引擎 | deepseek-r1-250528 | `LLM.DEEPSEEK_R1` |
|
||
| 心缘 | gpt-4o | `LLM.GPT_4O` |
|
||
| 心缘 | gpt-4o-mini | `LLM.GPT_4O_MINI` |
|
||
| 心缘 | claude-sonnet-4-20250514 | `LLM.CLAUDE_SONNET_4` |
|
||
|
||
所有模型通过 `LLM.XXX.create(**kwargs)` 创建 LangChain `ChatOpenAI` 实例,kwargs 透传 temperature、max_tokens 等参数。
|
||
|
||
## 7️⃣ 与 Java 后端的关系
|
||
- **共享数据库**:Python 端与 Java 端(back-end)连接同一 MySQL 数据库(offerpie),ORM 模型对应相同的表
|
||
- **共享 Redis**:共享登录态(`login:token:{userId}`),JWT Secret 一致
|
||
- **共享权限体系**:功能权限校验逻辑与 Java 端 `FuncPermissionAspect` 完全对齐
|
||
- **职责分工**:Java 端负责业务 CRUD(用户、简历、岗位等),Python 端负责 AI 能力(LLM 调用、智能分析等)
|
||
|
||
## 8️⃣ 构建与运行
|
||
- **虚拟环境**:项目使用 `.venv` 目录管理 Python 虚拟环境
|
||
- **依赖安装**:`pip install -r requirements.txt`
|
||
- **开发启动**:`python -m app.main`(默认 ENV=dev,端口由 settings.server_port 控制)
|
||
- **生产部署**:通过 Gunicorn + Uvicorn Worker 运行
|
||
- **环境切换**:通过 `.env` / `.env.test` / `.env.prod` 文件控制环境变量
|