KeyError with MultiQueryRetriever and Custom Prompt for Fetching data from ChromaDB #28169
-
Checked other resources
Commit to Help
Example Codechroma_prompt = PromptTemplate(
input_variables=["allegations", "description", "num_allegations"],
template=(
"""You are an AI language model assistant. Your task is to analyze the following civilian complaint
description against a police officer, and the allegations that are raised against the officer. Identify
potential acts of misconduct or crimes committed by the officer, and generate {num_allegations} different queries to
retrieve relevant sections from the Police Rulebook (one query per allegation-description combination), stored in a vector database.
By generating multiple perspectives on the analysis, your goal is to help the user overcome some of the limitations of the
distance-based similarity search. Provide these alternative analyses as distinct queries, separated by newlines.
Allegations made against officer: {allegations}
Incident description: {description}
"""
)
)
def fetch_from_chroma(allegations, description, ia_num, llm, k=2):
"""
Fetches relevant documents from Chroma using Maximal Marginal Relevance (MMR).
Parameters:
- allegations (list): a string list of allegations against an officer.
- description (str): a description of the event
- ia_num (int): Internal Affairs number for logging/debugging.
- k (int): Number of results to fetch (from chroma) per LLM generated query, set to 2 by default.
Returns:
- context_text (str): Combined context text from retrieved documents.
- sources (list): List of source metadata.
"""
embedding_function = OpenAIEmbeddings()
db = Chroma(persist_directory=CHROMA_PATH, embedding_function=embedding_function)
chain = chroma_prompt | llm
retriever = MultiQueryRetriever.from_llm(
retriever=db.as_retriever(search_type="similarity", search_kwargs={"k": k}),
llm_chain=chain)
# Invoke the retriever with the input dictionary
results = retriever.invoke({
"allegations": ", ".join(allegations), #convert list to string
"description": description,
"num_allegations": str(len(allegations)) # I want one LLM generated query per allegation
})
if len(results) == 0:
print(f"{ia_num} - Unable to find matching results.")
return "No Context Available", "No Sources Available"
context_text = "\n\n---\n\n".join([doc.page_content for doc in results])
sources = [doc.metadata.get("source", None) for doc in results]
print(f"{ia_num} - Found matching results.")
return context_text, sources DescriptionI am having trouble using MultiQueryRetriever and PromptTemplate. My goal is to take a list of allegations against a police officer, and using the MultiQueryRetriever, have the LLM generate one query per allegation + description combination, in order to fetch the most relevant rule broken for each allegation. I have Chroma as my vector store, it contains a police department officer rule book. To do this, I am using a custom prompt that instructs the LLM to generate one Chroma query for each allegation. In order to generate this query, it must look at the allegation and try to extract potential violations (relevant to the allegation) from the description, then form a query that can be used to fetch relevant rules from Chroma. (Take a look at the actual prompt for more detail) However, I am getting this error and have no idea why:
for some reason, it keeps saying that I only passed in a variable 'question', but when i call retriever.invoke(), I am clearly passing in the required variables. here is an example input that is being passed in:
System Infolangchain==0.2.2 using a mac Using Python 3.11.9 |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 3 replies
-
@AbdelazimLokma, try upgrading LangChain to the newest version by running try: retriever = MultiQueryRetriever.from_llm(
retriever=db.as_retriever(search_type="similarity", search_kwargs={"k": 2}),
llm=llm) |
Beta Was this translation helpful? Give feedback.
@AbdelazimLokma I was checking the documentation and found out that the default
generate_queries
implementation (thats is executed from theretriever.invoke
) puts all the inputs inside{ 'question': question }
.(Yes, the typing is
str
, but the "question" is actually the dictionary you pass in theinvoke
method.)I'm not entirely sure why it does that for now, but one possible solution is to create a custom
MultiQueryRetriever
and override the defaultgenerate_queries
with your own implementation. Basically, just useself.llm_chain.invoke(question)
.Here's an example: