Back to News & Insights
Artificial Intelligence September 2, 2026 · 22 min read

7 of My 8 Claude Code Agents Had Zero Calls in 30 Days: Finding Dead Agents Automatically

I had eight custom agents defined in Claude Code. When I finally counted, seven of them hadn't been...

7 of My 8 Claude Code Agents Had Zero Calls in 30 Days: Finding Dead Agents Automatically

I had eight custom agents defined in Claude Code. When I finally counted, seven of them hadn't been called once in the last 30 days. What keeps my ¥1.2M/month automation setup running isn't clever prompting. It's an environment that keeps checking, automatically, whether the things I built are actually doing anything.

Claude Code lets you define custom agents by dropping .md files into the ~/.claude/agents/ directory. You define specialists like architect (architecture design), code-reviewer (code review), and security-reviewer (security audits), and expect Claude Code to pick the right one on its own. It's a natural assumption.

Take my environment as an example. ~/.claude/agents/ currently holds eight agent definition files.

~/.claude/logs/agent-invocations.jsonl holds 682 records spanning May 28 to August 30, 2026. Aggregating the last 30 days gives this breakdown:

Of the eight defined agents, exactly one, code-reviewer, was called even once in 30 days. The other seven had zero calls. 87.5% of the agents I'd defined might as well not have existed.

Narrow it to the last 7 days and it gets worse: code-reviewer drops out too, and the zero-call list grows to eight.

This isn't just a "what a waste" story. Claude Code agent definitions are injected into the system prompt on every request. Open a large agent like architect.md and you'll find a definition of more than 220 lines. Seven unused agent definitions were burning tokens and quietly degrading inference quality the whole time.

The sense of accomplishment when you define an agent is real. "From now on, my code gets reviewed automatically." "When I think about architecture, an expert steps in." You believe that, and weeks go by.

In reality, unless an agent is explicitly specified, Claude picks the generic route (general-purpose) or Explore. Even if code-reviewer's description says "MUST BE USED for all code changes," that's text inside the definition. Claude doesn't autonomously read that instruction and act on it. The agent only works once there's a calling prompt or calling logic on the invoking side.

Token cost. The length of the agent catalog injected into the system prompt is paid on every invocation. More definition files means more tokens per request, eating into a large context window.

Cognitive cost. It's hard for a human to manually track which agents are actually functioning, and management gets more complex as definition files pile up. When definitions that don't reflect reality accumulate, trust in the environment erodes. The moment you wonder "is this agent even running?", your confidence in the autonomous setup wavers.

The solution is to decide based on real numbers, not gut feeling. Build an operational cycle that uses logs to automatically surface "agents not called once in the last 30 days" and then delete or tidy them up.

The key idea is to invest in the environment, not the task. Not a one-off "delete this agent today," but a standing state where "a script exists that can instantly show me unused agents at any time." Run it monthly, weekly, or on a cron schedule; the cadence can be decided later. What matters is being permanently in a position to judge from measured data.

The reason I could build a ¥1.2M/month autonomous environment in six months isn't that I expected "AI to get smarter." It's that I invested mainly in mechanisms that constantly watch for "AI moving in the wrong direction." Monitoring agent usage is one example.

(Layer 1: Recording. Claude Code's stop hook writes agent invocations to JSONL, one record per line with ts, sessionid, subagenttype, etc. Layer 2: Aggregation. agent-usage-summary.sh aggregates records for the given window, with a Bash shell for argument parsing and environment variables, and a Python3 heredoc for the logic: filter by window, count by subagenttype, cross-reference against ~/.claude/agents/.md. Layer 3: Output. Top 10 invocation ranking plus a zero-call agent list, which feeds delete/archive/redesign decisions.)

Claude Code has a stop hook that can run an arbitrary script when an agent invocation completes. I use this hook to append information about the invoked agent to a JSONL file.

ts (timestamp), subagenttype (agent type), and status (ok/error) are the main fields used for aggregation. Since durationms is there too, you also get the elapsed time per call. My environment currently holds 682 records, three months of tracking data since the first record on May 28, 2026.

The aggregation script is 103 lines. A Bash outer shell takes the arguments, and the logic is written in a Python3 heredoc. Two reasons: parsing JSONL in pure Bash gets messy, and handling shell-integrated argument processing in pure Python is a hassle. The design plays to each one's strengths.

Want to discuss this further?

Book a free strategy call with our team to see how these insights apply to your specific business goals.

Book a consultation