RAGASragas 0.4.3 · Python 3.10+
Dashboard
0%
1
Curious builder0 XP earned · 300 to level 2
0 daysFinish a lesson to begin
Badge collection0 of 6 unlocked
28 small wins to finish your pathNext lesson →

DiscreteMetric

DiscreteMetric is a RAGAS class that turns a question you write in plain words into a judged metric, where the judge must answer with one of the values you allow.

Last updated: 29 Sep, 2026 · RAGAS 0.4.3

Some qualities no formula can check: tone, politeness, whether an answer sounds like your brand. A DiscreteMetric puts that question to the judge and keeps its answer inside the list you give.

The DiscreteMetric API

python
from ragas.metrics import DiscreteMetric

metric = DiscreteMetric(
    name="...",
    allowed_values=["a", "b"],          # the only answers the judge may give
    prompt="Question ... {response}",   # sample fields go in braces
)
metric.score(response=..., llm=judge).value

The judge is passed when you score, not when you build the metric.

A tone check for the support bot

python
tone = DiscreteMetric(
    name="support_tone",
    allowed_values=["friendly", "blunt"],
    prompt="Is this customer support reply friendly or blunt? Answer friendly or blunt.\n\nReply: {response}",
)
Project files used on this pageThis lesson builds on a project from earlier lessons. The code below imports this file. Click a file to see its code, or follow the link to the lesson that wrote it. To run the code yourself, keep it in the same folder.
View the code here
judge.py
import os

from google import genai
from openai import AsyncOpenAI
from ragas.embeddings import GoogleEmbeddings
from ragas.llms import llm_factory

groq = AsyncOpenAI(
    api_key=os.environ.get("JUDGE_GROQ", os.environ["GROQ_API_KEY"]),
    base_url="https://api.groq.com/openai/v1",
)
judge = llm_factory("openai/gpt-oss-20b", provider="openai", client=groq)


class OneTextPerCall(GoogleEmbeddings):
    """gemini-embedding-2 turns a list into one embedding, so embed each text on its own."""

    def embed_texts(self, texts, **kwargs):
        return [self.embed_text(text) for text in texts]

    async def aembed_texts(self, texts, **kwargs):
        return [await self.aembed_text(text) for text in texts]


embeddings = OneTextPerCall(client=genai.Client(), model="gemini-embedding-2")

Judging the tone of two replies

ExampleAPI key
from judge import judge
from ragas.metrics import DiscreteMetric

tone = DiscreteMetric(
    name="support_tone",
    allowed_values=["friendly", "blunt"],
    prompt="Is this customer support reply friendly or blunt? Answer friendly or blunt.\n\nReply: {response}",
)
for reply in ["Thanks for asking! The PixelPhone 15 is priced at $899.", "$899. Read the website."]:
    result = tone.score(response=reply, llm=judge)
    print(result.value, "|", reply)

What the judge decided

  • The thanking reply is marked with one allowed value and the curt one with the other; the output shows which.
  • The value is always from allowed_values. RAGAS gives the judge a response class that only accepts those words, so a free-text answer cannot slip through.

DiscreteMetric vs a decorated function

DiscreteMetric@discrete_metric
Who decidesThe judge, reading your promptYour Python code
CostOne judge call per sampleFree
Good forTone, safety, styleRules a regex can check

When to write a DiscreteMetric

  • Brand voice or politeness rules that a reviewer would otherwise read by hand.
  • Safety checks, such as whether a reply gives medical or legal advice.
Watch out. Ask one thing per metric. A prompt that asks whether a reply is polite, correct and complete gets one value for three questions, and you cannot tell which one failed. Three metrics, one question each.
Try it yourself
  • Add a third allowed value, "rude", and a reply that should earn it.
  • Write a DiscreteMetric that asks whether a reply promises something the store might not do, with values safe and risky.

Slow is fine. Stopping is the only problem.