Justy: Okay, so this piece is arguing that basically every agent failure we think is a model problem is actually a tool-design problem. Cody: Yeah. Justy: Which is… I mean, that's either obvious or deeply under-appreciated depending on who you're talking to. Cody: It's both. It's obvious once someone says it out loud, and nobody actually does it. Justy: Fair. So what's the actual argument? Cody: The core claim is that a model can only reason from the interface it's given—the tool name, description, schema, parameter docs. If that interface is sloppy, the model fails predictably. Not because the model is dumb; because the interface is ambiguous. Stronger models reduce some mistakes, but they can't reliably compensate for a fundamentally broken tool design. Justy: Okay, so it's not 'bigger model solves everything.' It's 'fix the tool boundary first, then upgrade the model if you still have problems.' Cody: Exactly. And the article walks through five concrete patterns that work. Single-responsibility tools instead of multi-action ones—no action parameter that forces the model to choose a mode first. You'd have separate tools: create_customer, get_customer, suspend_customer. Each one is unambiguous. The model picks the right tool directly. Justy: That's a… that's not revolutionary, but it's a concrete principle. Cody: Right. It's not novel, but most agent systems still do the multi-action thing. The second pattern is tight schemas—enums, validation, constraints encoded so the model doesn't have to guess. Instead of a string for priority, you have an enum: LOW, MEDIUM, HIGH. Justy: So invalid states become impossible. Cody: Exactly. Third is descriptions that define scope and boundaries. A weak description is 'search the knowledge base.' A strong one says when to use it, when NOT to use it, and which other tool handles the case you're excluding. So if the user asks about real-time data, don't use search_knowledge_base—use get_live_data instead. Justy: That's the one that's actually under-appreciated, I think. Most tool descriptions are just… what it does. They don't say what it doesn't do. Cody: Yeah. Fourth is structured error returns. When a tool fails, instead of throwing a stack trace, you return error_code, recoverable flag, and suggested_action. If recoverable is false and suggested_action is 'notify the user and stop,' the model doesn't waste tokens retrying a quota error. Justy: Okay, that's… that's just good API design. Cody: It IS good API design. Except applied to the model-tool boundary instead of human-API boundary. And the fifth is idempotent mutations. Any tool that changes state should be safe to call twice. If the agent retries because it got a network timeout, you don't want duplicate records. Justy: Right, right. Okay, so the whole thesis is solid. Where does it break down? Cody: It doesn't, really. I think the scope is narrower than the article implies. The patterns work best in closed, well-defined domains—customer management, task creation, API-style tools. Where it gets messy is shell, filesystem, or browser tools. But the article flags this upfront. It's a useful default, not a universal rule. Justy: Okay, so who actually cares about this? Because I think the answer is 'people building production agent systems,' but I want to hear you say it. Cody: People building production agent systems. Specifically teams that have deployed an agent, watched it fail in unexpected ways, and then blamed the model instead of the tool interface. You have a coding agent or a support copilot that's hallucinating, picking the wrong tool, or retrying forever. And instead of upgrading Claude, you fix the tool definitions and the error handling, and suddenly the agent is reliable. Justy: And it's way cheaper than fine-tuning a model or waiting for the next release. Cody: Yeah. It's not a moonshot. It's just… do the basic work right. And most teams haven't. Justy: That's the episode.