|
|
ADK Callbacks and Observability
Author: Venkata Sudhakar
ADK callbacks let you intercept every step of agent execution - before and after the model generates a response, before and after each tool call. This is the hook system that makes production ADK agents observable. Use callbacks to log every tool call with arguments and results, track token costs per conversation, enforce guardrails by blocking suspicious inputs, and add latency tracing for performance monitoring. Without callbacks your agent is a black box; with them you have complete visibility into every decision it makes. ADK provides four callback points registered directly on the Agent: before_model_callback runs before the LLM is called and can inspect or block the request; after_model_callback runs after the LLM responds and can track usage or modify output; before_tool_callback runs before each tool executes and can log or validate inputs; after_tool_callback runs after each tool returns and can log or transform results. Each callback returns None to proceed normally or a modified object to override the default behaviour. The below example adds all four callbacks to the ShopMax customer service agent - logging every step with timestamps, tracking token costs per session, and blocking tool calls with suspicious SQL injection-style inputs before they reach the tool function.
Wiring callbacks to the agent and testing normal and suspicious queries,
It gives the following output with full callback logs visible,
2025-04-01 INFO [BEFORE MODEL] session=s1 messages=1
2025-04-01 INFO [BEFORE TOOL] tool=get_order_status args={"order_id": "ORD-88421"}
2025-04-01 INFO [AFTER TOOL] tool=get_order_status result_keys=["status", "eta"]
2025-04-01 INFO [AFTER MODEL] in=89 out=54 call_cost=$0.00029
Q1: Where is order ORD-88421?
A: Your order ORD-88421 is out for delivery and expected today by 7pm!
Session stats: {"input_tokens": 89, "output_tokens": 54, "tool_calls": 1}
2025-04-01 INFO [BEFORE MODEL] session=s2 messages=1
2025-04-01 INFO [BEFORE TOOL] tool=get_order_status args={"order_id": "DROP TABLE ..."}
2025-04-01 WARN [BLOCKED] Suspicious input detected: DROP TABLE orders; ORD-88421
Q2 (injection attempt): DROP TABLE orders; ORD-88421
A: I was unable to retrieve that order. Please provide a valid order ID
in the format ORD-XXXXX and I will be happy to help you track it.
# Every step logged with timestamp for full audit trail
# Cost tracked per session - alert when session exceeds budget threshold
# SQL injection blocked BEFORE it reached the tool function
Production callback patterns: use before_model_callback to scan for prompt injection attempts before the message reaches the LLM. Use after_model_callback to enforce response policies - check for PII exposure, off-brand language, or competitor mentions and replace if found. Use before_tool_callback to write every tool call to your audit database with user_id, session_id, timestamp, and arguments - this is your compliance trail. Use after_tool_callback to cache expensive tool results within a session so the same lookup is not repeated. Add latency timing in before/after pairs to identify which tool is slowing your agent. Callbacks are the right layer for all cross-cutting production concerns and they compose cleanly - you can have multiple callback files for different concerns.
|
|