# After optimization, test on unseen data
test_dataset = client.get_dataset(name="agent-opt-test")

test_results = evaluate_prompt(
    prompt=result.prompt,  # Best prompt from optimization
    dataset=test_dataset,
    scoring_metrics=[my_metric],
    task_threads=4,
)

print(f"Test score: {test_results.mean_scores}")
```

This final test score gives you confidence that improvements will transfer to real-world usage.

## Best practices

* **Keep datasets immutable** during an optimization run; create a new dataset version if you need to add rows.
* **Use validation datasets** to avoid overfitting—split your data 70/30 or 80/20 between training and validation sets.
* **Log context** fields if you run RAG-style prompts so failure analyses can surface missing passages.
* **Track splits via metadata** (e.g., `metadata["split"] = "eval"`) for additional organization beyond separate datasets.
* **Document ownership** using dataset descriptions so teams know who curates each collection.
* **Keep schema + prompt in sync** – if your prompt expects `{context}`, ensure every dataset row defines that key or provide defaults in the optimizer.

## Validation checklist

* Confirm row counts in the Opik **Datasets** tab (or by running `len(dataset.get_items())` in Python) before and after uploads.
* Spot-check rows in the dashboard’s Dataset viewer.
* If rows include multimodal assets or tool payloads, confirm they appear in the trace tree once you run an optimization.
* Run an initial small-batch optimization with a few rows of data to validate everything end to end.

## Next steps

Define how you will score results with [Define metrics](/agent_optimization/optimization/define_metrics), then follow [Optimize prompts](/agent_optimization/optimization/optimize_prompts) to launch experiments. For domain-specific scoring, extend the dataset with extra fields and reference them inside [Custom metrics](/agent_optimization/advanced/custom_metrics).