Self-Query Retriever
Implement self-query retriever for natural language to structured queries. Learn how to automatically extract query filters and metadata conditions from user questions.
Learning Goals
- Implement self-query retriever for structured queries
- Define query schemas and attribute mappings
Self-Query Retriever
Most RAG queries are purely semantic (e.g., "Tell me about climate change"). However, real-world questions often contain structured metadata constraints (e.g., "What were the sales in 2023 for the Western region?"). Usually, you have to write manual code to parse these filters. Self-Query Retriever automates this by using an LLM to "query itself"—it translates the user's natural language into a structured query that filters metadata and performs a vector search simultaneously.
This technique is essential for building "Smart Search" interfaces that understand dates, categories, and ranges without complex form-filling.
Learning Goals
- Define the Self-Query pattern and its use cases.
- Implement the
SelfQueryRetrieverin LangChain. - Map metadata field descriptions to help the LLM generate accurate filters.
Core Concepts
1. Natural Language to Structured Query
The LLM acts as a translator.
- User: "Show me horror movies from the 90s."
- LLM Output:
- Query: "horror movies"
- Filter:
{"genre": "horror", "year": {"$gte": 1990, "$lt": 2000}}
2. Attribute Information
To work correctly, the Self-Query retriever needs to know what metadata fields exist and what they mean. You provide a list of AttributeInfo objects that define the names and descriptions of your columns.
3. Search + Filter (Integrated)
The retriever performs a single call to the vector database that includes both the semantic query and the Boolean filter, ensuring high efficiency and accuracy.
Self-Query Workflow
Implementing Self-Query Retrieval
- 1Step 1
Describe your metadata fields so the LLM knows how to filter them:
1from langchain.chains.query_constructor.base import AttributeInfo 2 3metadata_field_info = [ 4 AttributeInfo(name="genre", description="The genre of the movie", type="string"), 5 AttributeInfo(name="year", description="The year the movie was released", type="integer"), 6 AttributeInfo(name="rating", description="A 1-10 rating for the movie", type="float"), 7] 8document_content_description = "Brief summary of a movie" - 2Step 2
Use a reasoning model like
gpt-4ofor the best parsing accuracy:1from langchain.retrievers.self_query.base import SelfQueryRetriever 2from langchain_openai import ChatOpenAI 3 4llm = ChatOpenAI(temperature=0) 5retriever = SelfQueryRetriever.from_llm( 6 llm, 7 vector_store, 8 document_content_description, 9 metadata_field_info, 10 verbose=True 11) - 3Step 3
The system will now handle the logic automatically:
1# This generates a filter for rating > 8.5 2results = retriever.invoke("What are some highly rated movies about space?")
Example: E-commerce Product Search
Imagine an e-commerce site. A user types: "Show me blue Nike shoes under $100."
- Semantic Query: "Nike shoes"
- Filter:
{"color": "blue", "brand": "Nike", "price": {"$lt": 100}}The system retrieves the exact products requested without the user ever touching a dropdown menu or price slider.
Common Mistakes
- Vague Descriptions: If your
AttributeInfodescription is just "The year," the LLM might struggle. Be specific: "The 4-digit release year of the document." - Unsupported Vector Stores: Not all vector stores support Self-Query filtering. Check the LangChain documentation for your specific database (Chroma, Pinecone, and Qdrant are well-supported).
Recap
- Self-Querying turns an LLM into a sophisticated query parser.
- It combines structured data filtering with unstructured semantic search.
- It provides a "zero-config" search experience for end users.
Knowledge Check
What is the primary role of the LLM in a Self-Query Retriever?