0%
1
Curious builder0 XP earned · 300 to level 2
0 daysFinish a lesson to begin
Badge collection0 of 6 unlocked
27 small wins to finish your pathNext lesson →

The desk agent and its tools

The shop desk is an Agent that answers an order question by calling a tool, the first piece of the support desk you finish in this part.

Last updated: 28 Sep, 2026 · openai-agents 0.22.3

Runner and the RunResult object arrived in the lesson on Runner and the RunResult object, and the tool decorator arrived in function_tool: a function the model can call. Here they meet: one agent, one tool, one order question, run against the ShopModel stand-in so no API key is needed.

The pieces, and where each came from

PieceFrom lesson
An Agent with a name and instructionsAgent: name, instructions and tools
A @function_tool the model can callfunction_tool: a function the model can call
Runner.run_sync and result.final_outputRunner and the RunResult object
ShopModel, a model that runs with no keyModel: a stand-in you can run without a key

The lookup tool

A tool is a plain function with the @function_tool decorator. Its docstring tells the model what it does.

python
@function_tool
def lookup_order(order_id: str) -> str:
    "Look up an order by its id."
    return f"Order {order_id}: shipped on 3 March, arriving 7 March."

The desk agent

The desk is an Agent that carries the tool in its tools list and uses the stand-in model.

python
desk = Agent(
    name="Shop desk",
    instructions="Help shoppers with their orders.",
    tools=[lookup_order],   # the desk may call this tool
    model=ShopModel(),      # the stand-in, no API key
)

Asking one order question

Runner.run_sync drives the run and hands back a result; final_output is the answer.

python
result = Runner.run_sync(desk, "Where is my order A17?")
print(result.final_output)

The desk answering an order question

The whole desk in one file, ready to run against the stand-in.

Example
from agents import Agent, Runner, function_tool, set_tracing_disabled
from shop_model import ShopModel
set_tracing_disabled(True)

@function_tool
def lookup_order(order_id: str) -> str:
    "Look up an order by its id."
    return f"Order {order_id}: shipped on 3 March, arriving 7 March."

desk = Agent(
    name="Shop desk",
    instructions="Help shoppers with their orders.",
    tools=[lookup_order],
    model=ShopModel(),
)
result = Runner.run_sync(desk, "Where is my order A17?")
print(result.final_output)

What the run produced

  • The stand-in saw the word order, so it asked to call lookup_order with id A17 instead of answering straight away.
  • The runner ran the tool and fed its return value back to the model.
  • The final answer is the tool's line, because the model turns a tool result into the reply.

A desk with a tool vs a desk with none

SetupThe desk's reply to the order question
Desk with lookup_orderOrder A17: shipped on 3 March, arriving 7 March.
Desk with no toolsHow can I help with your order?

When the desk needs a tool

  • Any answer that depends on live data, an order status, a balance, a booking, belongs in a tool, not in the instructions.
  • The desk stays small: the model decides, the tool fetches, the model replies.
Watch out. The tool's docstring is what the model reads to decide when to call it. Leave it out and the model has no idea the tool exists.
Try it yourself
  • Ask about a different order id and notice the stand-in still returns A17; a real model would read the id from your message.
  • Remove tools=[lookup_order] and rerun; the desk falls back to the greeting.
  • Add a second tool, store_hours(), and see that the stand-in still reaches for lookup_order on an order question.

Every expert started right here.