Annie.dev
Back to Blog
AIEthicsSoftware Engineering

The Thought Process of a Wise AI Developer

February 10, 20269 min read

Anyone can call an API and glue a chat interface to it in an afternoon. What separates a competent AI feature from a reckless one isn't the model you chose — it's the judgment applied before, during, and after you ship it. After building several AI-driven features and watching a few of my own early ones go wrong in small but instructive ways, here's the thought process I now run through every time.

Ask 'Should This Be AI at All?' First

The most common mistake I see — and one I've made myself — is reaching for an LLM because it's available, not because it's the right tool. If a problem has a deterministic answer (parsing a date, validating an email, calculating a total), a model is slower, costlier, and less reliable than a plain function. I now default to a simple rule: use AI for tasks that involve ambiguity, natural language, or judgment calls a human would otherwise make by hand. Use regular code for everything that has one correct answer.

Assume the Model Will Be Wrong Sometimes — Design for It

A wise AI developer doesn't ask 'will this hallucinate?' — the answer is always yes, eventually. The right question is 'what happens when it does, and how does the user find out?' That means building confidence signals, human-review checkpoints for high-stakes actions, and clear escape hatches. A feature that lets a model send an email or issue a refund unsupervised needs a much higher bar of scrutiny than one that drafts a suggestion for a human to approve.

Data Provenance Is a Design Decision, Not an Afterthought

Where does the training or context data come from, who consented to it being used, and what happens if a user asks you to delete their data? These questions used to live entirely with legal teams. Increasingly, they shape the architecture itself — how you structure retrieval systems, how you handle deletion requests against embeddings and caches, and whether you can even honor a 'forget me' request in a system built around vector stores. Thinking about this at design time is dramatically cheaper than retrofitting it after a compliance request lands.

Evaluate Rigorously, Not Vibes-Only

Early on, I judged whether a prompt 'worked' by trying it a few times and eyeballing the output. That doesn't scale and doesn't catch regressions. A wiser approach builds a small evaluation set — real or representative inputs with known-good expected properties — and runs it against every prompt or model change. It doesn't need to be elaborate. Even twenty hand-picked test cases checked automatically beats vibes-based judgment on every single change.

typescript
// A minimal eval loop — better than eyeballing outputs
const testCases = [
  { input: 'cancel my subscription', expectedIntent: 'cancellation' },
  { input: 'why was I charged twice', expectedIntent: 'billing_issue' },
  // ...representative real-world examples
];

for (const { input, expectedIntent } of testCases) {
  const result = await classifyIntent(input);
  if (result.intent !== expectedIntent) {
    console.warn(`Regression: "${input}" -> got ${result.intent}, expected ${expectedIntent}`);
  }
}

Know the Difference Between Impressive and Useful

It's easy to get seduced by what a model can technically do — write a poem, generate an image, hold a philosophical conversation — and lose sight of whether that capability solves a real problem for a real user. I've scrapped more AI feature ideas than I've shipped, usually because the honest answer to 'does this make the product meaningfully better' was no. A flashy demo and a useful feature are not the same thing, and a wise developer learns to tell them apart before writing any code.

Stay Skeptical of Your Own Prompts

A subtle trap: once you've spent hours tuning a prompt and it finally produces good outputs on your test inputs, it's tempting to consider the job done. But prompts are brittle in ways traditional code isn't — a model update, a slightly different phrasing from a user, or an edge case you didn't anticipate can silently degrade quality. Treat prompts like any other piece of production code: version them, test them, and revisit them when the underlying model changes.

The wise AI developer isn't the one who ships the most AI features. It's the one who can tell you, honestly, which of their features shouldn't exist.

None of this is about being anti-AI or overly cautious to the point of paralysis. It's about applying the same engineering discipline we'd apply to any powerful, imperfect tool — clear boundaries, honest evaluation, and a willingness to say no when the technology doesn't fit the problem. That discipline, more than any specific technique, is what separates durable AI features from the ones that quietly get rolled back six months later.