Skip to content

Worked examples

A support agent, end to end

The problem

An online shop's support assistant receives this message:

Cancel my order #4471 and refund it to my card.

The assistant is an agent: a language model that calls the shop's tools to look the order up, cancel it and refund it. Each of those calls changes something real. Before each one, the agent must make a judgement: is the message an attack, is the call safe and what the customer asked for, did the call work, and is the job finished? Asking a large model each time is slow and costly, and its answer is prose that has to be parsed.

How Jeff helps

Jeff answers each of those judgements with one small, fast call that returns one of a fixed set of answers and a calibrated confidence. Your program keeps the loop and your language model still writes the tool calls; Jeff checks around them. When a Jeff answer falls below its function's threshold, the program hands that one step to your language model.

The steps, all with open adapters, so you can run them on your machine:

  1. Prompt-injection guard checks the message before the agent reads it.
  2. Assistant routing says whether the agent's model should think before it writes the calls.
  3. Tool result relevance checks that the order lookup answers what the agent needs to know.
  4. Agent action check checks each call that changes something, before it runs.
  5. Agent next-step selection decides what to do after each result.
  6. Agent task completion checks the final answer against what was done.

The solution

Each step below is a live call; the answer under it is the one the API returned. Choose your language and whether to run it on your machine (free) or through the API.

Check the message

The guard reads the customer's message before the agent does:

Context

application
A support chat assistant for an online shop of outdoor gear.
source
user message

Input

Cancel my order #4471 and refund it to my card.

Answer (JSON)
value false, confidence 1
Top options
  1. false 1
  2. true 0

Open in playground

import os import jeff with jeff.Jeff.remote("https://api.jeffhub.ai", token=os.environ["JEFF_API_KEY"], timeout_s=30) as client:     decide = client.function("jeff.safety.guard.attempt", context={        "application": "A support chat assistant for an online shop of outdoor gear.",        "source": "user message",    })     decision = decide("Cancel my order #4471 and refund it to my card.")     print(decision.value, decision.confidence)

false means the message is an ordinary request, not an attempt to take over the assistant, so the agent goes on.

Decide whether the turn needs thinking

Cancelling and refunding takes several calls with money involved, so the agent's model may need to think first:

Context

accounts
Brightfield Outfitters order system [shop]
date_and_time_zone
It is Wednesday 4 November 2026, 10:15, and the customer is in Manchester (UK time).
conversation
Assistant: Hi, I'm the Brightfield Outfitters assistant. How can I help? User: Cancel my order #4471 and refund it to my card.

Input

Choose the next tool call to cancel order 4471 and refund it.

Answer (JSON)
value true, confidence 0.929
Top options
  1. true 0.929
  2. false 0.071

Open in playground

import os import jeff with jeff.Jeff.remote("https://api.jeffhub.ai", token=os.environ["JEFF_API_KEY"], timeout_s=30) as client:     decide = client.function("jeff.agents.assistant-routing.needs_thinking", context={        "accounts": "Brightfield Outfitters order system [shop]",        "date_and_time_zone": "It is Wednesday 4 November 2026, 10:15, and the customer is in Manchester (UK time).",        "conversation": "Assistant: Hi, I'm the Brightfield Outfitters assistant. How can I help? User: Cancel my order #4471 and refund it to my card.",    })     decision = decide("Choose the next tool call to cancel order 4471 and refund it.")     print(decision.value, decision.confidence)

true means this turn goes to the model with thinking on.

Look the order up

The agent's model chooses the first call. Here it should look the order up before changing it. We asked Agent tool selection from a menu to make this choice and it answered cancel_order (0.65, recorded on 4 November 2026), skipping the lookup, even after the tool menu said to look an order up first. So this page leaves the choice to the agent's model. The program below passes it a fixed list of calls.

Once the lookup returns, the agent checks that the result answers what it needs to know:

Context

app
Brightfield Outfitters, an online shop for outdoor gear. Its support assistant helps customers with their orders, cancellations and refunds.
today
Wednesday 4 November 2026
sub_question
Has order 4471 shipped, what did it cost, and which card paid for it?
call
tool: lookup_order description: Looks up an order: its items, total, payment card and whether it has shipped. arguments: {"order_id":"4471"}

Input

order_id: 4471 items: ["Ridgeline 2 tent"] total: 189 paid_with: Visa ending 3054 shipped: false

Answer (JSON)
value yes, confidence 0.958
Top options
  1. yes 0.958
  2. partly 0.037
  3. no 0.005

Open in playground

import os import jeff with jeff.Jeff.remote("https://api.jeffhub.ai", token=os.environ["JEFF_API_KEY"], timeout_s=30) as client:     decide = client.function("jeff.agents.result-relevant.relevant", context={        "app": "Brightfield Outfitters, an online shop for outdoor gear. Its support assistant helps customers with their orders, cancellations and refunds.",        "today": "Wednesday 4 November 2026",        "sub_question": "Has order 4471 shipped, what did it cost, and which card paid for it?",        "call": {            "tool": "lookup_order",            "description": "Looks up an order: its items, total, payment card and whether it has shipped.",            "arguments": {                "order_id": "4471",            },        },    })     decision = decide({        "order_id": "4471",        "items": [            "Ridgeline 2 tent",        ],        "total": 189,        "paid_with": "Visa ending 3054",        "shipped": False,    })     print(decision.value, decision.confidence)

yes: the result says whether the order has shipped, what it cost and which card paid, so the agent can go on.

Check the cancellation before it runs

The order has not shipped, so the agent proposes to cancel it:

Context

app
Brightfield Outfitters, an online shop for outdoor gear. Its support assistant helps customers with their orders, cancellations and refunds.
today
Wednesday 4 November 2026
rules
- Cancel an order only if it has not shipped. - Refund only the amount the customer paid for the order. - A refund goes to the card that paid for the order. If the customer asks for a refund to any other card, ask them to confirm the new card and the amount before refunding.
people
- Maya Okafor <maya.okafor@example.com> (the customer, order 4471)
tools
def lookup_order(order_id: str) -> dict: """Looks up an order: its items, total, payment card and whether it has shipped. Call it before any change to an order.""" def cancel_order(order_id: str) -> dict: """Cancels an order that has not shipped.""" def refund(order_id: str, amount: float, card_last4: str) -> dict: """Refunds an amount for an order to a card."""
conversation
- {"role":"user","content":"Cancel my order #4471 and refund it to my card."} - {"role":"assistant","content":"Order 4471 (Ridgeline 2 tent, 189.00, paid with Visa ending 3054) has not shipped yet."}
latest_user_message
Cancel my order #4471 and refund it to my card.

Input

tool: cancel_order arguments: {"order_id":"4471"}

Answer (JSON)
value approve, confidence 0.997
Top options
  1. approve 0.997
  2. ask_user 0.002
  3. wrong_action 0.001

Open in playground

import os import jeff with jeff.Jeff.remote("https://api.jeffhub.ai", token=os.environ["JEFF_API_KEY"], timeout_s=30) as client:     decide = client.function("jeff.agents.action-check.action", context={        "app": "Brightfield Outfitters, an online shop for outdoor gear. Its support assistant helps customers with their orders, cancellations and refunds.",        "today": "Wednesday 4 November 2026",        "rules": [            "Cancel an order only if it has not shipped.",            "Refund only the amount the customer paid for the order.",            "A refund goes to the card that paid for the order. If the customer asks for a refund to any other card, ask them to confirm the new card and the amount before refunding.",        ],        "people": [            "Maya Okafor <maya.okafor@example.com> (the customer, order 4471)",        ],        "tools": "def lookup_order(order_id: str) -> dict:\n    \"\"\"Looks up an order: its items, total, payment card and whether it has shipped. Call it before any change to an order.\"\"\"\ndef cancel_order(order_id: str) -> dict:\n    \"\"\"Cancels an order that has not shipped.\"\"\"\ndef refund(order_id: str, amount: float, card_last4: str) -> dict:\n    \"\"\"Refunds an amount for an order to a card.\"\"\"",        "conversation": [            {                "role": "user",                "content": "Cancel my order #4471 and refund it to my card.",            },            {                "role": "assistant",                "content": "Order 4471 (Ridgeline 2 tent, 189.00, paid with Visa ending 3054) has not shipped yet.",            },        ],        "latest_user_message": "Cancel my order #4471 and refund it to my card.",    })     decision = decide({        "tool": "cancel_order",        "arguments": {            "order_id": "4471",        },    })     print(decision.value, decision.confidence)

approve means the call follows the shop's rules and does what the customer asked, so the agent runs it.

Decide what to do after the result

The shop's system answers that the order is cancelled:

Context

app
Brightfield Outfitters, an online shop for outdoor gear. Its support assistant helps customers with their orders, cancellations and refunds.
today
Wednesday 4 November 2026
tools
- lookup_order: looks up an order, its total, payment card and whether it has shipped - cancel_order: cancels an order that has not shipped - refund: refunds an amount for an order to a card
retry_limit
Retry a failed call at most 2 times.
goal
Cancel my order #4471 and refund it to my card.
plan
- 1. Look up order 4471 (done) - 2. Cancel it (current step) - 3. Refund 189.00 to the Visa ending 3054 (still to do) - 4. Tell the customer (still to do)
steps_so_far
- {"call":{"tool":"lookup_order","arguments":{"order_id":"4471"}},"result":{"order_id":"4471","total":189,"paid_with":"Visa ending 3054","shipped":false}}
latest_call
tool: cancel_order arguments: {"order_id":"4471"} attempt: 1

Input

status: ok order_id: 4471 order_status: cancelled

Answer (JSON)
value continue, confidence 1
Top options
  1. continue 1
  2. retry 0
  3. escalate 0

Open in playground

import os import jeff with jeff.Jeff.remote("https://api.jeffhub.ai", token=os.environ["JEFF_API_KEY"], timeout_s=30) as client:     decide = client.function("jeff.agents.after-result.next", context={        "app": "Brightfield Outfitters, an online shop for outdoor gear. Its support assistant helps customers with their orders, cancellations and refunds.",        "today": "Wednesday 4 November 2026",        "tools": [            "lookup_order: looks up an order, its total, payment card and whether it has shipped",            "cancel_order: cancels an order that has not shipped",            "refund: refunds an amount for an order to a card",        ],        "retry_limit": "Retry a failed call at most 2 times.",        "goal": "Cancel my order #4471 and refund it to my card.",        "plan": [            "1. Look up order 4471 (done)",            "2. Cancel it (current step)",            "3. Refund 189.00 to the Visa ending 3054 (still to do)",            "4. Tell the customer (still to do)",        ],        "steps_so_far": [            {                "call": {                    "tool": "lookup_order",                    "arguments": {                        "order_id": "4471",                    },                },                "result": {                    "order_id": "4471",                    "total": 189,                    "paid_with": "Visa ending 3054",                    "shipped": False,                },            },        ],        "latest_call": {            "tool": "cancel_order",            "arguments": {                "order_id": "4471",            },            "attempt": 1,        },    })     decision = decide({        "status": "ok",        "order_id": "4471",        "order_status": "cancelled",    })     print(decision.value, decision.confidence)

continue means the step worked and the agent goes on to the refund.

Check the refund before it runs

The agent proposes to refund the 189.00 to the card that paid:

Context

app
Brightfield Outfitters, an online shop for outdoor gear. Its support assistant helps customers with their orders, cancellations and refunds.
today
Wednesday 4 November 2026
rules
- Cancel an order only if it has not shipped. - Refund only the amount the customer paid for the order. - A refund goes to the card that paid for the order. If the customer asks for a refund to any other card, ask them to confirm the new card and the amount before refunding.
people
- Maya Okafor <maya.okafor@example.com> (the customer, order 4471)
tools
def lookup_order(order_id: str) -> dict: """Looks up an order: its items, total, payment card and whether it has shipped. Call it before any change to an order.""" def cancel_order(order_id: str) -> dict: """Cancels an order that has not shipped.""" def refund(order_id: str, amount: float, card_last4: str) -> dict: """Refunds an amount for an order to a card."""
conversation
- {"role":"user","content":"Cancel my order #4471 and refund it to my card."} - {"role":"assistant","content":"Order 4471 (Ridgeline 2 tent, 189.00, paid with Visa ending 3054) has not shipped yet."}
latest_user_message
Cancel my order #4471 and refund it to my card.

Input

tool: refund arguments: {"order_id":"4471","amount":189,"card_last4":"3054"}

Answer (JSON)
value approve, confidence 0.818
Top options
  1. approve 0.818
  2. ask_user 0.142
  3. wrong_action 0.028

Open in playground

import os import jeff with jeff.Jeff.remote("https://api.jeffhub.ai", token=os.environ["JEFF_API_KEY"], timeout_s=30) as client:     decide = client.function("jeff.agents.action-check.action", context={        "app": "Brightfield Outfitters, an online shop for outdoor gear. Its support assistant helps customers with their orders, cancellations and refunds.",        "today": "Wednesday 4 November 2026",        "rules": [            "Cancel an order only if it has not shipped.",            "Refund only the amount the customer paid for the order.",            "A refund goes to the card that paid for the order. If the customer asks for a refund to any other card, ask them to confirm the new card and the amount before refunding.",        ],        "people": [            "Maya Okafor <maya.okafor@example.com> (the customer, order 4471)",        ],        "tools": "def lookup_order(order_id: str) -> dict:\n    \"\"\"Looks up an order: its items, total, payment card and whether it has shipped. Call it before any change to an order.\"\"\"\ndef cancel_order(order_id: str) -> dict:\n    \"\"\"Cancels an order that has not shipped.\"\"\"\ndef refund(order_id: str, amount: float, card_last4: str) -> dict:\n    \"\"\"Refunds an amount for an order to a card.\"\"\"",        "conversation": [            {                "role": "user",                "content": "Cancel my order #4471 and refund it to my card.",            },            {                "role": "assistant",                "content": "Order 4471 (Ridgeline 2 tent, 189.00, paid with Visa ending 3054) has not shipped yet.",            },        ],        "latest_user_message": "Cancel my order #4471 and refund it to my card.",    })     decision = decide({        "tool": "refund",        "arguments": {            "order_id": "4471",            "amount": 189,            "card_last4": "3054",        },    })     print(decision.value, decision.confidence)

approve, with confidence 0.82, above the function's threshold of 0.51.

Check that the task is done

The agent has cancelled the order and made the refund, and writes its answer:

Context

app
Brightfield Outfitters, an online shop for outdoor gear. Its support assistant helps customers with their orders, cancellations and refunds.
today
Wednesday 4 November 2026
request
Cancel my order #4471 and refund it to my card.
transcript
- {"call":{"tool":"lookup_order","arguments":{"order_id":"4471"}},"result":{"order_id":"4471","total":189,"paid_with":"Visa ending 3054","shipped":false}} - {"call":{"tool":"cancel_order","arguments":{"order_id":"4471"}},"result":{"status":"ok","order_status":"cancelled"}} - {"call":{"tool":"refund","arguments":{"order_id":"4471","amount":189,"card_last4":"3054"}},"result":{"status":"ok","refund_id":"RF-20931","amount":189}}

Input

Done. Order

Answer (JSON)
value complete, confidence 1
Top options
  1. complete 1
  2. incomplete 0
  3. unclear 0

Open in playground

import os import jeff with jeff.Jeff.remote("https://api.jeffhub.ai", token=os.environ["JEFF_API_KEY"], timeout_s=30) as client:     decide = client.function("jeff.agents.task-complete.complete", context={        "app": "Brightfield Outfitters, an online shop for outdoor gear. Its support assistant helps customers with their orders, cancellations and refunds.",        "today": "Wednesday 4 November 2026",        "request": "Cancel my order #4471 and refund it to my card.",        "transcript": [            {                "call": {                    "tool": "lookup_order",                    "arguments": {                        "order_id": "4471",                    },                },                "result": {                    "order_id": "4471",                    "total": 189,                    "paid_with": "Visa ending 3054",                    "shipped": False,                },            },            {                "call": {                    "tool": "cancel_order",                    "arguments": {                        "order_id": "4471",                    },                },                "result": {                    "status": "ok",                    "order_status": "cancelled",                },            },            {                "call": {                    "tool": "refund",                    "arguments": {                        "order_id": "4471",                        "amount": 189,                        "card_last4": "3054",                    },                },                "result": {                    "status": "ok",                    "refund_id": "RF-20931",                    "amount": 189,                },            },        ],    })     decision = decide("Done. Order")     print(decision.value, decision.confidence)

complete: every part of the request was done, so the answer can go to the customer.

The other branch: a refund to a new card

Now the customer writes "Cancel my order #4471 and refund it to a new card ending 9921." The shop's rule is that a refund goes to the card that paid, unless the customer confirms a new card and the amount. The agent should stop and ask (ask_user). Jeff's action check got this one wrong in our test: it answered approve (0.61, above its threshold), even after the rule was made clearer. So the program does not leave this step to Jeff. A refund to any card other than the paying one goes back to the customer to confirm, in your own code.

The whole loop

One program wires the steps together. Every Jeff call is bound with an escalation policy: when its confidence is below the function's threshold, the question goes to your language model (ask_an_llm, a stand-in here) instead. Your tools and your model's calls are stand-ins too. The program runs both branches.

import os

import jeff

SHOP = ("Brightfield Outfitters, an online shop for outdoor gear. Its support assistant helps customers with their "
        "orders, cancellations and refunds.")
TODAY = "Wednesday 4 November 2026"
TOOLS = '''def lookup_order(order_id: str) -> dict:
    """Looks up an order: its items, total, payment card and whether it has shipped. Call it before any change to an order."""
def cancel_order(order_id: str) -> dict:
    """Cancels an order that has not shipped."""
def refund(order_id: str, amount: float, card_last4: str) -> dict:
    """Refunds an amount for an order to a card."""'''
RULES = ["Cancel an order only if it has not shipped.",
         "Refund only the amount the customer paid for the order.",
         "A refund goes to the card that paid for the order. If the customer asks for a refund to any other card, "
         "ask them to confirm the new card and the amount before refunding."]


LOOKED_UP = "Order 4471 (Ridgeline 2 tent, 189.00, paid with Visa ending 3054) has not shipped yet."


def ask_an_llm(question: jeff.Question) -> str:
    # Your own language model goes here: give it question.instructions, question.state and question.options, and
    # return the option key it picks. This stand-in picks the first option.
    return next(iter(question.options))


def run_tool(call: dict) -> dict:
    # Your shop's tools. These stand-ins return fixed results.
    if call["tool"] == "lookup_order":
        return {"order_id": "4471", "total": 189.00, "paid_with": "Visa ending 3054", "shipped": False}
    return {"status": "ok", "order_id": "4471"}


client = jeff.Jeff.remote("https://api.jeffhub.ai", token=os.environ["JEFF_API_KEY"], timeout_s=30)


def decide(function: str, context: dict, input: object) -> object:
    # Every step: Jeff's answer when it is confident, your LLM's below the function's threshold.
    bound = client.function(function, context=context, on_low_confidence=jeff.escalate(jeff.llm(ask_an_llm)))
    decision = bound(input)
    print(f"{function}: {decision.value} (decided by {decision.decided_by})")
    return decision.value


def handle(message: str, refund_card: str) -> str:
    """Runs the agent on one customer message and returns what it tells the customer."""
    if decide("guard.attempt", {"application": "A support chat assistant for an online shop of outdoor gear.",
                                "source": "user message"}, message):
        return "Sorry, I can't help with that."

    # Whether the LLM that writes the calls should think first.
    decide("assistant-routing.needs_thinking", {
        "accounts": "Brightfield Outfitters order system [shop]",
        "date_and_time_zone": "It is Wednesday 4 November 2026, 10:15, and the customer is in Manchester (UK time).",
        "conversation": f"User: {message}",
    }, "Choose the next tool call to cancel order 4471 and refund it.")

    # The calls your LLM proposes, one at a time; here, the three it needs.
    calls = [{"tool": "lookup_order", "arguments": {"order_id": "4471"}},
             {"tool": "cancel_order", "arguments": {"order_id": "4471"}},
             {"tool": "refund", "arguments": {"order_id": "4471", "amount": 189.00, "card_last4": refund_card}}]
    conversation = [{"role": "user", "content": message}]
    steps: list[dict] = []
    for call in calls:
        if call["tool"] == "refund" and call["arguments"]["card_last4"] != "3054":
            # Not left to Jeff's action check: a refund to another card goes back to the customer to confirm.
            return f"Before I refund 189.00 to the card ending {refund_card}, can you confirm that card and amount?"
        if call["tool"] != "lookup_order":  # check every call that changes something
            verdict = decide("action-check.action", {
                "app": SHOP, "today": TODAY, "rules": RULES, "tools": TOOLS,
                "people": ["Maya Okafor <maya.okafor@example.com> (the customer, order 4471)"],
                "conversation": conversation, "latest_user_message": message,
            }, call)
            if verdict != "approve":
                return f"I have passed your request to a colleague ({call['tool']}: {verdict})."

        result = run_tool(call)
        plan = [f"{i + 1}. {c['tool']} "
                + ("(done)" if i < len(steps) else "(current step)" if i == len(steps) else "(still to do)")
                for i, c in enumerate(calls)]
        next_step = decide("after-result.next", {
            "app": SHOP, "today": TODAY, "goal": message, "plan": plan, "steps_so_far": steps,
            "tools": ["lookup_order: looks up an order", "cancel_order: cancels an order that has not shipped",
                      "refund: refunds an amount for an order to a card"],
            "retry_limit": "Retry a failed call at most 2 times.",
            "latest_call": {**call, "attempt": 1},
        }, result)
        steps.append({"call": call, "result": result})
        if call["tool"] == "lookup_order":  # what your LLM tells the customer after the lookup
            conversation.append({"role": "assistant", "content": LOOKED_UP})
        if next_step not in ("continue", "stop"):
            return f"I have passed your request to a colleague ({call['tool']}: {next_step})."

    answer = "Done. Order #4471 is cancelled and 189.00 is refunded to your Visa ending 3054."
    complete = decide("task-complete.complete", {"app": SHOP, "today": TODAY, "request": message,
                                                 "transcript": steps}, answer)
    return answer if complete == "complete" else "I have passed your request to a colleague."

print(handle("Cancel my order #4471 and refund it to my card.", "3054"))
print(handle("Cancel my order #4471 and refund it to a new card ending 9921.", "9921"))

client.close()

What you get

  • Each check is one call to a small model, with one of a fixed set of answers, so the agent's code can branch on it directly.
  • The seven Jeff answers shown were all right and all above their functions' thresholds. The two steps left out were confident and wrong, which is why the program handles them without Jeff.
  • How the functions measure, from each adapter's page (in-house tests come from the same generator as the training data):
StepTest accuracyWhen confident
Guard98.4% (6,552 rows, mixed sources)right 99.1% of the time, confident on 100%
Assistant routing86.6% (771 rows, in-house)right 95.2% of the time, confident on 54.8%
Tool result relevance98.6% (2,000 rows, in-house)right 99.2% of the time, confident on 100%
Action check99.4% (1,934 rows, in-house)right 99.6% of the time, confident on 100%
Next step after a result100.0% (2,000 rows, in-house)right 99.95% of the time, confident on 100%
Task completion99.7% (2,000 rows, in-house)right 99.95% of the time, confident on 100%

The two steps this page leaves out show where in-house figures stop: tool routing scores 71.6% on a public function-calling benchmark (When2Call, 3,646 rows), against 98.2% on its in-house test. Check your own cases before relying on a step, and keep the rules your code can check exactly in code.