Spaces:
Build error
Build error
| import streamlit as st | |
| import os | |
| import openai | |
| from dotenv import load_dotenv | |
| import os | |
| from openai import AzureOpenAI | |
| from azure.core.credentials import AzureKeyCredential | |
| # Load environment variables from .env file | |
| load_dotenv() | |
| # Set environment variables for Azure OpenAI | |
| ENDPOINT = os.getenv("AZURE_OPENAI_ENDPOINT") | |
| API_KEY = os.getenv("AZURE_OPENAI_API_KEY") | |
| DEPLOYMENT_NAME = os.getenv("AZURE_OPENAI_DEPLOYMENT_NAME") | |
| API_VERSION = os.getenv("AZURE_OPENAI_API_VERION") | |
| # Check if the necessary environment variables are loaded | |
| if not API_KEY or not ENDPOINT or not DEPLOYMENT_NAME: | |
| st.error("Azure OpenAI credentials are missing. Please check your .env file.") | |
| st.stop() | |
| client = AzureOpenAI( | |
| api_version=API_VERSION, | |
| azure_endpoint=ENDPOINT, | |
| api_key=API_KEY, | |
| ) | |
| # Function to extract information from PD using Azure OpenAI GPT-4 model | |
| def extract_PD_info_from_azure(text): | |
| prompt = f""" | |
| 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. | |
| - Requirements Categories to Extract: | |
| - Location | |
| - Country | |
| - City | |
| - Department | |
| - Required Years of Experience | |
| - Responsibilities | |
| - Skills | |
| - Experience | |
| - Education | |
| - Other Factors | |
| - Languages | |
| PD Text: | |
| {text} | |
| """ | |
| response = client.chat.completions.create( | |
| messages=[ | |
| { | |
| "role": "system", | |
| "content": "You are a helpful assistant.", | |
| }, | |
| { | |
| "role": "user", | |
| "content": prompt, | |
| } | |
| ], | |
| max_tokens=4096, | |
| temperature=1.0, | |
| top_p=1.0, | |
| model=DEPLOYMENT_NAME | |
| ) | |
| try: | |
| result = response.choices[0].message.content | |
| return result | |
| except Exception as e: | |
| st.error(f"Error occurred while contacting Azure OpenAI: {e}") | |
| return None | |
| # Function to extract information from PD using Azure OpenAI GPT-4 model | |
| def extract_criterions_from_azure(text): | |
| prompt = f""" | |
| 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: | |
| Instructions: | |
| - Criterions should represent each item listed under each PD section (Skills,Education, Experience, Other Factors): | |
| 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"" . | |
| - PD sections with NA value, dont create Crtierion for it at all. | |
| - Ensure to add Criterions for Languages Proficiency based on its identified level | |
| - Ensure to add Criterions that has clue within the PD to measure it, if no clue in PD, do not consider it. | |
| **Important:** | |
| - Output all Criterion items together under each other as follows, make sure category part formated in bold: | |
| 1- Item 1 (Category: Skills) | |
| 2- Item 2 (Category: Experience) | |
| PD Text: | |
| {text} | |
| """ | |
| response = client.chat.completions.create( | |
| messages=[ | |
| { | |
| "role": "system", | |
| "content": "You are a helpful assistant.", | |
| }, | |
| { | |
| "role": "user", | |
| "content": prompt, | |
| } | |
| ], | |
| max_tokens=4096, | |
| temperature=1.0, | |
| top_p=1.0, | |
| model=DEPLOYMENT_NAME | |
| ) | |
| try: | |
| result = response.choices[0].message.content | |
| return result | |
| except Exception as e: | |
| st.error(f"Error occurred while contacting Azure OpenAI: {e}") | |
| return None | |
| def extract_weights_from_azure(text): | |
| prompt = f""" | |
| 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. | |
| Requirements Categories to Evaluate and Assign Weights: | |
| Location (keyword: Location) | |
| Required Years of Experience (keyword: Required_Years_of_Experience) | |
| Responsibilities (keyword: Responsibilities) | |
| Skills (keyword: Skills) | |
| Experience (keyword: Experience) | |
| Education (keyword: Education) | |
| Other Factors (keyword: Other_Factors) | |
| Languages (keyword: Language_Proficiency) | |
| Instructions: | |
| Dynamic Handling of Categories: | |
| **Include categories that have explicit criteria mentioned in the Criterions JSON Content. | |
| **Exclude categories that are not present in the content. | |
| **Adjust the weights dynamically so the sum of all assigned weights does not exceed 100. | |
| Weight Assignment: | |
| **Assign a weight (1β100) to each category based on its importance to the job. | |
| **Distribute weights logically, ensuring critical categories like Skills, Experience, Education, and Language Proficiency are well represented. | |
| **Ensure the sum of all weights, including Extra_Requirement_Three if present, totals exactly 100. | |
| **If the total exceeds or is less than 100, proportionally adjust the weights of the other categories. | |
| Category Justification: | |
| **For each category, provide a detailed justification of its importance, tied to the specific requirements in the job description. | |
| **Explain how the requirements support the assigned weight and their direct relevance to job performance or success. | |
| Final Adjustment Rule: | |
| After assigning initial weights: | |
| ** Check if the total weight equals 100. | |
| ** If the total is less than 100, proportionally increase the weights of all present categories. | |
| ** If the total is more than 100, proportionally decrease the weights of all present categories. | |
| ** Preserve explicit weight floors (e.g., Experience greater than or equal to 15%) when adjusting. | |
| ** The final output must sum to exactly 100. | |
| Output Format: | |
| **The response must strictly follow below, including the Category_Description for each category. | |
| **Ensure that all categories in the PD criteria are represented in the weights, and no category is missing. | |
| **If Language_Proficiency is found in the criteria, it should have a weight assigned and be included in the output. | |
| **If Extra_Requirement_One is found in the criteria, it should have a weight assigned and be included in the output. | |
| **If Extra_Requirement_Two is found in the criteria, it should have a weight assigned and be included in the output. | |
| **If Extra_Requirement_Three is found in the criteria, it should have a weight assigned and be included in the output. | |
| Example Output: | |
| 1- Skills (Weight: 35%): <short description about required skills for this job> | |
| 2- Experience (Weight: 25%): <short description about required experiences for this job> | |
| 3- Education (Weight: 25%): <short description about required education for this job> | |
| 4- Language Proficincy (Weight: 15%): <short description about required languages for this job> | |
| Criterions list: | |
| {text} | |
| """ | |
| response = client.chat.completions.create( | |
| messages=[ | |
| { | |
| "role": "system", | |
| "content": "You are a helpful assistant.", | |
| }, | |
| { | |
| "role": "user", | |
| "content": prompt, | |
| } | |
| ], | |
| max_tokens=4096, | |
| temperature=1.0, | |
| top_p=1.0, | |
| model=DEPLOYMENT_NAME | |
| ) | |
| try: | |
| result = response.choices[0].message.content | |
| return result | |
| except Exception as e: | |
| st.error(f"Error occurred while contacting Azure OpenAI: {e}") | |
| return None | |
| # Streamlit App UI | |
| st.title("AI Screening - Post Description Information Extraction") | |
| st.write("Enter the PD text below, and the agent will extract relevant information such as job title, location, skills, experience, and education, Criterions, Criterion Weights.") | |
| # Text area for entering PD content manually | |
| pd_text = st.text_area("Enter PD Text", height=300) | |
| if pd_text: | |
| # Display the entered PD text | |
| # st.subheader("Entered Text from PD") | |
| # st.text_area("PD Text", pd_text, height=300) | |
| # Extract relevant information using Azure OpenAI GPT-4 | |
| extracted_info = extract_PD_info_from_azure(pd_text) | |
| # Display the extracted information | |
| if extracted_info: | |
| st.subheader("Extracted Information") | |
| with st.chat_message("assistant", avatar="π€"): | |
| st.markdown( | |
| f"<div class='chat-message assistant'>{extracted_info}</div>", | |
| unsafe_allow_html=True, | |
| ) | |
| # st.write(extracted_info) | |
| else: | |
| st.write("Could not extract information. Please try again.") | |
| # Extract Criterions | |
| extracted_criterions = extract_criterions_from_azure(extracted_info) | |
| # Display the extracted information | |
| if extracted_criterions: | |
| st.subheader("Extracted Criterion List") | |
| # Immediately display the assistant's response | |
| with st.chat_message("assistant", avatar="π€"): | |
| st.markdown( | |
| f"<div class='chat-message assistant'>{extracted_criterions}</div>", | |
| unsafe_allow_html=True, | |
| ) | |
| # st.write(extracted_criterions) | |
| else: | |
| st.write("Could not extract criterion information. Please try again.") | |
| # Extract Criterions | |
| extracted_weights = extract_weights_from_azure(extracted_criterions) | |
| # Display the extracted information | |
| if extracted_weights: | |
| st.subheader("Extracted Weights List") | |
| with st.chat_message("assistant", avatar="π€"): | |
| st.markdown( | |
| f"<div class='chat-message assistant'>{extracted_weights}</div>", | |
| unsafe_allow_html=True, | |
| ) | |
| # st.write(extracted_weights) | |
| else: | |
| st.write("Could not extract weights information. Please try again.") # | |