We Gave Our Agent a Third Tool. Then We Deleted It.
Melio — the AI nutrition agent I work on — generates day meal plans through a LangGraph ReAct loop. Yesterday we closed the hardening program for its tooling layer, and the most valuable result wasn't a feature we shipped. It was a tool we deleted.
The two-tool baseline
Exactly two tools are advertised to the LLM:
lookup_usda_batch— a schema-enforced, batch-per-meal USDA lookup. The server caches the full 59-nutrient panel; the model only ever sees a 4-macro hint (calories, protein, fat, carbs). The Anthropic API is stateless and re-sends the whole conversation every turn, so those trimmed payloads are exactly why the loop is cheap.DayPlanLLMSubmit— a synthetic, strict-schema exit tool with no nutrition fields. It's bound as a tool but never executes; calling it is the day plan. The server computes every number from the cached USDA panels, so the model literally cannot hallucinate a calorie.
The tempting third tool
We had a verify_meal_against_target self-check tool sitting unbound in the codebase — a deterministic deviation check with a fix hint. Back in the Haiku days, binding it made the model oscillate on adjust-and-re-verify, so it stayed off. But the deployed model is Sonnet now, and the argument kept coming back: surely a smarter model would use one polite verify call before submitting.
So we bound it and ran the eval:
- Tool calls per plan: 2 → 10.7
- Force-commit rate: 0 → 1.0 — every single day hit the round budget and had to be forced to submit
- Redundant call rate: 0 → 0.375
- Cost per plan: $0.34 → $1.20 (3.5×)
- Calorie deviation: worse, 1.36% → 3.62%
Delete, don't disable
The bound self-check tool was rejected — code, flag, budget and telemetry carve-outs, all deleted — and the rejection is written into the layer docs as part of the final design: don't re-add a self-check tool without a bounded verify-round cap designed in from the start and a fresh eval pass. Before the experiment, the two-tool surface was generating plans at $0.34 with zero force-commits. It still is.
The lesson
Two things turned this into a 30-minute decision instead of a week of debate. First, the design thesis was explicit and written down, so the experiment had a falsifiable claim to test. Second, the eval harness: without cost_per_plan and force_commit_rate as measured metrics, "the verify tool feels helpful" would have won the argument. Every tool you bind is a cost the model pays on every turn — and numbers, not taste, are what let you delete code with confidence.

Oleksandr Yusypenko
Senior Full-Stack + AI Engineer. Building in public — AI agents, LangGraph, production systems.
Related Posts
Jul 13, 2026
Claude Code config is a team asset, not a personal file
On the robbed monorepo I set up Claude Code the way you'd set up CI or CODEOWNERS: a shared, version-controlled, enforced config so every engineer and every AI agent inherits the same conventions, ownership boundaries, and guardrails.
Jul 3, 2026
Two planes of quality: making meal-plan generation both evaluable and observable
How Melio's meal-plan pipeline splits quality into two planes — online validation and offline evaluation — plus the observability layer that makes them measure the same things, and the reasoning behind which metrics are allowed to block a deploy.
Jun 14, 2026
Streaming Live Solana Trades Through Cloudflare Workers (The Wire-Splice Trick)
How I move on-chain data end to end — ingesting Solana into a database from a Rust server, then streaming it live to a Next.js app through a Cloudflare Worker that acts as a zero-copy SSE wire splice.
Query-based CDC over WAL: keeping a CQRS Postgres → ClickHouse read model fresh
NextThe Prompt Cache That Silently Did Nothing