I’m building a diagnostic agent — you tell it “I can’t get online,” and it investigates, fixes, and verifies on its own. Early on, every time it missed something, the reflex was the same: add that case to the system prompt. Teach it to recognize a carrier-grade NAT range. Teach it this captive portal, that fake-IP subnet. The prompt grew a bestiary of specific symptoms.

It’s a trap, and it has a name: whack-a-mole. The specific patterns are infinite; you’ll never finish enumerating them, and every one you add makes the prompt longer and more brittle.

The model already knows the symptoms. In my own transcripts it identified a proxy’s fake-IP range without being told. What it needs from you isn’t trivia — it’s structure.

Three buckets

The discipline is to sort every “the agent should know X” into one of three, and only one belongs in the prompt:

  • Structural capability — something a tool must do right, independent of the specific problem: operate on the active network interface; re-test with a real HTTP request instead of a ping. This goes in code, permanently.
  • General principle — a domain-agnostic rule of behavior: find the root cause before changing anything; if the cause is software the user installed working as designed, hand it back instead of fighting it with system changes. This can go in the prompt.
  • Specific symptom knowledge — fake-IP subnets, particular error strings. This goes nowhere. Leave it to the model.

The structural version

The move that actually opened up the agent’s range wasn’t a longer prompt — it was a general read-only shell behind an allowlist. Curate the allowlist once, and it can investigate anything, the way a coding agent runs commands freely but safely. One structural decision bought unbounded diagnostic breadth; a hundred prompt lines would have bought a hundred special cases and a maintenance bill.

Before you add a line to a system prompt, ask: is this a principle, or am I memorizing one specific pattern? If it’s the latter, delete it. The model’s got it.