Skip to main content
Every prompt the Luria pipeline runs — intake admin checklists, NSE summarization, per-domain interpretation, SIRF synthesis — lives in a single canonical reference. Each prompt is templated with Jinja2, so the same prompt text works for every patient. You fill in the placeholders at runtime from config.patient.yml and per-domain context. This guide covers what the prompt system is, when to use it, and how to extend it.
Templated prompts make patient data substitution mechanical, but they do not remove your clinical responsibility. Review every agent output before it lands in a final report.

What the prompts system is

The prompts system has three pieces that work together:
PieceRole
agents/prompts/PROMPTS.mdCanonical reference for every prompt, organized by pipeline phase
Jinja2 placeholders{{variable}} syntax that adapts each prompt to the current patient
fill_prompt() runtime helperRenders a named prompt against a context dictionary
The reference is the single source of truth. If a prompt is not in PROMPTS.md, it is not part of the pipeline.

When to use templated prompts

Reach for the prompts system when you need to:
  • Run the same prompt across many patients without rewriting the prose each time
  • Add an optional clause (for example, a parent rater block) that only fires when a flag is set
  • Loop over a variable-length list (domain scores, evaluation dates, validity flags)
  • Keep clinic-specific identity (clinician name, clinic name, ROI defaults) in one config file
If you are writing a one-off prompt for a single patient, skip the template layer and write it inline. The system is built for repeated runs.

Where prompts live in the pipeline

The reference is organized by the same phases described in the agent pipeline.
PhasePrompt nameUsed by
ANSE_ADMINnse_admin intake check
ANSE_STTnse_stt_transcript
ANSE_COD_SUMMARYnse_cod_summary
ANSE_REPORTnse_report
BDOMAIN_INTERPRETATIONevery domain_text run
CSIRF_SYNTHESISsirf_summary
CSIRF_RECOMMENDATIONSsirf_recs
DREPORT_TYPSTreport_assemble

The three Jinja2 patterns you actually need

You do not need to learn the full Jinja2 language. Three patterns cover every Luria prompt.

1. Variable substitution

Wrap any variable name in double curly braces.
Patient {{patient_first_name}}, age {{patient_age}}, presented with {{chief_complaint}}.
With the runtime context:
context = {
    "patient_first_name": "Sarah",
    "patient_age": 14,
    "chief_complaint": "difficulty concentrating at school",
}
The rendered prompt becomes:
Patient Sarah, age 14, presented with difficulty concentrating at school.

2. Conditional blocks

Use {% if %} to include a block only when a flag is set.
{% if has_parent_rater %}
Parent and patient ratings aligned on {{domain_name}} strengths.
{% else %}
Patient self-report on {{domain_name}} unavailable; rely on clinician observation.
{% endif %}
This is how the domain interpretation prompts conditionally pull in parent or teacher rater language without producing dead clauses when those raters are missing.

3. For loops

Use {% for %} to iterate over lists — multiple evaluation dates, a panel of validity flags, or a set of domain scores.
Evaluation occurred over the following dates:
{% for date in evaluation_dates %}
- {{date}}
{% endfor %}

Standard context variables

The runtime always passes a baseline set of variables loaded from config.patient.yml. You can use any of these in any prompt.
# Patient identity
patient_first_name: str        # "Sarah"
patient_last_name: str         # "Chen"
patient_full_name: str         # "Sarah Chen"
patient_age: int               # 14
patient_dob: str               # "2010-05-15"
patient_pronouns: str          # "she/her"
he_she: str                    # "she"
his_her: str                   # "her"

# Evaluation context
evaluation_date: str           # "2025-01-15"
evaluation_dates: list[str]    # ["2025-01-15", "2025-01-22"]
referral_source: str           # "PCP Dr. Smith"
chief_complaint: str           # "difficulty concentrating"

# Clinician identity
clinician_name: str            # "Joey Trampush, Ph.D."
clinic_name: str               # "Brainworkup Neuropsychology, LLC"
Phase B and C prompts receive additional per-domain variables (domain_name, domain_scores, has_parent_rater, validity_concerns) that are passed in by the calling agent.

Rendering a prompt at runtime

Call fill_prompt() with the name of the prompt from PROMPTS.md and the context dictionary.
from luria.prompts import fill_prompt

context = {
    "patient_first_name": "Sarah",
    "patient_age": 14,
    "chief_complaint": "difficulty concentrating",
    "domain_name": "Memory",
    "has_parent_rater": True,
}

rendered = fill_prompt("DOMAIN_INTERPRETATION", context)
# Pass `rendered` to your model client of choice.
The helper looks up the named section in PROMPTS.md, renders it against the context, and returns the final string ready to send to a model.

Adding a new prompt

  1. Add a new section to agents/prompts/PROMPTS.md with the required fields: Role, Worker, Task, Input, Output, and the prompt body in a fenced block.
  2. Use {{variable}} placeholders for anything that varies per patient or per run.
  3. Document any non-standard variables in the Input field so the calling agent knows what context to pass.
  4. Reference the new prompt from the calling agent by name — never inline the prompt text in code.
Keeping the prompts in one file means you can audit, diff, and version every change to the clinical reasoning the pipeline performs.
Last modified on June 3, 2026