How to handle multiple retrievers
This guide assumes familiarity with the following:
Sometimes, a query analysis technique may allow for selection of which retriever to use. To use this, you will need to add some logic to select the retriever to do. We will show a simple example (using mock data) of how to do that.
Setupβ
Install dependenciesβ
- npm
- yarn
- pnpm
npm i @langchain/community @langchain/openai zod chromadb
yarn add @langchain/community @langchain/openai zod chromadb
pnpm add @langchain/community @langchain/openai zod chromadb
Set environment variablesβ
OPENAI_API_KEY=your-api-key
# Optional, use LangSmith for best-in-class observability
LANGSMITH_API_KEY=your-api-key
LANGCHAIN_TRACING_V2=true
Create Indexβ
We will create a vectorstore over fake information.
import { Chroma } from "@langchain/community/vectorstores/chroma";
import { OpenAIEmbeddings } from "@langchain/openai";
import "chromadb";
const texts = ["Harrison worked at Kensho"];
const embeddings = new OpenAIEmbeddings({ model: "text-embedding-3-small" });
const vectorstore = await Chroma.fromTexts(texts, {}, embeddings, {
  collectionName: "harrison",
});
const retrieverHarrison = vectorstore.asRetriever(1);
const texts = ["Ankush worked at Facebook"];
const embeddings = new OpenAIEmbeddings({ model: "text-embedding-3-small" });
const vectorstore = await Chroma.fromTexts(texts, {}, embeddings, {
  collectionName: "ankush",
});
const retrieverAnkush = vectorstore.asRetriever(1);
Query analysisβ
We will use function calling to structure the output. We will let it return multiple queries.
import { z } from "zod";
const searchSchema = z.object({
  query: z.string().describe("Query to look up"),
  person: z
    .string()
    .describe(
      "Person to look things up for. Should be `HARRISON` or `ANKUSH`."
    ),
});
Pick your chat model:
- OpenAI
- Anthropic
- FireworksAI
- MistralAI
- Groq
- VertexAI
Install dependencies
- npm
- yarn
- pnpm
npm i @langchain/openai 
yarn add @langchain/openai 
pnpm add @langchain/openai 
Add environment variables
OPENAI_API_KEY=your-api-key
Instantiate the model
import { ChatOpenAI } from "@langchain/openai";
const llm = new ChatOpenAI({
  model: "gpt-3.5-turbo",
  temperature: 0
});
Install dependencies
- npm
- yarn
- pnpm
npm i @langchain/anthropic 
yarn add @langchain/anthropic 
pnpm add @langchain/anthropic 
Add environment variables
ANTHROPIC_API_KEY=your-api-key
Instantiate the model
import { ChatAnthropic } from "@langchain/anthropic";
const llm = new ChatAnthropic({
  model: "claude-3-5-sonnet-20240620",
  temperature: 0
});
Install dependencies
- npm
- yarn
- pnpm
npm i @langchain/community 
yarn add @langchain/community 
pnpm add @langchain/community 
Add environment variables
FIREWORKS_API_KEY=your-api-key
Instantiate the model
import { ChatFireworks } from "@langchain/community/chat_models/fireworks";
const llm = new ChatFireworks({
  model: "accounts/fireworks/models/firefunction-v1",
  temperature: 0
});
Install dependencies
- npm
- yarn
- pnpm
npm i @langchain/mistralai 
yarn add @langchain/mistralai 
pnpm add @langchain/mistralai 
Add environment variables
MISTRAL_API_KEY=your-api-key
Instantiate the model
import { ChatMistralAI } from "@langchain/mistralai";
const llm = new ChatMistralAI({
  model: "mistral-large-latest",
  temperature: 0
});
Install dependencies
- npm
- yarn
- pnpm
npm i @langchain/groq 
yarn add @langchain/groq 
pnpm add @langchain/groq 
Add environment variables
GROQ_API_KEY=your-api-key
Instantiate the model
import { ChatGroq } from "@langchain/groq";
const llm = new ChatGroq({
  model: "mixtral-8x7b-32768",
  temperature: 0
});
Install dependencies
- npm
- yarn
- pnpm
npm i @langchain/google-vertexai 
yarn add @langchain/google-vertexai 
pnpm add @langchain/google-vertexai 
Add environment variables
GOOGLE_APPLICATION_CREDENTIALS=credentials.json
Instantiate the model
import { ChatVertexAI } from "@langchain/google-vertexai";
const llm = new ChatVertexAI({
  model: "gemini-1.5-pro",
  temperature: 0
});
import { ChatPromptTemplate } from "@langchain/core/prompts";
import {
  RunnableSequence,
  RunnablePassthrough,
} from "@langchain/core/runnables";
const system = `You have the ability to issue search queries to get information to help answer user information.`;
const prompt = ChatPromptTemplate.fromMessages([
  ["system", system],
  ["human", "{question}"],
]);
const llmWithTools = llm.withStructuredOutput(searchSchema, {
  name: "Search",
});
const queryAnalyzer = RunnableSequence.from([
  {
    question: new RunnablePassthrough(),
  },
  prompt,
  llmWithTools,
]);
We can see that this allows for routing between retrievers
await queryAnalyzer.invoke("where did Harrison Work");
{ query: "workplace of Harrison", person: "HARRISON" }
await queryAnalyzer.invoke("where did ankush Work");
{ query: "Workplace of Ankush", person: "ANKUSH" }
Retrieval with query analysisβ
So how would we include this in a chain? We just need some simple logic to select the retriever and pass in the search query
const retrievers = {
  HARRISON: retrieverHarrison,
  ANKUSH: retrieverAnkush,
};
import { RunnableConfig, RunnableLambda } from "@langchain/core/runnables";
const chain = async (question: string, config?: RunnableConfig) => {
  const response = await queryAnalyzer.invoke(question, config);
  const retriever = retrievers[response.person];
  return retriever.invoke(response.query, config);
};
const customChain = new RunnableLambda({ func: chain });
await customChain.invoke("where did Harrison Work");
[ Document { pageContent: "Harrison worked at Kensho", metadata: {} } ]
await customChain.invoke("where did ankush Work");
[ Document { pageContent: "Ankush worked at Facebook", metadata: {} } ]
Next stepsβ
Youβve now learned some techniques for handling multiple retrievers in a query analysis system.
Next, check out some of the other query analysis guides in this section, like how to deal with cases where no query is generated.