Tutorial: Custom Prompts
On this page
RAGSystem supports three ways to control the prompt sent to your LLM, tried in this priority order (see RAGSystem._resolve_prompt):
- A custom prompt passed at construction time (or via
set_prompt()). - The built-in
PromptRouter(language + question-type aware) — the default when no custom prompt is given. - A hard-coded fallback template — used only if you explicitly disable prompt routing and don't supply a custom prompt.
Option 1 — A template object with .format()
Any object exposing a .format(context=..., question=...) method works. This matches the shape of a typical PromptTemplate class from a prompt-templating library.
from dataclasses import dataclass
@dataclass
class PromptTemplate:
template: str
def format(self, context, question):
return self.template.format(context=context, question=question)
tpl = PromptTemplate(
template=(
"You are a helpful support agent.\n\n"
"Context:\n{context}\n\n"
"Customer question: {question}\n"
"Your answer:"
)
)
rag = RAGSystem(
vector_db=vector_db, llm=llm, chunker=chunker,
context_manager=context_manager, prompt=tpl,
)
If your template names the parameter query instead of question, that's handled automatically — _resolve_prompt retries with query= if the first call raises KeyError/TypeError.
Option 2 — A plain callable
def my_prompt_fn(context: str, query: str) -> str:
return f"Given:\n{context}\n\nAnswer this in one sentence: {query}"
rag = RAGSystem(
vector_db=vector_db, llm=llm, chunker=chunker,
context_manager=context_manager, prompt=my_prompt_fn,
)
Option 3 — A raw format string
rag = RAGSystem(
vector_db=vector_db, llm=llm, chunker=chunker,
context_manager=context_manager,
prompt="Context: {context}\n\nQuestion: {question}\nAnswer:",
)
Swapping prompts after construction
rag.set_prompt(tpl) # switch to a custom template
# ... later ...
rag.set_prompt(None) # restore PromptRouter (if enable_prompt_routing=True)
Using PromptRouter directly (outside RAGSystem)
If you're building a custom pipeline and just want the language/type-aware prompt building without the rest of RAGSystem:
from zerda.rag.core import PromptRouter
router = PromptRouter(include_few_shot=True)
lang = router.detect_language(query)
qtype = router.detect_question_type(query, lang)
prompt = router.build(query=query, context=context, language=lang, question_type=qtype)
See PromptRouter API reference for the full list of detected question types and their trigger keywords.
Disabling prompt routing entirely
from zerda.rag.core import RAGConfig
rag = RAGSystem(
vector_db=vector_db, llm=llm, chunker=chunker,
context_manager=context_manager,
config=RAGConfig(enable_prompt_routing=False),
)
With no custom prompt and routing disabled, RAGSystem falls back to its own hard-coded bilingual instruction template (see RAGSystem._build_prompt).