# Custom Metric: One template/prompt to extract 4 scores/results
class EvaluateSummary(base_metric.BaseMetric):
    # Constructor
    def __init__(self, name: str):
        self.name = name

    def score(
        self, summary: str, instruction: str, model: str = "gpt-4o-mini", **kwargs
    ):
        prompt = f"""
            Summary: {summary}
            Instruction: {instruction}

            Evaluate the summary based on the following criteria:
            1. Relevance (1-5): How well does the summary address the given instruction?
            2. Conciseness (1-5): How concise is the summary while retaining key information?
            3. Technical Accuracy (1-5): How accurately does the summary convey technical details?

            Your response MUST be in the following JSON format:
            {{
                "relevance": {{
                    "score": <int>,
                    "explanation": "<string>"
                }},
            "conciseness": {{
                "score": <int>,
                "explanation": "<string>"
                }},
            "technical_accuracy": {{
                "score": <int>,
                "explanation": "<string>"
                }}
            }}

            Ensure that the scores are integers between 1 and 5, and that the explanations are concise.
        """

        response = openai_client.chat.completions.create(
            model=model,
            max_tokens=1000,
            messages=[{"role": "user", "content": prompt}],
            response_format=json_schema,
        )

        eval_dict = json.loads(response.choices[0].message.content)

        return [
            score_result.ScoreResult(
                name="summary_relevance",
                value=eval_dict["relevance"]["score"],
                reason=eval_dict["relevance"]["explanation"],
            ),
            score_result.ScoreResult(
                name="summary_conciseness",
                value=eval_dict["conciseness"]["score"],
                reason=eval_dict["conciseness"]["explanation"],
            ),
            score_result.ScoreResult(
                name="summary_technical_accuracy",
                value=eval_dict["technical_accuracy"]["score"],
                reason=eval_dict["technical_accuracy"]["explanation"],
            ),
            score_result.ScoreResult(
                name="summary_average_score",
                value=round(sum(eval_dict[k]["score"] for k in eval_dict) / 3, 2),
                reason="The average of the 3 summary evaluation metrics",
            ),
        ]
```

### Create the task we want to evaluate

We can now create the task we want to evaluate. In this case, we will have the dataset item as an input and return a dictionary containing the summary and the instruction so that we can use this in the evaluation metrics:

```python
import requests
import io
from PyPDF2 import PdfReader
from typing import Dict