Skip to content

Evaluations

The Shield360 SDK provides server-side evaluations via shield360.eval() (Python) and shield360.eval() (JS/TS). Evaluations use the same engine, rules, contexts, and custom eval types configured in the Shield360 dashboard - working identically for development (offline) and production (online) stages.


Offline evaluations run on the Shield360 server using the same evaluation engine as online/auto evaluations. The SDK sends your prompt and response to the server, which runs LLM-as-judge evaluation and returns structured results.

  1. A running Shield360 instance with evaluation configured in the dashboard.
  2. A Shield360 API key (create one in the dashboard under Settings > API Keys).
import shield360
# Option 1: Configure once via init()
shield360.init(
shield360_url="http://localhost:3000",
shield360_api_key="shield360-xxxxx",
)
# Run evaluation
result = shield360.eval(
prompt="What is the capital of France?",
response="The capital of France is Lyon.",
contexts=["Paris is the capital and largest city of France."],
)
# Use in assertions
assert result.passed, f"Evaluation failed: {result.failed_evals}"
# Option 2: Pass credentials directly (overrides init/env vars)
result = shield360.eval(
prompt="Explain quantum computing",
response="Quantum computers use qubits...",
shield360_url="http://localhost:3000",
shield360_api_key="shield360-xxxxx",
)

You can also configure via environment variables:

Terminal window
export SHIELD360_URL="http://localhost:3000"
export SHIELD360_API_KEY="shield360-xxxxx"

shield360.eval() / shield360.eval({}) Parameters

Section titled “shield360.eval() / shield360.eval({}) Parameters”
ParameterTypeDescriptionDefault
promptstrThe user prompt sent to the LLM. Required.-
responsestrThe LLM’s response to evaluate. Required.-
contextslist[str]Ground truth context for the evaluation.None
eval_typeslist[str]Specific eval types to run (e.g. ["hallucination", "toxicity"]). Runs all enabled types if omitted.None
attributesdictTrace attributes for rule engine matching (overrides auto-resolved attributes).None
threshold_scorefloatScore threshold for verdict determination.0.5
store_resultsboolWhether to store results in the Shield360 database.True
run_idstrIdentifier to group related evaluations.None
metadatadictCustom key-value metadata to attach to results.None
shield360_api_keystrAPI key (overrides init() and env var).None
shield360_urlstrServer URL (overrides init() and env var).None
print_resultsboolPrint formatted summary to terminal.True

shield360.eval() returns an OfflineEvalResult with these properties:

PropertyTypeDescription
successboolWhether the evaluation completed without errors.
passedboolTrue if no evaluation types returned a “yes” verdict.
evaluationslist[OfflineEvaluation]Individual evaluation results per type.
failed_evalslist[OfflineEvaluation]Evaluations that returned a “yes” verdict.
context_appliedContextInfoInformation about rule-matched context.
metadatadictModel, run ID, token usage, and cost metadata.
errorstrError message if success is False.

Each OfflineEvaluation contains:

FieldTypeDescription
typestrThe evaluation type (e.g. “hallucination”).
scorefloatThe evaluation score (0.0 to 1.0).
verdictstr“yes” if detected, “no” otherwise.
classificationstrCategory of the detection or “none”.
explanationstrBrief explanation of the evaluation result.

Run specific evaluation types instead of all enabled ones:

result = shield360.eval(
prompt="Discuss workplace equality",
response="Older workers can't learn new tech.",
eval_types=["bias", "toxicity"],
)
types = shield360.get_eval_types()
for t in types:
print(f"{t.id}: {t.label} (custom={t.is_custom}, enabled={t.enabled})")

Evaluate multiple prompt/response pairs concurrently:

dataset = [
{
"prompt": "What is 2+2?",
"response": "2+2 equals 4.",
"contexts": ["Basic arithmetic."],
},
{
"prompt": "Who wrote Hamlet?",
"response": "Hamlet was written by Charles Dickens.",
},
{
"prompt": "Describe gravity",
"response": "Gravity is the force of attraction between masses.",
"eval_types": ["hallucination"],
},
]
batch_result = shield360.eval_batch(
dataset=dataset,
eval_types=["hallucination", "toxicity"],
max_concurrent=5,
)
print(f"Pass rate: {batch_result.pass_rate:.0%}")
assert batch_result.all_passed
ParameterTypeDescriptionDefault
datasetlist[dict]List of items with prompt and response keys. Required.-
eval_typeslist[str]Default eval types (can be overridden per item).None
attributesdictDefault attributes (can be overridden per item).None
threshold_scorefloatDefault threshold score.0.5
store_resultsboolStore all results in the database.True
run_idstrGroup all batch evaluations under this ID. Auto-generated if omitted.None
max_concurrentintMaximum number of concurrent evaluations.5
print_resultsboolPrint aggregate summary to terminal.True

The SDK automatically resolves trace attributes for rule engine matching, enabling context-aware evaluations without extra configuration. The resolution order (last wins):

  1. OTEL_RESOURCE_ATTRIBUTES environment variable
  2. OTEL_SERVICE_NAME environment variable
  3. SHIELD360_ENVIRONMENT / OTEL_DEPLOYMENT_ENVIRONMENT environment variable
  4. shield360.init() configuration (application_name, environment)
  5. Explicit attributes parameter (highest priority)
import shield360
# These are auto-detected for rule matching:
shield360.init(
application_name="my-chatbot",
environment="staging",
)
# Rules configured in the dashboard for service.name="my-chatbot"
# and deployment.environment="staging" will automatically match.
result = shield360.eval(
prompt="Hello",
response="Hi there!",
)
# Override auto-resolved attributes:
result = shield360.eval(
prompt="Hello",
response="Hi there!",
attributes={
"service.name": "different-service",
"custom.tag": "experiment-v2",
},
)

Use offline evaluations in your test suite or CI pipeline:

import shield360
import pytest
def test_no_hallucination():
result = shield360.eval(
prompt="What year did WW2 end?",
response="World War 2 ended in 1945.",
eval_types=["hallucination"],
print_results=False,
)
assert result.passed, f"Hallucination detected: {result.failed_evals}"
def test_batch_quality():
dataset = load_test_cases() # your test data
result = shield360.eval_batch(
dataset=dataset,
print_results=False,
)
assert result.pass_rate >= 0.95, f"Pass rate too low: {result.pass_rate:.0%}"

For shield360_api_key and shield360_url, the resolution order is:

  1. Explicit function parameter (highest priority)
  2. shield360.init() configuration
  3. SHIELD360_API_KEY / SHIELD360_URL environment variables