liveBook · Manning

Retriever router

As explained in Essential GraphRAG

A retriever router is a function that selects the most appropriate retriever for a user question and may extract the retriever's input arguments.

A retriever router selects the most appropriate retriever for a user question and may extract the arguments required to call it. It forms the main interface of agentic RAG, where specialized retrieval agents can handle different kinds of questions. section 5.0 section 5.1

The router usually uses an LLM with tool or function-calling support. It receives the question and available retriever descriptions, chooses one or more tools, and supplies complete arguments. The surrounding application—not the LLM—executes the selected retriever. section 5.1.2 section 5.3.1

Build the routing loop around four operational steps:

  • Describe each retriever clearly, including its purpose and parameter schema. section 5.3.1
  • Update follow-up questions with answers from earlier turns so each routed question becomes atomic, specific, and complete. section 5.3.2
  • Ask the LLM to select a tool, then dispatch its returned calls through a tools dictionary. section 5.3.2
  • Add specialized retrievers incrementally and retain a broad fallback such as text-to-Cypher when narrower tools do not fit. section 5.3.1 section 5.4

Routing a country-capital question

Given “What is the capital of France?” and two database retrievers—capital_by_country and country_by_capital—the router chooses capital_by_country and extracts “France,” producing the call capital_by_country("France"). section 5.1.2

Listing 5.1 Available retriever tools
text2cypher_description = {
    "type": "function",
    "function": {
        "name": "text2cypher",
        "description": "Query the database with a user question. When other tools don't fit, fallback to use this one.",
        "parameters": {
            "type": "object",
            "properties": {
                "question": {
                    "type": "string",
                    "description": "The user question to find the answer for",
                }
            },
            "required": ["question"],
        },
    },
}


def text2cypher(question: str):
    """Query the database with a user question."""
    t2c = Text2Cypher(neo4j_driver)
    t2c.set_prompt_section("question", question)
    cypher = t2c.generate_cypher()
    records, _, _ = neo4j_driver.execute_query(cypher)
    return [record.data() for record in records]


movie_info_by_title_description = {
    "type": "function",
    "function": {
        "name": "movie_info_by_title",
        "description": "Get information about a movie by providing the title",
        "parameters": {
            "type": "object",
            "properties": {
                "title": {
                    "type": "string",
                    "description": "The movie title",
                }
            },
            "required": ["title"],
        },
    },
}


def movie_info_by_title(title: str):
    """Return movie information by title."""
    query = """
    MATCH (m:Movie)
    WHERE toLower(m.title) CONTAINS $title
    OPTIONAL MATCH (m)<-[:ACTED_IN]-(a:Person)
    OPTIONAL MATCH (m)<-[:DIRECTED]-(d:Person)
    RETURN m AS movie, collect(a.name) AS cast, collect(d.name) AS directors
    """
    records, _, _ = neo4j_driver.execute_query(query, title=title.lower())
    return [record.data() for record in records]


movies_info_by_actor_description = {
    "type": "function",
    "function": {
        "name": "movies_info_by_actor",
        "description": "Get information about a movie by providing an actor",
        "parameters": {
            "type": "object",
            "properties": {
                "actor": {
                    "type": "string",
                    "description": "The actor name",
                }
            },
            "required": ["actor"],
        },
    },
}


def movies_info_by_actor(actor: str):
    """Return movie information by actor."""
    query = """
    MATCH (a:Person)-[:ACTED_IN]->(m:Movie)
    OPTIONAL MATCH (m)<-[:ACTED_IN]-(a:Person)
    OPTIONAL MATCH (m)<-[:DIRECTED]-(d:Person)
    WHERE toLower(a.name) CONTAINS $actor
    RETURN m AS movie, collect(a.name) AS cast, collect(d.name) AS directors
    """
    records, _, _ = neo4j_driver.execute_query(query, actor=actor.lower())
    return [record.data() for record in records]

Inspect a concrete tool schema containing a text-to-Cypher fallback and a generic answer_given retriever for answers already present in context. section 5.3.1

For multi-question interactions, route questions sequentially and append retrieved answers to the conversation. An answer critic can detect missing information, generate new complete questions, and send them through the router again; enforce exit criteria to prevent loops. section 5.3.2 section 5.3.3

How Essential GraphRAG covers it

How deep it goes
Implements tool selection, argument dispatch, sequential query updating, and optional iterative critique.
Examples
Uses country-capital routing, movie-by-title and movie-by-actor tools, text-to-Cypher fallback, and answer extraction from context.
What it assumes
Assumes basic RAG and retriever concepts while teaching tool schemas, function dispatch, and query updating.
What you can do after
Build it from scratch by defining retriever tools, routing LLM calls, dispatching arguments, and updating dependent questions.
How it connects
Connects agentic RAG with retriever agents, answer critics, tool calling, and text-to-Cypher retrieval.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Essential GraphRAG. The section links point to the parts of the book it draws on.