Versioned prompts¶
A prompt is part of your app's behavior, so HarnessWeaver keeps prompts in files, versions them, and names the exact version in the spec. A change to a prompt is then a reviewed change, and every run's trace says which version it used.
A prompt file¶
Create prompts/triage@1.md:
You triage messages sent to Acme's support desk.
Reply with one line: the category (billing, bug, account or other), the priority
(1 is the most urgent, 4 the least), and a one-sentence summary of what the
customer wants.
The file name is <name>@<version>.md. The version can be 1, 1.2 or 1.2.0, and .txt works as well as .md.
Use it in the task¶
apiVersion: harnessweaver/v1
kind: Harness
metadata:
name: support-desk
owner: support-team
models:
provider: openai.chat
base_url: http://localhost:4000
api_key_env: LITELLM_API_KEY
default: fast
aliases: { fast: fast-chat, strong: strong-chat }
prices:
fast-chat: { input_per_mtok: 0.25, output_per_mtok: 2.00 }
strong-chat: { input_per_mtok: 3.00, output_per_mtok: 15.00 }
tasks:
triage:
runner: direct
model: fast
prompt: triage@1
output: str
The direct runner sends the prompt as the system message and the task's input as the user message. Run it as before:
$ HARNESSWEAVER_ENV=offline uv run python main.py
completed
billing, priority 2: charged twice for the Pro plan, wants one refund.
Picking a version¶
| Reference | Picks |
|---|---|
triage@1.2.0 |
Exactly that version |
triage@1 |
The file named triage@1.md, or else the highest 1.x.y |
triage |
The highest version, or the unversioned triage.md |
Name an exact version in production specs, so a new prompt file can't change behavior until the spec says so.
Tip
Prompts live in prompts/ next to the spec. Set prompts.dir to keep them elsewhere.
Placeholders¶
A prompt can hold placeholders in braces, such as {text}. For a task, they are filled from the input's fields, and {input} is the whole input. In your own code, s.prompt("triage@1", text=...) renders one with the values you pass (Sessions).
Placeholders follow Python's str.format_map: {{ and }} are literal braces, and a missing value is an error, not an empty string. HarnessWeaver has no template language with loops or conditions. Build any text that needs logic in your code, and pass it in as a value.
Recap¶
- Prompts are files named
<name>@<version>.mdinprompts/. - A task's
promptnames one, and thedirectrunner sends it as the system message. - Placeholders are filled from the input's fields, with no template language.