Yesterday's agent had one tool. What happens when you give it two tools and the prompt could require either one?
The agent reads the prompt, reads both tool docstrings, and picks the one that matches. If I ask 'how many words is this?' it uses word_count. If I ask 'how many characters?' it uses char_count.
Exactly. Register both tools with @agent.tool_plain. The agent's decision-making selects the right one. You don't write if/else — the model routes:
def agent_two_tools(prompt: str) -> str:
agent = Agent(model)
@agent.tool_plain
def word_count(text: str) -> int:
"""Count the number of words in a text string."""
return len(text.split())
@agent.tool_plain
def char_count(text: str) -> int:
"""Count the number of characters in a text string."""
return len(text)
return agent.run_sync(prompt).outputWhat if the prompt is ambiguous and the agent picks the wrong tool?
Tool selection depends on prompt clarity and docstring quality. An ambiguous prompt ('how long is this text?') might invoke either tool. A specific prompt ('how many words in this text?') reliably invokes word_count. The fix is always: sharpen the docstring and sharpen the prompt. Both sides of the interface matter:
def agent_two_tools(prompt: str) -> str:
agent = Agent(model)
@agent.tool_plain
def word_count(text: str) -> int:
"""Count the number of words in a text string."""
return len(text.split())
@agent.tool_plain
def char_count(text: str) -> int:
"""Count the number of characters in a text string."""
return len(text)
result = agent.run_sync(prompt)
print(f"Output: {result.output}")
return result.outputThe agent is making routing decisions based on my docstrings. It's like a function dispatcher where the dispatch logic is the model's reasoning, not an if/else chain.
That's a precise characterisation. The model is a reasoning dispatcher. Your tools are the capabilities. The prompt is the intent. The docstrings are the routing table. Good routing tables have unambiguous entries.
I've been writing if/else routing logic for years. Turns out you can just explain it to a model and let it route.
For deterministic routing — 'if X then tool A, if Y then tool B' — an if/else is still clearer and faster. Use model routing when the mapping is complex or context-dependent. Simple cases don't need a model.
agent = Agent(model)
@agent.tool_plain
def word_count(text: str) -> int:
"""Count words in a text string."""
return len(text.split())
@agent.tool_plain
def char_count(text: str) -> int:
"""Count characters in a text string."""
return len(text)The agent reads both docstrings and selects the right tool based on what the prompt asks for. "How many words?" triggers word_count; "How many characters?" triggers char_count. Clear, distinct docstrings are essential.
If the prompt requires neither counting task, the model answers from its training data without calling any tool. Both tools are available — the agent chooses zero, one, or both.
Tools can be called multiple times in a single run_sync. If the prompt asks for both word and character counts, the agent calls both tools and combines the results in its final answer.
Yesterday's agent had one tool. What happens when you give it two tools and the prompt could require either one?
The agent reads the prompt, reads both tool docstrings, and picks the one that matches. If I ask 'how many words is this?' it uses word_count. If I ask 'how many characters?' it uses char_count.
Exactly. Register both tools with @agent.tool_plain. The agent's decision-making selects the right one. You don't write if/else — the model routes:
def agent_two_tools(prompt: str) -> str:
agent = Agent(model)
@agent.tool_plain
def word_count(text: str) -> int:
"""Count the number of words in a text string."""
return len(text.split())
@agent.tool_plain
def char_count(text: str) -> int:
"""Count the number of characters in a text string."""
return len(text)
return agent.run_sync(prompt).outputWhat if the prompt is ambiguous and the agent picks the wrong tool?
Tool selection depends on prompt clarity and docstring quality. An ambiguous prompt ('how long is this text?') might invoke either tool. A specific prompt ('how many words in this text?') reliably invokes word_count. The fix is always: sharpen the docstring and sharpen the prompt. Both sides of the interface matter:
def agent_two_tools(prompt: str) -> str:
agent = Agent(model)
@agent.tool_plain
def word_count(text: str) -> int:
"""Count the number of words in a text string."""
return len(text.split())
@agent.tool_plain
def char_count(text: str) -> int:
"""Count the number of characters in a text string."""
return len(text)
result = agent.run_sync(prompt)
print(f"Output: {result.output}")
return result.outputThe agent is making routing decisions based on my docstrings. It's like a function dispatcher where the dispatch logic is the model's reasoning, not an if/else chain.
That's a precise characterisation. The model is a reasoning dispatcher. Your tools are the capabilities. The prompt is the intent. The docstrings are the routing table. Good routing tables have unambiguous entries.
I've been writing if/else routing logic for years. Turns out you can just explain it to a model and let it route.
For deterministic routing — 'if X then tool A, if Y then tool B' — an if/else is still clearer and faster. Use model routing when the mapping is complex or context-dependent. Simple cases don't need a model.
agent = Agent(model)
@agent.tool_plain
def word_count(text: str) -> int:
"""Count words in a text string."""
return len(text.split())
@agent.tool_plain
def char_count(text: str) -> int:
"""Count characters in a text string."""
return len(text)The agent reads both docstrings and selects the right tool based on what the prompt asks for. "How many words?" triggers word_count; "How many characters?" triggers char_count. Clear, distinct docstrings are essential.
If the prompt requires neither counting task, the model answers from its training data without calling any tool. Both tools are available — the agent chooses zero, one, or both.
Tools can be called multiple times in a single run_sync. If the prompt asks for both word and character counts, the agent calls both tools and combines the results in its final answer.
Create a free account to get started. Paid plans unlock all tracks.