Spaces:
Build error
Build error
Update src/streamlit_app.py
Browse filesadding criterions analysis and weights for screening process
- src/streamlit_app.py +193 -12
src/streamlit_app.py
CHANGED
|
@@ -28,17 +28,177 @@ client = AzureOpenAI(
|
|
| 28 |
)
|
| 29 |
|
| 30 |
# Function to extract information from CV using Azure OpenAI GPT-4 model
|
| 31 |
-
def
|
| 32 |
prompt = f"""
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 41 |
{text}
|
|
|
|
|
|
|
| 42 |
"""
|
| 43 |
response = client.chat.completions.create(
|
| 44 |
messages=[
|
|
@@ -74,11 +234,11 @@ cv_text = st.text_area("Enter CV Text", height=300)
|
|
| 74 |
|
| 75 |
if cv_text:
|
| 76 |
# Display the entered CV text
|
| 77 |
-
st.subheader("Entered Text from CV")
|
| 78 |
-
st.text_area("CV Text", cv_text, height=300)
|
| 79 |
|
| 80 |
# Extract relevant information using Azure OpenAI GPT-4
|
| 81 |
-
extracted_info =
|
| 82 |
|
| 83 |
# Display the extracted information
|
| 84 |
if extracted_info:
|
|
@@ -86,3 +246,24 @@ if cv_text:
|
|
| 86 |
st.write(extracted_info)
|
| 87 |
else:
|
| 88 |
st.write("Could not extract information. Please try again.")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 28 |
)
|
| 29 |
|
| 30 |
# Function to extract information from CV using Azure OpenAI GPT-4 model
|
| 31 |
+
def extract_PD_info_from_azure(text):
|
| 32 |
prompt = f"""
|
| 33 |
+
Act as an HR recruiter. Carefully evaluate the provided job description (PD) document and extract the following information into the specified structured format. Ensure that all fields are populated. If a field is not explicitly mentioned in the text, use ""N/A"" as the default value.
|
| 34 |
+
|
| 35 |
+
- Requirements Categories to Extract:
|
| 36 |
+
|
| 37 |
+
- Location
|
| 38 |
+
|
| 39 |
+
- Country
|
| 40 |
+
|
| 41 |
+
- City
|
| 42 |
+
|
| 43 |
+
- Department
|
| 44 |
+
|
| 45 |
+
- Required Years of Experience
|
| 46 |
+
|
| 47 |
+
- Responsibilities
|
| 48 |
+
|
| 49 |
+
- Skills
|
| 50 |
+
|
| 51 |
+
- Experience
|
| 52 |
+
|
| 53 |
+
- Education
|
| 54 |
+
|
| 55 |
+
- Other Factors
|
| 56 |
+
|
| 57 |
+
- Languages
|
| 58 |
+
|
| 59 |
+
|
| 60 |
+
PD Text:
|
| 61 |
+
{text}
|
| 62 |
+
"""
|
| 63 |
+
response = client.chat.completions.create(
|
| 64 |
+
messages=[
|
| 65 |
+
{
|
| 66 |
+
"role": "system",
|
| 67 |
+
"content": "You are a helpful assistant.",
|
| 68 |
+
},
|
| 69 |
+
{
|
| 70 |
+
"role": "user",
|
| 71 |
+
"content": prompt,
|
| 72 |
+
}
|
| 73 |
+
],
|
| 74 |
+
max_tokens=4096,
|
| 75 |
+
temperature=1.0,
|
| 76 |
+
top_p=1.0,
|
| 77 |
+
model=DEPLOYMENT_NAME
|
| 78 |
+
)
|
| 79 |
+
|
| 80 |
+
try:
|
| 81 |
+
|
| 82 |
+
result = response.choices[0].message.content
|
| 83 |
+
return result
|
| 84 |
+
except Exception as e:
|
| 85 |
+
st.error(f"Error occurred while contacting Azure OpenAI: {e}")
|
| 86 |
+
return None
|
| 87 |
+
|
| 88 |
+
# Function to extract information from CV using Azure OpenAI GPT-4 model
|
| 89 |
+
def extract_criterions_from_azure(text):
|
| 90 |
+
prompt = f"""
|
| 91 |
+
Act as an HR recruiter. Based on the main criteria categories defined below, extract bullet items from the provided PD text. For each bullet item, create a Criterion Object with the following fields:
|
| 92 |
+
Instructions:
|
| 93 |
+
- Criterions should represent each item listed under each PD section (Skills,Education, Experience, Other Factors):
|
| 94 |
+
1- For each item under PD sections mentioned above, ensure to have related criteria item created to measure it. only skip those items may not relevant or negate a state such as ""There are no extra requirements specified for this position"" .
|
| 95 |
+
- PD sections with NA value, dont create Crtierion for it at all.
|
| 96 |
+
- Ensure to add Criterions for Languages Proficiency based on its identified level
|
| 97 |
+
- Ensure to add Criterions that has clue within the PD to measure it, if no clue in PD, do not consider it.
|
| 98 |
+
|
| 99 |
+
**Important:**
|
| 100 |
+
- Output all Criterion items together under each other as follows, make sure category part formated in bold:
|
| 101 |
+
1- Item 1 (Category: Skills)
|
| 102 |
+
2- Item 2 (Category: Experience)
|
| 103 |
+
|
| 104 |
+
|
| 105 |
+
|
| 106 |
+
|
| 107 |
+
PD Text:
|
| 108 |
+
{text}
|
| 109 |
+
"""
|
| 110 |
+
response = client.chat.completions.create(
|
| 111 |
+
messages=[
|
| 112 |
+
{
|
| 113 |
+
"role": "system",
|
| 114 |
+
"content": "You are a helpful assistant.",
|
| 115 |
+
},
|
| 116 |
+
{
|
| 117 |
+
"role": "user",
|
| 118 |
+
"content": prompt,
|
| 119 |
+
}
|
| 120 |
+
],
|
| 121 |
+
max_tokens=4096,
|
| 122 |
+
temperature=1.0,
|
| 123 |
+
top_p=1.0,
|
| 124 |
+
model=DEPLOYMENT_NAME
|
| 125 |
+
)
|
| 126 |
+
|
| 127 |
+
try:
|
| 128 |
+
|
| 129 |
+
result = response.choices[0].message.content
|
| 130 |
+
return result
|
| 131 |
+
except Exception as e:
|
| 132 |
+
st.error(f"Error occurred while contacting Azure OpenAI: {e}")
|
| 133 |
+
return None
|
| 134 |
+
|
| 135 |
+
def extract_weights_from_azure(text):
|
| 136 |
+
prompt = f"""
|
| 137 |
+
Act as an HR recruiter. Based on the extracted criteria records from the previous step, evaluate the importance of each requirement category type based on provided criteria and assign a weight to it. The weight should reflect how critical the category is for the job, with a score from 1 to 100, ensuring that the sum of all weights does not exceed 100.
|
| 138 |
+
|
| 139 |
+
Requirements Categories to Evaluate and Assign Weights:
|
| 140 |
+
Location (keyword: Location)
|
| 141 |
+
|
| 142 |
+
Required Years of Experience (keyword: Required_Years_of_Experience)
|
| 143 |
+
|
| 144 |
+
Responsibilities (keyword: Responsibilities)
|
| 145 |
+
|
| 146 |
+
Skills (keyword: Skills)
|
| 147 |
+
|
| 148 |
+
Experience (keyword: Experience)
|
| 149 |
+
|
| 150 |
+
Education (keyword: Education)
|
| 151 |
+
|
| 152 |
+
Other Factors (keyword: Other_Factors)
|
| 153 |
+
|
| 154 |
+
Languages (keyword: Language_Proficiency)
|
| 155 |
+
|
| 156 |
+
|
| 157 |
+
Instructions:
|
| 158 |
+
|
| 159 |
+
Dynamic Handling of Categories:
|
| 160 |
+
**Include categories that have explicit criteria mentioned in the Criterions JSON Content.
|
| 161 |
+
**Exclude categories that are not present in the content.
|
| 162 |
+
**Adjust the weights dynamically so the sum of all assigned weights does not exceed 100.
|
| 163 |
+
|
| 164 |
+
|
| 165 |
+
Weight Assignment:
|
| 166 |
+
**Assign a weight (1–100) to each category based on its importance to the job.
|
| 167 |
+
**Distribute weights logically, ensuring critical categories like Skills, Experience, Education, and Language Proficiency are well represented.
|
| 168 |
+
**Ensure the sum of all weights, including Extra_Requirement_Three if present, totals exactly 100.
|
| 169 |
+
**If the total exceeds or is less than 100, proportionally adjust the weights of the other categories.
|
| 170 |
+
|
| 171 |
+
Category Justification:
|
| 172 |
+
**For each category, provide a detailed justification of its importance, tied to the specific requirements in the job description.
|
| 173 |
+
**Explain how the requirements support the assigned weight and their direct relevance to job performance or success.
|
| 174 |
+
|
| 175 |
+
Final Adjustment Rule:
|
| 176 |
+
After assigning initial weights:
|
| 177 |
+
** Check if the total weight equals 100.
|
| 178 |
+
** If the total is less than 100, proportionally increase the weights of all present categories.
|
| 179 |
+
** If the total is more than 100, proportionally decrease the weights of all present categories.
|
| 180 |
+
** Preserve explicit weight floors (e.g., Experience greater than or equal to 15%) when adjusting.
|
| 181 |
+
** The final output must sum to exactly 100.
|
| 182 |
+
|
| 183 |
+
Output Format:
|
| 184 |
+
**The response must strictly follow below, including the Category_Description for each category.
|
| 185 |
+
**Ensure that all categories in the PD criteria are represented in the weights, and no category is missing.
|
| 186 |
+
**If Language_Proficiency is found in the criteria, it should have a weight assigned and be included in the output.
|
| 187 |
+
**If Extra_Requirement_One is found in the criteria, it should have a weight assigned and be included in the output.
|
| 188 |
+
**If Extra_Requirement_Two is found in the criteria, it should have a weight assigned and be included in the output.
|
| 189 |
+
**If Extra_Requirement_Three is found in the criteria, it should have a weight assigned and be included in the output.
|
| 190 |
+
|
| 191 |
+
|
| 192 |
+
Example Output:
|
| 193 |
+
1- Skills (Weight: 35%): <short description about required skills for this job>
|
| 194 |
+
2- Experience (Weight: 25%): <short description about required experiences for this job>
|
| 195 |
+
3- Education (Weight: 25%): <short description about required education for this job>
|
| 196 |
+
4- Language Proficincy (Weight: 15%): <short description about required languages for this job>
|
| 197 |
+
|
| 198 |
+
Criterions list:
|
| 199 |
{text}
|
| 200 |
+
|
| 201 |
+
|
| 202 |
"""
|
| 203 |
response = client.chat.completions.create(
|
| 204 |
messages=[
|
|
|
|
| 234 |
|
| 235 |
if cv_text:
|
| 236 |
# Display the entered CV text
|
| 237 |
+
# st.subheader("Entered Text from CV")
|
| 238 |
+
# st.text_area("CV Text", cv_text, height=300)
|
| 239 |
|
| 240 |
# Extract relevant information using Azure OpenAI GPT-4
|
| 241 |
+
extracted_info = extract_PD_info_from_azure(cv_text)
|
| 242 |
|
| 243 |
# Display the extracted information
|
| 244 |
if extracted_info:
|
|
|
|
| 246 |
st.write(extracted_info)
|
| 247 |
else:
|
| 248 |
st.write("Could not extract information. Please try again.")
|
| 249 |
+
|
| 250 |
+
|
| 251 |
+
# Extract Criterions
|
| 252 |
+
extracted_criterions = extract_criterions_from_azure(extracted_info)
|
| 253 |
+
|
| 254 |
+
# Display the extracted information
|
| 255 |
+
if extracted_criterions:
|
| 256 |
+
st.subheader("Extracted Criterion List")
|
| 257 |
+
st.write(extracted_criterions)
|
| 258 |
+
else:
|
| 259 |
+
st.write("Could not extract criterion information. Please try again.")
|
| 260 |
+
|
| 261 |
+
# Extract Criterions
|
| 262 |
+
extracted_weights = extract_weights_from_azure(extracted_criterions)
|
| 263 |
+
|
| 264 |
+
# Display the extracted information
|
| 265 |
+
if extracted_weights:
|
| 266 |
+
st.subheader("Extracted Weights List")
|
| 267 |
+
st.write(extracted_weights)
|
| 268 |
+
else:
|
| 269 |
+
st.write("Could not extract weights information. Please try again.")
|