Design Principles

Seven laws extracted from building an agent that reads, remembers, analyzes, and decides. Every principle is backed by a specific phase and outcome. Nothing here is theory — it all comes from watching the agent actually work.

These principles transfer. They came from building an article intelligence agent, but they apply to any agent that reads, classifies, recalls, analyzes, and decides. The architecture is different each time. The laws are the same.

Principle 1
Design the output shape before the prompt
Before the agent sees a single article, someone decided the shape of BriefResult — 10 fields, each forcing a specific decision. The schema is the hidden architecture. Vague fields produce vague output. When article_type and reading_depth were added as required enums, the agent's analysis became more structured and auditable. The shape constrains the thinking.
Phase 3: BriefResult schema designed with 10 required fields. Phase 7: 30 articles tested — output quality correlated directly with field specificity. Vague fields → vague output. Clear fields → clear thinking.
Principle 2
Rules in code beat rules in prompts
The post-processing filter catches fabricated citations. The Librarian queries the database — the model never touches SQL. The empty-drawer case is handled in Python, not in a prompt that says "if there are no briefs..." Code is reliable. Prompts are probabilistic. When a rule matters, put it in code.
Phase 15: Citation verification runs in Python post-processing. Phase 14: Database queries run in Python, not in model-generated SQL. The Librarian retrieves; the Analyst reads.
Principle 3
Saying no is a feature
The agent chose stop_here for the IBM article. It didn't search the web. It recognized that the article is its own primary source and additional search would add no value. A system that always "does something" is a system that wastes resources. The no-op tool — stop_here — is as important as the action tool. Refusal is functional.
Trace run-019e6027: chosen_tool=stop_here, rationale="the core thesis is a well-established practitioner viewpoint... searching would likely surface either the article itself or generic AI-hype discourse that adds no marginal value."
Principle 4
One concept per phase
Phase 3 classifies. Phase 14 recalls. Phase 6 analyzes. Phase 18 decides. Each phase does exactly one thing. When phases tried to do multiple things — classify AND analyze, recall AND evaluate — the output quality dropped. Separation of concerns isn't just code hygiene. It's cognitive architecture. The model thinks better when it thinks about one thing at a time.
Phase 6 (analysis) was split from Phase 3 (classification) after early testing showed that combining them produced conflated output. The model would classify based on its analysis rather than the article's actual content.
Principle 5
Empirical pressure before architectural complexity
30 articles run before the Critic was built. Isolation testing with injected errors before the pipeline was declared working. The 60/40 tool split wasn't designed — it emerged from real article runs with better docstrings. You can't design an agent in your head and then test it. The testing IS the design.
Phase 7: 30 articles run before Critic. Phase 15: isolation testing with injected errors (5/5 KNOWN_MISSES caught). Phase 18: 169 runs audit revealed gate exhaust, not knowledge breadth.
Principle 6
Tool docstrings ARE the prompt
Early versions of the agent almost always chose search_web — 95%+ of the time. The model defaulted to "do something." The fix wasn't a routing rule or a prompt that said "consider stopping." The fix was better docstrings. When stop_here was documented as a first-class choice with clear "use when" and "do not use" criteria, the model started choosing it appropriately (60% stop_here, 40% search_web). The docstring IS the instruction. Write it like a prompt. Include edge cases. Include when NOT to use the tool.
Before: vague docstrings → 95%+ search_web rate. After: clear docstrings with USE WHEN / DO NOT USE sections → 60/40 split emerged naturally. No routing logic changed. Only the documentation.
Principle 7
You can't improve what you can't see
Every field in BriefResult is observable. Every citation is traceable. Every tool choice has a rationale. The trace records are the raw evidence — not summaries, not mockups, but the actual agent output. When something goes wrong, you can see exactly where. Without this visibility, agent behavior is a black box. With it, every decision is auditable and every failure mode is discoverable.
Trace records: run-019e6027 (article analysis), run-019e6394 (query with 8 past_brief citations), run-019e63a0 (query with 10 past_brief citations). Each trace contains inputs, outputs, classification, recalled briefs, result, tool choice + rationale, and citations — complete audit trail from entry to decision.

These principles are not complete. They're what one build taught.

Every agent build will add to this list. Some principles will be refined. Some will be replaced. But the method — design the shape first, test with real data, put rules in code, make everything visible — that's not going to change. It worked for an agent that reads articles. It'll work for whatever comes next.