DEV Community

Cover image for I Almost Used AI to Classify User Input. Simple Rules Worked Better
Warren
Warren

Posted on

I Almost Used AI to Classify User Input. Simple Rules Worked Better

I’ve been rebuilding a small name tattoo tool recently, and I ran into a problem that looked like a good use case for AI.

The user enters some text.

At first, I treated every input basically the same:

text → show a set of lettering styles

That works for simple names.

But these are all very different inputs:

  • Emma
  • A.M.
  • Jack + Mia
  • Amelia · 1998-11-14
  • Anna-Marie
  • Forever Dad

Showing the exact same recommendations for all of them started to feel wrong.

My first thought was: classify the input with an LLM.

I already use AI elsewhere in the product, so sending the text through another model call would have been easy enough.

But after listing the cases I actually cared about, I realized the classification problem was tiny.

The input types were predictable

I didn’t need to understand arbitrary human language.

I mostly needed to distinguish things like:

  • initials
  • initials + date
  • name + date
  • two names
  • hyphenated names
  • multi-word text
  • short single names
  • medium single names
  • long single names

So instead of adding another model call, I used deterministic rules.

A simplified version looks roughly like this:

function getNameStructure(text: string) {
  const value = text.trim()

  if (looksLikeInitialsAndDate(value)) {
    return "initials-date"
  }

  if (looksLikeNameAndDate(value)) {
    return "name-date"
  }

  if (looksLikeInitials(value)) {
    return "initials"
  }

  if (looksLikeNamePair(value)) {
    return "name-pair"
  }

  if (value.includes("-")) {
    return "hyphenated"
  }

  if (value.split(/\s+/).length > 1) {
    return "multi-word"
  }

  if (value.length <= 5) {
    return "short"
  }

  if (value.length <= 9) {
    return "medium"
  }

  return "long"
}
Enter fullscreen mode Exit fullscreen mode

The real implementation has a few more checks, especially around dates and separators, but the idea is the same.

Nothing clever.

And that turned out to be a good thing.

Classification only mattered because it changed the UI

I didn’t want classification for its own sake.

I wanted the first few lettering options to make more sense for the input.

For example, compact initials can tolerate directions that might feel too heavy for a long name.

A name pair needs enough spacing to keep both names readable.

A name + date has a second piece of information competing for attention.

A long name usually needs a little more restraint than a short one.

So the structure changes the recommendation order.

Something like:

const recommendations = {
  initials: [
    "bold",
    "minimal",
    "gothic",
  ],

  "name-pair": [
    "minimal",
    "script",
    "serif",
  ],

  "name-date": [
    "serif",
    "minimal",
    "script",
  ],

  short: [
    "script",
    "signature",
    "bold",
  ],
}
Enter fullscreen mode Exit fullscreen mode

The exact presets aren’t important here.

What mattered was that recommendations became predictable.

And I still keep the other styles visible.

The classifier doesn’t decide:

This is the correct style for your tattoo.

It only decides:

These are probably useful directions to show first.

That distinction helped keep the rules small.

Why I ended up preferring rules over AI here

The more I worked on it, the less attractive an AI classifier became.

With deterministic rules:

  • there’s no extra inference cost
  • there’s no network latency
  • the same input always gets the same classification
  • edge cases are easy to reproduce
  • I can see exactly why a recommendation appeared
  • changing product behavior means changing a rule, not changing a prompt and hoping the model interprets it the same way

Most importantly, the problem itself wasn’t fuzzy enough to justify a model.

The product still uses AI when the user wants an actual custom lettering composition with flowers, symbols, flourishes, or other supporting details.

But deciding whether A.M. looks like initials?

That doesn’t need intelligence.

It needs a regex.

I ended up using this approach in the Name Tattoo Generator, where the lightweight preview stays deterministic and the AI step only comes later when the user actually wants custom composition.

I think I was using the wrong default

For a while my default question was:

Could AI handle this?

Now I’m trying to ask:

Is there enough uncertainty here that AI is actually useful?

If the input space is small, the rules are understandable, and predictability matters, a boring classifier can be a better product decision.

AI is much more valuable later in this workflow, where the user asks for something genuinely open-ended.

The funny part is that making the AI product better in this case meant using less AI.

I’m curious how other people draw this line.

What’s something you originally planned to solve with an LLM, then replaced with normal code?

Top comments (0)