Unit 07.03: Watching the tool calls, not just the output
The arguments an agent passes are where the interesting failures are, and they are invisible in the final answer.
Near-duplicate arguments mean retrying, not progressing
Logging the tool name, the arguments and the result per step makes a wasted call visible.
The code shows a three-step trace where two calls differ only in a plural.
import json
trace = [
{"step": 1, "tool": "read_account", "args": {"account_id": "ACC-1187"},
"result": "record for ACC-1187", "ms": 12},
{"step": 2, "tool": "check_policy", "args": {"topic": "refunds"},
"result": "policy text for refunds", "ms": 8},
{"step": 3, "tool": "check_policy", "args": {"topic": "refund"},
"result": "policy text for refund", "ms": 8},
]
print(json.dumps(trace, indent=1))
topics = [s["args"] for s in trace if s["tool"] == "check_policy"]
print(f"\ncheck_policy called {len(topics)}x with {topics}")
print("near-duplicate arguments -- the agent is retrying, not progressing")
# The final answer would look fine. The trace shows a wasted call caused by
# singular/plural drift, which is the class of problem invisible in the output
# and obvious in the arguments.
check_policy was called with "refunds" and then "refund". The final answer would look entirely fine; the trace shows a paid call wasted on singular/plural drift.
That class of problem - the agent retrying with a trivially different argument because the first result was not what it hoped - is common, cheap to detect, and completely invisible without argument-level logging.
The mistake this prevents
The mistake is logging tool names without arguments. "Called check_policy twice" could be two legitimate lookups or one lookup and one confused retry, and only the arguments distinguish them.
Takeaway
Log arguments as well as tool names. Near-duplicate arguments across consecutive calls are the signature of an agent retrying rather than progressing.
