Evaluator SDK Basics
Score AI outputs against built-in eval templates with fi.evals: judged checks, deterministic checks, and batch loops with the Evaluator class.
Initialize the Evaluator class from fi.evals, then run built-in eval templates against real support replies: a judged context-adherence check, a deterministic JSON check, a PII screen, and a batch conciseness pass. Each call returns an output (a score or a pass/fail verdict, depending on the template) and a reason.
| Time | Difficulty | Package |
|---|---|---|
| 15 min | Beginner | ai-evaluation |
- Future AGI account → app.futureagi.com
- API keys:
FI_API_KEYandFI_SECRET_KEY(see API keys) - Python 3.11+
Install
pip install ai-evaluation
export FI_API_KEY="your-api-key"
export FI_SECRET_KEY="your-secret-key"
Tutorial
Initialize the evaluator
import os
from fi.evals import Evaluator
evaluator = Evaluator(
fi_api_key=os.environ["FI_API_KEY"],
fi_secret_key=os.environ["FI_SECRET_KEY"],
)No output to check here. The Evaluator instance is what every later step calls .evaluate() on.
Score a support reply for context adherence
context_adherence is a judged template: it needs a model_name to act as the grading model.
support_context = (
"Refunds are issued within 5-7 business days to the original payment method. "
"Store credit is available immediately as an alternative."
)
support_reply = "You'll get your refund back on the original card within 5 to 7 business days."
result = evaluator.evaluate(
eval_templates="context_adherence",
inputs={"context": support_context, "output": support_reply},
model_name="turing_flash",
)
item = result.eval_results[0]
print(item.output)
print(item.reason)You should see something like this (illustrative, exact wording varies by run):
0.92
The response accurately reflects the refund timeline stated in the context.item.output is the 0-1 adherence score, item.reason is the grading model’s explanation.
Run a deterministic check with no judge model
Deterministic templates don’t grade with a model. Pass eval_templates and inputs only, no model_name.
order_confirmation = '{"order_id": "SO-48213", "status": "shipped", "refund_issued": false}'
result = evaluator.evaluate(
eval_templates="is_json",
inputs={"text": order_confirmation},
)
print(result.eval_results[0].output)You should see:
Passed Screen a customer message for PII
pii is a judged safety template. Run it on inbound text before it reaches a log or a downstream store.
customer_message = "My order number is SO-48213 and my name is Jordan Reyes."
result = evaluator.evaluate(
eval_templates="pii",
inputs={"input": customer_message},
model_name="turing_flash",
)
item = result.eval_results[0]
print(item.output)
print(item.reason)You should see the check fail the message and name what it found (illustrative):
Failed
The message contains a personal name (Jordan Reyes) and an order identifier. Batch-score replies for conciseness
Loop evaluate() over a list of candidate replies and compare scores directly.
support_replies = [
"Your refund will be back on your card within 5 to 7 business days after we process the return.",
"Sure, no problem at all, happy to help, let me just check on that for you real quick, one moment please.",
]
for reply in support_replies:
result = evaluator.evaluate(
eval_templates="is_concise",
inputs={"output": reply},
model_name="turing_flash",
)
item = result.eval_results[0]
print(f"{item.output!s:<8} {reply[:50]}")You should see the first reply pass and the second fail on filler (illustrative):
Passed Your refund will be back on your card within 5
Failed Sure, no problem at all, happy to help, let meThe second reply fails on filler. Tighten it and rerun the same check:
tightened_reply = "Your refund will be back on your card within 5 to 7 business days."
result = evaluator.evaluate(
eval_templates="is_concise",
inputs={"output": tightened_reply},
model_name="turing_flash",
)
item = result.eval_results[0]
print(f"before: Failed")
print(f"after: {item.output!s}")You should see the failure close:
before: Failed
after: Passed Catch evaluation errors before they reach production
Wrap evaluate() so a bad template name or a transient API error doesn’t crash a batch job.
def score_reply(template, output, **extra_inputs):
try:
result = evaluator.evaluate(
eval_templates=template,
inputs={"output": output, **extra_inputs},
model_name="turing_flash",
)
item = result.eval_results[0]
return item.output, item.reason
except Exception as exc:
print(f"Eval '{template}' failed: {exc}")
return None, None
status, reason = score_reply("toxicity", "I completely disagree, but I respect your view.")
print(status, reason)You should see the toxicity check pass with no exception:
Passed The response is respectful and contains no toxic language.The try/except here is what turns a bad template name into a logged failure instead of a stopped script.
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
AuthenticationError on evaluator.evaluate() | FI_API_KEY or FI_SECRET_KEY missing or unexported | Re-run the export block in the current shell, then re-run the script |
ModuleNotFoundError: No module named 'fi.evals' | ai-evaluation not installed, or an unrelated fi package shadows it | pip install ai-evaluation, and check pip show fi doesn’t point at a different package |
evaluate() raises an unknown-template error | Typo in the eval_templates string | Check the exact name against the built-in eval catalog |
IndexError on result.eval_results[0] | The call ran but returned no results, usually a rate limit or timeout | Check result.eval_results is non-empty before indexing, retry the call, and lower max_workers on the Evaluator() constructor if you’re hitting rate limits |
A judged template like context_adherence, pii, or is_concise errors out or scores every row the same | model_name was left out, but judged templates require one | Pass model_name="turing_flash" for any non-deterministic, non-statistical template |
A deterministic template like is_json raises a model-related error | model_name was passed but isn’t needed for deterministic or statistical templates | Drop the model_name kwarg for those categories |
Browse the full set of built-in templates in the built-in eval catalog.
Questions & Discussion