|
|
import os |
|
|
import logging |
|
|
from mistralai import Mistral |
|
|
|
|
|
from model import ApplicantDocument, JobDocument, ApplicantEvaluation |
|
|
from .constant import MISTRAL_MODEL |
|
|
|
|
|
logger = logging.getLogger(__name__) |
|
|
logging.basicConfig(level=logging.INFO) |
|
|
|
|
|
class ApplicantEvaluator: |
|
|
def __init__(self, api_key: str = None): |
|
|
if api_key is None: |
|
|
|
|
|
api_key = os.environ.get("MISTRAL_API_KEY") |
|
|
if not api_key: |
|
|
raise ValueError("API key for Mistral is not set.") |
|
|
self.client = Mistral(api_key=api_key) |
|
|
|
|
|
def evaluate_applicant( |
|
|
self, applicant_doc: ApplicantDocument, job_doc: JobDocument |
|
|
) -> dict: |
|
|
""" |
|
|
Evaluate the applicant's CV against the job description. |
|
|
|
|
|
Parameters |
|
|
---------- |
|
|
applicant_doc: ApplicantDocument |
|
|
The applicant's CV document containing structured information. |
|
|
job_doc: JobDocument |
|
|
The job description document containing structured information. |
|
|
|
|
|
Returns |
|
|
------- |
|
|
dict: A dictionary containing the evaluation results. |
|
|
""" |
|
|
if not applicant_doc or not job_doc: |
|
|
raise ValueError("Applicant Documeent or Job Document is empty.") |
|
|
|
|
|
response = {"applicant": applicant_doc, "job": job_doc} |
|
|
|
|
|
|
|
|
logger.info("Evaluating applicant document against job document") |
|
|
evaluation_response = self.client.chat.parse( |
|
|
model=MISTRAL_MODEL, |
|
|
messages=[ |
|
|
{ |
|
|
"role": "system", |
|
|
"content": "Evaluate the match between the applicant's CV and the job description. Give a clear indication of the degree of match and give thorough justification for your conclusion. If user provide invalid CV or empty job description, just return no match evaluation. The evaluation should include a match score, reasoning, and match labels. Match score should be a float between 0 and 1, where 0 means no match and 1 means perfect match. ", |
|
|
}, |
|
|
{ |
|
|
"role": "user", |
|
|
"content": f"CV: \n{applicant_doc}\n=========\nJob Description: \n{job_doc}", |
|
|
}, |
|
|
], |
|
|
response_format=ApplicantEvaluation, |
|
|
temperature=0, |
|
|
) |
|
|
|
|
|
response["evaluation"] = evaluation_response.choices[0].message.content |
|
|
return response |
|
|
|
|
|
|
|
|
if __name__ == "__main__": |
|
|
pass |
|
|
|