@tool decorator, hand them to create_agent, and get back a callable that runs a tight ReAct loop: the model decides which tools to call, infy runs them, and the results go back to the model until it produces a final answer.
Define a tool
Decorate any function with@tool. infy reads the function name, docstring, and type-annotated signature to build the JSON schema the model needs. No separate schema class, no manual argument validation.
name becomes get_weather, the description comes from the docstring, and city becomes a required string parameter. Parameters with defaults become optional; parameters without defaults are marked required.
The docstring is the tool description the model sees. Write it for the model: say what the tool does and when to use it.
How the schema is built
infy maps Python annotations to JSON schema types automatically.
A parameter with no default is added to the schema’s
required list. A parameter with a default is optional, and its default is recorded in the schema. A parameter with an unrecognized annotation falls back to string, but a parameter with no annotation at all gets no type. The self and cls parameters are skipped, so methods work too.
At call time, Tool.invoke accepts either a dict or a JSON string, drops any keys the schema does not declare, fills in defaults for missing required arguments where a default exists, and raises ValueError if a truly required argument is absent.
Async tools
@tool works on async def functions with no extra ceremony. infy detects the coroutine and awaits it. A sync tool called from an async agent is run in a thread pool so it never blocks the event loop.
Governance metadata
@tool accepts optional keyword arguments that describe a tool’s risk profile. They are inert on their own and are consumed only when you attach a Governance object to the agent. They cost nothing if you never opt in.
name, risk_tier (low, medium, high, or critical), verb (for example READ, WRITE, EXECUTE, NETWORK, DB, FS, EXTERNAL_API, FINANCIAL, SENSITIVE_DATA), reversibility, blast_radius, cost_class, side_effect, and scopes.
Run an agent
Pass a model and a list of tools tocreate_agent. It returns a plain callable. Call it with a string or a list of messages and it returns an AgentResult.
Options
create_agent and create_async_agent take the same keyword arguments.
ChatModel
required
The chat model that drives the loop.
list[Tool] | None
The tools the model may call. Omit it for a plain chat loop with no tools.
str | None
A system message prepended to the conversation.
int
default:"10"
The maximum number of model turns before the loop stops and returns.
bool
default:"True"
When the model requests several tools in one turn, run them concurrently. Set to
False to run them in order.Governance | None
An optional in-process control plane. When set, every tool call is policy-checked and every step is audited. See Governance.
Async agents
create_async_agent has the identical signature and returns a coroutine function. Await the call to get your AgentResult.
The AgentResult
Every run returns anAgentResult with these fields.
status, pending_approvals, and run_id are only meaningful with durable approval via DurableAgent. For a plain create_agent run, status is always "completed". See Durable approval.Every tool call gets a result
infy guarantees exactly one result message per tool call, even in failure cases. An unknown tool name, a raised exception inside a tool, or a governance denial all produce aToolMessage with status="error" rather than a missing entry. This keeps the conversation well-formed, since most providers reject a request where a tool call has no matching result.
When to use the graph instead
create_agent is a fixed loop: model, tools, repeat, stop. That is the right shape for most agents. Reach for the graph runtime when your control flow needs more than a loop:
Branching
Route to different paths based on state, not just tool calls.
Persistence
Checkpoint state and resume a run later.
Interrupts
Pause for input mid-run and continue where you left off.
Custom loops
Multi-agent hand-offs, retries, and cycles you define yourself.
StateGraph with checkpointing and interrupts, in both sync and async. The agent loop is the fast path; the graph is the escape hatch.
Next steps
Governance
Add deny-by-default policy, human approval, and a tamper-evident audit to any agent.
The graph runtime
Build branching, persistent, interruptible workflows.