File size: 9,687 Bytes
ab1ad86
 
 
 
 
 
 
1ee9de7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ab1ad86
 
 
 
1ee9de7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6c8af71
 
1ee9de7
6c8af71
 
 
 
 
 
 
 
1ee9de7
 
6c8af71
 
 
1ee9de7
 
 
 
6c8af71
 
 
 
 
1ee9de7
 
6c8af71
 
 
 
1ee9de7
 
 
 
 
6c8af71
 
 
 
 
 
 
1ee9de7
 
 
6c8af71
 
 
1ee9de7
 
 
6c8af71
 
 
 
1ee9de7
6c8af71
 
 
1ee9de7
 
 
 
 
 
 
 
 
 
 
 
 
 
ab1ad86
1ee9de7
ab1ad86
1ee9de7
 
 
 
 
 
 
 
 
ab1ad86
1ee9de7
 
 
 
 
 
ab1ad86
1ee9de7
ab1ad86
1ee9de7
 
 
 
 
 
ab1ad86
1ee9de7
ab1ad86
1ee9de7
 
 
ab1ad86
1ee9de7
 
 
 
ab1ad86
1ee9de7
 
 
 
ab1ad86
 
1ee9de7
ab1ad86
1ee9de7
ab1ad86
1ee9de7
ab1ad86
1ee9de7
 
 
 
 
ab1ad86
1ee9de7
ab1ad86
6c8af71
ab1ad86
6c8af71
ab1ad86
6c8af71
 
 
 
 
 
 
ab1ad86
1ee9de7
 
 
 
 
 
 
6c8af71
 
 
 
 
1ee9de7
 
 
 
 
 
 
ab1ad86
1ee9de7
6c8af71
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
# 📑 技术规格说明(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支持不同语言的求职信生成