Skip to content

Commit 09adf55

Browse files
committed
docs: add semantic router documentation
1 parent e4d6c7d commit 09adf55

File tree

2 files changed

+224
-0
lines changed

2 files changed

+224
-0
lines changed

docs/content/modules/ROOT/nav.adoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
.API
55
* xref:llmcache.adoc[LLM Cache]
66
* xref:message-history.adoc[Message History]
7+
* xref:semantic-router.adoc[Semantic Router]
78
* xref:vectorizers.adoc[Vectorizers]
89
* xref:rerankers.adoc[Rerankers]
910
Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,223 @@
1+
= Semantic Routing
2+
:navtitle: Semantic Router
3+
4+
RedisVL provides a `SemanticRouter` interface to utilize Redis' built-in search & aggregation in order to perform KNN-style classification over a set of `Route` references to determine the best match.
5+
6+
This notebook will go over how to use Redis as a Semantic Router for your applications
7+
8+
== Define the Routes
9+
10+
Below we define 3 different routes. One for `technology`, one for `sports`, and another for `entertainment`. Now for this example, the goal here is surely topic "classification". But you can create routes and references for almost anything.
11+
12+
Each route has a set of references that cover the "semantic surface area" of the route. The incoming query from a user needs to be semantically similar to one or more of the references in order to "match" on the route.
13+
14+
Additionally, 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.
15+
16+
[source,java]
17+
----
18+
import com.redis.vl.extensions.router.Route;
19+
import java.util.*;
20+
21+
// Define routes for the semantic router
22+
Route technology = Route.builder()
23+
.name("technology")
24+
.references(List.of(
25+
"what are the latest advancements in AI?",
26+
"tell me about the newest gadgets",
27+
"what's trending in tech?"
28+
))
29+
.metadata(Map.of("category", "tech", "priority", 1))
30+
.distanceThreshold(0.71)
31+
.build();
32+
33+
Route sports = Route.builder()
34+
.name("sports")
35+
.references(List.of(
36+
"who won the game last night?",
37+
"tell me about the upcoming sports events",
38+
"what's the latest in the world of sports?",
39+
"sports",
40+
"basketball and football"
41+
))
42+
.metadata(Map.of("category", "sports", "priority", 2))
43+
.distanceThreshold(0.72)
44+
.build();
45+
46+
Route entertainment = Route.builder()
47+
.name("entertainment")
48+
.references(List.of(
49+
"what are the top movies right now?",
50+
"who won the best actor award?",
51+
"what's new in the entertainment industry?"
52+
))
53+
.metadata(Map.of("category", "entertainment", "priority", 3))
54+
.distanceThreshold(0.7)
55+
.build();
56+
----
57+
58+
== Initialize the SemanticRouter
59+
60+
`SemanticRouter` will automatically create an index within Redis upon initialization for the route references. By default, it uses the `HFTextVectorizer` to generate embeddings for each route reference.
61+
62+
[source,java]
63+
----
64+
import com.redis.vl.extensions.router.SemanticRouter;
65+
import com.redis.vl.utils.vectorize.HFTextVectorizer;
66+
import redis.clients.jedis.UnifiedJedis;
67+
68+
UnifiedJedis jedis = new UnifiedJedis("redis://localhost:6379");
69+
70+
// Initialize the SemanticRouter
71+
SemanticRouter router = new SemanticRouter(
72+
"topic-router",
73+
new HFTextVectorizer(),
74+
List.of(technology, sports, entertainment),
75+
jedis,
76+
true // overwrite - blow away any other routing index with this name
77+
);
78+
----
79+
80+
== Simple routing
81+
82+
[source,java]
83+
----
84+
// Query the router with a statement
85+
RouteMatch routeMatch = router.route("Can you tell me about the latest in artificial intelligence?");
86+
System.out.println(routeMatch);
87+
// Output: RouteMatch(name='technology', distance=0.419145941734)
88+
89+
// Query the router with a statement and return a miss
90+
RouteMatch miss = router.route("are aliens real?");
91+
System.out.println(miss);
92+
// Output: RouteMatch(name=null, distance=null)
93+
----
94+
95+
We can also route a statement to many routes and order them by distance:
96+
97+
[source,java]
98+
----
99+
// Perform multi-class classification with routeMany() -- toggle the maxK and the distanceThreshold
100+
List<RouteMatch> routeMatches = router.routeMany("How is AI used in basketball?", 3);
101+
System.out.println(routeMatches);
102+
// Output: [RouteMatch(name='technology', distance=0.556493639946), RouteMatch(name='sports', distance=0.671060085297)]
103+
----
104+
105+
[source,java]
106+
----
107+
// Toggle the aggregation method -- note the different distances in the result
108+
import com.redis.vl.extensions.router.schema.DistanceAggregationMethod;
109+
110+
List<RouteMatch> routeMatches = router.routeMany(
111+
"How is AI used in basketball?",
112+
DistanceAggregationMethod.MIN,
113+
3
114+
);
115+
System.out.println(routeMatches);
116+
// Output: [RouteMatch(name='technology', distance=0.556493639946), RouteMatch(name='sports', distance=0.629264354706)]
117+
----
118+
119+
Note the different route match distances. This is because we used the `min` aggregation method instead of the default `avg` approach.
120+
121+
== Update the routing config
122+
123+
[source,java]
124+
----
125+
import com.redis.vl.extensions.router.RoutingConfig;
126+
127+
router.updateRoutingConfig(
128+
new RoutingConfig(DistanceAggregationMethod.MIN, 3)
129+
);
130+
131+
List<RouteMatch> routeMatches = router.routeMany("Lebron James");
132+
System.out.println(routeMatches);
133+
// Output: [RouteMatch(name='sports', distance=0.663253903389)]
134+
----
135+
136+
== Router serialization
137+
138+
[source,java]
139+
----
140+
Map<String, Object> routerDict = router.toDict();
141+
System.out.println(routerDict);
142+
----
143+
144+
Output:
145+
----
146+
{
147+
name=topic-router,
148+
routes=[
149+
{name=technology, references=[...], metadata={category=tech, priority=1}, distance_threshold=0.71},
150+
{name=sports, references=[...], metadata={category=sports, priority=2}, distance_threshold=0.72},
151+
{name=entertainment, references=[...], metadata={category=entertainment, priority=3}, distance_threshold=0.7}
152+
],
153+
vectorizer={type=hf, model=sentence-transformers/all-mpnet-base-v2},
154+
routing_config={max_k=3, aggregation_method=min}
155+
}
156+
----
157+
158+
[source,java]
159+
----
160+
SemanticRouter router2 = SemanticRouter.fromDict(router.toDict(), jedis);
161+
assert router2.toDict().equals(router.toDict());
162+
163+
router.toYaml("router.yaml", true);
164+
165+
SemanticRouter router3 = SemanticRouter.fromYaml("router.yaml", jedis);
166+
assert router3.toDict().equals(router2.toDict()) && router2.toDict().equals(router.toDict());
167+
----
168+
169+
== Add route references
170+
171+
[source,java]
172+
----
173+
List<String> addedIds = router.addRouteReferences(
174+
"technology",
175+
List.of("latest AI trends", "new tech gadgets")
176+
);
177+
System.out.println(addedIds);
178+
----
179+
180+
== Get route references
181+
182+
[source,java]
183+
----
184+
// by route name
185+
List<Map<String, Object>> refs = router.getRouteReferences("technology");
186+
System.out.println(refs);
187+
188+
// by reference id
189+
List<Map<String, Object>> refs = router.getRouteReferences(List.of(refs.get(0).get("reference_id")));
190+
System.out.println(refs);
191+
----
192+
193+
== Delete route references
194+
195+
[source,java]
196+
----
197+
// by route name
198+
int deletedCount = router.deleteRouteReferences("sports");
199+
System.out.println(deletedCount); // Output: 5
200+
201+
// by id
202+
int deletedCount = router.deleteRouteReferences(List.of(refs.get(0).get("reference_id")));
203+
System.out.println(deletedCount); // Output: 1
204+
----
205+
206+
== Clean up the router
207+
208+
[source,java]
209+
----
210+
// Use clear to flush all routes from the index
211+
router.clear();
212+
213+
// Use delete to clear the index and remove it completely
214+
router.delete();
215+
----
216+
217+
== Learn More
218+
219+
* xref:llmcache.adoc[LLM Cache]
220+
* xref:message-history.adoc[Message History]
221+
* xref:vectorizers.adoc[Vectorizers]
222+
* link:../../../javadoc/aggregate/index.html[Full API Documentation^]
223+
* https://github.com/redis/redis-vl-java/tree/main/notebooks/08_semantic_router.ipynb[Interactive Notebook Example^]

0 commit comments

Comments
 (0)