Where we left off
Lessons 10-14 all print the strategy choice as a separate line, after the answer, from this course's own code, print(f"strategy: {strategy}") sitting next to the answer but not part of it. That's fine for a terminal demo, but the moment the answer leaves this script (copied into a chat log, read back later, shown to someone without the code), the strategy and the reason for it disappear with it. This lesson moves that disclosure into the answer text itself.
The system prompt is the whole change
Nothing about routing changes in this lesson, classify, then dispatch, exactly like Beginner Lesson 4. What changes is the instruction handed to the model generating the final answer:
SYSTEM_PROMPT = """You answer questions using only the provided context, \citing each fact's source document in brackets, e.g. [pizza-dough.md]. \If the context doesn't contain the answer, say so plainly instead of \guessing.
End every answer with one final line in exactly this form:Strategy used: <strategy name> (<one-line reason why this strategy fit this question>)"""The first paragraph is the same grounded-answer, cite-your-sources instruction this series has used since naive_rag Lesson 15. The new part is the last line's format: the model is told to close every answer with a strategy disclosure, in a fixed, parseable shape, as text the model itself generates, not something appended by this course's code after the fact.
The code, piece by piece
def generate_answer(question: str, strategy: str, retrieved: list[dict]) -> str: context = "\n\n".join(f"[Source: {r['source']}]\n{r['text']}" for r in retrieved) reason = STRATEGY_REASONS[strategy] prompt = ( f"{SYSTEM_PROMPT}\n\n" f"The retrieval strategy used for this question was '{strategy}', " f"chosen because: {reason}.\n\n" f"Context:\n{context}\n\nQuestion: {question}" )The model isn't asked to guess why a strategy was chosen, reason is handed to it directly (this course's own routing logic already knows why, from STRATEGY_REASONS), so the model's job is just to fold that already-known reason into fluent prose at the end of its answer, not to reconstruct or invent it.
Checkpoint
- Disclosure that lives in the answer text survives outside this script; disclosure printed alongside it by the harness doesn't.
- The system prompt's job here is narrow: tell the model the exact closing format to use, then hand it the already-known reason so it only has to phrase it, not invent it.
- This is a small prompt change with a real reliability cost: nothing guarantees the model always follows the closing-line format exactly. A production system disclosing strategy choice this way would still want to validate the format, not just trust the prompt.
If anything here still feels unclear, ask before moving to Lesson 16.