Skip to content

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:

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

harness.yaml
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).

Summarize this message from a {plan} customer: {text}

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>.md in prompts/.
  • A task's prompt names one, and the direct runner sends it as the system message.
  • Placeholders are filled from the input's fields, with no template language.