Generating Multi-Faceted Queries
Consider a RAG system that needs to search through a large database of code examples and tutorials. A user might ask for โPython examples using the chat endpointโ or โJavaScript tutorials for text summarizationโ.
In a basic RAG setup, these queries would be passed as-is to a search function, potentially missing important context or failing to leverage the structured nature of the data. For example, the code examples database might consist of metadata such as the programming language, the created time, the tech stack used, and so on.
It would be great if we could design a system that could leverage this metadata as a filter to retrieve only the relevant results.
We can achieve this using a tool use approach. Here, we can build a system that generates multi-faceted queries to capture the full intent of a userโs request. This allows for more precise and relevant results by utilizing the semi-structured nature of the data.
Here are some examples of how this approach can be applied:
- E-commerce product searches: Filtering by price range, category, brand, customer ratings, and availability.
- Academic research databases: Narrowing results by publication year, field of study, citation count, and peer-review status.
- Job search platforms: Refining job listings by location, experience level, salary range, and required skills.
In this tutorial, weโll cover:
- Defining the function for data querying
- Creating the tool for generating multi-faceted queries
- Building an agent for performing multi-faceted queries
- Running the agent
Weโll build an agent that helps developers find relevant code examples and tutorials for using Cohere.
Setup
To get started, first we need to install the cohere
library and create a Cohere client.
Defining the function for data querying
Weโll remove the other tools from Part 1 and just use one โ search_code_examples
.
Now, instead of just the query
parameter, weโll add two more parameters: programming_language
and endpoints
:
programming_language
: The programming language of the code example or tutorial.endpoints
: The Cohere endpoints used in the code example or tutorial.
Weโll use these parameters as the metadata to filter the code examples and tutorials.
Letโs rename the function to search_code_examples_detailed
to reflect this change.
And as in Part 1, for simplicity, we create query
as just a mock parameter and no actual search logic will be performed based on it.
IMPORTANT:
The source code for tool definitions can be found here. Make sure to have the tool_def.py
file in the same directory as this notebook for the imports to work correctly.
Creating the tool for generating multi-faceted queries
With the search_code_examples
modified, we now need to modify the tool definition as well. Here, we are adding the two new properties to the tool definition:
programming_language
: This is a string property which we provide a list of options for the model to choose from. We do this by adding โPossible enum valuesโ to the description, which in our case ispy, js
.endpoints
: We want the model to be able to choose from more than one endpoint, and so here we define an array property. When defining an array property, we need to specify the type of the items in the array using theitems
key, which in our case isstring
. We also provide a list of endpoint options for the model to choose from, which ischat, embed, rerank, classify
.
We make only the query
parameter required, while the other two parameters are optional.
Building an agent for performing multi-faceted queries
Next, letโs create a run_agent
function to run the agentic RAG workflow, the same as in Part 1.
The only change we are making here is to make the system message simpler and more specific since the agent now only has one tool.
Running the agent
Letโs start with a broad query about โRAG code examplesโ.
Since itโs broad, this query shouldnโt require any metadata filtering.
And this is shown by the agentโs response, which provides only one parameter, query
, in its tool call.
Letโs try a more specific query about โjavascript tutorials on text summarizationโ.
This time, the agent uses the programming_language
parameter and passed the value js
to it.
Letโs now try a query that involves filtering based on the endpoints. Here, the user asks for โcode examples of using embed and rerank endpointsโ.
And since we have set up the endpoints
parameter to be an array, the agent is able to call the tool with a list of endpoints as its argument.
Finally, letโs try a query that involves filtering based on both the programming language and the endpoints. Here, the user asks for โPython examples of using the chat endpointโ.
And the agent correctly uses both parameters to query the code examples.
Summary
In this tutorial, we learned about:
- How to define the function for data querying
- How to create the tool for generating multi-faceted queries
- How to build an agent for performing multi-faceted queries
- How to run the agent
By implementing multi-faceted queries over semi-structured data, weโve enhanced our RAG system to handle more specific and targeted searches. This approach allows for better utilization of metadata and more precise filtering of results, which is particularly useful when dealing with large collections of code examples and tutorials.
While this tutorial demonstrates how to work with semi-structured data, the agentic RAG approach can be applied to structured data as well. That means we can build agents that can translate natural language queries into queries for tables or relational databases.
In Part 5, weโll learn how to perform RAG over structured data (tables).