Spaces:
Sleeping
Sleeping
Zekun Wu
commited on
Commit
·
6adf9db
1
Parent(s):
c8f2cf0
update
Browse files- app.py +108 -0
- requirements.txt +3 -0
app.py
ADDED
@@ -0,0 +1,108 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import requests
|
2 |
+
import streamlit as st
|
3 |
+
import json
|
4 |
+
from tqdm import tqdm
|
5 |
+
from openai import AzureOpenAI
|
6 |
+
import json_repair
|
7 |
+
import backoff
|
8 |
+
import os
|
9 |
+
|
10 |
+
|
11 |
+
# API setting constants
|
12 |
+
API_MAX_RETRY = 5
|
13 |
+
API_RETRY_SLEEP = 10
|
14 |
+
|
15 |
+
class GPTAgent:
|
16 |
+
def __init__(self):
|
17 |
+
self.client = AzureOpenAI(
|
18 |
+
api_key=os.getenv("OPENAI_API_KEY"),
|
19 |
+
api_version="2024-02-15-preview",
|
20 |
+
azure_endpoint=os.getenv("END_POINTS")
|
21 |
+
)
|
22 |
+
|
23 |
+
self.deployment_name = ("gpt-4o-mini")
|
24 |
+
|
25 |
+
@backoff.on_exception(backoff.expo, requests.exceptions.RequestException, max_tries=8)
|
26 |
+
def invoke(self, text):
|
27 |
+
|
28 |
+
|
29 |
+
prompt = """You are a creative recruitment specialist tasked with generating witty and engaging recruitment potshots. Your goal is to craft short, attention-grabbing statements designed to attract potential candidates for job openings. These potshots should be tailored to the role, audience, and company values provided, and should make the job opportunity stand out in a competitive market."""
|
30 |
+
temperature = 0.9
|
31 |
+
max_tokens = 3500
|
32 |
+
|
33 |
+
|
34 |
+
response = self.client.chat.completions.create(
|
35 |
+
model=self.deployment_name,
|
36 |
+
messages=[
|
37 |
+
{"role": "system", "content": prompt},
|
38 |
+
{"role": "user", "content": text},
|
39 |
+
],
|
40 |
+
temperature=temperature,
|
41 |
+
max_tokens=max_tokens,
|
42 |
+
)
|
43 |
+
|
44 |
+
output = response.choices[0].message.content
|
45 |
+
return output
|
46 |
+
|
47 |
+
|
48 |
+
def generate_potshot_prompt(batch, role, tone, audience, values):
|
49 |
+
prompt = f"""You are a recruitment specialist tasked with generating witty and engaging recruitment potshots.
|
50 |
+
|
51 |
+
Your goal is to craft short, attention-grabbing statements designed to attract potential job candidates for the role of {role}. These statements should appeal to {audience} and reflect the company's values: {values}.
|
52 |
+
|
53 |
+
Please adopt a tone that is {tone}. Your objective is to make the job opportunity stand out and be highly appealing to the intended audience.
|
54 |
+
|
55 |
+
Provide this list of {batch} recruitment potshots in JSON format, for example:
|
56 |
+
{{"potshots": ["potshot 1", "potshot 2", ..., "potshot n"]}}
|
57 |
+
|
58 |
+
Remember to focus on being engaging, playful, and sharp in these recruitment potshots."""
|
59 |
+
return prompt.strip()
|
60 |
+
|
61 |
+
|
62 |
+
# Function to get recruitment potshots with customizations
|
63 |
+
def get_potshots(n_repeat=1, batch=20, role="Developer", tone="humorous", audience="tech-savvy candidates",
|
64 |
+
values="innovation, teamwork"):
|
65 |
+
total_potshots = []
|
66 |
+
desired_count = n_repeat * batch
|
67 |
+
with tqdm(total=desired_count, desc="Generating potshots") as pbar:
|
68 |
+
while len(total_potshots) < desired_count:
|
69 |
+
needed = min(batch, desired_count - len(total_potshots))
|
70 |
+
prompt = generate_potshot_prompt(batch=needed, role=role, tone=tone, audience=audience, values=values)
|
71 |
+
response = GPTAgent.invoke(prompt, mode="generate")
|
72 |
+
try:
|
73 |
+
batch_potshots = json.loads(response).get("potshots", [])
|
74 |
+
total_potshots.extend(batch_potshots)
|
75 |
+
pbar.update(len(batch_potshots))
|
76 |
+
except json.JSONDecodeError:
|
77 |
+
# Attempt to repair the JSON if decoding fails
|
78 |
+
try:
|
79 |
+
repaired_json = json_repair.repair_json(response, skip_json_loads=True, return_objects=False)
|
80 |
+
batch_potshots = json.loads(repaired_json).get("potshots", [])
|
81 |
+
total_potshots.extend(batch_potshots)
|
82 |
+
pbar.update(len(batch_potshots))
|
83 |
+
except json.JSONDecodeError:
|
84 |
+
st.error("Failed to decode JSON response even after repair attempt. Skipping this batch.")
|
85 |
+
|
86 |
+
if len(total_potshots) > desired_count:
|
87 |
+
total_potshots = total_potshots[:desired_count]
|
88 |
+
|
89 |
+
prompt_list = [{"prompt": potshot} for potshot in total_potshots]
|
90 |
+
return {"potshots": prompt_list}
|
91 |
+
|
92 |
+
|
93 |
+
# Streamlit App Interface
|
94 |
+
st.title("Customized Recruiting Potshots Generator")
|
95 |
+
|
96 |
+
# Input Fields for Customization
|
97 |
+
role = st.text_input("Job Role", "Developer")
|
98 |
+
tone = st.selectbox("Tone of the Potshots", ["humorous", "serious", "edgy", "motivational", "playful"])
|
99 |
+
audience = st.text_input("Target Audience", "tech-savvy candidates")
|
100 |
+
values = st.text_area("Company Values", "innovation, teamwork, transparency")
|
101 |
+
batch_size = st.number_input("Batch Size", min_value=1, max_value=100, value=10)
|
102 |
+
repeat_times = st.number_input("Number of Batches", min_value=1, max_value=10, value=1)
|
103 |
+
|
104 |
+
if st.button("Generate Potshots"):
|
105 |
+
with st.spinner("Generating customized potshots..."):
|
106 |
+
results = get_potshots(n_repeat=repeat_times, batch=batch_size, role=role, tone=tone, audience=audience,
|
107 |
+
values=values)
|
108 |
+
st.json(results)
|
requirements.txt
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
openai
|
2 |
+
json-repair
|
3 |
+
backoff
|