TeddyYao commited on
Commit
3733579
·
verified ·
1 Parent(s): a9f0320

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +178 -165
app.py CHANGED
@@ -1,194 +1,207 @@
1
  import streamlit as st
2
  import openai
3
  import logging
 
4
  from typing import Optional
5
 
6
  # 配置日志
7
- logging.basicConfig(level=logging.INFO)
8
 
9
- def generate_email(profile1: str, profile2: str, style: str = "friendly", temperature: float = 0.7) -> str:
 
 
 
 
 
 
10
  """
11
- 基于两个 LinkedIn 简介生成个性化的 Coffee Chat 邮件。
12
 
13
  参数:
14
- profile1 (str): 发送者的 LinkedIn 简介文本
15
- profile2 (str): 接收者的 LinkedIn 简介文本
16
  style (str): 邮件风格,可选项为 "formal", "friendly", "humorous"
17
- temperature (float): 控制生成内容的创造性,较高的值产生更多样化的结果
 
18
 
19
  返回:
20
- str: 生成的邮件文本
21
-
22
- 异常:
23
- Exception: 当 API 调用失败时抛出
24
- """
25
-
26
- # 验证输入参数
27
- if not profile1 or not profile2:
28
- raise ValueError("两个个人简介都不能为空")
29
-
30
- valid_styles = ["formal", "friendly", "humorous"]
31
- if style not in valid_styles:
32
- raise ValueError(f"风格必须是以下之一: {', '.join(valid_styles)}")
33
-
34
- if not 0 <= temperature <= 2:
35
- raise ValueError("temperature 参数必须在 0 到 2 之间")
36
-
37
- # 为不同风格构建指导
38
- style_guidance = {
39
- "formal": "保持专业和礼貌。使用正式语言和结构。",
40
- "friendly": "友好而专业。使用热情但不过分随意的语气。",
41
- "humorous": "适当使用幽默,同时保持专业。加入一两个轻松的评论,但不要过分。"
42
- }
43
-
44
- # 构建 GPT-4 的提示语
45
- prompt = f"""
46
- 我需要生成一封个性化的 Coffee Chat 邮件,邮件发送者和接收者的 LinkedIn 简介信息如下:
47
-
48
- 发送者简介:
49
- {profile1}
50
-
51
- 接收者简介:
52
- {profile2}
53
-
54
- 请分析这两个简介并找出所有有意义的共同点,如:
55
- - 共同的教育背景(大学、学位等)
56
- - 共同的工作经验或行业
57
- - 相似的技能、专业知识领域
58
- - 共同的兴趣爱好、志愿活动等
59
- - 共同的联系人或组织
60
-
61
- 基于这些共同点,编写一封邀请接收者进行 Coffee Chat 的邮件。邮件应该:
62
- 1. 包含个性化的开场白,提及你是如何找到对方的
63
- 2. 简短地介绍自己(不要重复简介中的所有内容)
64
- 3. 明确地提到你们的共同点,展示你已经研究过对方
65
- 4. 说明你联系的目的(Coffee Chat),并解释为什么你认为这次交谈对双方都有价值
66
- 5. 提出具体的后续行动建议
67
- 6. 以礼貌的结束语和签名结尾
68
-
69
- 邮件风格要求: {style_guidance[style]}
70
-
71
- 邮件应该自然流畅,就像一个真实的人写的,避免模板化的感觉。确保内容有深度但简明扼要,总长度应在 150-250 个单词之间。
72
-
73
- 只返回邮件正文,不包含任何解释或其他内容。
74
  """
75
-
76
  try:
77
- # 调用 OpenAI API
78
- response = openai.ChatCompletion.create(
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
79
  model="gpt-4",
80
- messages=[{"role": "user", "content": prompt}],
 
 
 
81
  temperature=temperature,
82
  max_tokens=1000
83
  )
84
 
85
- # 提取生成的邮件文本
86
  email_text = response.choices[0].message.content.strip()
87
  return email_text
88
 
 
 
 
 
 
 
89
  except Exception as e:
90
- logging.error(f"OpenAI API 调用失败: {str(e)}")
91
- raise Exception(f"生成邮件时出错: {str(e)}")
92
-
93
- # Streamlit 应用主函数
94
- def main():
95
- # 设置页面标题和图标
96
- st.set_page_config(
97
- page_title="Coffee Chat 邮件生成器",
98
- page_icon="☕",
99
- layout="wide"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
100
  )
101
 
102
- # 页面标题
103
- st.title("☕ Coffee Chat 邮件生成器")
104
- st.markdown("### 基于 LinkedIn 简介生成个性化的 Coffee Chat 邮件")
105
-
106
- # 侧边栏 - API 密钥配置
107
- with st.sidebar:
108
- st.header("设置")
109
- api_key = st.text_input("OpenAI API 密钥", type="password")
110
- if api_key:
111
- openai.api_key = api_key
112
-
113
- st.markdown("---")
114
- st.markdown("### 关于")
115
- st.markdown("这个工具帮助求职者生成个性化的 Coffee Chat 邮件,基于 LinkedIn 简介进行分析和匹配。")
116
-
117
- # 主要内容区域
118
- col1, col2 = st.columns(2)
119
-
120
- with col1:
121
- st.subheader("🧑‍💼 你的 LinkedIn 简介")
122
- profile1 = st.text_area(
123
- "粘贴你的 LinkedIn 简介文本",
124
- height=300,
125
- placeholder="例如: 我是一名在纽约金融科技公司工作的数据分析师,拥有哥伦比亚大学金融学硕士学位和4年工作经验。我精通 Python、SQL 和数据可视化..."
126
- )
127
-
128
- with col2:
129
- st.subheader("👨‍💻 目标联系人简介")
130
- profile2 = st.text_area(
131
- "粘贴目标联系人的 LinkedIn 简介文本",
132
- height=300,
133
- placeholder="例如: 资深投资银行家,摩根斯坦利副总裁,负责科技和金融行业并购。哥伦比亚大学 MBA,曾在多家初创企业担任顾问..."
134
- )
135
-
136
- # 配置选项
137
- st.subheader("⚙️ 邮件配置")
138
- col3, col4 = st.columns(2)
139
-
140
- with col3:
141
- style = st.selectbox(
142
- "邮件风格",
143
- options=["friendly", "formal", "humorous"],
144
- format_func=lambda x: {
145
- "friendly": "友好 (推荐)",
146
- "formal": "正式",
147
- "humorous": "幽默"
148
- }.get(x)
149
- )
150
 
151
- with col4:
152
- temperature = st.slider(
153
- "创造性程度",
154
- min_value=0.0,
155
- max_value=1.0,
156
- value=0.7,
157
- step=0.1,
158
- help="较低的值使输出更加可预测,较高的值使输出更加多样化和创造性"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
159
  )
160
-
161
- # 生成按钮
162
- if st.button("✨ 生成 Coffee Chat 邮件", type="primary", use_container_width=True):
163
- if not api_key:
164
- st.error("请在侧边栏中输入你的 OpenAI API 密钥")
165
- elif not profile1 or not profile2:
166
- st.error("请填写两个 LinkedIn 简介")
167
- else:
168
- try:
169
- with st.spinner("正在生成邮件..."):
170
- email = generate_email(profile1, profile2, style, temperature)
171
-
172
- # 显示结果
173
- st.subheader("📧 生成的邮件")
174
- st.success("邮件已生成!")
175
- st.markdown("---")
176
- st.markdown(email)
177
- st.markdown("---")
178
-
179
- # 复制按钮
180
- st.button(
181
- "📋 复制到剪贴板",
182
- on_click=lambda: st.write('<script>navigator.clipboard.writeText(`' + email.replace('`', '\\`') + '`);</script>', unsafe_allow_html=True)
183
- )
184
-
185
- except Exception as e:
186
- st.error(f"出错了: {str(e)}")
187
-
188
- # 页脚
189
- st.markdown("---")
190
- st.caption("注意: 请根据实际情况编辑生成的邮件内容,以确保准确性和个人风格。")
191
 
192
- # 运行应用
193
- if __name__ == "__main__":
194
- main()
 
 
 
 
 
 
 
1
  import streamlit as st
2
  import openai
3
  import logging
4
+ import os
5
  from typing import Optional
6
 
7
  # 配置日志
8
+ logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
9
 
10
+ def generate_email(
11
+ profile1: str,
12
+ profile2: str,
13
+ style: str = "friendly",
14
+ temperature: float = 0.7,
15
+ api_key: Optional[str] = None
16
+ ) -> str:
17
  """
18
+ 基于两个LinkedIn简介生成个性化咖啡聊天邀请邮件。
19
 
20
  参数:
21
+ profile1 (str): 发件人的LinkedIn简介文本
22
+ profile2 (str): 收件人的LinkedIn简介文本
23
  style (str): 邮件风格,可选项为 "formal", "friendly", "humorous"
24
+ temperature (float): 生成文本的创造性程度 (0.0-1.0)
25
+ api_key (str, optional): OpenAI API密钥,如果未提供则使用环境变量
26
 
27
  返回:
28
+ str: 生成的个性化咖啡聊天邮件
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  """
 
30
  try:
31
+ # 验证输入
32
+ if not profile1 or not profile2:
33
+ raise ValueError("两个简介都不能为空")
34
+
35
+ valid_styles = ["formal", "friendly", "humorous"]
36
+ if style not in valid_styles:
37
+ logging.warning(f"不支持的风格 '{style}',使用默认的 'friendly'")
38
+ style = "friendly"
39
+
40
+ if temperature < 0.0 or temperature > 1.0:
41
+ logging.warning(f"温度 {temperature} 超出范围,调整至 0.7")
42
+ temperature = 0.7
43
+
44
+ # 设置API密钥
45
+ if api_key:
46
+ openai.api_key = api_key
47
+
48
+ # 构建提示词
49
+ prompt = f"""
50
+ I need to write a personalized coffee chat invitation email based on two LinkedIn profiles.
51
+
52
+ MY PROFILE:
53
+ {profile1}
54
+
55
+ TARGET PERSON'S PROFILE:
56
+ {profile2}
57
+
58
+ TASK:
59
+ 1. Analyze both profiles to identify meaningful common points or connections (universities, companies, industries, skills, interests, etc.)
60
+ 2. Write a personalized coffee chat invitation email from me to the target person
61
+ 3. The email should:
62
+ - Start with a brief introduction of myself
63
+ - Mention 2-3 specific commonalities or interesting points from our profiles
64
+ - Express genuine interest in their work/experience
65
+ - Include a clear but polite request for a 15-30 minute coffee chat
66
+ - Suggest flexibility for their schedule
67
+ - End with a professional closing
68
+
69
+ STYLE:
70
+ The tone should be {style}. If formal: professional and respectful; if friendly: warm and conversational; if humorous: light and engaging but still professional.
71
+
72
+ IMPORTANT GUIDELINES:
73
+ - Keep the email concise (150-250 words)
74
+ - Make it feel authentic and human, not templated
75
+ - Focus on creating a genuine connection
76
+ - Avoid generic flattery
77
+ - Be specific about shared connections or interests
78
+ - Don't be pushy or demanding
79
+
80
+ Format the response as a complete, ready-to-send email without explanations.
81
+ """
82
+
83
+ # 调用OpenAI API
84
+ response = openai.chat.completions.create(
85
  model="gpt-4",
86
+ messages=[
87
+ {"role": "system", "content": "You are an expert email writer who helps professionals create personalized networking messages."},
88
+ {"role": "user", "content": prompt}
89
+ ],
90
  temperature=temperature,
91
  max_tokens=1000
92
  )
93
 
94
+ # 提取并返回生成的邮件
95
  email_text = response.choices[0].message.content.strip()
96
  return email_text
97
 
98
+ except ValueError as e:
99
+ logging.error(f"输入错误: {str(e)}")
100
+ return f"发生错误: {str(e)}"
101
+ except openai.OpenAIError as e:
102
+ logging.error(f"OpenAI API错误: {str(e)}")
103
+ return f"OpenAI API错误: {str(e)}"
104
  except Exception as e:
105
+ logging.error(f"意外错误: {str(e)}")
106
+ return f"发生未预期的错误: {str(e)}"
107
+
108
+ # 页面配置
109
+ st.set_page_config(
110
+ page_title="个性化咖啡聊天邮件生成器",
111
+ page_icon="☕",
112
+ layout="wide"
113
+ )
114
+
115
+ # 标题和说明
116
+ st.title("☕ 个性化咖啡聊天邮件生成器")
117
+ st.markdown("""
118
+ 此应用可以帮助求职者生成个性化的咖啡聊天邀请邮件。
119
+ 只需输入您的简介和目标联系人的简介,系统将分析共同点并生成一封真诚的邀请邮件。
120
+ """)
121
+
122
+ # 侧边栏 - API密钥设置
123
+ with st.sidebar:
124
+ st.header("设置")
125
+ api_key = st.text_input("OpenAI API密钥", type="password", key="api_key")
126
+ if api_key:
127
+ os.environ["OPENAI_API_KEY"] = api_key
128
+ else:
129
+ # 尝试从环境变量获取
130
+ api_key = os.environ.get("OPENAI_API_KEY")
131
+ if not api_key:
132
+ st.warning("请输入OpenAI API密钥以使用此应用")
133
+
134
+ st.subheader("邮件风格")
135
+ style = st.radio(
136
+ "选择风格:",
137
+ ["formal", "friendly", "humorous"],
138
+ index=1,
139
+ format_func=lambda x: {
140
+ "formal": "正式专业",
141
+ "friendly": "友好温暖",
142
+ "humorous": "幽默轻松"
143
+ }[x]
144
  )
145
 
146
+ temperature = st.slider("创造性程度", min_value=0.0, max_value=1.0, value=0.7, step=0.1,
147
+ help="较低的值使输出更可预测,较高的值使输出更创意")
148
+
149
+ # 主界面 - 两栏布局
150
+ col1, col2 = st.columns(2)
151
+
152
+ with col1:
153
+ st.header("您的简介")
154
+ profile1 = st.text_area(
155
+ "粘贴您的LinkedIn简介或专业背景",
156
+ height=300,
157
+ placeholder="例如:\n我是一名拥有5年经验的金融分析师,毕业于北京大学金融学专业。我在摩根士丹利工作了3年,专注于投资银行业务..."
158
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
159
 
160
+ with col2:
161
+ st.header("目标联系人的简介")
162
+ profile2 = st.text_area(
163
+ "粘贴目标联系人的LinkedIn简介或专业背景",
164
+ height=300,
165
+ placeholder="例如:\n高级投资银行家,现任高盛副总裁。清华大学MBA毕业,擅长并购交易,在科技行业有丰富经验..."
166
+ )
167
+
168
+ # 生成按钮和结果显示
169
+ submit_disabled = not api_key or not profile1 or not profile2
170
+ if submit_disabled:
171
+ if not api_key:
172
+ reason = "请先输入OpenAI API密钥"
173
+ else:
174
+ reason = "请填写两个简介"
175
+ st.warning(reason)
176
+
177
+ if st.button("生成邮件", type="primary", disabled=submit_disabled):
178
+ with st.spinner("正在分析简介并创建个性化邮件..."):
179
+ email = generate_email(
180
+ profile1=profile1,
181
+ profile2=profile2,
182
+ style=style,
183
+ temperature=temperature,
184
+ api_key=api_key
185
  )
186
+
187
+ st.success("邮件已生成!")
188
+
189
+ # 显示结果
190
+ st.header("您的个性化咖啡聊天邮件")
191
+ st.text_area("可复制的邮件内容", email, height=400)
192
+ st.download_button(
193
+ label="下载邮件",
194
+ data=email,
195
+ file_name="咖啡聊天邀请.txt",
196
+ mime="text/plain"
197
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
198
 
199
+ # 使用提示
200
+ st.markdown("---")
201
+ st.subheader("💡 使用提示")
202
+ st.markdown("""
203
+ - **简介内容越详细**,生成的邮件就越个性化和有针对性
204
+ - **尝试不同风格**以适应不同的行业和联系人
205
+ - 生成后可以**微调邮件内容**,添加您认为合适的个人细节
206
+ - 适合用于**金融、咨询和科技行业**的专业人士
207
+ """)