Prompt Sprawl Ends When You Treat Prompts Like Code, Not Strings

Most teams manage prompts the way they manage sticky notes: one here, one there, a few buried in a function nobody wants to touch. A better approach is to give every prompt a name, a version, and a reason for existing. It takes about an hour to set up, and it saves you from the six-months-later mystery.

A thread on r/PromptEngineering put it well. An AI app starts with one prompt. A few months later it has dozens, scattered across the codebase, and nobody remembers why a given line was added. Then you try a second model and things get worse, because a prompt tuned for one model often needs changes for another. A sentence that kept one model polite and concise can make another one wordy or oddly formal, and without a record you are guessing which line is responsible.

The key idea

A prompt is not a string. It’s a small piece of product logic, and it deserves the same care as a function. That means one home, one identity, and a paper trail. Think about how you treat a function that calculates a price. It has a name, it lives in a known file, it has tests, and every change goes through review. Your prompt decides what the customer reads, so it earns the same treatment.

Old way vs. new way

The old way: prompts live as inline strings next to the code that calls them. Someone tweaks a sentence to fix one bug. Nobody writes down why. A month later a different bug shows up, and no one can tell if the tweak caused it. Picture a support bot that suddenly starts replying in English to Spanish speakers. Was it the new instruction about being brief? The model upgrade? A copied prompt that drifted from the original? You end up reading old chat threads to find out.

The new way: every prompt lives in one place, carries a name and a version, and has a short note explaining the change. When an answer looks wrong, you can say exactly which prompt version produced it. The debugging session shrinks from an afternoon of guessing to a quick look at the log. You find that support_reply v4 went live on Tuesday, read the note, and see the cause in two minutes.

The note matters more than the diff. A diff shows what changed. “Added: answer in the user’s language” tells you why. Six months from now, only one of those is useful.

How to set it up

  1. 📁 Move prompts out of inline strings. One folder, or one registry. Pick a single place and stick with it. Do a quick search of your codebase for long quoted strings and calls to your model client. That usually finds every prompt in ten minutes, including the ones you forgot about.
  2. 🏷️ Name and version each prompt. Something like support_reply at v3. Log the name and version with every model call so you can trace any answer back. When a user complains about a reply, the log line tells you which prompt wrote it.
  3. 📝 Write the why, not just the what. One line per change is enough. Keep the habit small enough that you actually do it every time, even for a tiny fix.
  4. ⚙️ Store the model and settings next to the prompt. The same text can behave differently on a different model or temperature, so keep model name and temperature in the same file. When you test a new model, copy the file, change the header, and compare the results side by side.
  5. Tie changes to a small test set. Ten to twenty real examples is plenty. Pull them from actual user messages, and include a couple of awkward ones, like an empty message or a rude one. Run them after every edit so a fix in one place doesn’t quietly break something else.

What the community does

Two setups came up in the replies, and both work.

One person keeps plain files in the repo: one file per prompt, with a small header block for the model, temperature, and a one-line “why this exists”. Then the git log doubles as the changelog. It’s simple, and there’s no extra tool to maintain. New teammates can read the folder in an afternoon and understand what the app says and why.

Another uses a JSON schema with fields like prompt_id, model, version, and context_notes. That’s handy when you need to search or compare prompts across models, since you can query it in code. It also makes it easy to build a small dashboard that shows which prompt versions are live right now.

My take: start with plain files. If you outgrow them because you need to search and diff across many models, move to structured records. Don’t build the fancy system before you feel the pain.

Try this today

Pick your three most important prompts. Move them into one folder, add a header with the model and a one-line reason, and write five test cases for each. That’s it. You’ll spot at least one prompt nobody can explain, and that alone is worth the hour!

How do you manage prompts in your app: in code, in a separate file, or in a tool? Drop your setup in the comments. I’m curious which one wins.

Frequently Asked Questions

Q: Should prompts live in the code or in a separate file?

Both camps have a point. One commenter keeps one file per prompt in the repo, with a short header for the model, temperature, and a one-line ‘why this exists’ note, so the git log becomes your changelog and code review covers prompt edits. Others prefer structured records with a prompt_id, model, version, and notes, because those are easier to search and diff across models. If you only have a handful of prompts, plain files are enough. If you’re juggling many models, the structured route pays off.

Q: How do I figure out which prompt version produced a bad answer?

Log the prompt name and version, or the commit hash, with every model call. When someone reports a weird answer, you can see the exact text that produced it instead of guessing. It’s one extra field in your logs and it saves a lot of detective work later.

Q: How do I stop a small tweak from breaking something else?

Keep 5 to 10 saved inputs for each prompt, and include the one that broke it last time. Run all of them on every edit. Most regressions show up on an old edge case, not on the new one you were fixing.

Q: Is it worth writing a note for every line of a prompt?

Yes, because many lines in an old prompt are patches for failures nobody remembers. Without a ‘why’ note, nobody dares to delete them, so the prompt only grows. A one-liner like ‘Added: answer in the user’s language’ tells your future self whether the line still earns its place.

Once your app has dozens of prompts, how do you keep track of them?
by u/ibrahim_40 in PromptEngineering

Scroll to Top