Skip to main content
What are Objectives? Objectives are evaluation prompts that guide a conversation toward concrete outcomes and let an evaluator LLM determine completion and extract structured variables. They influence both the conversational LLM (what to work toward) and the evaluator (what to verify and extract).This guide is a deep dive on best practices for structuring your objectives. For basic setup, parameters, and API details, see the main Objectives documentation:

How the System Works

Tavus uses two LLM roles during a conversation:
  • Conversational LLM: talks to the user and steers toward completing objectives.
  • Evaluator LLM: checks completion status and extracts variables from conversation history.
Your objective_prompt influences both:
  • It is injected into the conversational behavior (what to gather and confirm).
  • It is used by the evaluator to decide completion and extraction quality.
That means prompt clarity directly affects both conversation quality and workflow correctness.

What Good Prompts Look Like

Good objective/guardrail prompts are:
  • Clear: unambiguous and concrete
  • Specific: one goal at a time
  • Testable: easy to validate with sample conversations
  • Robust: handle real user variation and edge cases

Objective Prompt Template

[Action] [specific information or condition] [optional criteria] Examples:
  • Collect the user's first name, last name, and email address
  • User has explicitly agreed to the terms and conditions
  • Check if an error message is visible on shared screen and extract error code

Objective Types

1) Information Extraction Objectives

Use when you need structured data.
{
  "objective_name": "get_contact_info",
  "objective_prompt": "Collect the user's first name, last name, and email address",
  "output_variables": ["first_name", "last_name", "email"]
}
{
  "objective_name": "get_appointment_preference",
  "objective_prompt": "Determine the user's preferred appointment date and time",
  "output_variables": ["preferred_date", "preferred_time"]
}
Avoid:
{
  "objective_prompt": "Get user information",
  "output_variables": ["info"]
}
Why bad: vague prompt + vague variable.

2) Condition Check Objectives

Use when a verifiable condition must be true before proceeding.
{
  "objective_name": "terms_accepted",
  "objective_prompt": "User has explicitly agreed to the terms and conditions",
  "output_variables": []
}
{
  "objective_name": "issue_resolved",
  "objective_prompt": "User has confirmed their issue is resolved and they are satisfied",
  "output_variables": []
}
Avoid subjective checks:
{
  "objective_prompt": "User seems happy"
}

3) Visual Objectives

Use for camera or screen-share analysis.
{
  "objective_name": "verify_id_visible",
  "objective_prompt": "User is holding a government-issued ID that is clearly visible and legible",
  "modality": "visual",
  "output_variables": []
}
{
  "objective_name": "screen_error_detection",
  "objective_prompt": "Check if an error message is visible on shared screen. Extract error code and message text.",
  "modality": "visual",
  "output_variables": ["error_code", "error_message"]
}
Tip: visual prompts should describe clear, observable signals, not interpretation-heavy judgments.

Output Variables Best Practices

Naming

Good variable names:
  • first_name, last_name
  • preferred_contact_method
  • appointment_date, appointment_time
  • reason_for_visit
Bad variable names:
  • info, data, thing1, user_response

Granularity

Prefer atomic fields over one giant blob. Good:
{
  "objective_prompt": "Collect shipping address",
  "output_variables": ["street_address", "city", "state", "zip_code"]
}
Less useful:
{
  "objective_prompt": "Collect shipping address",
  "output_variables": ["full_address"]
}

NOTFOUND

If a value is missing, evaluator may return "NOTFOUND". That is expected. Do not put NOTFOUND handling instructions inside objective prompts. Handle it in app logic.

Conditional Objectives

Use conditional objectives to route a workflow.
{
  "objective_name": "classify_request",
  "objective_prompt": "Determine what type of request the user has",
  "next_conditional_objectives": {
    "technical_issue": "if user reports bugs, errors, or product malfunction",
    "billing_issue": "if user asks about charges, invoices, or refunds",
    "general_question": "for all other questions"
  }
}
Guidelines:
  • Prefer 2-5 branches.
  • Keep branch conditions distinct.
  • Include a catch-all path.
  • Base conditions on conversation content (not hidden database state).

Guardrails

Guardrails are passive monitors for policy/safety/compliance conditions.
  • Continuously evaluated in background
  • Do not drive normal workflow progression
  • Trigger callback/webhook logic when violated
Example guardrails:
{
  "guardrail_name": "no_sensitive_data",
  "guardrail_prompt": "User is sharing full credit card numbers, social security numbers, or passwords"
}
{
  "guardrail_name": "single_user_only",
  "guardrail_prompt": "More than one person is visible in camera view",
  "modality": "visual"
}
Guardrail vs objective:
  • Use objective for information/workflow progress.
  • Use guardrail for monitoring violations/alerts.

Common Mistakes (and Fixes)

1) Writing instructions instead of outcomes

Bad:
{ "objective_prompt": "Ask the user for email politely" }
Good:
{ "objective_prompt": "Collect the user's email address" }

2) Future-state checks

Bad:
{ "objective_prompt": "User will receive confirmation email" }
Good:
{ "objective_prompt": "User has acknowledged they will receive a confirmation email" }

3) Overloaded objectives

Bad: one objective collects 15 unrelated fields. Good: split into focused objectives (get_name, get_contact, get_address).

4) Overlapping conditional branches

Bad:
{
  "next_conditional_objectives": {
    "path_a": "if user needs help",
    "path_b": "if user has a question"
  }
}
Reason this is bad: paths are not distinct enough and can overlap, so both conditions may match the same user message. Good:
{
  "next_conditional_objectives": {
    "technical_support": "if user reports product bugs or errors",
    "billing_support": "if user asks about charges or refunds",
    "other": "for all other requests"
  }
}

Testing Checklist

Before shipping prompts:
  • Test one-message answers (user gives everything at once)
  • Test multi-turn collection (piece by piece)
  • Test corrections (Actually, it's Jon not John)
  • Test refusal cases (I'd rather not share that)
  • Test ambiguity cases (Sometime next week)
  • Track variable-level NOTFOUND rates in production
Simple test fixture example:
{
  "objective": {
    "objective_prompt": "Collect first name and email",
    "output_variables": ["first_name", "email"]
  },
  "conversation": [
    {"role": "assistant", "content": "What is your name and email?"},
    {"role": "user", "content": "I'm Ana. ana@example.com"}
  ],
  "expected": {
    "first_name": "Ana",
    "email": "ana@example.com"
  }
}

Example Blueprint (Support Triage)

{
  "objectives": [
    {
      "objective_name": "identify_customer",
      "objective_prompt": "Collect account email or order number",
      "output_variables": ["account_identifier"],
      "next_required_objective": "classify_issue"
    },
    {
      "objective_name": "classify_issue",
      "objective_prompt": "Determine what issue type the user needs help with",
      "output_variables": ["issue_type"],
      "next_conditional_objectives": {
        "technical": "if user reports bugs/errors",
        "billing": "if user asks about payments/refunds",
        "shipping": "if user asks about delivery/order status",
        "general": "for all other requests"
      }
    },
    {
      "objective_name": "technical",
      "objective_prompt": "Collect error details, when it started, and what was already tried",
      "output_variables": ["error_details", "when_started", "steps_tried"]
    }
  ],
  "guardrails": [
    {
      "guardrail_name": "abusive_language",
      "guardrail_prompt": "User uses threats, abuse, or hate speech"
    }
  ]
}

Final Guidance

Start simple, ship, observe, and iterate. Strong prompts should make objective completion predictable, extraction reliable, and debugging straightforward.