13 KiB
13 KiB
inclusion
| 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
│ ├─ resume_extractor/ # 简历 AI 提取模块
│ │ ├─ prompts.py # 5 个提取任务的 System Prompt(个人信息/教育/工作+实习/项目/竞赛)
│ │ └─ extractor.py # AI 并行提取(extract_all 入口,asyncio.gather 5 路并行)
│ ├─ resume_diagnoser/ # 简历 AI 诊断模块
│ │ ├─ prompts.py # 诊断 Prompt 模板(分模块诊断 + 汇总评价 + 润色优化)
│ │ └─ diagnoser.py # AI 并行诊断(diagnose_all 入口 + generate_summary 汇总评价 + polish_content 润色优化)
│ ├─ skill_gap_analyzer/ # 技能差距分析 + 定制简历 AI 模块
│ │ ├─ prompts.py # 差距分析 + 简历优化 + Agent 规划(原子化操作)/ 单条记录修改 / 新增记录 Prompt 模板 + MODULE_SCHEMAS
│ │ └─ analyzer.py # AI 调用逻辑(差距分析 + summary优化 + 经历优化 + Agent规划 + 单条记录修改 + 新增记录)
│ └─ job_agent/ # 求职助手 Agent 对话 AI 模块
│ ├─ prompts.py # 对话 System Prompt 模板
│ └─ chat.py # AI 对话引擎(构造 prompt + 拼 messages + 调 LLM + 解析返回)
│
├─ api/ # **路由层**(REST API 接口)
│ ├─ health.py # 健康检查接口 GET /health/
│ ├─ resume.py # 简历接口 POST /resume/upload(上传文件AI解析)
│ ├─ resume_diagnose.py # 简历诊断接口(POST 触发诊断 / GET 查询报告 / PUT 标记处理+用户评价 / POST 润色优化)
│ ├─ skill_gap.py # 技能差距分析 + 定制简历接口(差距分析 / 生成定制简历 / 查询 / 编辑 / 回滚 / AI对话编辑)
│ └─ job_agent_chat.py # 求职助手对话接口 POST /job-agent/chat
│
├─ 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)
│ ├─ user_resume.py # 用户简历主表(bg_user_resume)
│ ├─ user_resume_education.py # 简历-教育经历表(bg_user_resume_education)
│ ├─ user_resume_work.py # 简历-工作经历表(bg_user_resume_work)
│ ├─ user_resume_internship.py # 简历-实习经历表(bg_user_resume_internship)
│ ├─ user_resume_project.py # 简历-项目经历表(bg_user_resume_project)
│ ├─ user_resume_competition.py # 简历-竞赛经历表(bg_user_resume_competition)
│ ├─ resume_diagnosis_report.py # 简历诊断报告表(bg_resume_diagnosis_report)
│ ├─ resume_diagnosis_issue.py # 简历诊断问题表(bg_resume_diagnosis_issue)
│ ├─ job.py # 岗位表(bg_job,只读,用于技能差距分析)
│ └─ job_agent_config.py # 求职助手配置表(bg_job_agent_config)
│
├─ tool/ # **工具层**(无状态、无业务依赖的通用工具)
│ ├─ file_parser.py # 文件解析工具(PDF/Word/TXT → 纯文本,parse_to_text 入口方法)
│ ├─ json_helper.py # AI 输出 JSON 解析工具(自动去除 markdown 代码块包裹 + json_repair 容错,parse_llm_json 入口方法)
│ └─ snowflake.py # 雪花 ID 生成工具(next_id)
│
├─ schemas/ # **Schema 层**(Pydantic 请求/响应/缓存模型)
│ ├─ skill_gap.py # 技能差距分析 Schema(SkillGapParam、CustomizeResumeParam、AiEditParam)
│ ├─ customize_resume.py # 定制简历 Schema(CustomizeResume、ResumeProfile、Education、Work、Internship、Project、Competition、Paragraph)
│ └─ job_agent_chat.py # 求职助手对话 Schema(JobAgentChatParam、JobAgentChatDto、ToolParams)
│
└─ services/ # **业务逻辑层**
├─ func_permission_service.py # 功能权限服务(校验+扣减+回退,逻辑与Java端一致)
├─ resume_parse_service.py # 简历解析服务(文件解析→AI结构化→写入主表+5张子表)
├─ resume_diagnose_service.py # 简历诊断服务(加载简历→AI并行诊断→统计评级→写入报告)
├─ skill_gap_service.py # 技能差距分析服务(差距分析→定制简历生成→AI对话编辑)
├─ resume_loader.py # 简历统一查询模块(按ID查/自动选默认+5张子表,返回 ResumeDetail dataclass)
├─ customize_resume_store.py # 定制简历 Redis 存取模块(保存自动回滚备份、查询、回滚)
└─ job_agent_chat_service.py # 求职助手对话服务(查简历→序列化→调AI模块完成对话)
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 模型管理 + 业务 AI 能力 | LLM 枚举、resume_extractor/(简历并行提取)、resume_diagnoser/(简历诊断)、skill_gap_analyzer/(技能差距分析 + 定制简历优化 + Agent 原子化规划 + 单条记录修改/新增)、job_agent/(求职助手对话) |
| api | REST API 路由定义 | health.py(健康检查)、resume.py(简历上传解析)、resume_diagnose.py(简历诊断)、skill_gap.py(技能差距分析 + 定制简历)、job_agent_chat.py(求职助手对话) |
| models | SQLAlchemy ORM 模型,与 Java 端共享同一数据库 | FuncPermission、UserFuncPermissionStock、UserFuncUsageLog、UserResume、UserResumeEducation/Work/Internship/Project/Competition、ResumeDiagnosisReport、ResumeDiagnosisIssue、Job(只读)、JobAgentConfig |
| tool | 无状态通用工具,不依赖数据库/Redis/用户上下文 | file_parser.py(PDF/Word/TXT 文件解析为纯文本)、json_helper.py(AI 输出 JSON 解析,去 markdown 代码块 + json_repair 容错)、snowflake.py(雪花ID生成) |
| services | 业务逻辑实现 | FuncPermissionService(功能权限校验、扣减、回退)、ResumeParseService(简历文件解析→AI结构化→入库)、ResumeDiagnoseService(简历诊断→AI并行分析→评级→入库)、SkillGapService(技能差距分析→定制简历生成→AI对话编辑)、resume_loader(简历统一查询,返回ResumeDetail)、customize_resume_store(定制简历Redis存取,自动回滚备份)、JobAgentChatService(求职助手对话→查简历→调AI模块) |
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,其次 HeaderToken - 白名单路径(
/health/**、/docs/**、/redoc/**、/openapi.json)跳过鉴权 - 功能权限校验通过
func_permission(func_code)依赖注入实现,逻辑与 Java 端FuncPermissionAspect完全一致:- 校验每日免费额度
- 查付费库存(时间+次数维度)
- SQL 原子扣减
- 业务异常自动回退
6️⃣ AI 模型配置
| 供应商 | 模型 | 枚举值 |
|---|---|---|
| 火山引擎 | doubao-1-5-pro-32k-250115 | LLM.DOUBAO_PRO_32K |
| 火山引擎 | deepseek-v3-250324 | LLM.DEEPSEEK_V3 |
| 火山引擎 | deepseek-r1-250528 | LLM.DEEPSEEK_R1 |
| 火山引擎 | doubao-seed-2-0-lite-260215 | LLM.DOUBAO_SEED_LITE |
| 火山引擎 | doubao-seed-2-0-pro-260215 | LLM.DOUBAO_SEED_PRO |
| 加鱼 | gpt-4o | LLM.GPT_4O |
| 接口 | gpt-4o-mini | LLM.GPT_4O_MINI |
| 接口 | gemini-2.5-flash | LLM.GEMINI_FLASH |
| 加鱼 | claude-sonnet-4.5 | LLM.JIAYU_CLAUDE_SONNET_4_5 |
| 加鱼 | claude-haiku-4.5 | LLM.JIAYU_CLAUDE_HAIKU_4_5 |
| 加鱼 | deepseek-3.2 | LLM.JIAYU_DEEPSEEK_3_2 |
| 加鱼 | glm-5 | LLM.JIAYU_GLM_5 |
| 加鱼 | qwen3-coder-next | LLM.JIAYU_QWEN3_CODER_NEXT |
| 加鱼 | minimax-m2.5 | LLM.JIAYU_MINIMAX_M2_5 |
所有模型通过 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文件控制环境变量