{
  "id": "semantic_router",
  "title": "Route Queries with SemanticRouter",
  "url": "https://redis.io/docs/latest/develop/ai/redisvl/user_guide/how_to_guides/semantic_router/",
  "summary": "",
  "tags": [],
  "last_updated": "2026-05-06T11:49:45+02:00",
  "page_type": "content",
  "content_hash": "27056b5446c930253531cdea4a6522eba00582bd769ebb064ad86814d5970429",
  "sections": [
    {
      "id": "overview",
      "title": "Overview",
      "role": "overview",
      "text": "RedisVL provides a `SemanticRouter` interface that uses Redis' built-in search and aggregation to perform KNN-style classification over a set of `Route` references to determine the best match.\n\nThis guide covers how to use Redis as a Semantic Router for your applications."
    },
    {
      "id": "prerequisites",
      "title": "Prerequisites",
      "role": "content",
      "text": "Before you begin, ensure you have:\n- Installed RedisVL: `pip install redisvl`\n- A running Redis instance ([Redis 8+](https://redis.io/downloads/) or [Redis Cloud](https://redis.io/cloud))"
    },
    {
      "id": "what-you-ll-learn",
      "title": "What You'll Learn",
      "role": "content",
      "text": "By the end of this guide, you will be able to:\n- Define routes with references and distance thresholds\n- Initialize and configure a `SemanticRouter`\n- Route queries to single or multiple matching routes\n- Serialize and restore router configurations\n- Manage route references dynamically"
    },
    {
      "id": "define-the-routes",
      "title": "Define the Routes",
      "role": "content",
      "text": "Below we define 3 different routes. One for `technology`, one for `sports`, and\nanother for `entertainment`. Now for this example, the goal here is\nsurely topic \"classification\". But you can create routes and references for\nalmost anything.\n\nEach route has a set of references that cover the \"semantic surface area\" of the\nroute. The incoming query from a user needs to be semantically similar to one or\nmore of the references in order to \"match\" on the route.\n\nAdditionally, each route has a `distance_threshold` which determines the maximum distance between the query and the reference for the query to be routed to the route. This value is unique to each route and uses Redis COSINE distance units (0-2], where lower values require stricter matching.\n\n\n[code example]"
    },
    {
      "id": "initialize-the-semanticrouter",
      "title": "Initialize the SemanticRouter",
      "role": "content",
      "text": "``SemanticRouter`` will automatically create an index within Redis upon initialization for the route references. By default, it uses the `HFTextVectorizer` to \ngenerate embeddings for each route reference.\n\n\n[code example]\n\n\n[code example]\n\n    \n    \n    Index Information:\n    ╭──────────────────┬──────────────────┬──────────────────┬──────────────────┬──────────────────╮\n    │ Index Name       │ Storage Type     │ Prefixes         │ Index Options    │ Indexing         │\n    ├──────────────────┼──────────────────┼──────────────────┼──────────────────┼──────────────────┤\n    | topic-router     | HASH             | ['topic-router'] | []               | 0                |\n    ╰──────────────────┴──────────────────┴──────────────────┴──────────────────┴──────────────────╯\n    Index Fields:\n    ╭─────────────────┬─────────────────┬─────────────────┬─────────────────┬─────────────────┬─────────────────┬─────────────────┬─────────────────┬─────────────────┬─────────────────┬─────────────────╮\n    │ Name            │ Attribute       │ Type            │ Field Option    │ Option Value    │ Field Option    │ Option Value    │ Field Option    │ Option Value    │ Field Option    │ Option Value    │\n    ├─────────────────┼─────────────────┼─────────────────┼─────────────────┼─────────────────┼─────────────────┼─────────────────┼─────────────────┼─────────────────┼─────────────────┼─────────────────┤\n    │ reference_id    │ reference_id    │ TAG             │ SEPARATOR       │ ,               │                 │                 │                 │                 │                 │                 │\n    │ route_name      │ route_name      │ TAG             │ SEPARATOR       │ ,               │                 │                 │                 │                 │                 │                 │\n    │ reference       │ reference       │ TEXT            │ WEIGHT          │ 1               │                 │                 │                 │                 │                 │                 │\n    │ vector          │ vector          │ VECTOR          │ algorithm       │ FLAT            │ data_type       │ FLOAT32         │ dim             │ 768             │ distance_metric │ COSINE          │\n    ╰─────────────────┴─────────────────┴─────────────────┴─────────────────┴─────────────────┴─────────────────┴─────────────────┴─────────────────┴─────────────────┴─────────────────┴─────────────────╯\n\n\n\n[code example]\n\n\n\n\n    11"
    },
    {
      "id": "simple-routing",
      "title": "Simple routing",
      "role": "content",
      "text": "[code example]\n\n\n\n\n    RouteMatch(name='technology', distance=0.419146001339)\n\n\n\n\n[code example]\n\n\n\n\n    RouteMatch(name=None, distance=None)\n\n\n\nWe can also route a statement to many routes and order them by distance:\n\n\n[code example]\n\n\n\n\n    [RouteMatch(name='technology', distance=0.556494116783),\n     RouteMatch(name='sports', distance=0.671060025692)]\n\n\n\n\n[code example]\n\n\n\n\n    [RouteMatch(name='technology', distance=0.556494116783),\n     RouteMatch(name='sports', distance=0.629264295101)]\n\n\n\nNote the different route match distances. This is because we used the `min` aggregation method instead of the default `avg` approach."
    },
    {
      "id": "update-the-routing-config",
      "title": "Update the routing config",
      "role": "content",
      "text": "[code example]\n\n\n[code example]\n\n\n\n\n    [RouteMatch(name='sports', distance=0.663253962994)]"
    },
    {
      "id": "router-serialization",
      "title": "Router serialization",
      "role": "content",
      "text": "[code example]\n\n\n\n\n    {'name': 'topic-router',\n     'routes': [{'name': 'technology',\n       'references': ['what are the latest advancements in AI?',\n        'tell me about the newest gadgets',\n        \"what's trending in tech?\"],\n       'metadata': {'category': 'tech', 'priority': 1},\n       'distance_threshold': 0.71},\n      {'name': 'sports',\n       'references': ['who won the game last night?',\n        'tell me about the upcoming sports events',\n        \"what's the latest in the world of sports?\",\n        'sports',\n        'basketball and football'],\n       'metadata': {'category': 'sports', 'priority': 2},\n       'distance_threshold': 0.72},\n      {'name': 'entertainment',\n       'references': ['what are the top movies right now?',\n        'who won the best actor award?',\n        \"what's new in the entertainment industry?\"],\n       'metadata': {'category': 'entertainment', 'priority': 3},\n       'distance_threshold': 0.7}],\n     'vectorizer': {'type': 'hf',\n      'model': 'sentence-transformers/all-mpnet-base-v2'},\n     'routing_config': {'max_k': 3, 'aggregation_method': 'min'}}\n\n\n\n\n[code example]\n\n\n[code example]\n\n\n[code example]"
    },
    {
      "id": "add-route-references",
      "title": "Add route references",
      "role": "content",
      "text": "[code example]\n\n\n\n\n    ['topic-router:technology:f243fb2d073774e81c7815247cb3013794e6225df3cbe3769cee8c6cefaca777',\n     'topic-router:technology:7e4bca5853c1c3298b4d001de13c3c7a79a6e0f134f81acc2e7cddbd6845961f']"
    },
    {
      "id": "get-route-references",
      "title": "Get route references",
      "role": "content",
      "text": "[code example]\n\n\n\n\n    [{'id': 'topic-router:technology:f243fb2d073774e81c7815247cb3013794e6225df3cbe3769cee8c6cefaca777',\n      'reference_id': 'f243fb2d073774e81c7815247cb3013794e6225df3cbe3769cee8c6cefaca777',\n      'route_name': 'technology',\n      'reference': 'latest AI trends'},\n     {'id': 'topic-router:technology:851f51cce5a9ccfbbcb66993908be6b7871479af3e3a4b139ad292a1bf7e0676',\n      'reference_id': '851f51cce5a9ccfbbcb66993908be6b7871479af3e3a4b139ad292a1bf7e0676',\n      'route_name': 'technology',\n      'reference': 'what are the latest advancements in AI?'},\n     {'id': 'topic-router:technology:7e4bca5853c1c3298b4d001de13c3c7a79a6e0f134f81acc2e7cddbd6845961f',\n      'reference_id': '7e4bca5853c1c3298b4d001de13c3c7a79a6e0f134f81acc2e7cddbd6845961f',\n      'route_name': 'technology',\n      'reference': 'new tech gadgets'},\n     {'id': 'topic-router:technology:149a9c9919c58534aa0f369e85ad95ba7f00aa0513e0f81e2aff2ea4a717b0e0',\n      'reference_id': '149a9c9919c58534aa0f369e85ad95ba7f00aa0513e0f81e2aff2ea4a717b0e0',\n      'route_name': 'technology',\n      'reference': \"what's trending in tech?\"},\n     {'id': 'topic-router:technology:85cc73a1437df27caa2f075a29c497e5a2e532023fbb75378aedbae80779ab37',\n      'reference_id': '85cc73a1437df27caa2f075a29c497e5a2e532023fbb75378aedbae80779ab37',\n      'route_name': 'technology',\n      'reference': 'tell me about the newest gadgets'}]\n\n\n\n\n[code example]\n\n\n\n\n    [{'id': 'topic-router:technology:f243fb2d073774e81c7815247cb3013794e6225df3cbe3769cee8c6cefaca777',\n      'reference_id': 'f243fb2d073774e81c7815247cb3013794e6225df3cbe3769cee8c6cefaca777',\n      'route_name': 'technology',\n      'reference': 'latest AI trends'}]"
    },
    {
      "id": "delete-route-references",
      "title": "Delete route references",
      "role": "content",
      "text": "[code example]\n\n\n\n\n    5\n\n\n\n\n[code example]\n\n\n\n\n    1"
    },
    {
      "id": "clean-up-the-router",
      "title": "Clean up the router",
      "role": "content",
      "text": "[code example]\n\n\n[code example]"
    },
    {
      "id": "next-steps",
      "title": "Next Steps",
      "role": "content",
      "text": "Now that you understand semantic routing, explore these related guides:\n\n- [Manage LLM Message History](https://redis.io/docs/latest/message_history) - Store and retrieve conversation history\n- [Cache LLM Responses](https://redis.io/docs/latest/llmcache) - Reduce API costs with semantic caching\n- [Query and Filter Data](https://redis.io/docs/latest/complex_filtering) - Learn more about filter expressions"
    }
  ],
  "examples": [
    {
      "id": "define-the-routes-ex0",
      "language": "python",
      "code": "from redisvl.extensions.router import Route\n\n# Define routes for the semantic router\ntechnology = Route(\n    name=\"technology\",\n    references=[\n        \"what are the latest advancements in AI?\",\n        \"tell me about the newest gadgets\",\n        \"what's trending in tech?\"\n    ],\n    metadata={\"category\": \"tech\", \"priority\": 1},\n    distance_threshold=0.71\n)\n\nsports = Route(\n    name=\"sports\",\n    references=[\n        \"who won the game last night?\",\n        \"tell me about the upcoming sports events\",\n        \"what's the latest in the world of sports?\",\n        \"sports\",\n        \"basketball and football\"\n    ],\n    metadata={\"category\": \"sports\", \"priority\": 2},\n    distance_threshold=0.72\n)\n\nentertainment = Route(\n    name=\"entertainment\",\n    references=[\n        \"what are the top movies right now?\",\n        \"who won the best actor award?\",\n        \"what's new in the entertainment industry?\"\n    ],\n    metadata={\"category\": \"entertainment\", \"priority\": 3},\n    distance_threshold=0.7\n)",
      "section_id": "define-the-routes"
    },
    {
      "id": "initialize-the-semanticrouter-ex0",
      "language": "python",
      "code": "import os\nfrom redisvl.extensions.router import SemanticRouter\nfrom redisvl.utils.vectorize import HFTextVectorizer\n\nos.environ[\"TOKENIZERS_PARALLELISM\"] = \"false\"\n\n# Initialize the SemanticRouter\nrouter = SemanticRouter(\n    name=\"topic-router\",\n    vectorizer=HFTextVectorizer(),\n    routes=[technology, sports, entertainment],\n    redis_url=\"redis://localhost:6379\",\n    overwrite=True # Blow away any other routing index with this name\n)",
      "section_id": "initialize-the-semanticrouter"
    },
    {
      "id": "initialize-the-semanticrouter-ex1",
      "language": "python",
      "code": "# look at the index specification created for the semantic router\n!rvl index info -i topic-router",
      "section_id": "initialize-the-semanticrouter"
    },
    {
      "id": "initialize-the-semanticrouter-ex2",
      "language": "python",
      "code": "router._index.info()[\"num_docs\"]",
      "section_id": "initialize-the-semanticrouter"
    },
    {
      "id": "simple-routing-ex0",
      "language": "python",
      "code": "# Query the router with a statement\nroute_match = router(\"Can you tell me about the latest in artificial intelligence?\")\nroute_match",
      "section_id": "simple-routing"
    },
    {
      "id": "simple-routing-ex1",
      "language": "python",
      "code": "# Query the router with a statement and return a miss\nroute_match = router(\"are aliens real?\")\nroute_match",
      "section_id": "simple-routing"
    },
    {
      "id": "simple-routing-ex2",
      "language": "python",
      "code": "# Perform multi-class classification with route_many() -- toggle the max_k and the distance_threshold\nroute_matches = router.route_many(\"How is AI used in basketball?\", max_k=3)\nroute_matches",
      "section_id": "simple-routing"
    },
    {
      "id": "simple-routing-ex3",
      "language": "python",
      "code": "# Toggle the aggregation method -- note the different distances in the result\nfrom redisvl.extensions.router.schema import DistanceAggregationMethod\n\nroute_matches = router.route_many(\"How is AI used in basketball?\", aggregation_method=DistanceAggregationMethod.min, max_k=3)\nroute_matches",
      "section_id": "simple-routing"
    },
    {
      "id": "update-the-routing-config-ex0",
      "language": "python",
      "code": "from redisvl.extensions.router import RoutingConfig\n\nrouter.update_routing_config(\n    RoutingConfig(aggregation_method=DistanceAggregationMethod.min, max_k=3)\n)",
      "section_id": "update-the-routing-config"
    },
    {
      "id": "update-the-routing-config-ex1",
      "language": "python",
      "code": "route_matches = router.route_many(\"Lebron James\")\nroute_matches",
      "section_id": "update-the-routing-config"
    },
    {
      "id": "router-serialization-ex0",
      "language": "python",
      "code": "router.to_dict()",
      "section_id": "router-serialization"
    },
    {
      "id": "router-serialization-ex1",
      "language": "python",
      "code": "router2 = SemanticRouter.from_dict(router.to_dict(), redis_url=\"redis://localhost:6379\")\n\nassert router2.to_dict() == router.to_dict()",
      "section_id": "router-serialization"
    },
    {
      "id": "router-serialization-ex2",
      "language": "python",
      "code": "router.to_yaml(\"router.yaml\", overwrite=True)",
      "section_id": "router-serialization"
    },
    {
      "id": "router-serialization-ex3",
      "language": "python",
      "code": "router3 = SemanticRouter.from_yaml(\"router.yaml\", redis_url=\"redis://localhost:6379\")\n\nassert router3.to_dict() == router2.to_dict() == router.to_dict()",
      "section_id": "router-serialization"
    },
    {
      "id": "add-route-references-ex0",
      "language": "python",
      "code": "router.add_route_references(route_name=\"technology\", references=[\"latest AI trends\", \"new tech gadgets\"])",
      "section_id": "add-route-references"
    },
    {
      "id": "get-route-references-ex0",
      "language": "python",
      "code": "# by route name\nrefs = router.get_route_references(route_name=\"technology\")\nrefs",
      "section_id": "get-route-references"
    },
    {
      "id": "get-route-references-ex1",
      "language": "python",
      "code": "# by reference id\nrefs = router.get_route_references(reference_ids=[refs[0][\"reference_id\"]])\nrefs",
      "section_id": "get-route-references"
    },
    {
      "id": "delete-route-references-ex0",
      "language": "python",
      "code": "# by route name\ndeleted_count = router.delete_route_references(route_name=\"sports\")\ndeleted_count",
      "section_id": "delete-route-references"
    },
    {
      "id": "delete-route-references-ex1",
      "language": "python",
      "code": "# by id\ndeleted_count = router.delete_route_references(reference_ids=[refs[0][\"reference_id\"]])\ndeleted_count",
      "section_id": "delete-route-references"
    },
    {
      "id": "clean-up-the-router-ex0",
      "language": "python",
      "code": "# Use clear to flush all routes from the index\nrouter.clear()",
      "section_id": "clean-up-the-router"
    },
    {
      "id": "clean-up-the-router-ex1",
      "language": "python",
      "code": "# Use delete to clear the index and remove it completely\nrouter.delete()",
      "section_id": "clean-up-the-router"
    }
  ]
}
