apply-helper / docs /spec.md
hanbinChen's picture
Refactor LLM service and analysis logic for improved structure and error handling
6c8af71

📑 技术规格说明(SPR) — AI-powered Resume & Cover Letter Generator

1. 项目结构

apply-helper/
├── pyproject.toml           # 项目依赖与配置
├── uv.lock                  # UV 依赖锁定文件
├── .env.example             # 环境变量配置模板
├── src/                     # 源代码根目录
│   ├── streamlit_app.py     # Streamlit 前端主入口
│   ├── mock_data.py         # 测试用模拟数据
│   ├── services/            # 业务逻辑层
│   │   ├── __init__.py
│   │   ├── analyse_service.py   # JD/用户信息分析与总结
│   │   ├── generation_service.py # 简历与求职信生成
│   │   └── llm_service.py       # LLM/LiteLLM 统一封装与调用
│   └── llm/                     # LLM集成层
│       ├── __init__.py
│       ├── litellm_client.py    # LiteLLM API 封装
│       └── prompt_templates.py  # LLM Prompt 模板管理
├── docs/                    # 文档目录
│   ├── prd.md              # 产品需求文档
│   ├── spec.md             # 技术规格说明(本文件)
│   ├── services.spec.md    # 服务层规格说明
│   └── llm.spec.md         # LLM集成规格说明
└── tests/                  # 单元测试(待实现)

2. 主要 Python 文件与函数

2.1 src/streamlit_app.py — Streamlit 前端主入口

  • 页面布局: 侧边栏输入控制,主区域双列预览(简历 + 求职信)
  • 会话状态管理: 使用 st.session_state 持久化分析结果、生成文档和错误状态
  • 主要函数
    • main():应用入口,负责页面配置、UI渲染与交互逻辑
    • initialize_session_state():初始化会话状态变量
    • handle_analyse(jd: str, user_info: str):分析按钮回调,包含输入验证、调用服务、异常处理
    • handle_refine(feedback: str):优化按钮回调,基于反馈更新分析
    • handle_mock_analyse():模拟分析按钮回调,加载预设测试数据
  • 模拟数据功能: 三个按钮支持加载模拟JD、简历和完整分析结果
  • 错误处理: 集中化错误显示,用户友好提示信息

2.2 LLM 集成层

src/services/llm_service.py — LLM服务包装层

  • 核心功能: 提供LLM调用的统一接口,负责提示词模板格式化和LiteLLM调用
  • 主要函数:
    • analyse_llm(jd: str, user_info: str) -> str: 工作分析,返回原始LLM响应字符串
    • refine_llm(summary_json: str, feedback: str) -> str: 基于反馈优化分析,返回原始LLM响应
    • generate_resume_llm(summary_json: str, user_info: str) -> str: 生成Markdown格式简历
    • generate_cover_letter_llm(job_description: str, user_info: str) -> str: 生成德语求职信

src/llm/litellm_client.py — LiteLLM客户端集成

  • 多Provider支持: 优先支持Azure OpenAI,备用支持标准OpenAI
  • 自动配置: 基于环境变量自动检测和配置最优客户端
  • 主要函数:
    • call_llm(prompt: str, model: str = None, max_tokens: int = 800, temperature: float = 1.0) -> str
    • get_azure_client() -> dict: 配置Azure OpenAI客户端
    • get_openai_client() -> dict: 配置标准OpenAI客户端
    • 包含连接测试和调试模式,支持litellm debug

src/llm/prompt_templates.py — 提示词模板管理

  • 模板类型: analyse, refine, generate_resume, generate_cover_letter
  • 函数: get_template(name: str) -> str
  • 特点:
    • 字典存储,包含详细的JSON输出格式要求
    • ANALYSE_PROMPT: 德国科技市场专家角色,8-12个技能提取,4-6个匹配点分析
    • GENERATE_COVER_LETTER_PROMPT: 德语商务求职信生成,符合德国商务信函规范
    • 所有模板包含明确的输出格式要求和角色设定

核心处理逻辑

  • 提示词管理: 从模板获取提示词,使用Python字符串format动态替换参数
  • LLM调用: 通过LiteLLM统一接口调用不同provider的模型
  • 错误处理: LiteLLM层处理API调用异常,服务层处理业务逻辑异常
  • 响应处理: 返回原始字符串响应,由上层服务负责结构化解析

2.3 业务服务层

src/services/analyse_service.py — 分析服务

  • 功能: 职位描述与用户背景的匹配分析,使用Pydantic数据模型
  • 数据模型: AnalysisResult(BaseModel) - 结构化分析结果
    • key_skills: List[str] - 关键技能列表
    • match_points: List[str] - 匹配优势点
    • gap_points: List[str] - 技能差距点
    • suggestions: List[str] - 改进建议
    • pitch: str - 价值主张
  • 主要逻辑:
    • 验证输入参数非空
    • 委托LLM服务进行分析
    • _parse_analysis_response() - 复杂JSON解析逻辑,处理代码块包装
    • analyse() - 初始分析,返回AnalysisResult对象
    • refine() - 基于反馈优化分析,使用model_dump_json()序列化

src/services/generation_service.py — 文档生成服务

  • 功能: 编排简历和求职信的生成
  • 主要接口:
    • generate_resume(summary: AnalysisResult, user_info: str) -> str - 生成简历
    • generate_cover_letter(job_description: str, user_info: str) -> str - 生成求职信
    • generate_both(summary: AnalysisResult, user_info: str, job_description: str) -> Tuple[str, str] - 生成完整文档对
  • 主要逻辑:
    • 使用AnalysisResult对象和原始文本作为输入
    • 调用LLM服务生成简历(Markdown)和求职信(德语文本)
    • 支持动态导入处理,兼容模块和独立运行
    • 返回生成的文档元组

2.4 模拟数据系统

src/mock_data.py — 测试数据管理

  • MOCK_JD: 完整的高级软件工程师职位描述
  • MOCK_RESUME: John Smith 的详细简历信息
  • Analysis_Summary: 结构化分析结果(Dict格式)
    • key_skills, match_points, gap_points, suggestions, pitch
  • Resume: 生成的Markdown格式简历
  • Cover_Letter: 生成的纯文本求职信
  • 用途: 支持无需LLM调用的完整工作流测试

3. Streamlit UI 实现

3.1 页面布局

  • 侧边栏(Sidebar)

    • 模拟数据按钮: 三列布局 - "Load Mock JD", "Load Mock Resume", "Mock Analyse"
    • 输入区域:
      • Job Description 文本区域(高度150px)
      • User Resume/Info 文本区域(高度200px)
    • 控制按钮: "Analyse" 按钮(全宽)
    • 优化区域:
      • Feedback 文本区域(高度100px)
      • "Refine" 按钮(全宽)
  • 主区域(Main Area)

    • 错误显示: 使用 st.error() 显示异常信息
    • 分析摘要: 使用 st.json() 展示结构化分析结果
    • 双列预览:
      • 左列: Resume 预览(Markdown 渲染)
      • 右列: Cover Letter 预览(纯文本显示)

3.2 会话状态管理

状态变量:

  • summary - 分析摘要结果
  • resume_md - 生成的简历Markdown
  • cover_letter_txt - 生成的求职信文本
  • error - 错误信息显示
  • user_info_input - 用户输入缓存

3.3 交互流程

  1. 标准工作流:

    • 输入JD和用户信息 → 点击"Analyse" → 显示分析和生成结果
    • 输入反馈 → 点击"Refine" → 更新分析和重新生成
  2. 模拟数据工作流:

    • 点击"Load Mock JD" → 自动填充职位描述
    • 点击"Load Mock Resume" → 自动填充简历信息
    • 点击"Mock Analyse" → 直接加载完整分析结果
  3. 错误处理:

    • 输入验证: 检查空值,显示友好错误信息
    • 异常捕获: 包装在try-catch中,显示具体错误消息
    • 状态清理: 成功时清除error状态

4. 技术实现详情

4.1 依赖管理

核心依赖: streamlit (UI), litellm (LLM调用), python-dotenv (环境变量), weasyprint (PDF,未使用), pydantic (验证,未使用)

安装和运行:

  1. pip install uv - 安装包管理器
  2. uv sync - 同步依赖
  3. cp .env.example .env - 配置环境变量
  4. uv run streamlit run src/streamlit_app.py - 启动应用

4.2 LLM集成配置

多Provider支持: 优先Azure OpenAI,备用标准OpenAI

Azure OpenAI配置: AZURE_OPENAI_API_KEY, AZURE_OPENAI_ENDPOINT, AZURE_OPENAI_MODEL, AZURE_OPENAI_API_VERSION(默认2024-12-01-preview)

OpenAI配置: OPENAI_API_KEY(使用gpt-3.5-turbo模型)

配置逻辑:

  • 优先检测Azure配置,如果完整则使用Azure
  • Azure不可用时回退到标准OpenAI
  • 支持模型参数覆盖,但仅支持azure/前缀的模型
  • 包含详细的配置验证和错误提示

4.3 开发和测试

模拟数据测试:

  • 无需配置LLM即可测试完整UI流程
  • src/mock_data.py 包含完整测试数据集
  • 点击"Mock Analyse"按钮即可加载预设结果

调试和测试模式:

  • python src/llm/litellm_client.py - 测试LLM连接和配置验证
  • python src/services/analyse_service.py - 测试分析服务完整流程
  • python src/services/generation_service.py - 测试文档生成流程
  • 包含litellm._turn_on_debug()调试支持

4.4 架构特点

模块化设计:

  • 业务逻辑与UI分离
  • LLM集成层独立封装
  • 服务层薄包装,便于替换实现

扩展点:

  • 添加新的LLM provider: 扩展 litellm_client.py 中的客户端配置函数
  • 添加PDF导出: 实现 pdf_service.py 集成WeasyPrint
  • 添加新的生成模板: 在 prompt_templates.py 中添加新模板常量
  • 数据验证增强: 当前使用Pydantic AnalysisResult模型,可扩展更多验证模型
  • 多语言支持: 扩展prompt_templates支持不同语言的求职信生成