Quickstart

On this page

This walkthrough builds a small but realistic router with three intent groups — RAG, tools, and chat — using the built-in group templates.

1. Define handlers

Handlers implement BaseHandler.handle(). See BaseHandler for the full contract.

Python · 18 lines
from zerda.router import BaseHandler, HandlerRequest, HandlerResponse

class DocsQAHandler(BaseHandler):
    def handle(self, request: HandlerRequest) -> HandlerResponse:
        # Pretend this retrieves from a vector store and synthesises an answer
        answer = f"[docs] Answer to: {request.query}"
        return HandlerResponse.ok(answer, source="docs_index")


class WeatherHandler(BaseHandler):
    def handle(self, request: HandlerRequest) -> HandlerResponse:
        city = request.context.get("city", "unknown")
        return HandlerResponse.ok(f"It's sunny in {city}.")


class ChatHandler(BaseHandler):
    def handle(self, request: HandlerRequest) -> HandlerResponse:
        return HandlerResponse.ok(f"You said: {request.query}")

2. Build route groups

router ships templates for the three most common LLM application intent domains: make_rag_group, make_tools_group, and make_chat_group. Each returns a pre-configured RouteGroup with sensible intent examples, keywords, and priority.

Python · 29 lines
from zerda.router import make_rag_group, make_tools_group, make_chat_group, Route, RouteKeywords

rag_group = make_rag_group()
rag_group.add_route(Route(
    name="docs_qa",
    description="Answer questions from the internal documentation",
    handler=DocsQAHandler(),
    examples=[
        "What does the refund policy say?",
        "How do I reset my password according to the docs?",
    ],
))

tools_group = make_tools_group()
tools_group.add_route(Route(
    name="weather",
    description="Get the current weather for a city",
    handler=WeatherHandler(),
    examples=["What's the weather in Cairo?", "Is it raining in London?"],
    keywords=RouteKeywords(any_of=["weather", "temperature", "forecast"], boost=0.15),
))

chat_group = make_chat_group()
chat_group.add_route(Route(
    name="general_chat",
    description="Handle general conversation",
    handler=ChatHandler(),
    examples=["how are you", "tell me a joke"],
))

3. Register groups with the router

Python · 6 lines
from zerda.router import HierarchicalRouter

router = HierarchicalRouter()
router.register_group(rag_group)
router.register_group(tools_group)
router.register_group(chat_group)

register_group immediately computes embeddings for the group's intent examples and every route's examples (see HierarchicalRouter.register_group), so the first route_query call doesn't pay an encoding-on-first-use penalty for these routes.

4. Route a query

Python · 7 lines
result = router.route_query("What is the weather in Cairo right now?")

print(result.matched)       # True
print(result.route_name)    # "weather"
print(result.group_name)    # "tools"
print(result.confidence)    # ConfidenceLevel.HIGH (or MEDIUM/LOW depending on embeddings)
print(result.content)       # "It's sunny in unknown."  (no "city" in context)

Pass context through to handlers via the context argument:

Python · 5 lines
result = router.route_query(
    "What is the weather in Cairo right now?",
    context={"city": "Cairo"},
)
print(result.content)  # "It's sunny in Cairo."

5. Inspect the decision

Every RoutingResult carries a full RoutingTrace so you can see why a route was chosen:

Python
print(result.trace.to_dict())

This includes the ranked candidate list with per-signal scores (semantic, keyword, LLM), timing breakdowns, and any notes the pipeline attached (e.g. "Best score 0.412 is below fallback threshold 0.4").

6. Record feedback (optional)

If your application can later determine whether the routed response was actually useful (a thumbs-up, a follow-up question, etc.), feed that back in:

Python
router.feedback(route_name="weather", success=True, score=0.9)

Over time this shifts score_bias on the weather route via the FeedbackEngine, making it more (or less) likely to win close scoring decisions.

Next steps

  • Read Concepts to understand how scoring and confidence work in detail.
  • Read Architecture for the full request lifecycle.
  • See Configuration to tune thresholds, weights, caching, and execution mode.

Related pages