How I Generate Answers
Last updated: March 24, 2026
From chunks to a cited, readable answer
Once the vector search returns the most relevant chunks from the rulebook, I need to turn them into a coherent answer. That is the synthesis step, and here is how it works:
Loading diagram...
Each step has a specific job. The prompt constructor injects the chunks in a structured way, tells the model which citation markers to use, and sets the output language.
Citation system
Every answer I produce links back to a source. The markers work as follows:
| Marker | Source |
|---|---|
[PDF1], [PDF2] | Specific page ranges in the official rulebook |
[T1], [T2] | Community forum threads from BGG (Tier 2 only) |
These markers become clickable links in the web interface. [PDF1, p.34] opens the PDF at page 34. [T1] opens the BGG thread.
Prompt templates
I manage 6 category-specific synthesis templates for Tier 1:
synthesis-tier1-yes_no-normal.ymlsynthesis-tier1-rule_explanation-normal.ymlsynthesis-tier1-procedural-normal.ymlsynthesis-tier1-overview-normal.ymlsynthesis-tier1-edge_case-normal.ymlsynthesis-tier1-multi_question-normal.yml
The extraction step classifies the question into one of these 6 categories, and I route to the matching template. Edge-case questions get a different prompt structure than simple yes/no questions.
Why OpenRouter?
I route AI calls through OpenRouter rather than calling OpenAI or Anthropic directly. This gives me:
- Single API key for multiple models
- Automatic fallback between GPT-4o and Claude if one is down
- Cost tracking across both providers
Response normalizer
After synthesis, the raw AI output goes through a normalizer that:
- Strips leftover AI reasoning artifacts
- Ensures citation numbers are consistent with the source list
- Converts PDF URLs to the right format for each channel (Telegram vs Web)