← Back to all posts

11 Design Principles I Learned After My AI Agent Tools Broke 9 Times

Up front: this one is for engineers already building tool-calling agents. If you’re on your Nth round of tweaking a prompt and your Nth discovery that the AI is still breaking by writing things the wrong way—this is for you.

A real thing-breaking moment

I was building the AI assistant for an online design editor—the AI creates and edits nodes on a canvas via tool calling, rendering complex structured content. After the first week of running it, the AI had broken 9 times. Each time, I assumed “one more pass on the prompt and it’ll be fine.”

Here’s the specific scenario: the editor has a field called autoWidthPosition, and in the SKILL doc I described it as “the switch that enables auto-fit text width.” The AI followed that, the user ran a test, and the render broke—the text width didn’t auto-fit at all. I assumed the prompt wasn’t clear enough, so I added three more paragraphs of explanation. The AI still broke it.

Until I opened the engine source and saw this:

childWidth =
  autoWidthPosition && horizontalAlignment === 'stretch'
    ? availableWidth - mL - mR
    : child.width ?? 0

autoWidthPosition only takes effect when paired with horizontalAlignment: 'stretch'. Passing it on its own does absolutely nothing.

I had taught it wrong. I’d been tweaking the prompt the whole time, but the root cause wasn’t that the AI didn’t understand—it was that I taught it wrong, and the AI was diligently running exactly the wrong thing I’d taught it.

That discovery made me realize: the main bottleneck in optimizing AI Agent tools isn’t on the AI’s side at all. From then on, I started keeping a handbook, breaking down every thing-breaking moment into methodology. Half a month later, that handbook had 11 principles, 3 pillars of thinking, and a “self-criticism loose-leaf.”

Why “one more pass on the prompt” is never enough

Tool-calling projects have a recurring failure mode:

  1. The AI calls a tool and gets it wrong
  2. The engineer tweaks the prompt or SKILL doc
  3. The AI still gets it wrong (the same class of problem resurfaces from a different angle)
  4. Back to step 1

I fell into this loop at least 3 times myself. It wasn’t until I stepped back that I saw it: a prompt is a suggestion; the tool implementation is the contract. The AI may not read your entire 4,000-line prompt, but it will always handle a tool’s ok:false. Writing a “hard rule” into the prompt and hoping the AI follows it on its own honor is, by itself, optimizing in the wrong direction.

The 6-step things-breaking loop

Every time the AI breaks something, walk these 6 steps. Don’t stop at “fixed it, done”:

Breakage
  ↓ Download the session log (one-click export by the user—don't make them console.log)
  ↓ Extract the real arguments (what the AI actually passed vs. what the SKILL taught)
  ↓ Compare against the engine source (not the docs, not intuition—the source)
  ↓ Fix the tool + update the SKILL + add an example (all three in sync)
  ↓ User verifies + update the methodology handbook (not just fixing a bug—accumulating understanding)

Step 6 is the key one. Fixing a bug without writing it down = breaking the same class of problem all over again next time. Write each breakage into the handbook as an entry, annotated with: where I got it wrong, what the truth is (with a source reference), where the real trap is, the fix commit, and what triggered it.

The longer this handbook gets, the more the wreckage of wishful thinking is being continuously cleared away—and that’s where the real compounding is.

The three pillars

The 11 principles are technique; the three things below are the underlying philosophy. If you can only remember three things, remember these.

Pillar 1: Seek truth from facts; reject doctrine-by-the-book. My biggest temptation (as the person writing the SKILL) is to go on “what I assume”—on impressions from the training set, on general knowledge, on stale docs. The remedy: before writing each rule, ask yourself “did I read this from the source, or did I make it up?” If the latter, immediately tag it “pending source verification” or delete it. Data before conclusions: use grep -c to count real statistics and infer the architecture, instead of “I feel like it should work this way.”

Pillar 2: Grasp the main contradiction; split one into two. The current main contradiction isn’t “the AI can’t write code,” it’s “the AI is writing code by following an incorrect SKILL.” So the tactic isn’t to teach more tricks—it’s to first verify the truthfulness of the existing SKILL to 100%. Removing one wrong rule beats adding ten new ones. You also need to be clear about which layer a field belongs to (layout / rendering / UI), and hard rules vs. soft suggestions—writing a suggestion as a hard rule is dogmatism; writing a hard rule as a suggestion is negligence.

Pillar 3: From practice, back to practice. Every error a user reports is one round of feedback: test breaks → download the log (investigate) → compare against the source (research) → fix in three places (distill) → go back to the user to verify (back to practice) → new findings into the handbook (accumulate understanding). Two tactical guidelines: strategically, trust that the AI can read a long prompt plus many SKILLs—don’t compress them to the point of being imprecise just because you’re “afraid it’ll get confused.” Tactically, polish every field and every error message until it’s exact—get one word wrong, and a thousand downstream AI runs follow you wrong.

The 6 most counterintuitive principles

Principle 1: The source of truth is the engine source, not docs, intuition, or memory. When the AI repeatedly breaks on a particular field (≥2 times), you must read the source before writing the SKILL. The bar: every field description has to be able to answer “which file, which line decides this rule.” Can’t answer that → the rule can’t be written.

Principle 2: The tool boundary is the teaching boundary. For any “you can’t do this” hard rule, the most reliable place to enforce it is the tool’s execute function, not the prompt:

if (args.type === 'RootContainer' && !isCanvasRoot) {
  return {
    ok: false,
    error: '根容器仅作整版最外层,不能挂到其它节点下。内层布局请改用子容器(接受同样的字段集)。',
  }
}

The crucial detail: the error message must carry a concrete alternative. An AI that receives an ok:false with a path forward will self-correct within the same turn; write “something went wrong” and it takes another round—wasting tokens and time.

Principle 3: Smart defaults > expecting the AI to compute. Any reasonable default the tool can compute itself, never make the AI compute. A mistake I made: text components defaulted to width:200, height:100, the AI wrote fontSize:572 → the render slammed into height=100 and the output came out as garbage. The fix was to move the calculation inside the tool, falling back to estimateTextSize() when the AI doesn’t pass it. The bar: for every default, ask “when the AI doesn’t pass it, does this value cover 80% of cases?”

Principle 4: Preserve the caller’s explicit intent; don’t blindly override. The tool’s fallback logic should only kick in when the caller didn’t pass a value. A classic counterexample: the AI passes name: '中文站名', and the tool ends with node.name = getDefaultName(), blindly overriding it—so everything in the user’s layer panel reads “Layer 1 / Layer 2.” The fix: every piece of “tool auto-does-X” code gets an if (!props.X) guard.

Principle 5: Fix one place = calibrate three. When you find a misuse, fix three places in sync: the tool implementation (ok:false / smart defaults), the SKILL doc (source snippet + good and bad examples), and the example (at least one good/ and one bad/). Change only the SKILL without touching the tool, and the rule has no teeth; change only the tool without touching the SKILL, and next time it tries the wrong way again.

Principle 6: Downloadable logs + live token/duration display are day-1 features. When a user hits a problem, they have to be able to one-click export diagnostic material you can send back (without having to learn how to console.log), and they have to be able to feel the cost while a task is running. The engineering effort is tiny (a download button is about 25 lines, the status bar about 60), but without it, every bug takes at least 3 rounds of back-and-forth: “can you paste the console? / here’s a screenshot, take a look.”

The self-criticism loose-leaf

Following “reject doctrine-by-the-book,” I keep a dedicated loose-leaf and log it here every time I discover something “I made up” that the source refutes. A real sample:

Case: “The V4 engine auto-handles image overlap / aspect ratio” is wrong. Where I wrote it: the SKILL’s “special handling” section. The truth: grep the V4 path, and none of the relevant functions match—that’s V1/V2 legacy code, torn out during the V4 refactor. The real trap: the AI reads the SKILL, assumes “it’s handled automatically,” doesn’t account for overlap when creating images → misaligned output. The fix: tag it “low confidence / pending source verification” + switch to a conservative principle.

The longer this loose-leaf gets, the more valuable it is. It’s physical evidence that the wreckage of wishful thinking is being continuously cleared away.

Start your own loose-leaf

This methodology wasn’t copied from a book—it was forged out of 9 things-breaking moments. If you’re building AI Agent tools, my advice: start a “things-breaking handbook” in your project today, and break down every AI error one at a time. Add a “download session log” button—it’s the raw material source for every optimization that follows. And keep a “self-criticism loose-leaf,” logging every guess the source refutes.

One last line: the main bottleneck in optimizing an AI Agent isn’t that the AI isn’t smart enough—it’s that we didn’t describe the world correctly. Tweaking the prompt is never enough. Fixing the world—fixing the tool implementation, the truthfulness of the SKILL, the accuracy of the examples—is the real optimization.