Skip to main content
It is recommended to study this section together with the tutorial Branch Structure.

Function

In complex RAG reasoning tasks, it is often necessary to dynamically decide the subsequent execution path based on intermediate results (such as the model’s current generated content or retrieval results). The Router Server is a key component designed for this purpose — it judges the current state based on input information and returns a custom branch label (state identifier) to drive branch jumps and dynamic control in the Pipeline.

Implementation Example

The following example shows how to implement a Router Tool. Suppose in the current RAG process, the model needs to judge whether the currently retrieved documents contain enough information to answer the question: if the information is sufficient, end the process, otherwise continue retrieval. You can implement a Router Tool like this:
servers/router/src/router.py
@app.tool(output="ans_ls->ans_ls")
def check_model_state(ans_ls: List[str]) -> Dict[str, List[Dict[str, str]]]:
    def check_state(text):
        if "<search>" in text:
            return True
        else:
            return False
    ans_ls = [
        {
            "data": answer,
            "state": "continue" if check_state(answer) else "stop",
        }
        for answer in ans_ls
    ]
    return {"ans_ls": ans_ls}
This Tool will tag each answer with a state label to guide the subsequent process execution:
  • continue: Insufficient information, need to continue retrieval;
  • stop: Information is sufficient, terminate the process.

Usage Example

The defined Router Tool needs to be used in conjunction with branch structures branch: and router: to jointly realize dynamic jumps based on state labels.
https://mintcdn.com/ultrarag/T7GffHzZitf6TThi/images/yaml.svg?fit=max&auto=format&n=T7GffHzZitf6TThi&q=85&s=69b41e79144bc908039c2ee3abbb1c3bexamples/rag_branch.yaml
# MCP Server
servers:
  benchmark: servers/benchmark
  retriever: servers/retriever
  prompt: servers/prompt
  generation: servers/generation
  evaluation: servers/evaluation
  custom: servers/custom
  router: servers/router

# MCP Client Pipeline
pipeline:
- benchmark.get_data
- retriever.retriever_init
- generation.generation_init
- retriever.retriever_search
- loop:
    times: 10
    steps:
    - prompt.check_passages
    - generation.generate
    - branch:
        router:
        - router.check_model_state
        branches:
          continue:
          - prompt.gen_subq
          - generation.generate:
              output:
                ans_ls: subq_ls
          - retriever.retriever_search:
              input:
                query_list: subq_ls
              output:
                ret_psg: temp_psg
          - custom.merge_passages
          stop: []
- prompt.qa_rag_boxed
- generation.generate
- custom.output_extract_from_boxed
- evaluation.evaluate
This example demonstrates a typical cyclic reasoning process: When router.check_model_state judges that the model output contains the <search> identifier, it enters the continue branch to continue retrieval; otherwise, it enters the stop branch to directly end the loop.