C.W.K.
Stream
Lesson 01 of 04 · published

Instruction and Input Stay Separate

~11 min · macros, separation, template, legibility

Level 0Dead Zone
0 XP0/32 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"A macro is a reusable instruction plus a slot for today's input. Blur the two into one string and you've lost the thing that made it reusable."

What a Macro Actually Is

A prompt macro is a saved, reusable prompt — "translate this to Korean," "summarize this in three bullets," "critique this drawing's composition." But a macro is only useful because it has two parts that stay distinct: the instruction (the reusable part you saved) and the input (the specific content you're applying it to right now). The instruction is the template; the input is what fills the slot. Keeping them separate is what lets you save the instruction once and reuse it against a hundred different inputs.

Why Folding Them Together Rots the Macro

The lazy implementation concatenates them early: instruction + "\n" + input, stored and sent as one blob. It works in a demo and quietly rots:

  • You can't edit the instruction anymore. Once it's fused with input, changing the reusable prompt means untangling it from whatever content happened to be attached the first time.
  • You can't re-apply it cleanly. The whole point — same instruction, new input — requires the instruction to exist independently of any one input. Fused, it doesn't.
  • The boundary gets ambiguous. Where does the instruction end and the input begin? A model reading one blended string has to guess, and guesses at that boundary are where prompt-injection and misinterpretation live.

Keep the Seam Explicit

Model a macro as a structure with named parts — an instruction field and an input field — and keep them separate all the way to the point of sending, letting the request format carry the distinction rather than a string join. This keeps the instruction independently editable (change the template without touching any input), makes reuse trivial (swap the input, keep the instruction), and keeps the boundary legible to both the user and the model. The seam between "the reusable thing" and "today's thing" is the whole value of a macro; preserve it in the data model, don't dissolve it into a string.

Code

Two named parts, kept separate to the boundary·typescript
// A macro is a structure, not a pre-concatenated string.
type PromptMacro = {
  id: string;
  name: string;
  instruction: string;   // the reusable template — edited independently
};

// At use time, instruction and input stay distinct parts of the request.
function buildMacroCall(macro: PromptMacro, input: string, images: ResolvedImage[]) {
  return {
    instruction: macro.instruction, // reusable
    input,                           // today's content — a separate slot
    images,
  };
}

// WRONG: `const prompt = macro.instruction + "\n" + input;`
// Fusing them early destroys editability, reuse, and the legible boundary.

External links

Exercise

Take a reusable prompt you use often (a translation, a summary, a review rubric). Write it two ways: once as a single string with the input concatenated in, once as a structure with a separate instruction field and input field. Now try to 'edit the instruction' in each. Notice how the concatenated version forces you to find and preserve the input boundary, while the structured version lets you edit the template freely.
Hint
The structured version makes 'change the instruction, keep applying it to new inputs' a one-field edit. The concatenated version makes it an untangling exercise every time — which is why real macro systems keep the two parts separate in storage and on the wire.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.