tanujg78 commited on
Commit
c3f7d1b
·
verified ·
1 Parent(s): e6c28f0

added app for analysis

Browse files
Files changed (4) hide show
  1. analysis.py +24 -0
  2. app.py +213 -166
  3. interview_questons.py +76 -0
  4. resume_with_job.py +104 -0
analysis.py ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ def generate_analysis(jd_data,resume_data,pipe):
2
+ # jd_text = truncate_text(jd_data)
3
+
4
+ prompt = f"""
5
+ Analyze the following resume and job description. Provide a detailed analysis of the match, including strengths, weaknesses, and an overall fit score between 0 and 1.
6
+
7
+ Resume: {resume_data}
8
+
9
+ Job Description: {jd_data}
10
+
11
+ Provide your analysis in the following format:
12
+ Score: [score between 0 and 1 (for resemblance of resume with job description)]
13
+ Analysis: [Your detailed analysis in point-wise]
14
+ Weaknesses:[weaknesses of the resume according to Job Description in point-wise]
15
+ Strengths:[Strengths of the resume according to Job Description in point-wise]
16
+ Areas of non-Alignment: [Areas of Alignment where the candidate is missing according to job description in point-wise]
17
+ Areas of Alignment: [Areas of Alignment where the candidate is matching according to job description in point-wise]
18
+
19
+ **PLEASE USE HEADINGS Score,Analysis,Weaknesses,Strengths,Areas of Alignment as it is**
20
+ """
21
+ response = pipe(prompt,max_new_tokens=5000, do_sample=True, temperature=0.7)
22
+
23
+ return response, prompt
24
+ # return prompt
app.py CHANGED
@@ -1,166 +1,213 @@
1
- from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline, BitsAndBytesConfig
2
- from json_repair import repair_json
3
- import torch
4
- from huggingface_hub import login
5
- import streamlit as st
6
- import os,json
7
- from dotenv import load_dotenv
8
- from functions import get_json
9
- from resume_prompt import analyze_resume
10
- from jd_prompt import analyze_jd
11
- from sq_and_query import generate_screening_question, generate_search_query
12
- import fitz
13
- import time
14
-
15
- load_dotenv()
16
-
17
-
18
- SECRET_KEY = os.getenv("SECRET_KEY")
19
- login(SECRET_KEY)
20
-
21
-
22
- model_name =os.getenv("MODEL")
23
- bnb_config = BitsAndBytesConfig(
24
- load_in_4bit=True,
25
- bnb_4bit_compute_dtype=torch.float16,
26
- bnb_4bit_use_double_quant=True
27
- )
28
-
29
- tokenizer = AutoTokenizer.from_pretrained(model_name)
30
- model = AutoModelForCausalLM.from_pretrained(
31
- model_name,
32
- quantization_config=bnb_config,
33
- device_map="auto",
34
- )
35
- pipe = pipeline("text-generation", model=model, tokenizer=tokenizer)
36
-
37
- ##Resume
38
- upload_resume = 'uploaded_resumes'
39
-
40
- if not os.path.exists(upload_resume):
41
- os.mkdir(upload_resume)
42
-
43
- st.header("Upload Resume")
44
-
45
- uploaded_file = st.file_uploader("Choose a Resume", type=["pdf", "docx"])
46
-
47
- if uploaded_file is not None:
48
- file_name = uploaded_file.name
49
- saved_resume_path = os.path.join(upload_resume, file_name)
50
-
51
- with open(saved_resume_path, "wb") as f:
52
- f.write(uploaded_file.getbuffer())
53
-
54
- st.success(f'Resume successfully uploaded to {saved_resume_path}')
55
-
56
- resume_text=""
57
- with fitz.open(saved_resume_path) as doc:
58
- for page in doc:
59
- resume_text += page.get_text()
60
- start_time=time.time()
61
- resume_result,resume_prompt = analyze_resume(resume_text,pipe)
62
- resume_response_text = resume_result[0]["generated_text"]
63
- resume_result_resume = resume_response_text.replace(resume_prompt, "", 1)
64
-
65
- resume_json_str = get_json(resume_result_resume)
66
- resume_good_json_string = repair_json(resume_json_str)
67
- resume_data=json.loads(resume_good_json_string)
68
- st.success(f'time took {time.time()-start_time}')
69
-
70
- st.subheader("📄 Extracted Resume JSON")
71
- st.json(resume_data)
72
-
73
-
74
- resume_json_download = json.dumps(resume_data, indent=4)
75
- st.download_button(
76
- label="Download Resume JSON",
77
- data=resume_json_download,
78
- file_name="resume_data.json",
79
- mime="application/json"
80
- )
81
-
82
-
83
- ##Job Description
84
- upload_jd = 'uploaded_job_desc'
85
-
86
- if not os.path.exists(upload_resume):
87
- os.mkdir(upload_resume)
88
-
89
- st.header("Upload Job Description")
90
-
91
- uploaded_file = st.file_uploader("Choose a Job Description to Upload", type=["pdf", "docx","txt"])
92
-
93
- if uploaded_file is not None:
94
- file_name = uploaded_file.name
95
- saved_jd_path = os.path.join(upload_resume, file_name)
96
-
97
- with open(saved_jd_path, "wb") as f:
98
- f.write(uploaded_file.getbuffer())
99
-
100
- st.success(f'Job Description successfully uploaded to {saved_jd_path}')
101
-
102
- jd_text=""
103
- if saved_jd_path.endswith(".pdf") or saved_jd_path.endswith(".docx"):
104
- with fitz.open(saved_jd_path) as doc:
105
- for page in doc:
106
- jd_text += page.get_text()
107
- elif saved_jd_path.endswith(".txt"):
108
- with open(saved_jd_path, "r", encoding="utf-8") as file:
109
- jd_text = file.read()
110
- start_time=time.time()
111
- jd_result,jd_prompt = analyze_jd(jd_text,pipe)
112
-
113
- jd_response_text = jd_result[0]["generated_text"]
114
- jd_result_resume = jd_response_text.replace(jd_prompt, "", 1)
115
- jd_json_str =get_json(jd_result_resume)
116
- jd_good_json_string = repair_json(jd_json_str)
117
- jd_data=json.loads(jd_good_json_string)
118
- st.success(f'time took {time.time()-start_time}')
119
- st.subheader("📄 Extracted Job Description JSON")
120
- st.json(jd_data)
121
-
122
- jd_json_download = json.dumps(jd_data, indent=4)
123
- st.download_button(
124
- label="Download Job Description JSON",
125
- data=jd_json_download,
126
- file_name="jd_data.json",
127
- mime="application/json"
128
- )
129
-
130
- st.header("Screening Questions:")
131
-
132
- start_time=time.time()
133
- sq_result,sq_prompt =generate_screening_question(jd_data,pipe)
134
- sq_response_text = sq_result[0]["generated_text"]
135
- sq_result_resume = sq_response_text.replace(sq_prompt, "", 1)
136
- sq_json_str =get_json(sq_result_resume)
137
- sq_good_json_string = repair_json(sq_json_str)
138
- sq_data=json.loads(sq_good_json_string)
139
- st.success(f'time took {time.time()-start_time}')
140
- st.subheader("📄 Extracted Screening Question JSON")
141
- st.json(sq_data)
142
- st.download_button(
143
- label="Download Screening Questions JSON",
144
- data=json.dumps(sq_data),
145
- file_name="screening_questions_data.json",
146
- mime="application/json"
147
- )
148
-
149
- st.header("Search Query:")
150
- start_time=time.time()
151
- search_q_result,search_q_prompt=generate_search_query(jd_text,jd_data['keywords'],pipe)
152
- search_q_final_result=search_q_result[0]["generated_text"]
153
- serach_q_text = search_q_final_result.replace(search_q_prompt, "", 1)
154
- serach_q_json=get_json(serach_q_text)
155
- serach_q_data=json.loads(repair_json(serach_q_json))
156
- st.success(f'time took {time.time()-start_time}')
157
- st.subheader("📄 Extracted Search Query JSON")
158
- st.json(serach_q_data)
159
- st.download_button(
160
- label="Download Search Query JSON",
161
- data=json.dumps(serach_q_data),
162
- file_name="search_query_data.json",
163
- mime="application/json"
164
- )
165
-
166
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline, BitsAndBytesConfig
2
+ from json_repair import repair_json
3
+ import torch
4
+ from huggingface_hub import login
5
+ import streamlit as st
6
+ import os,json
7
+ from dotenv import load_dotenv
8
+ from functions import get_json
9
+ from resume_prompt import analyze_resume
10
+ from jd_prompt import analyze_jd
11
+ from sq_and_query import generate_screening_question, generate_search_query
12
+ from resume_with_job import generate_resume_with_job
13
+ from analysis import generate_analysis
14
+ from interview_questons import generate_interview_questions
15
+ import fitz
16
+ import time
17
+
18
+ load_dotenv()
19
+
20
+
21
+ SECRET_KEY = os.getenv("SECRET_KEY")
22
+ login(SECRET_KEY)
23
+
24
+
25
+ model_name =os.getenv("MODEL")
26
+ bnb_config = BitsAndBytesConfig(
27
+ load_in_4bit=True,
28
+ bnb_4bit_compute_dtype=torch.float16,
29
+ bnb_4bit_use_double_quant=True
30
+ )
31
+
32
+ tokenizer = AutoTokenizer.from_pretrained(model_name)
33
+ model = AutoModelForCausalLM.from_pretrained(
34
+ model_name,
35
+ quantization_config=bnb_config,
36
+ device_map="auto",
37
+ )
38
+ pipe = pipeline("text-generation", model=model, tokenizer=tokenizer)
39
+
40
+ ##Resume
41
+ upload_resume = 'uploaded_resumes'
42
+
43
+ if not os.path.exists(upload_resume):
44
+ os.mkdir(upload_resume)
45
+
46
+ st.header("Upload Resume")
47
+
48
+ uploaded_file_r = st.file_uploader("Choose a Resume", type=["pdf", "docx"])
49
+
50
+ if uploaded_file_r is not None:
51
+ file_name = uploaded_file_r.name
52
+ saved_resume_path = os.path.join(upload_resume, file_name)
53
+
54
+ with open(saved_resume_path, "wb") as f:
55
+ f.write(uploaded_file_r.getbuffer())
56
+
57
+ st.success(f'Resume successfully uploaded to {saved_resume_path}')
58
+
59
+ resume_text=""
60
+ with fitz.open(saved_resume_path) as doc:
61
+ for page in doc:
62
+ resume_text += page.get_text()
63
+ start_time=time.time()
64
+ resume_result,resume_prompt = analyze_resume(resume_text,pipe)
65
+ resume_response_text = resume_result[0]["generated_text"]
66
+ resume_result_resume = resume_response_text.replace(resume_prompt, "", 1)
67
+
68
+ resume_json_str = get_json(resume_result_resume)
69
+ resume_good_json_string = repair_json(resume_json_str)
70
+ resume_data=json.loads(resume_good_json_string)
71
+ st.success(f'time took {time.time()-start_time}')
72
+
73
+ st.subheader("📄 Extracted Resume JSON")
74
+ st.json(resume_data)
75
+
76
+
77
+ resume_json_download = json.dumps(resume_data, indent=4)
78
+ st.download_button(
79
+ label="Download Resume JSON",
80
+ data=resume_json_download,
81
+ file_name="resume_data.json",
82
+ mime="application/json"
83
+ )
84
+
85
+
86
+ ##Job Description
87
+ upload_jd = 'uploaded_job_desc'
88
+
89
+ if not os.path.exists(upload_resume):
90
+ os.mkdir(upload_resume)
91
+
92
+ st.header("Upload Job Description")
93
+
94
+ uploaded_file_jd = st.file_uploader("Choose a Job Description to Upload", type=["pdf", "docx","txt"])
95
+
96
+ if uploaded_file_jd is not None:
97
+ file_name = uploaded_file_jd.name
98
+ saved_jd_path = os.path.join(upload_resume, file_name)
99
+
100
+ with open(saved_jd_path, "wb") as f:
101
+ f.write(uploaded_file_jd.getbuffer())
102
+
103
+ st.success(f'Job Description successfully uploaded to {saved_jd_path}')
104
+
105
+ jd_text=""
106
+ if saved_jd_path.endswith(".pdf") or saved_jd_path.endswith(".docx"):
107
+ with fitz.open(saved_jd_path) as doc:
108
+ for page in doc:
109
+ jd_text += page.get_text()
110
+ elif saved_jd_path.endswith(".txt"):
111
+ with open(saved_jd_path, "r", encoding="utf-8") as file:
112
+ jd_text = file.read()
113
+ start_time=time.time()
114
+ jd_result,jd_prompt = analyze_jd(jd_text,pipe)
115
+
116
+ jd_response_text = jd_result[0]["generated_text"]
117
+ jd_result_resume = jd_response_text.replace(jd_prompt, "", 1)
118
+ jd_json_str =get_json(jd_result_resume)
119
+ jd_good_json_string = repair_json(jd_json_str)
120
+ jd_data=json.loads(jd_good_json_string)
121
+ st.success(f'time took {time.time()-start_time}')
122
+ st.subheader("📄 Extracted Job Description JSON")
123
+ st.json(jd_data)
124
+
125
+ jd_json_download = json.dumps(jd_data, indent=4)
126
+ st.download_button(
127
+ label="Download Job Description JSON",
128
+ data=jd_json_download,
129
+ file_name="jd_data.json",
130
+ mime="application/json"
131
+ )
132
+
133
+ st.header("Screening Questions:")
134
+
135
+ start_time=time.time()
136
+ sq_result,sq_prompt =generate_screening_question(jd_data,pipe)
137
+ sq_response_text = sq_result[0]["generated_text"]
138
+ sq_result_resume = sq_response_text.replace(sq_prompt, "", 1)
139
+ sq_json_str =get_json(sq_result_resume)
140
+ sq_good_json_string = repair_json(sq_json_str)
141
+ sq_data=json.loads(sq_good_json_string)
142
+ st.success(f'time took {time.time()-start_time}')
143
+ st.subheader("📄 Extracted Screening Question JSON")
144
+ st.json(sq_data)
145
+ st.download_button(
146
+ label="Download Screening Questions JSON",
147
+ data=json.dumps(sq_data),
148
+ file_name="screening_questions_data.json",
149
+ mime="application/json"
150
+ )
151
+
152
+ st.header("Search Query:")
153
+ start_time=time.time()
154
+ search_q_result,search_q_prompt=generate_search_query(jd_text,jd_data['keywords'],pipe)
155
+ search_q_final_result=search_q_result[0]["generated_text"]
156
+ serach_q_text = search_q_final_result.replace(search_q_prompt, "", 1)
157
+ serach_q_json=get_json(serach_q_text)
158
+ serach_q_data=json.loads(repair_json(serach_q_json))
159
+ st.success(f'time took {time.time()-start_time}')
160
+ st.subheader("📄 Extracted Search Query JSON")
161
+ st.json(serach_q_data)
162
+ st.download_button(
163
+ label="Download Search Query JSON",
164
+ data=json.dumps(serach_q_data),
165
+ file_name="search_query_data.json",
166
+ mime="application/json"
167
+ )
168
+
169
+
170
+ if uploaded_file_r is not None and uploaded_file_jd is not None:
171
+ st.header("Resume With Job:")
172
+ start_time = time.time()
173
+ rwj_result,rwj_prompt=generate_resume_with_job(jd_data,resume_data,pipe)
174
+ rwj_final_result=rwj_result[0]["generated_text"]
175
+ rwj_text = rwj_final_result.replace(rwj_prompt, "", 1)
176
+ match=json.loads(repair_json(get_json(rwj_text)))
177
+ st.success(f'time took {time.time()-start_time}')
178
+ st.subheader("📄 Extracted Resume With Job JSON")
179
+ st.json(match)
180
+ st.download_button(
181
+ label="Download Resume With Job JSON",
182
+ data=json.dumps(match),
183
+ file_name="resume_with_job_data.json",
184
+ mime="application/json"
185
+ )
186
+
187
+
188
+ st.header("Analysis:")
189
+ start_time = time.time()
190
+ analysis_result,analysis_prompt = generate_analysis(jd_data,resume_data,pipe)
191
+ analysis_final_result=analysis_result[0]["generated_text"]
192
+ analysis_result_resume = analysis_final_result.replace(analysis_prompt, "", 1)
193
+ analysis_result_resume = analysis_result_resume.replace("-", "").strip()
194
+ st.success(f'time took {time.time()-start_time}')
195
+ st.subheader("📄 Extracted Resume With Job JSON")
196
+ st.text_area("Analysis Content", analysis_result_resume, height=250)
197
+
198
+
199
+ st.header("Interview Questions:")
200
+ start_time = time.time()
201
+ interview_que,interview_que_prompt=generate_interview_questions(jd_data,match,pipe)
202
+ interview_que_result=interview_que[0]["generated_text"]
203
+ interview_que_text=interview_que_result.replace(interview_que_prompt, "", 1)
204
+ interview_questions=json.loads(repair_json(get_json(interview_que_text)))
205
+ st.success(f'time took {time.time()-start_time}')
206
+ st.subheader("📄 Extracted Interview Questions JSON")
207
+ st.json(interview_questions)
208
+ st.download_button(
209
+ label="Download Interview Questions JSON",
210
+ data=json.dumps(interview_questions),
211
+ file_name="resume_with_job_data.json",
212
+ mime="application/json"
213
+ )
interview_questons.py ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ def generate_interview_questions(job_data,match_result,pipe):
2
+ job_title = job_data.get('title', '')
3
+ primary_function = job_data.get('primary_job_function', '')
4
+ matching_skills = match_result.get('matching_skills', [])
5
+ missing_skills = match_result.get('missing_skills', [])
6
+ prompt = f"""
7
+ Generate structured interview questions for a {job_title} position, focusing on three main sections:
8
+
9
+ 1. Missing Skills Assessment:
10
+ For each missing skill {missing_skills}, create:
11
+ - An initial question to check if they have worked with the skill
12
+ - A detailed follow-up question if they indicate experience
13
+ - Focus on practical experience and specific examples
14
+
15
+ 2. Experience Validation:
16
+ Create questions to validate their claimed experience in:
17
+ {matching_skills}
18
+ - Focus on specific projects and implementations
19
+ - Ask about challenges and solutions
20
+ - Verify depth of expertise
21
+
22
+ 3. Role-Specific Technical Deep Dive:
23
+ Create questions focused on {primary_function} that assess:
24
+ - Problem-solving approach
25
+ - Best practices understanding
26
+ - Technical decision-making
27
+ - Architecture and design thinking
28
+
29
+ Return the questions in this exact JSON format:
30
+ {{
31
+ "missing_skills_questions": [
32
+ {{
33
+ "skill": "Name of missing skill",
34
+ "screening_question": {{
35
+ "question": "Have you worked with [skill]?",
36
+ "look_for": ["Indicators of experience"],
37
+ "red_flags": ["Warning signs"]
38
+ }},
39
+ "follow_up": {{
40
+ "question": "Detailed follow-up question if they have experience",
41
+ "purpose": "What to evaluate",
42
+ "look_for": ["Expected positive points"],
43
+ "red_flags": ["Warning signs"]
44
+ }}
45
+ }}
46
+ ],
47
+ "experience_questions": [
48
+ {{
49
+ "skill": "Specific skill or area",
50
+ "question": "Detailed question about their experience",
51
+ "purpose": "What this evaluates",
52
+ "look_for": ["Expected positive points"],
53
+ "red_flags": ["Warning signs"]
54
+ }}
55
+ ],
56
+ "technical_questions": [
57
+ {{
58
+ "area": "Technical area being assessed",
59
+ "question": "Technical or scenario-based question",
60
+ "purpose": "What this evaluates",
61
+ "look_for": ["Expected positive points"],
62
+ "red_flags": ["Warning signs"]
63
+ }}
64
+ ]
65
+ }}
66
+
67
+ Ensure:
68
+ 1. Questions are specific and practical
69
+ 2. No repetition across sections
70
+ 3. Clear evaluation criteria for each question
71
+ 4. Natural flow from basic to complex topics
72
+ 5. Ensure questions are specific to the candidate's profile and the role requirements.
73
+ """
74
+ response = pipe(prompt,max_new_tokens=5000, do_sample=True, temperature=0.7)
75
+ return response, prompt
76
+
resume_with_job.py ADDED
@@ -0,0 +1,104 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ def generate_resume_with_job(jd_data,resume_data,pipe):
2
+ # jd_text = truncate_text(jd_data)
3
+
4
+ prompt = f"""
5
+ You are an expert ATS system analyzing the match between a resume and job description.
6
+ Provide a highly detailed technical analysis focusing on actual relevance, not just keyword matches.
7
+ Be critical and thorough in analyzing all aspects including experience, education, and job function.
8
+
9
+ Resume: {json.dumps(resume_data)}
10
+ Job Description: {json.dumps(jd_data)}
11
+
12
+ Evaluation Instructions:
13
+ 1. Skills Analysis:
14
+ - Look for exact matches AND related/equivalent skills
15
+ - Consider depth of experience with each skill
16
+ - Distinguish between core skills and peripheral knowledge
17
+ - Weight technical skills based on their importance to the role
18
+
19
+ 2. Experience Analysis (Most Critical):
20
+ - Evaluate actual relevance of past roles, not just years
21
+ - Analyze responsibilities and projects in detail
22
+ - Consider recency and depth of relevant experience
23
+ - Look for specific achievements and implementations
24
+ - Rate experience relevance on specific job requirements
25
+ - Consider domain/industry relevance
26
+ - Evaluate leadership and project scope alignment
27
+
28
+ 3. Education Analysis (Must be detailed):
29
+ - Evaluate degree level match (Bachelors, Masters, PhD)
30
+ - Assess field relevance to role requirements
31
+ - Analyze coursework alignment with technical needs
32
+ - Evaluate certifications and professional qualifications
33
+ - Consider continuing education and training
34
+ - Assess academic achievements and specializations
35
+ - Compare institution reputation if relevant
36
+ - Identify any educational gaps or additional needs
37
+ - Consider impact of education on role performance
38
+
39
+ 4. Job Function Analysis (Must be detailed):
40
+ - Evaluate direct career path alignment with role
41
+ - Assess progression within the function
42
+ - Analyze depth of functional expertise
43
+ - Evaluate industry-specific functional knowledge
44
+ - Consider team and project management in function
45
+ - Assess cross-functional experience relevance
46
+ - Evaluate strategic and leadership capabilities
47
+ - Identify functional strengths and weaknesses
48
+ - Consider future growth potential in function
49
+
50
+ 5. Technical Depth Analysis:
51
+ - Evaluate complexity of past projects
52
+ - Assess technical leadership experience
53
+ - Consider architecture and design experience
54
+ - Evaluate hands-on implementation experience
55
+
56
+ Provide your detailed analysis in this JSON format:
57
+ {{
58
+ "match_score": [score between 0 and 1, be strict and realistic],
59
+ "component_scores": {{
60
+ "skills": [score with detailed explanation],
61
+ "experience": [score with detailed relevance analysis],
62
+ "education": [score with comprehensive education analysis],
63
+ "job_function": [score with detailed function alignment analysis]
64
+ }},
65
+ "analysis": [comprehensive analysis of overall fit],
66
+ "matching_skills": [list with proficiency details],
67
+ "missing_skills": [list with impact analysis],
68
+ "experience_match": {{
69
+ "score": [score based on actual relevance],
70
+ "relevant_experience": [years of truly relevant experience],
71
+ "analysis": [detailed analysis of experience relevance],
72
+ "role_relevance": [specific analysis of each role's relevance]
73
+ }},
74
+ "education_match": {{
75
+ "score": [score based on requirements match],
76
+ "degree_match": [analysis of degree level and field relevance],
77
+ "certifications": [analysis of professional certifications],
78
+ "gaps": [specific educational gaps],
79
+ "strengths": [educational strengths],
80
+ "recommendations": [educational development suggestions]
81
+ }},
82
+ "job_function_match": {{
83
+ "score": [score based on function alignment],
84
+ "function_relevance": [analysis of functional experience],
85
+ "progression": [career progression analysis],
86
+ "expertise_level": [assessment of functional expertise],
87
+ "gaps": [functional gaps identified],
88
+ "strengths": [functional strengths],
89
+ "growth_potential": [potential in the function]
90
+ }},
91
+ "strengths": [specific strengths with concrete examples],
92
+ "weaknesses": [specific gaps with improvement suggestions],
93
+ "overall_fit": [comprehensive assessment of fit]
94
+ }}
95
+
96
+ BE VERY STRICT in scoring. A score of 1.0 should only be given for perfect matches.
97
+ Focus on ACTUAL RELEVANCE, not just superficial matches.
98
+ ENSURE detailed analysis is provided for both education and job function sections.
99
+ **return only json**
100
+ """
101
+
102
+ response = pipe(prompt,max_new_tokens=5000, do_sample=True, temperature=0.7)
103
+ return response, prompt
104
+ # return prompt