# Generated by SnakeBridge v0.13.0 - DO NOT EDIT MANUALLY # Regenerate with: mix compile # Library: dspy 3.1.2 # Python module: dspy.evaluate.metrics defmodule Dspy.Evaluate.Metrics do @moduledoc """ Submodule bindings for `dspy.evaluate.metrics`. ## Version - Requested: 3.1.2 - Observed at generation: 3.1.2 ## Runtime Options All functions accept a `__runtime__` option for controlling execution behavior: Dspy.Evaluate.Metrics.some_function(args, __runtime__: [timeout: 120_000]) ### Supported runtime options - `:timeout` - Call timeout in milliseconds (default: 120,000ms / 2 minutes) - `:timeout_profile` - Use a named profile (`:default`, `:ml_inference`, `:batch_job`, `:streaming`) - `:stream_timeout` - Timeout for streaming operations (default: 1,800,000ms / 30 minutes) - `:session_id` - Override the session ID for this call - `:pool_name` - Target a specific Snakepit pool (multi-pool setups) - `:affinity` - Override session affinity (`:hint`, `:strict_queue`, `:strict_fail_fast`) ### Timeout Profiles - `:default` - 2 minute timeout for regular calls - `:ml_inference` - 10 minute timeout for ML/LLM workloads - `:batch_job` - Unlimited timeout for long-running jobs - `:streaming` - 2 minute timeout, 30 minute stream_timeout ### Example with timeout override # For a long-running ML inference call Dspy.Evaluate.Metrics.predict(data, __runtime__: [timeout_profile: :ml_inference]) # Or explicit timeout Dspy.Evaluate.Metrics.predict(data, __runtime__: [timeout: 600_000]) # Route to a pool and enforce strict affinity Dspy.Evaluate.Metrics.predict(data, __runtime__: [pool_name: :strict_pool, affinity: :strict_queue]) See `SnakeBridge.Defaults` for global timeout configuration. """ @doc false def __snakebridge_python_name__, do: "dspy.evaluate.metrics" @doc false def __snakebridge_library__, do: "dspy" @doc """ Evaluate exact match or F1-thresholded match for an example/prediction pair. If `example.answer` is a string, compare `pred.answer` against it. If it's a list, compare against any of the references. When `frac >= 1.0` (default), use EM; otherwise require that the maximum F1 across references is at least `frac`. ## Parameters - `example` - `dspy.Example` object with field `answer` (str or list[str]). - `pred` - `dspy.Prediction` object with field `answer` (str). - `trace` - Unused; reserved for compatibility. - `frac` - Threshold in [0.0, 1.0]. `1.0` means EM. (type: `float()`) ## Returns Returns `boolean()`. True if the match condition holds; otherwise False. ## Examples ```python import dspy example = dspy.Example(answer=["Eiffel Tower", "Louvre"]) pred = dspy.Prediction(answer="The Eiffel Tower") answer_exact_match(example, pred, frac=1.0) # equivalent to EM, True answer_exact_match(example, pred, frac=0.5) # True ``` """ @spec answer_exact_match(term(), term()) :: {:ok, term()} | {:error, Snakepit.Error.t()} @spec answer_exact_match(term(), term(), keyword()) :: {:ok, term()} | {:error, Snakepit.Error.t()} @spec answer_exact_match(term(), term(), term()) :: {:ok, term()} | {:error, Snakepit.Error.t()} @spec answer_exact_match(term(), term(), term(), keyword()) :: {:ok, term()} | {:error, Snakepit.Error.t()} @spec answer_exact_match(term(), term(), term(), term()) :: {:ok, term()} | {:error, Snakepit.Error.t()} @spec answer_exact_match(term(), term(), term(), term(), keyword()) :: {:ok, term()} | {:error, Snakepit.Error.t()} def answer_exact_match(example, pred) do SnakeBridge.Runtime.call(__MODULE__, :answer_exact_match, [example, pred], []) end def answer_exact_match(example, pred, opts) when is_list(opts) and (opts == [] or (is_tuple(hd(opts)) and tuple_size(hd(opts)) == 2 and is_atom(elem(hd(opts), 0)))) do SnakeBridge.Runtime.call(__MODULE__, :answer_exact_match, [example, pred], opts) end def answer_exact_match(example, pred, trace) do SnakeBridge.Runtime.call(__MODULE__, :answer_exact_match, [example, pred, trace], []) end def answer_exact_match(example, pred, trace, opts) when is_list(opts) and (opts == [] or (is_tuple(hd(opts)) and tuple_size(hd(opts)) == 2 and is_atom(elem(hd(opts), 0)))) do SnakeBridge.Runtime.call(__MODULE__, :answer_exact_match, [example, pred, trace], opts) end def answer_exact_match(example, pred, trace, frac) do SnakeBridge.Runtime.call(__MODULE__, :answer_exact_match, [example, pred, trace, frac], []) end def answer_exact_match(example, pred, trace, frac, opts) when is_list(opts) and (opts == [] or (is_tuple(hd(opts)) and tuple_size(hd(opts)) == 2 and is_atom(elem(hd(opts), 0)))) do SnakeBridge.Runtime.call(__MODULE__, :answer_exact_match, [example, pred, trace, frac], opts) end @doc """ Return True if any passage in `pred.context` contains the answer(s). Strings are normalized (and passages also use DPR normalization internally). ## Parameters - `example` - `dspy.Example` object with field `answer` (str or list[str]). - `pred` - `dspy.Prediction` object with field `context` (list[str]) containing passages. - `trace` - Unused; reserved for compatibility. ## Returns Returns `boolean()`. True if any passage contains any reference answer; otherwise False. ## Examples ```python import dspy example = dspy.Example(answer="Eiffel Tower") pred = dspy.Prediction(context=["The Eiffel Tower is in Paris.", "..."]) answer_passage_match(example, pred) # True ``` """ @spec answer_passage_match(term(), term()) :: {:ok, term()} | {:error, Snakepit.Error.t()} @spec answer_passage_match(term(), term(), keyword()) :: {:ok, term()} | {:error, Snakepit.Error.t()} @spec answer_passage_match(term(), term(), term()) :: {:ok, term()} | {:error, Snakepit.Error.t()} @spec answer_passage_match(term(), term(), term(), keyword()) :: {:ok, term()} | {:error, Snakepit.Error.t()} def answer_passage_match(example, pred) do SnakeBridge.Runtime.call(__MODULE__, :answer_passage_match, [example, pred], []) end def answer_passage_match(example, pred, opts) when is_list(opts) and (opts == [] or (is_tuple(hd(opts)) and tuple_size(hd(opts)) == 2 and is_atom(elem(hd(opts), 0)))) do SnakeBridge.Runtime.call(__MODULE__, :answer_passage_match, [example, pred], opts) end def answer_passage_match(example, pred, trace) do SnakeBridge.Runtime.call(__MODULE__, :answer_passage_match, [example, pred, trace], []) end def answer_passage_match(example, pred, trace, opts) when is_list(opts) and (opts == [] or (is_tuple(hd(opts)) and tuple_size(hd(opts)) == 2 and is_atom(elem(hd(opts), 0)))) do SnakeBridge.Runtime.call(__MODULE__, :answer_passage_match, [example, pred, trace], opts) end @doc """ Compute the Exact Match (EM) metric between a prediction and reference answers. Returns True if any reference exactly matches the prediction after normalization; otherwise False. Normalization applies Unicode NFD, lowercasing, punctuation removal, English article removal ("a", "an", "the"), and whitespace collapse. ## Parameters - `prediction` - Predicted answer string. (type: `String.t()`) - `answers_list` - List of reference answers. (type: `list(String.t())`) ## Returns Returns `boolean()`. Whether any reference exactly equals the prediction after normalization. ## Examples ```python EM("The Eiffel Tower", ["Eiffel Tower", "Louvre"]) # True EM("paris", ["Paris"]) # True EM("paris", ["Paris, France"]) # False ``` """ @spec em(term(), term(), keyword()) :: {:ok, term()} | {:error, Snakepit.Error.t()} def em(prediction, answers_list, opts \\ []) do SnakeBridge.Runtime.call(__MODULE__, "EM", [prediction, answers_list], opts) end @doc """ Compute boolean exact match after normalization. ## Parameters - `prediction` - Predicted answer. (type: `String.t()`) - `ground_truth` - Reference answer. (type: `String.t()`) ## Returns Returns `boolean()`. True if normalized strings are identical; otherwise False. ## Examples ```python em_score("Paris", "paris") # True ``` """ @spec em_score(term(), term(), keyword()) :: {:ok, term()} | {:error, Snakepit.Error.t()} def em_score(prediction, ground_truth, opts \\ []) do SnakeBridge.Runtime.call(__MODULE__, :em_score, [prediction, ground_truth], opts) end @doc """ Compute the maximum token-level F1 score against reference answers. Strings are normalized (same as in `EM`) and whitespace-tokenized. The function returns the maximum F1 over all provided references. ## Parameters - `prediction` - Predicted answer string. (type: `String.t()`) - `answers_list` - List of reference answers. (type: `list(String.t())`) ## Returns Returns `float()`. Highest F1 score in [0.0, 1.0]. ## Examples ```python round(F1("Eiffel Tower is in Paris", ["Paris"]), 2) # 0.33 ``` """ @spec f1(term(), term(), keyword()) :: {:ok, term()} | {:error, Snakepit.Error.t()} def f1(prediction, answers_list, opts \\ []) do SnakeBridge.Runtime.call(__MODULE__, "F1", [prediction, answers_list], opts) end @doc """ Compute token-level F1 between prediction and reference (after normalization). Strings are normalized (see `normalize_text`) and split by whitespace. F1 is computed from token precision and recall. If there is no token overlap, returns 0. If both sides are empty, a diagnostic message is printed; score remains 0. ## Parameters - `prediction` - Predicted answer. (type: `String.t()`) - `ground_truth` - Reference answer. (type: `String.t()`) ## Returns Returns `float()`. F1 score in [0.0, 1.0]. ## Examples ```python round(f1_score("the Eiffel Tower", "Eiffel Tower"), 2) # 1.0 ``` """ @spec f1_score(term(), term(), keyword()) :: {:ok, term()} | {:error, Snakepit.Error.t()} def f1_score(prediction, ground_truth, opts \\ []) do SnakeBridge.Runtime.call(__MODULE__, :f1_score, [prediction, ground_truth], opts) end @doc """ Compute the maximum HotPotQA-style F1 score against reference answers. Like `F1`, but if either normalized side is one of {"yes", "no", "noanswer"} and they differ, the score is 0. Otherwise, standard token-level F1 is used. ## Parameters - `prediction` - Predicted answer. (type: `String.t()`) - `answers_list` - List of reference answers. (type: `list(String.t())`) ## Returns Returns `float()`. Highest HotPotQA-style F1 in [0.0, 1.0]. ## Examples ```python HotPotF1("yes", ["no"]) # 0.0 ``` """ @spec hot_pot_f1(term(), term(), keyword()) :: {:ok, term()} | {:error, Snakepit.Error.t()} def hot_pot_f1(prediction, answers_list, opts \\ []) do SnakeBridge.Runtime.call(__MODULE__, "HotPotF1", [prediction, answers_list], opts) end @doc """ Compute HotPotQA-style token F1 with special labels. If either normalized string is in {"yes", "no", "noanswer"} and they differ, the score is 0. Otherwise compute standard token F1 after normalization. ## Parameters - `prediction` - Predicted answer. (type: `String.t()`) - `ground_truth` - Reference answer. (type: `String.t()`) ## Returns Returns `float()`. HotPotQA-style F1 score in [0.0, 1.0]. ## Examples ```python hotpot_f1_score("no", "yes") # 0.0 ``` """ @spec hotpot_f1_score(term(), term(), keyword()) :: {:ok, term()} | {:error, Snakepit.Error.t()} def hotpot_f1_score(prediction, ground_truth, opts \\ []) do SnakeBridge.Runtime.call(__MODULE__, :hotpot_f1_score, [prediction, ground_truth], opts) end @doc """ Normalize text for string and token comparisons. Steps: 1) Unicode NFD normalization 2) lowercasing 3) punctuation removal 4) English article removal ("a", "an", "the") 5) whitespace collapse ## Parameters - `s` - Input string. (type: `String.t()`) ## Returns Returns `String.t()`. Normalized string. ## Examples ```python normalize_text("The, Eiffel Tower!") # "eiffel tower" ``` """ @spec normalize_text(term(), keyword()) :: {:ok, term()} | {:error, Snakepit.Error.t()} def normalize_text(s, opts \\ []) do SnakeBridge.Runtime.call(__MODULE__, :normalize_text, [s], opts) end @doc """ Compute token-level precision of prediction against reference (after normalization). Precision is (# overlapping tokens) / (# tokens in prediction). If there is no token overlap, returns 0. If both sides are empty, a diagnostic message is printed; precision remains 0. ## Parameters - `prediction` - Predicted answer. (type: `String.t()`) - `ground_truth` - Reference answer. (type: `String.t()`) ## Returns Returns `float()`. Precision in [0.0, 1.0]. ## Examples ```python precision_score("eiffel tower in paris", "eiffel tower") # 0.67 ``` """ @spec precision_score(term(), term(), keyword()) :: {:ok, term()} | {:error, Snakepit.Error.t()} def precision_score(prediction, ground_truth, opts \\ []) do SnakeBridge.Runtime.call(__MODULE__, :precision_score, [prediction, ground_truth], opts) end end