Skip to main content
Hooks let you log, time, or measure agent execution without touching the agent logic itself. Pass a Hooks object to the agent constructor.

Lifecycle events

HookFired when
on_agent_start / onAgentStartA run begins.
on_agent_end / onAgentEndA run completes (or fails).
on_iteration_start / onIterationStartA new think→act cycle.
on_llm_call / onLLMCallAbout to send a request to the model.
on_llm_response / onLLMResponseGot a model response.
on_tool_start / onToolStartAbout to execute a tool.
on_tool_end / onToolEndTool finished (with duration_ms).

Example

from opperai.agent import Agent, Hooks, tool

hooks = Hooks(
    on_agent_start=lambda ctx: print(f'-> {ctx["agent"]}: {ctx["input"]}'),
    on_tool_start=lambda ctx: print(f'  tool {ctx["name"]}({ctx["input"]})'),
    on_tool_end=lambda ctx: print(f'  -> {ctx["output"]} ({ctx["duration_ms"]:.0f}ms)'),
    on_agent_end=lambda ctx: print(
        f'<- done in {ctx["result"].meta.iterations} iterations'
        if ctx.get("result") else f'<- failed: {ctx.get("error")}'
    ),
)

agent = Agent(name="city-expert", instructions="...", tools=[lookup_city], hooks=hooks)

Common uses

  • Logging — print or ship events to your logger.
  • Timing — accumulate duration_ms per tool to find bottlenecks (see 05_hooks_timing).
  • Custom metrics — push counters / histograms to your metrics backend.
  • Span enrichment — attach extra metadata to the trace span the SDK already creates.
Hooks are additive on top of built-in tracing — every run, LLM call, and tool execution already lands in the Opper dashboard without any setup.