Files
offerpai_python_ai/.kiro/steering/项目结构说明.md
T

199 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
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 # 请求上下文变量(RequestContextrequest_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 # 统一响应模型 StandardResponsecode/msg/data/timestamp/uuid
├─ ai/ # **AI 能力层**
│ ├─ models.py # LLM 模型枚举(LLM.DOUBAO_PRO_32K、DEEPSEEK_V3、GPT_4O 等),基于 LangChain ChatOpenAI
│ ├─ model_config.py # AI 模型场景配置(集中管理各模块的模型选择与参数,业务代码引用此文件而非直接使用 LLM 枚举)
│ ├─ 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 + 岗位简历优化 Prompt 模板
│ │ ├─ chat.py # AI 对话引擎(构造 prompt + 拼 messages + 调 LLM + 解析返回)
│ │ └─ resume_optimizer.py # 岗位简历优化 AI 引擎(summary优化 + 经历优化,独立 chain)
│ └─ nova_chat/ # Nova 对话助手 AI 模块
│ ├─ prompts.py # Nova 对话 System Prompt(岗位匹配评估 + 简历优化建议 + 通用求职对话)
│ └─ chat.py # Nova 对话 AI 引擎(拼 prompt + 调 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对话编辑)
│ ├─ customize_resume.py # 定制简历接口(查询 / 修改 / 回滚)
│ ├─ job_agent_chat.py # 求职助手接口(POST /job-agent/chat 对话、POST /job-agent/optimize-resume 岗位简历优化)
│ └─ nova_chat.py # Nova 对话助手接口(POST /nova-chat/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
│ └─ user_job_customize_resume.py # 用户岗位定制简历表(bg_user_job_customize_resume
├─ 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 # 技能差距分析 SchemaSkillGapParam、CustomizeResumeParam、AiEditParam
│ ├─ customize_resume.py # 定制简历 SchemaCustomizeResume、ResumeProfile、Education、Work、Internship、Project、Competition、Paragraph
│ ├─ job_agent_chat.py # 求职助手对话 SchemaJobAgentChatParam、JobAgentChatDto、ToolParams
│ └─ nova_chat.py # Nova 对话助手 SchemaNovaChatParam、NovaChatDto
└─ 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模块完成对话)
└─ nova_chat_service.py # Nova 对话助手服务(查简历+查岗位(可选)→调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` 枚举(models.py)、`model_config.py`(场景模型配置)、`resume_extractor/`(简历并行提取)、`resume_diagnoser/`(简历诊断)、`skill_gap_analyzer/`(技能差距分析 + 定制简历优化 + Agent 原子化规划 + 单条记录修改/新增)、`job_agent/`(求职助手对话 + 岗位简历优化)、`nova_chat/`Nova 对话助手,纯对话) |
| **api** | REST API 路由定义 | `health.py`(健康检查)、`resume.py`(简历上传解析)、`resume_diagnose.py`(简历诊断)、`skill_gap.py`(技能差距分析 + 生成定制简历 + AI对话编辑)、`customize_resume.py`(定制简历查询/修改/回滚)、`job_agent_chat.py`(求职助手对话 + 岗位简历优化)、`nova_chat.py`Nova 对话助手) |
| **models** | SQLAlchemy ORM 模型,与 Java 端共享同一数据库 | `FuncPermission``UserFuncPermissionStock``UserFuncUsageLog``UserResume``UserResumeEducation`/`Work`/`Internship`/`Project`/`Competition``ResumeDiagnosisReport``ResumeDiagnosisIssue``Job`(只读)、`JobAgentConfig``UserJobCustomizeResume` |
| **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`(求职助手对话+岗位简历优化)、`NovaChatService`(Nova对话助手,查简历+查岗位→调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`,其次 Header `Token`
- 白名单路径(`/health/**``/docs/**``/redoc/**``/openapi.json`)跳过鉴权
- 功能权限校验通过 `func_permission(func_code)` 依赖注入实现,逻辑与 Java 端 `FuncPermissionAspect` 完全一致:
1. 校验每日免费额度
2. 查付费库存(时间+次数维度)
3. SQL 原子扣减
4. 业务异常自动回退
## 6️⃣ AI 模型配置
### 模型定义(`app/ai/models.py`
| 供应商 | 模型 | 枚举值 |
|--------|------|--------|
| 火山引擎 | doubao-1-5-pro-32k-250115 | `LLM.DOUBAO_PRO_32K` |
| 火山引擎 | doubao-1-5-lite-32k-250115 | `LLM.DOUBAO_LITE_32K` |
| 火山引擎 | deepseek-v3-250324 | `LLM.DEEPSEEK_V3` |
| 火山引擎 | deepseek-r1-250528 | `LLM.DEEPSEEK_R1` |
| 火山引擎 | doubao-seed-2-0-mini-260215 | `LLM.DOUBAO_SEED_MINI` |
| 火山引擎 | 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` |
| ZM | gpt-5.5 | `LLM.ZM_GPT_5_5` |
| ZM | gpt-5.4 | `LLM.ZM_GPT_5_4` |
| ZM | gpt-5.4-mini | `LLM.ZM_GPT_5_4_MINI` |
| ZM | gpt-5.2 | `LLM.ZM_GPT_5_2` |
所有模型通过 `LLM.XXX.create(**kwargs)` 创建 LangChain `ChatOpenAI` 实例,kwargs 透传 temperature、max_tokens 等参数。
### 场景模型配置(`app/ai/model_config.py`
业务代码**不直接使用** `LLM` 枚举,而是通过 `model_config.py` 中的场景配置类引用预创建的模型实例。修改模型或参数只需改此文件。
| 配置类 | 场景 | 说明 |
|--------|------|------|
| `SkillGapModel` | ANALYSIS / SUMMARY / EXPERIENCE / AGENT_PLAN / AGENT_EDIT / AGENT_ADD | 技能差距分析模块 |
| `JobAgentModel` | CHAT / SUMMARY / EXPERIENCE | 求职助手Agent模块 |
| `NovaChatModel` | CHAT | Nova智能聊天模块 |
| `ResumeExtractorModel` | PARSE | 简历解析模块 |
| `DiagnoserModel` | MODULE / SUMMARY / POLISH | 简历诊断模块 |
| `BrowserPlugModel` | FORM_FILL | 浏览器插件模块 |
业务代码引用示例:`from app.ai.model_config import SkillGapModel`,然后在 chain 中直接使用 `SkillGapModel.ANALYSIS`
## 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` 文件控制环境变量