interviewer / tests /grader.py
IliaLarchenko's picture
Grader refactoring
cb330d2
import json
from typing import Dict, Any, List
from openai import OpenAI
from tests.testing_prompts import grader_prompt
BASE_URL = "https://api.openai.com/v1"
JSON_INDENT = 4
def format_interview_data(interview_data):
return [
f"Interview type: {interview_data['inputs']['interview_type']}",
f"Interview difficulty: {interview_data['inputs']['difficulty']}",
f"Interview topic: {interview_data['inputs']['topic']}",
]
def generate_interview_summary(interview_data: Dict[str, Any]) -> List[str]:
"""
Generate a summary of the interview data.
:param interview_data: Dictionary containing interview data.
:return: List of summary strings.
"""
summary = format_interview_data(interview_data)
if interview_data["inputs"]["requirements"]:
summary.append(f"Interview requirements: {interview_data['inputs']['requirements']}")
summary.append(f"Problem statement proposed by interviewer: {interview_data['problem_statement']}")
summary.append(f"\nTranscript of the whole interview below:")
summary += interview_data["transcript"]
summary.append(f"\nTHE MAIN PART OF THE INTERVIEW ENDED HERE.")
summary.append(f"Feedback provided by interviewer: {interview_data['feedback']}")
return summary
def grade(json_file_path: str, model: str = "gpt-4o", suffix: str = "") -> Dict[str, Any]:
"""
Grade the interview data and provide feedback.
:param json_file_path: Path to the JSON file containing interview data.
:param model: Model to use for grading.
:param suffix: Suffix to add to the feedback file name.
:return: Feedback dictionary.
"""
try:
with open(json_file_path) as file:
interview_data = json.load(file)
except FileNotFoundError:
return {"error": "File not found"}
except json.JSONDecodeError:
return {"error": "Invalid JSON format"}
interview_summary_list = generate_interview_summary(interview_data)
messages = [
{"role": "system", "content": grader_prompt},
{"role": "user", "content": f"Please evaluate the interviewer based on the following data: \n {'\n'.join(interview_summary_list)}"},
]
feedback = call_openai_api(messages, model)
populate_feedback_metadata(feedback, json_file_path, interview_data, model)
calculate_overall_score(feedback)
save_feedback(json_file_path, feedback, suffix)
return feedback
def call_openai_api(messages, model):
client = OpenAI(base_url=BASE_URL)
response = client.chat.completions.create(model=model, messages=messages, temperature=0, response_format={"type": "json_object"})
return json.loads(response.choices[0].message.content)
def populate_feedback_metadata(feedback: Dict[str, Any], json_file_path: str, interview_data: Dict[str, Any], model: str) -> None:
"""
Populate feedback metadata with interview details.
:param feedback: Feedback dictionary to populate.
:param json_file_path: Path to the JSON file containing interview data.
:param interview_data: Dictionary containing interview data.
:param model: Model used for grading.
"""
feedback.update(
{
"file_name": json_file_path,
"agent_llm": interview_data["interviewer_llm"],
"candidate_llm": interview_data["candidate_llm"],
"grader_model": model,
"type": interview_data["inputs"]["interview_type"],
"difficulty": interview_data["inputs"]["difficulty"],
"topic": interview_data["inputs"]["topic"],
"average_response_time_seconds": interview_data["average_response_time_seconds"],
"number_of_messages": len(interview_data["transcript"]),
}
)
def calculate_overall_score(feedback: Dict[str, Any]) -> None:
"""
Calculate the overall score from the feedback.
:param feedback: Feedback dictionary containing scores.
"""
scores = [
feedback[key]
for key in feedback
if (key.startswith("interviewer_") or key.startswith("feedback_") or key.startswith("problem_")) and feedback[key] is not None
]
feedback["overall_score"] = sum(scores) / len(scores)
def save_feedback(json_file_path: str, feedback: Dict[str, Any], suffix: str) -> None:
"""
Save the feedback to a JSON file.
:param json_file_path: Path to the original JSON file.
:param feedback: Feedback dictionary to save.
:param suffix: Suffix to add to the feedback file name.
"""
with open(json_file_path.replace(".json", f"_feedback_{suffix}.json"), "w") as file:
json.dump(feedback, file, indent=JSON_INDENT)