~5 min read Something that has bothered me for a while with agents that I only recently put my finger on is that they violate this principle. The Robustness Principle, AKA Postel's Law, states that you should be loose in what you accept and strict in what you reply with. The idea is that a system can afford to be forgiving a bit to users on what they send in, but these same users need rely on these outputs from you. So you should hold yourself to a higher strictness standard in what you send back to them. Agents violate this by being relatively unpredictable in their outputs, even for the the same inputs. In many ways, this is a feature. You don't want every session with Claude to converge to the same output. Over enough sessions, though, people have a way they expect these sessions to go, and anytime it diverges users can annoyed by their agent violating their working pattern. In a sense, people believe they have developed a working norm with their agent, and when it's violated, people get very frustrated. Indeed, I remember last year in August - September being extremely annoyed with Claude Code when I was trying to work on a website rework for RefactorGVL. I tried many different ways to get it to try to conform to my expectations via CLAUDE.md, which functions like session preamble prompt. I would do things like add in lines like, "write unit tests" or "always use branches" or "use conventional commits.” Indeed once I discovered superpowers and realized it functions a bit like a tool call, that it fit exactly the bill for me in trying to get better outcomes for my SDLC process. (I know several people prefer spec kit. I'm just used to superpowers now, and it works for my varied use cases.) My experience is normative from my discussions with others over the past year or so. This all points to the idea of conforming work outputs. Basically, people implicitly expect some kind of contract to be met for work at specific stages and particularly at the end step. But agents don’t behave that way. They make no such guarantees and thus are violate the expectations that people have for them to be relatively loose with their inputs but expect the systems to regularly behave the same way across multiple interactions. Will Larson hints at this same expectation on this article recently. He talks in there about how, “I’ve seen too many pull requests go to CICD that had failed basic lints that could have been run locally to believe the harness was always running them. Now the harness has to explicitly document that it’s done those steps, or acknowledge it hasn’t.” He calls this the verification pattern, and he references several Twitter posts, but honestly, at the risk of being reductive, what I read there is about trying to figure out how to cleverly hint to agents at specific points in the process that they should follow a strict process suddenly. I understand this tendency, but I think it's important to remember what the underlying technology is. In the same way that the LLM hallucinating is a feature, not a bug, the LLM not following an expected process is itself a feature, not a bug, because it's a behavior that's RLed. You desire it. It’s just that you don't desire it all the time. Sometimes the conformance in the output pattern is something that’s desirable, and sometimes novelty is desirable. Sure, you can add it into your prompt workflow very clever means, and gain more 9s of conformance and shove the tails out further out when it doesn't conform with enough RL potentially for it behavior to follow directions given in the prompt, but practically, we ain't anywhere close to that. (Also, I expect that there's other emergent behavior that we lose when we do that.) As a quick aside, I thought for a short period of time that Jev or classifier models like it might be an interesting strategy, but I think the jury is still out on whether there's anything to gained with this approach. And even then, all my comments on hallucination and tails of behavior still apply. Therefore, solution-wise, we need good-ole-fashioned deterministic code being called. So as I see our options, for integrations, are just three:
The harness. I mean things like using some hook in the harness' lifecycle or, if you're like me and use pi, to make an extension to change the behavior of the harness directly. Either way, it means having deterministic code that runs at specific points that intercepts calls at specific known points. The problem with this approach is that Claude Code in particular doesn't expose a ton of detail, so this probably doesn't make a ton of sense for most people. External tools themselves. I primarily mean adding in implicit behavior to the tools, like git using its hooks, so that when you call commit, you invoke other behavior, likely through hk or other tools. This way, you can recreate the behavior when you too call the tools yourself from the command line. The limits with this approach are that not too many tools offer life cycle hooks or equivalent functionality, so this would be limited to almost exclusively git. Tool gateway. This is probably the thing I've seen people talk about the least, but I think may be the most promising. Right now agents run locally, inside a VM, or in a container. I can imagine a tool gateway around an agent harness, such that all tool calls go through this other code, much in the same way AI or model gateways proxy calls to the model makers. I can imagine this offering people a lot of options for changing the call pattern to an MCP call in addition to local tools. In many ways, it behaves a bit like guardrail. So yes, I admit this is the most complex of the options as well, and this complexity is probably a reason why I haven't heard others talk about this before. I have tried each of these to some degree over the past year. I was doing a lot with Claude's hook ecosystem back in Jan and Feb before abandoning it due to its instability and moving to pi and use its extension ecosystem instead. Would love to hear if any of you all have approaches to this problem space — Robert This message is 100% organic human effort, so it will have typos. No, I didn't send it through an LLM to typo check it. It was made with just my fingers and my eyes and talking aloud to speech-to-text sometimes. |