Spaces:
No application file
No application file
File size: 8,385 Bytes
37d3a3b |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 |
import openai;
import json, os,sys
from dotenv import load_dotenv
load_dotenv()
# openai.api_key = os.environ.get("OPENAI_API_KEY")
import openai; openai.api_key = "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"
from Candidate import JobCandidate
import litellm
from litellm import completion
import xml.etree.ElementTree as ET
def printc(obj, color="cyan"):
color_code = {
"black": "30", "red": "31", "green": "32", "yellow": "33",
"blue": "34", "magenta": "35", "cyan": "36", "white": "37"
}
colored_text = f"\033[{color_code[color]}m{obj}\033[0m" if color in color_code else obj
print(colored_text)
LLM=os.environ.get("COMPARATOR_LLM","chat-bison")
# LLM=os.environ.get("COMPARATOR_LLM","gpt-3.5-turbo-1106")
def getContent(candidateA, candidateB) -> str:
return (
"Given the following two candidates, choose between the two. Here is the rubric: "
+ get_rubric()
+ "Candidate A: "
+ "\nRESUME:\n" +candidateA.resume_text+"\nEND Resume\n"
+ "\nGITHUB:\n" +candidateA.github_text+"\nEND GITHUB\n"
+ " END OF Candidate A"
+ "\n\nCandidate B: "
+ "\nRESUME:\n" +candidateB.resume_text+"\nEND Resume\n"
+ "\nGITHUB:\n" +candidateB.github_text+"\nEND GITHUB\n"
+ " END OF Candidate B"
)
def google_compare_resumes(content:str, nameA="", nameB=""):
choice =0
messages=[
{"role": "user", "content": "You are an LLM recrutier who will choose between two candidates based on an provided rubric"},
{"role": "user", "content":
"""
You are an LLM recrutier who will choose between two candidates based on an provided rubric,
you will only use bullet point and broken english instead of proper english to be more concise
"""
},
{"role": "assistant", "content":
"""
I can assist you in evaluating two candidates based on a provided rubric.
Provide me with the rubric or the criteria you'd like to use for the evaluation,
and I'll help you assess the candidates accordingly and explain myself in less that 50 words
"""
},
{"role": "user", "content": content}
]
response =completion(model=LLM, messages=messages,max_tokens=170,)
printc(response["choices"][0]["message"],'red')
messages=[
{"role": "assistant","content":str(response["choices"][0]["message"])},
{"role": "user","content":"okay so now with just a single token select A or B, <select>choice letter goes here</select>"}
]
retries=3
while retries >0:
response =completion(model=LLM, messages=messages,max_tokens=5,temperature=0.01)
# printc(response,'cyan')
html=''.join(str(response["choices"][0]["message"]['content']).split())
if "<select>" in html:
xml_content = f'<root>{html}</root>'
root = ET.fromstring(xml_content)
select_element = root.find('select')
letter = str(select_element.text)
else:
letter = str(html)[0]
if letter == 'A':
printc(nameA+" wins over "+nameB,"cyan")
return -1
elif letter == 'B':
printc(nameB+" wins over "+nameA,"green")
return 1
retries-=1
return choice
def compare_resumes(content:str, nameA="", nameB=""):
retries = 3
choice = 0
while retries > 0:
try:
response = openai.ChatCompletion.create(
model='gpt-4-0613',
messages=[
{"role": "user", "content":
"""
You are an LLM recrutier who will choose between two candidates based on an provided rubric,
you will only use bullet point and broken english instead of proper english to be more concise in your justification
You will also provide args for selectCandidate
"""
},
{"role": "assistant", "content":
"""
I can assist you in evaluating two candidates based on a provided rubric.
Provide me with the rubric or the criteria you'd like to use for the evaluation,
and I'll help you assess the candidates accordingly and explain myself conscisely and will
provide args for selectCandidate
"""
},
{"role": "user", "content": content}
],
functions=[
{
"name": "selectCanidate",
"description": "choose between the two canidates",
"parameters": {
"type": "object",
"properties": {
"choice_num": {
"type": "integer",
"description": "1 for Candidate A is the best fit, 2 for Candidate B is the best fit",
"required": ["choice_num"],
},
"justifcation": {
"type": "string",
"description": "justifcation for why you chose the candidate",
"required": ["justifcation"],
},
}
},
}
],
function_call="auto",
)
message = response["choices"][0]["message"]
if message.get("function_call"):
function_name = message["function_call"]["name"]
function_args = json.loads(message["function_call"]["arguments"])
choice = (int(function_args["choice_num"]))
if function_name == "selectCanidate":
if choice == 1:
choice = -1
printc(nameA+" wins over "+nameB, "cyan")
elif choice == 2:
choice = 1
printc(nameB+" wins over "+nameA, "green")
printc(function_args["justifcation"], "yellow")
break # Break the loop if everything went well
except Exception as e:
printc("Error: " + str(e), "red")
retries -= 1
if retries == 0:
printc("Maximum retries reached.", "red")
return 0 # Or any other default value or error indicator
return choice
def get_rubric():
text = open("rubric.txt","r").read()
return "\nRubric:\n" +str(text)+"\nEND Rubric\n"
def comp(candidateA:JobCandidate, candidateB:JobCandidate, rub_id:int=0 ) -> int:
comp_table= json.load(open("comparisons.json","r"))
tag= (candidateA.email+"#"+candidateB.email+"#"+str(rub_id))
inv_tag= (candidateB.email+"#"+candidateA.email+"#"+str(rub_id))
if tag in comp_table:
if comp_table[tag]==1:
printc(candidateA.name+" wins over "+candidateB.name,"magenta")
elif comp_table[tag]==-1:
printc(candidateB.name+" wins over "+candidateA.name,"magenta")
return comp_table[tag]
elif inv_tag in comp_table:
if comp_table[inv_tag]==1:
printc(candidateA.name+" wins over "+candidateB.name,"magenta")
elif comp_table[inv_tag]==-1:
printc(candidateB.name+" wins over "+candidateA.name,"magenta")
else:
choice = compare_resumes(getContent(candidateA, candidateB), candidateA.name, candidateB.name)
comp_table[tag]=choice
comp_table[inv_tag]=choice*-1
json.dump(comp_table, open("comparisons.json","w"))
return choice
def compute_scores(candidates):
scores = {candidate.email: 0 for candidate in candidates}
for i, candidateA in enumerate(candidates):
for candidateB in candidates[i+1:]:
result = comp(candidateA, candidateB)
scores[candidateA.email] += result
scores[candidateB.email] -= result
print(scores)
return scores
def bubble_sort(candidates: list) -> list:
scores = compute_scores(candidates)
return sorted(candidates, key=lambda x: scores[x.email]) |