agentleFS
omidnwomidnw/my-skills/skills/llm-agent-tool-discipline/SKILL.md

llm-agent-tool-discipline

Skill0 starsChanged 12 days agoMITView on GitHub

Design patterns and a debugging procedure for LLM agent loops that call tools — use when the agent ignores tools it should call, fires excessive parallel tool calls ("shotgun"), claims an action succeeded without calling anything, invents tool-call markup in prose, or when building/changing the layers between "user message" and "tool execution": intent routing, tool binding, loop caps, and write enforcement. Trigger phrases: agent not calling tools, tool binding, tool shotgun, fake tool call, intent router, action not performed, agent answered but nothing happened.

The file

We split this skill into the rules it gives an agent

5 rules. About 0 are common, 5 are distinctive, and 0 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈5

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 0

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    No tool events at all + no routing log + no pre-step data → transport / bridge / auth is down.

    line 46
  2. Distinctive:

    If the router says "this turn needs tools", eligibility and enablement must provide the required available tools within existing …

    line 79
  3. Distinctive:

    Scoped bind: never bind the full catalog blindly.

    line 83
  4. Distinctive:

    Every emitted tool_call_id receives a reply — dropped calls get a corrective message.

    line 126
  5. Distinctive:

    Never stream a write-intent prose answer before checking it called tools.

    line 128

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

LLM Agent Tool Discipline

Purpose

Turn "the agent behaves badly with tools" (ignores them, spams them, or fakes success) into a systematic layered fix. Distilled from a real debugging arc where an agent ignored an entire subsystem in any language, couldn't apply changes, and fired ~50 parallel tool calls for one question — fixed with an 8-layer stack, verified layer by layer.

When to use

  • Agent doesn't call tools for requests that clearly need them (reads OR writes)
  • Agent fires excessive parallel tool calls; context/latency/cost explode
  • Agent answers "done" in prose without performing the action (fake compliance)
  • Agent writes invented tool-call markup (<tool>{json}</tool>) into its reply
  • Agent ignores an entire subsystem or claims it "doesn't exist / can't be changed"
  • Adding a new subsystem/domain to an existing agent loop
  • Designing an intent router or tool-binding layer for an agent

Preconditions

  • You can observe one failed turn's telemetry end-to-end (logs of routing, tool binding, loop steps, tool calls) — or can add that logging first
  • A test harness exists (or can be built) that reproduces a turn's manifest without calling the real LLM

Workflow

A. Diagnose — trace the WHOLE chain, never one gate

  1. Classify the failure signature from telemetry:
    • No tool events at all + no routing log + no pre-step data → transport / bridge / auth is down. Fix that first; nothing upstream matters.
    • Router/understanding ran and picked tools, but the loop logs 0 tools → a gate between the decision and the bind is closed.
    • Loop logs a large tool count (128 tools) and the model fires dozens of parallel calls → full-catalog bind is drowning the model (shotgun).
    • Loop ran, zero tool calls, non-empty prose answer, intent = write → fake compliance (described instead of did).
    • Reply contains literal tool-call syntax → markup hallucination.
  2. Enumerate every gate between the routing decision and the loop's final tools.length: eligibility gate → enable gate → rounds/budget gate → bind filter. A fix at one gate is invisible if the next still zeroes. The only truth is the loop's own log line (max N steps, M tools).
  3. Check process staleness: agent services usually load code/bundles at launch. A telemetry timestamp older than the last deploy means you are diagnosing old code. Restart, retest, then judge.

B. Fix — the layered stack (apply the layers the diagnosis names)

  1. Knowledge block: the model can't use a subsystem it doesn't know exists. Define it in the system prompt (what it is, which tools, read-first contract). Make the block conditional on availability — when the subsystem is disabled, the prompt must say so, so the model never promises changes it cannot make.
  2. Understanding pass (intent router): keyword detectors are whack-a-mole across languages and paraphrases. Replace with a small one-shot LLM call that reads the request + a compact tool catalog (name + one-line purpose) and returns structured JSON: intent, needed tool names, data domains. Contract: validate the picks against the real catalog (drop hallucinated names), and on ANY failure (timeout, bad JSON, empty) return null and fall back to the previous heuristic — the router can only improve routing, never break the turn.
  3. Gate audit: make every downstream gate respect the understanding pass. If the router says "this turn needs tools", eligibility and enablement must provide the required available tools within existing authorization/security limits; router picks never override disabled capabilities or permissions. Give authorized tool-needing turns a rounds floor (≥1 agent round) even when a context/tier system says "cheap turn, zero rounds" — zero rounds silently kills every tool call.
  4. Scoped bind: never bind the full catalog blindly. When the router picked tools, bind those (+ small safety-net sets, capped). Use a wider cap for write intents (writes need discovery for multi-step sequences) and a tighter one for reads. Without router picks, keep the previous behavior as fallback.
  5. Prompt call-discipline: explicit numeric rules beat vibes — "every call must be needed for THIS request; at most N parallel calls per step; read results before the next call; exploratory batches are a correctness failure, not thoroughness."
  6. Hard loop cap: prompt rules are not enforcement. Cap parallel tool calls per step in the loop itself; reject overflow with an explicit tool message teaching the model to be selective. Note the API contract: every tool_call_id the model emitted must receive a tool reply — dropped calls get a corrective message, never silence.
  7. Write-nudge: an action-intent turn answered in pure prose with zero tool calls did NOT perform the action. Intercept BEFORE streaming the answer, append the model's prose + a corrective internal/system instruction ("your reply performed no action — call the tool now; prose only if genuinely impossible, state why"), and grant one bounded extra round without fabricating a human message or new authorization. This also prevents a false "done!" from ever reaching the user.
  8. Markup sanitizer: as a hard guarantee, strip invented tool-call markup from replies (conservative pattern: snake_case tag wrapping a JSON-ish payload; never touch prose/fences/HTML). If stripping empties the reply, synthesize an honest answer from the pre-fetched data instead.

C. Verify

  • Unit tests that reproduce the EXACT production condition (worst-case tier, disabled router, empty catalog) — not just the happy path
  • A no-regression test proving genuinely trivial turns stay tool-free
  • Full suite green, service rebuilt
  • Live retest after restart; confirm the loop's own log line shows the expected N steps, M tools and 1–3 purposeful tool calls

Rules

  • Trace to the loop's actual tools.length before believing any upstream fix.
  • The understanding pass is advisory-only: any failure → fallback, never throw.
  • Router tool picks are validated against the real catalog; a hallucinated name can never bind.
  • Logging must redact secrets and private payloads; prefer tool names, timing, IDs and sanitized error classes. A tool call alone does not prove a write: completion requires a successful mutation result or readback of the intended state.
  • Sanitizers preserve user-requested literal code/HTML/tool examples; detect false execution claims using structured events rather than blindly deleting matching text.
  • Tool-needing turns get at least one agent round.
  • Every emitted tool_call_id receives a reply — dropped calls get a corrective message.
  • Never stream a write-intent prose answer before checking it called tools.
  • Conditional knowledge: the prompt states capability honestly (available / disabled), so the model never fabricates.
  • Fixing behavior = prompt rule AND loop enforcement together; one without the other fails on weak models.

Common mistakes

  • Fixing one gate of a stacked gate chain and declaring victory (the next gate still zeroes the tools).
  • Diagnosing telemetry from a stale process (sidecar/bundle loaded at launch).
  • Prompt-only fixes for behavioral bugs — weak models ignore them under pressure; add loop-level enforcement.
  • Streaming the reply before validating that a write actually happened.
  • Scoping write intents too tightly — writes legitimately need discovery headroom for multi-step sequences.
  • Abandoning keyword detectors abruptly — keep them as the fallback net for when the understanding pass is disabled or fails.
  • Forgetting the tool-reply API contract when dropping calls (missing replies for emitted tool_call_ids cause API errors, not graceful degradation).

Validation

  • Failure-signature tests: one per class (gate-closed, shotgun, fake-write, markup-hallucination) reproducing the exact production condition
  • No-regression test: trivial turns still skip the loop
  • Full suite green + artifact rebuilt
  • Live: restart, retest, read the loop log line and tool-call count; confirm the reply cites real tool results (not plausible prose)

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.