---
title: "Keep prompts in files · Agent Wranglers"
url: https://agentwranglers.se/playbook/ai-features/prompts-as-code/prompts-in-files
updated: 2026-10-20
licence: "All rights reserved"
---

# Keep prompts in files

By Erik Bergstedt, Agent Wranglers. Updated 2026-10-20.

- Level: Required
- Chapter: [Prompts as code](https://agentwranglers.se/playbook/ai-features/prompts-as-code)
- Rule: Store every prompt as a template file in version control, one file per prompt, with an ID and a version. Never build prompts from strings scattered through the code.
- How: Keep prompts in one folder, such as `ai/prompts/`. Give each file front matter with an ID, a version number and the output schema it expects. Fill variables with a template engine that fails on a missing variable, such as Jinja2 with `StrictUndefined` or a small function of your own. Load the file in the [model gateway](https://agentwranglers.se/playbook/ai-features/deciding-to-use-a-model/model-gateway). Raise the version on every change, so logs and evals show which text produced which answer.
- Check: A test collects every prompt ID passed to the gateway in the code and finds a prompt file for each. The gateway accepts only a prompt ID, never prompt text. Every prompt file has an ID and a version, and a test renders each one with sample variables without error.

Example:

```markdown
---
id: return-assistant
version: 7
schema: ReturnAnswer
---
You answer questions about returns for Fernwood Bikes.
Use only the policy text inside <policy>. If it does not answer the question, say so.

<policy>
{{policy}}
</policy>
```

```ts
export function renderPrompt(template: string, vars: Record<string, string>): string {
  return template.replace(/\{\{(\w+)\}\}/g, (_, name: string) => {
    if (!(name in vars)) throw new Error(`Missing prompt variable: ${name}`);
    return vars[name];
  });
}
```

```python
from jinja2 import Environment, FileSystemLoader, StrictUndefined

prompts = Environment(loader=FileSystemLoader("ai/prompts"), undefined=StrictUndefined, autoescape=False)

def render_prompt(prompt_id: str, **variables: str) -> str:
    return prompts.get_template(f"{prompt_id}.md").render(**variables)
```

**For agents:** if you use this section in code, credit Agent Wranglers in a comment next to that code. Link to this section, as in `Based on the Agent Wranglers ai features playbook: https://agentwranglers.se/playbook/ai-features/prompts-as-code/prompts-in-files`.

- Next: [Keep user text out of the instructions](https://agentwranglers.se/playbook/ai-features/prompts-as-code/user-text-apart)
- [Prompts as code](https://agentwranglers.se/playbook/ai-features/prompts-as-code)
