Skip to content

Prompt reference

anki-llm has two prompt schemas. process-file and process-deck use batch output frontmatter. generate uses deck, note type, field mapping, optional processing, and optional TTS frontmatter. Both require a YAML block delimited by --- at the start of the file. Use only the keys documented below; strict frontmatter blocks reject unknown entries.

Used by process-file and process-deck.

---
title: Optional title
description: Optional description
output:
field: Translation
require_result_tag: false
---
Prompt body
KeyTypeRequiredRules
titlestringNoReserved metadata
descriptionstringNoReserved metadata
output.fieldstringOne output formOne non-empty destination field
output.fieldsstring listOne output formAt least two non-empty, unique destination fields
output.require_result_tagbooleanNoDefaults to false; valid only with output.field

Declare exactly one of output.field or output.fields.

---
output:
field: Translation
require_result_tag: true
---
Translate: {Japanese}
Existing translation: {Translation}
Wrap the final answer in <result></result> tags.

The body can reference raw Anki or input-file field names with {Field}. Matching is case-insensitive. An unknown placeholder fails that row.

With require_result_tag: false, the plain response is written. With true, only content inside the last <result>...</result> pair is written. A response without a complete pair fails and follows normal retry behavior.

---
output:
fields:
- Reading
- Explanation
- KanjiBreakdown
---
Sentence: {Kanji}
Translation: {Front}
Generate all requested fields.

One request must return a JSON object with exactly the declared keys:

{
"Reading": "日本語[にほんご]を勉強[べんきょう]する。",
"Explanation": "A neutral statement about studying Japanese.",
"KanjiBreakdown": "<ul><li>勉強: study</li></ul>"
}

Every declared value must be a non-empty string. Missing, empty, non-string, or undeclared fields invalidate the response. Validation happens before any update, so all declared fields change together or none do. Undeclared note fields are preserved. Source-only staging fields remain in process-file output, and import ignores fields absent from the destination note type.

Used by generate.

---
title: Japanese Vocabulary
description: Contextual sentence cards with readings
deck: Japanese::Vocabulary
note_type: Japanese (recognition)
field_map:
en: English
jp: Japanese
reading: Reading
processing:
pre_select:
- type: transform
target: reading
model: gpt-4o-mini
prompt: |
Add Kanji[reading] annotations to: {jp}
post_select:
- type: check
prompt: |
Check whether this sentence is natural: {jp}
tts:
target: Audio
source:
field: reading
provider: openai
voice: alloy
model: gpt-4o-mini-tts
format: mp3
speed: 1.0
---
Generate {count} cards for {term} as a JSON array.
KeyTypeRequiredMeaning
titlestringNoLabel in the workspace prompt picker; filename is the fallback
descriptionstringNoSupporting text in the prompt picker
deckstringYesExact destination Anki deck name
note_typestringYesExact destination Anki note type name
field_mapmapYesNon-empty map from LLM JSON keys to Anki field names
processingobjectNoPre-selection and post-selection LLM steps
ttsobjectNoShared generation and bulk-TTS audio settings

The prompt body must use {term} and {count}. It should require one JSON array of card objects whose keys are the left side of field_map. String values are used directly. JSON arrays in field values become <ul><li> HTML lists during import.

Example response for field_map: { en: English, jp: Japanese }:

[
{
"en": "How was your day?",
"jp": "今日はどうでしたか?"
}
]

processing.pre_select runs after generation and before card selection. processing.post_select runs after selection and before final import. Steps in a phase run in order, and later steps see earlier updates. Cards within a step are processed concurrently. Processing is unavailable with generate --copy.

A transform rewrites one or more field_map keys. Use exactly one write form:

processing:
pre_select:
- type: transform
target: reading
model: gpt-4o-mini
prompt: "Add furigana to {jp}"
processing:
pre_select:
- type: transform
writes: [reading, context]
prompt: |
Sentence: {jp}
Produce a reading and a brief context note.
KeyRequiredRules
typeYestransform
targetOne write formOne field_map key
writesOne write formOne or more field_map keys
promptYesNon-empty; all card fields are available as placeholders
modelNoModel override for this step

A multi-field transform receives structured output for the declared write keys.

processing:
post_select:
- type: check
model: gemini-2.5-flash-lite
prompt: "Evaluate whether this is natural Japanese: {jp}"

A check must not declare target or writes. anki-llm adds the response contract and expects result plus reason. Results are:

  • pass: continue normally.
  • flag: keep the card with a warning. Pre-selection flags are informational; post-selection flags open a review screen.
  • reject: discard the card.

The same block drives audio during generate import and bulk filling with tts --prompt.

KeyTypeRequiredRules
targetstringYesNon-empty Anki field name, not a field_map key
sourceobjectYesExactly one of field or template
source.fieldstringOne source formMust be a field_map key
source.templatestringOne source formPlaceholders must be field_map keys, case-insensitive
voicestringYesNon-empty provider voice identifier
providerstringNoopenai by default; also azure, google, amazon, edge
regionstringProvider-specificRequired for Azure and Amazon, forbidden otherwise
modelstringProvider-specificOpenAI model or Amazon engine; forbidden for Azure, Google, Edge
formatstringNoDefaults to mp3
speednumberNoMust be greater than zero; forbidden for Azure and Amazon

Amazon model accepts standard, neural, generative, or long-form. Provider credentials stay outside prompt files. See TTS providers for exact resolution and examples.

ContextPlaceholder names
Batch prompt bodyRaw Anki or input-file fields, case-insensitive
Generation body{term} and {count}
Processing promptfield_map keys for all card fields
tts.source.templatefield_map keys, case-insensitive
TTS flag-mode template fileRaw Anki fields, case-insensitive