Skip to main content

Dynamic System Prompts

Agents support dynamic system prompts through callable functions that are executed each time the agent runs, providing fresh context.

Using Callable Functions

The preferred way to create dynamic system prompts is to pass a callable directly to system_prompt. This gives you full control over the system prompt construction and access to all runtime inputs:
Then call the agent with runtime data:

Using Template Syntax

Template syntax will be deprecated in a future release. We recommend using callable functions instead.
For simpler cases, you can use {module::function} syntax to embed dynamic values:
The previous example used a built-in function (datetime). You can also create your own custom functions:
my_functions.py
You can also pass dynamic parameters to these functions using RunContext data that you previously set in the context.
my_functions.py
The response will be in Catalan. Benefits:
  • Real-time context: System prompts reflect current state
  • Dynamic behavior: Agent adapts to changing conditions
  • Automatic execution: Functions run on each conversation
  • Performance: Template resolution is fast and cached
  • Sync/Async: Handles both sync and async functions automatically

Dynamic Tools

Timbal provides the ToolSet class for dynamic tool resolution. ToolSets resolve tools at runtime before each LLM call, enabling dynamic tool availability based on execution context. Use ToolSets instead of static tool lists when:
  • Context-dependent availability: Tools should only appear under certain conditions (user permissions, environment state, iteration count)
  • Lazy loading: Defer tool initialization until actually needed
  • Dynamic configuration: Tools need runtime parameters or state that isn’t known at agent creation
  • Conditional behavior: Tool availability changes during execution
  • Token efficiency: Reduce token consumption by exposing only relevant tools instead of all available tools
  • Improved clarity: When many tools exist but only a few are available per context, the agent sees fewer options and is less likely to get confused
Implement the resolve() method to return a list of tools. Access runtime data through get_run_context() to inspect the current execution state.

Example: Role-based tool access

This example shows accessing input parameters to conditionally provide tools. The role can be set via prehook or when calling the agent:
The resolve() method is called before each LLM call. It reads the role from the input parameters and returns different tools:
  • role == "admin": returns view_profile, delete_user, modify_permissions
  • Otherwise: returns only view_profile
The agent only sees the tools returned by resolve(), preventing unauthorized actions when the role is not “admin”.