# Load and extract text from PDFs
@opik.track
def load_pdf(pdf_url: str) -> str:
    # Download the PDF
    response = requests.get(pdf_url)
    pdf_file = io.BytesIO(response.content)

    # Read the PDF
    pdf_reader = PdfReader(pdf_file)

    # Extract text from all pages
    text = ""
    for page in pdf_reader.pages:
        text += page.extract_text()

    # Truncate the text to 100000 characters as this is the maximum supported by OpenAI
    text = text[:100000]
    return text


def evaluation_task(x: Dict):
    text = load_pdf(x["pdf_url"])
    instruction = x["instruction"]
    model = MODEL
    density_iterations = DENSITY_ITERATIONS

    result = chain_of_density_summarization(
        document=text,
        instruction=instruction,
        model=model,
        density_iterations=density_iterations,
    )

    return {"summary": result}
```

### Run the automated evaluation

We can now use the `evaluate` method to evaluate the summaries in our dataset:

```python
from opik.evaluation import evaluate

MODEL = "gpt-4o-mini"
DENSITY_ITERATIONS = 2

experiment_config = {
    "model": MODEL,
    "density_iterations": DENSITY_ITERATIONS,
}

res = evaluate(
    dataset=dataset,
    experiment_config=experiment_config,
    task=evaluation_task,
    scoring_metrics=[EvaluateSummary(name="summary-metrics")],
    prompts=[ITERATION_SUMMARY_PROMPT, FINAL_SUMMARY_PROMPT],
    project_name="Chain of Density Summarization - Experiments",
)
```

The experiment results are now available in the Opik UI:

![Trace UI](https://raw.githubusercontent.com/comet-ml/opik/main/apps/opik-documentation/documentation/static/img/cookbook/chain_density_experiment_cookbook.png)

## Comparing prompt templates

We will update the iteration summary prompt and evaluate its impact on the evaluation metrics.

```python
import opik

ITERATION_SUMMARY_PROMPT = opik.Prompt(
    name="Iteration Summary Prompt",
    prompt="""Document: {{document}}
Current summary: {{current_summary}}
Instruction to focus on: {{instruction}}

Generate a concise, entity-dense, and highly technical summary from the provided Document that specifically addresses the given Instruction.

Guidelines:
1. **Maximize Clarity and Density**: Revise the current summary to enhance flow, density, and conciseness.
2. **Eliminate Redundant Language**: Avoid uninformative phrases such as "the article discusses."
3. **Ensure Self-Containment**: The summary should be dense and concise, easily understandable without referring back to the document.
4. **Align with Instruction**: Make sure the summary specifically addresses the given instruction.

""".rstrip().lstrip(),
)
```

```python
from opik.evaluation import evaluate

MODEL = "gpt-4o-mini"
DENSITY_ITERATIONS = 2

experiment_config = {
    "model": MODEL,
    "density_iterations": DENSITY_ITERATIONS,
}

res = evaluate(
    dataset=dataset,
    experiment_config=experiment_config,
    task=evaluation_task,
    scoring_metrics=[EvaluateSummary(name="summary-metrics")],
    prompts=[ITERATION_SUMMARY_PROMPT, FINAL_SUMMARY_PROMPT],
    project_name="Chain of Density Summarization - Experiments",
)
```

You can now compare the results between the two experiments in the Opik UI:

![Trace UI](https://raw.githubusercontent.com/comet-ml/opik/main/apps/opik-documentation/documentation/static/img/cookbook/chain_density_trace_comparison_cookbook.png)