Skip to main content
An outcome is your definition of what a successful run looks like. AgentVista records the mechanics of every run automatically — tokens, latency, cost, errors. Outcomes let you layer in the business signal: did this run actually do what it was supposed to do?

The two outcome fields

Every trace has two optional outcome fields:
FieldTypeDescription
successbooleanWas this run successful by your definition?
outcomestringAn optional label describing the specific result
These fields are intentionally open-ended. You decide what “success” means. For a customer support bot, success might mean the ticket was resolved without human escalation. For a lead qualifier, it might mean the lead was correctly categorized. For a code reviewer, it might mean the PR was approved without feedback. outcome gives you a more granular label beyond the binary success/failure distinction. A run can be success=False with outcome="escalated" (the agent correctly recognized it couldn’t handle this one) or success=False with outcome="hallucinated" (the agent produced an incorrect answer). Those two failure modes call for very different responses.
Choose outcome labels that map to actions your team can take. “resolved”, “escalated”, “qualified”, “unqualified”, “approved”, “flagged” — these labels should mean something specific to the people reading the dashboard.

Setting outcomes

Context manager

The most common pattern is to set the outcome at the end of a with agentvista.run(...) block:
import agentvista

agentvista.init(api_key="av_xxxxx")

def handle_support_ticket(ticket_id: str):
    with agentvista.run("support-bot") as r:
        response = process_ticket(ticket_id)

        if response.resolved_automatically:
            r.set_outcome(success=True, outcome="resolved")
        elif response.needs_human:
            r.set_outcome(success=False, outcome="escalated")
        else:
            r.set_outcome(success=False, outcome="unclear")
r.set_outcome(success, outcome) accepts outcome as an optional keyword argument. If you only care about the boolean signal, you can omit it:
r.set_outcome(success=True)

Record (v1 API)

If you’re using agentvista.record() for simple single-span tracing, pass success and outcome directly:
agentvista.record(
    agent="lead-qualifier",
    success=True,
    outcome="qualified",
    cost=0.031,
)

Via the API

You can also update an outcome after the run has completed — useful when success is determined by a downstream process (for example, a human reviewing the agent’s output hours later):
PATCH /api/v1/dashboard/traces/{trace_id}/outcome
Content-Type: application/json

{
  "success": true,
  "outcome": "approved"
}
This is handy for workflows where the ground truth arrives asynchronously, such as:
  • A sales team confirming whether a qualified lead converted
  • A support manager reviewing whether auto-resolved tickets stayed closed
  • An automated test suite validating agent outputs offline

What the dashboard shows you

When you set outcomes, the AgentVista dashboard unlocks a set of views that go beyond raw trace data: Success rate chart — success rate over time for each agent. Drop after a prompt change? You’ll see it immediately. Outcome breakdown — a breakdown of how often each outcome label appears. If "escalated" is climbing while "resolved" is flat, something in your agent’s logic has changed. Outcome-to-cost linking — the dashboard surfaces the average cost per run for each outcome. This answers questions like: “Are we spending more on runs that end up failing anyway?” or “Our success rate improved — but did our cost per resolved ticket also go up?”

Use case examples

with agentvista.run("support-bot") as r:
    result = resolve_ticket(ticket)

    if result.status == "auto_resolved":
        r.set_outcome(success=True, outcome="resolved")
    elif result.status == "escalated_to_human":
        r.set_outcome(success=False, outcome="escalated")
    elif result.status == "csat_failed":
        r.set_outcome(success=False, outcome="unsatisfied")

Outcomes without the decorator

If you use @agentvista.trace_agent (the decorator pattern), you don’t get a handle to call set_outcome() on. In that case, switch to the context manager pattern for any agent where outcomes matter:
# Decorator — no outcome support
@agentvista.trace_agent("lead-qualifier")
def qualify_lead(data):
    return run_pipeline(data)  # outcome fields will be blank

# Context manager — full outcome support
def qualify_lead(data):
    with agentvista.run("lead-qualifier") as r:
        result = run_pipeline(data)
        r.set_outcome(success=result.success, outcome=result.category)
        return result
Outcomes are optional on every run. Traces without success or outcome still appear in the dashboard — they just won’t contribute to success rate charts or outcome breakdowns until those fields are populated.