Context Ranking Precision (ctx_rank_prec)
Contents
Metric Description
Context ranking precision measures how well the retrieved context chunks are ranked relative to their relevance for answering the original question (golden answer). It assesses whether the most relevant chunks appear higher in the ordering—not just whether relevant chunks exist. The metric blends (1) an LLM-as-a-Judge and (2) heuristic.
The score runs from 0 (poor ranking quality) to 100 (ideal ranking).
How to interpret the score
- Closer to 100: chunks are ranked in near-ideal order; the most relevant chunks appear first.
- Closer to 0: ranking is poor; irrelevant or weakly relevant chunks are ranked higher than highly relevant ones.
This metric evaluates the ranking quality of your RAG retrieval/reranking pipeline. It assumes the context has already been retrieved; it does not measure recall (whether all relevant documents were retrieved). Pair with context recall when you need to assess retrieval completeness.
API usage
Prerequisites
The examples call POST /runs/custom. Set AEGIS_API_KEY to your API key and AEGIS_API_BASE_URL to the API base URL, including the /api/v1 prefix (for example https://api.aegisevals.ai/api/v1). For a field-by-field description of the payload (top-level keys, evaluations, and each row in data), see Custom run request body.
Shortname: ctx_rank_prec
Default threshold: 80
Inputs (each object in data)
context(strorlistrequired): The retrieved context chunks to evaluate. Can be a single string or a list of chunk strings. There is no separateinputfield.golden_answer(strrequired): The question or query the chunks are judged against. The judge scores each chunk's relevance to this text, and embedding similarity is computed against it as well.
metric_args
ranks(list[number]optional): One rank per context chunk. When provided, chunks are reordered by these values before evaluation (lower rank first), for example to score a reranker's order. The numbers themselves are not returned. The list must have the same length as the context chunks. If omitted, chunks stay in the order given.
Evaluation metadata
On successful evaluation, the metric returns eval_metadata to interpret ranking quality and per-chunk relevance notes:
non_relevant_chunks_reasons(list[dict]): Chunk-level explanations for why a chunk is not perfectly relevant. Each object haschunk_position(int, 1-based position in the evaluated chunk list, after anyranksreorder) andreason(str).actual_ranks(list[int]): 0-based indexes of the evaluated chunks, listed in descending ideal-score order. These are the positions after anyranksreorder, not the rank numbers you sent.ideal_ranks(list[int]): Always0, 1, 2, …, parallel toactual_ranks.
Example
import json
import os
import requests
from dotenv import load_dotenv
load_dotenv(override=True)
_API_KEY = os.getenv("AEGIS_API_KEY")
_BASE_URL = os.getenv("AEGIS_API_BASE_URL")
_CUSTOM_RUN_URL = f"{_BASE_URL}/runs/custom"
def post_custom_run(payload: dict) -> requests.Response:
"""POST JSON payload to Aegis custom runs; returns the raw response."""
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {_API_KEY}",
}
return requests.post(
_CUSTOM_RUN_URL,
headers=headers,
data=json.dumps(payload),
)
if __name__ == "__main__":
data = [
{
"golden_answer": "What features does the new laptop have?",
"context": [
"The new laptop model has a high-resolution Retina display.",
"It includes a fast-charging battery with up to 12 hours of usage.",
"Security features include fingerprint authentication and an encrypted SSD.",
"Every purchase comes with a one-year warranty.",
"Pineapples taste great on pizza.",
],
}
]
payload = {
"threshold": 80,
"model_slug": "o4-mini",
"is_blocking": True,
"data_collection_id": None,
"evaluations": [
{
"metrics": [
{
"metric": "ctx_rank_prec",
"metric_args": {"ranks": [1, 0, 2, 3, 4]},
},
],
"threshold": 80,
"model_slug": "o4-mini",
"data": data,
}
],
}
response = post_custom_run(payload)
response.raise_for_status()
print(json.dumps(response.json(), indent=2))