soev for developers
soev-evalsReference

soev_evals.judges

An LLM judge with the prompts of the built-in judge criteria, and an offline language detector.

The judge criteria of soev_evals.criteria ask a Judge for a label, and reply.language asks a LanguageDetector for the language of each sentence. This package holds the built-in implementations of both ports. Give them in the CriterionContext of a run. For the CLI, a runtime provider gives the judge, and the CLI uses LangidDetector when the provider gives no detector.

Judges

LLMJudge grades with the prompts of this package through a model that you connect with a JudgeLLM adapter.

LLMJudge

classLLMJudge(llm, prompts)

A Judge that asks a model, through a JudgeLLM adapter, for a label.

For each request, the system message is the context prefix and then the prompt of the request's task. The user message is the request's inputs as JSON. It asks the model for a JSON object with a label from the allowed labels and a detail. Then it validates the answer.

Make a judge that uses llm with prompts.

paramllmJudgeLLM

The model that answers, through an adapter for your model provider.

parampromptsMapping[str, str]

The prompt of each task, by task name, for example from load_prompts. The judge copies it.

methodjudgeasync (request) -> JudgeResult

Return the label of the model for request.

paramrequestJudgeRequest

The task, the inputs and the allowed labels.

Returns

JudgeResult

The label that the model chose, one of request.allowed_labels, and its explanation.

Raises:

  • JudgeError: prompts has no prompt for the task, or the model's answer is not valid JSON of the schema, or has a label that the request does not allow. Also when the request has a context prefix and the model's context window is unknown or too small.

JudgeLLM

protocolJudgeLLM

The model of an LLMJudge: an adapter that sends one chat request and returns the JSON answer.

Write an adapter for your model provider. complete must raise JudgeError for a failed call: a criterion records it as a verdict with the status "error", but any other exception stops the run.

Example

from collections.abc import Mapping

import httpx
from pydantic import JsonValue

from soev_evals.core import JudgeError
from soev_evals.judges import LLMJudge, load_prompts


class ChatCompletionsLLM:
    context_window = 128_000

    def __init__(self, client: httpx.AsyncClient, model: str) -> None:
        self._client = client
        self._model = model

    async def complete(self, *, system: str, user: str, schema: Mapping[str, JsonValue]) -> str:
        schema_format = {"name": "verdict", "schema": dict(schema)}
        body = {
            "model": self._model,
            "messages": [{"role": "system", "content": system}, {"role": "user", "content": user}],
            "response_format": {"type": "json_schema", "json_schema": schema_format},
        }
        try:
            response = await self._client.post("chat/completions", json=body)
            response.raise_for_status()
            return response.json()["choices"][0]["message"]["content"]
        except (httpx.HTTPError, KeyError, IndexError, ValueError) as exc:
            raise JudgeError(f"judge call failed: {type(exc).__name__}") from exc


client = httpx.AsyncClient(base_url="http://localhost:8000/v1/")
judge = LLMJudge(ChatCompletionsLLM(client, "my-judge-model"), load_prompts())
attributecontext_windowint | None

The context window of the model, in tokens, or None when unknown.

LLMJudge reads it only for a request with a context prefix. It then refuses the request when the window is unknown, or when the estimated tokens do not fit with a safety margin.

methodcompleteasync (*, system, user, schema) -> str

Send one chat request and return the text of the answer.

paramsystemstr

The system message: the context prefix of the request, then the prompt of the task.

paramuserstr

The user message: the inputs of the request, as JSON.

paramschemaMapping[str, JsonValue]

The JSON schema that the answer must satisfy. Give it to the model as a structured output format when the provider supports one.

Returns

str

The text of the answer. LLMJudge parses it as JSON and validates it.

Raises:

  • JudgeError: The call failed.

load_prompts

functionload_prompts() -> dict[str, str]

Read the prompt of each built-in judge task.

The package ships one prompt file for each built-in judge kind: behaviour.expected, compare.equivalent, nuggets.coverage, privacy.names and rubric.judge.

Returns

dict[str, str]

The text of each prompt, by task name. Give it to LLMJudge, and its hashes to the run manifest.

prompt_shas

functionprompt_shas(prompts) -> dict[str, str]

Hash the exact prompt and rubric content used by a run.

The run manifest records the hashes, so a resumed run fails when a prompt changed.

parampromptsMapping[str, str]

The text of each prompt or rubric, by name.

Returns

dict[str, str]

The SHA-256 hex digest of each text, by the same name. Give it as shas to build_manifest of soev_evals.run.

Language detection

LangidDetector identifies the language offline, with a bundled model.

LangidDetector

classLangidDetector()

A LanguageDetector with the bundled model of py3langid.

The model runs offline and gives the same answer for the same text. The CLI gives this detector to the reply.language criterion when the runtime provider gives none.

Load the bundled model once, so that the first detect call is not slow.

methoddetect(text) -> str

Return an ISO language code for nonempty linguistic input.

paramtextstr

One sentence.

Returns

str

The ISO 639-1 code of the language, for example "nl".

Raises:

  • LanguageDetectionError: text is empty or blank, or the model finds no language in it.

On this page