Skip to main content
skill CX Codex

agent-tool-call-latency — Claude Code skill: latency audit and setup

This skill analyzes local session history to show how long agent tool calls take and where time is lost. Use it to investigate slow runs and rank possible fixes.

Install into Claude Code · Skills CLI (Vercel) All methods and platforms ↓
npx skills add exadel-inc/agentic-readiness-assessment --skill agent-tool-call-latency -a claude-code
Open on GitHub

What agent-tool-call-latency does

The skill gathers tool calls from session history across agent harnesses, measures their duration, and investigates slow commands, harness overhead, and waiting. Its workflow moves from inventory and measurement to diagnosis, proposed decisions, approved changes, and a report. The default analysis window is 30 days; an argument can narrow it to a time period, harness, or project.

Python 3 scripts extract, validate, and aggregate the records: extract.py, validate_calls.py, and aggregate.py. Session history is read-only, and command records with masked secrets stay in the work directory. Before ranking a cause, the audit checks it against a benchmark, current harness documentation, a repository line, or the raw log.

Changes wait for the user's approval. If a harness history lacks per-call timestamps, the skill proposes capturing calls with a hook; it does not alter or move session history. Running the audit requires Python 3 and access to local session history.

What it helps with

  • Find which commands consume the most tool time
  • Compare tool-call delays across agent harnesses
  • Separate necessary work from waiting and harness overhead
  • Rank proposed fixes by recoverable time
  • Track how an approved change affects the next audit

Example prompts for the agent

  • Audit agent tool-call latency over the last 14 days.
  • Check where tool time goes in this project's Claude Code sessions.
  • Find confirmed causes of waiting and propose fixes; don't apply anything yet.

How to install agent-tool-call-latency

1Skills CLI (Vercel)

npx skills add exadel-inc/agentic-readiness-assessment --skill agent-tool-call-latency -a claude-code

2Manually: put the files in place

~/.claude/skills/agent-tool-call-latency/SKILL.md

Copy the whole skill folder; for one project use .claude/skills/agent-tool-call-latency/

Step by step, with commands for each platform: How to install skills in Claude Code: five ways

Questions about agent-tool-call-latency

How do I install agent-tool-call-latency in Claude Code?

Run npx skills add exadel-inc/agentic-readiness-assessment --skill agent-tool-call-latency -a claude-code. The skill file is installed at ~/.claude/skills/agent-tool-call-latency/SKILL.md.

What does agent-tool-call-latency do?

It measures agent tool calls from local session history, investigates where time goes, and ranks possible fixes. It applies changes only after the user approves them.

What if a harness doesn't record timestamps for individual calls?

The audit records that the history cannot be measured and proposes capturing calls through a hook. Session history remains read-only.

Source text

SKILL.md · Apache-2.0
---
name: agent-tool-call-latency
description: >
  Measures every agent tool call on this machine from local session history (the
  user's chat logs), in any harness, finds where the time goes, and ranks fixes
  for slow commands, harness overhead and wasted waiting. Use when the user asks
  why their agents are slow, where agent run time goes, or how to cut the time
  agents spend waiting on tools.
license: Apache-2.0
disable-model-invocation: true
argument-hint: "[window, e.g. '14 days'; or a harness or project to focus on]"
---

# Agent tool-call latency

An **audit** of how long the agent's tool calls take, across every harness the user runs (CLI agents, desktop apps, frontends that drive other agents), measured from the user's own session history. It runs as **inventory**, **measure**, **diagnose**, **decisions** (the user rules on each fix), **execution** (approved fixes only) and **report**.

The skill's scripts are harness-neutral: adapters turn each harness's history into one [call record](references/SCHEMA.md) format, and everything after extraction reads only that format. A harness without a built-in adapter gets one written during the inventory.

Work in `~/.cache/agent-tool-call-latency/<today>/` (the **work directory**; create it first); `<skill>` below is this file's folder. The default window is 30 days; an argument narrows the window, the harnesses or the projects, and the phases stay the same.

## Guardrails

- **History is read-only.** Session files and databases are the user's chat history: open them read-only and never write, move or delete anything under a harness's directories.
- **Records stay local.** `calls.jsonl` holds commands, with secrets masked. It stays in the work directory; the report names command patterns, not full commands.
- **Causes are confirmed before they are ranked.** An entry in [CAUSES.md](references/CAUSES.md) is a hypothesis until this run confirms it on this machine with a benchmark, the harness's current documentation, a `path:line` in the repository, or the raw log.
- **Fixes remove waste.** Queueing, overhead, repeated start-up, killed and re-run work, foreground waiting, and tests the change cannot affect are waste. A change that makes a check prove less is not a fix.
- **The audit's own sessions are excluded.** Benchmarks run under `/tmp/agent-latency-bench/`. Every extraction of the user's history passes it to `--exclude-cwd`; only the benchmark's own extraction ([BENCHMARK.md](references/BENCHMARK.md)) selects it with `--include-cwd`.

## Phase 1: Inventory

1. Run `python3 <skill>/scripts/extract.py --list` to see which built-in adapters find history.
2. Find the harnesses they miss. Check the installed agent CLIs and apps (`ls /Applications`, `command -v` for agent CLIs, dot-directories in `~` that hold sessions), and keep those whose history changed inside the window.
3. Write an adapter for each one, following [ADAPTERS.md](references/ADAPTERS.md), into `<work directory>/adapters/`.

Done when every harness with history in the window has one of:

- an adapter that meets [ADAPTERS.md § Done when](references/ADAPTERS.md#done-when);
- a recorded reason it cannot be measured (for example, no per-call timestamps), which becomes a hook-capture proposal in phase 4;
- a recorded call count under 1% of the other harnesses' calls, which the report lists under *Not measured*.

## Phase 2: Measure

1. Extract: `python3 <skill>/scripts/extract.py --since <first day> --out <work directory>/calls.jsonl --exclude-cwd /agent-latency-bench/ [--adapter <file> ...]`. Exit status 2 means an adapter failed: the others' calls are written, and the failed one is fixed or replaced before going on. A line saying a source was skipped costs only that file's calls; list skipped files in the report's limits.
2. Validate: `python3 <skill>/scripts/validate_calls.py <work directory>/calls.jsonl`. A schema error or an unexplained WARN sends you back to the adapter.
3. Aggregate: `python3 <skill>/scripts/aggregate.py <work directory>/calls.jsonl --out-dir <work directory>` and read `summary.md`.
4. Name the unnamed buckets. For each family in *Unnamed shell commands* above 1 h, read its commands, add a `[category, label, regex]` row to `<work directory>/patterns.json`, and re-run step 3 with `--patterns`.

Done when every family above 1 h is named by a pattern, or explained in one line of the report (for example, one-off inline scripts with a sub-second median).

## Phase 3: Diagnose

Work down the candidates in order of hours: *Patterns by total time*, *Calls ending at a timeout cap*, gaps in *Cheap operations by harness, mode and approval path*, *Releases where cheap operations were slow*, reviewer time, and slow MCP servers. For each one:

1. Read at least five of its real commands from `calls.jsonl`, and open the session around one slow call through its `src`.
2. Split the time into **need** (the work itself: a five-minute suite that has to run) and **waste**.
3. Match the waste against [CAUSES.md](references/CAUSES.md) and confirm it here. Harness overhead is confirmed by a [benchmark](references/BENCHMARK.md); harness behaviour by its current documentation, quoted; a repository cause by the `path:line` that creates it.
4. Estimate the recoverable hours per month: waste per call × calls per month, with the arithmetic shown.

Category totals are tool time, not wall time: a subagent's duration contains its own calls.

Done when every pattern above 2% of tool time, every cap row, and every cheap-operation gap of 200 ms or more at p50 has a confirmed cause, a *need* verdict, or *not determined* after about five attempts.

## Phase 4: Decisions

Present the fixes grouped by owner (repository, agent environment, harness vendor) and ranked by recoverable hours. Each line carries the hours, the exact change (file and setting, or the repository and the script), how its effect will show in the next audit, and its risk. Add a hook-capture proposal for each harness phase 1 could not measure. Close with the three fixes you would apply first.

Then stop for the user's rulings. A fix the user does not approve stays untouched.

## Phase 5: Execution

Apply the approved fixes, each exactly as the user approved it:

- **Agent environment** (settings, rules, global instructions, hooks): copy the file to `<file>.pre-latency-audit-<YYYYMMDD-HHMMSS>` (a timestamp, so a later audit never overwrites the original), edit it, confirm the harness still loads it, and re-run the benchmark when the fix targets overhead.
- **Repository:** run `git status` first. If the checkout has uncommitted work or is not on its default branch, make the change in a new worktree from the default branch, never in the user's checkout. Then follow the repository's own workflow: a branch, its checks, and a pull request per repository.

Record every change in `<work directory>/changes.md`: the file or repository, the backup or branch, and how to undo it (`cp <backup> <file>`, or close the pull request). A temporary change, such as hooks wired for a capture window, also gets the date to remove it.

When an approved fix turns out unsafe or impossible as stated, do not apply a variant of it: describe what would change and ask the user again.

Done when every approved fix is applied or back with the user, and `changes.md` lists every file and repository the audit changed.

## Phase 6: Report

Write `<work directory>/report.md`, titled `# Agent tool-call latency — <machine, described generically>`, with these numbered sections in order. If the user's instructions set a visual style, follow it for any rendered version. The published example is [`examples/agent-tool-call-latency/report.md`](../../examples/agent-tool-call-latency/report.md).

1. **Verdict:** one paragraph: tool time and calls in the window, the waste range, the largest waste by fix ID, the largest one still open, and the time agents spent waiting on the user.
2. **Run and Scope:** one fenced yaml block: `audited_by`, `plugin_version` (the `version` of the plugin manifest that ships this skill, or `unknown`), `started`, `completed`, `window`, `platform`, `clients` (records and adapter per client), `not_extracted`, `excluded`, `calls`, `tool_hours`, `waste_hours`, `user_wait_hours`, `fixes` (count per status), `work_directory`.
3. **Glossary:** tool time, need, waste, waiting on you, at cap, approval path, p50 / p90, `F-nn`.
4. **Where the time goes:** the overall p50, p90 and calls over 30 s; the client table; the category table, with a need or waste verdict per row that names its fix IDs. *Waiting on you* is neither: it is time agents waited for the user to answer a question or approve a call. Keep it out of the waste range and describe it as a trait of how the machine is used (agents left running unattended, prompts nobody is there to answer). A fix that removes prompts the user never needed to see still belongs in *What to Fix*, with its hours marked as user wait.
5. **What to Fix:** an index table (`ID | Waste in the window | Owner | Status | The next audit shows it worked when`), then one `### F-nn` record per fix, ranked by recoverable hours, with each field as a bullet: **Problem**, **Evidence**, **Cause** (and how it was confirmed), **Fix**, **Owner**, **Status** (applied, approved, proposed, needs investigation, declined; for an applied fix, its early effect), **Verify**.
6. **Same operation, different client:** cheap operations' p50 / p90 per client, with one line per gap that names its cause or its fix ID.
7. **Patterns by total time:** the top patterns with hours, calls, p50, p90, calls at cap and where they ran; then one line on MCP servers.
8. **Ruled out:** each cause checked and rejected, with its evidence.
9. **Confidence and limits:** what timing each client's numbers rest on, how much data the early effects rest on, and what was not measured.
10. **Commands Executed:** the extraction, validation and aggregation commands, any queries used to build an adapter, and their results; then the changes from `changes.md`.
11. **Corrections to CAUSES.md:** entries this run confirmed, corrected or added, as replacement text.

Close with when to re-run (after a week of normal use, with `--since` set to the day after the last fix landed, comparing the rows named in the *Verify* fields), then a horizontal rule (`---`) and this line, verbatim:

This report covers one machine's agents. For the organization-level version, covering people and process as well as code, see Exadel's [AI Maturity & Readiness Assessment](https://exadel.com/services/ai-maturity-readiness-assessment/?utm_source=agent-tool-call-latency&utm_medium=plugin-report&utm_campaign=readiness-test-2026-10).

Name repositories by what they are (a desktop app, a 3D game), not by their names, and write paths relative to the repository or home directory, so the report can be shared without exposing the machine.

© exadel-inc · Apache-2.0 · exadel-inc/agentic-readiness-assessment

Similar skills

All skills for Agent setup: memory, context, orchestration →

From the same set2

Project sponsors

Companies that keep this analytics open
Gold sponsor

Impressions, clicks and code copies — open statistics. We keep the numbers public for the same reason NeBlask itself is public. Become a sponsor