Self-query retriever
A self-query retriever uses an LLM to translate a natural-language question into a structured query against your vector store. It extracts both the semantic search string and the metadata filters, so users can say things like “sci-fi films after 2015 rated above 8” without writing a filter DSL by hand.
1Describe your metadata schema
The retriever needs to know which fields exist on each document and what they mean. Provide an array of attribute descriptors with a name, type, and short human description. Keep the descriptions specific — the LLM uses them to decide whether a clause in the user question maps to a real filter or a free-text search.
2Wire the retriever
Pass the LLM, the vector store, the document-contents description, and the attribute info into SelfQueryRetriever.fromLLM. Meridian routes the structured-query step through azure/model-router so cheap classifications stay cheap.
import { SelfQueryRetriever } from "meridian/retrievers";
import { ChatOpenAI } from "meridian/chat";
const metadata = [
{ name: "genre", type: "string", description: "Film genre" },
{ name: "year", type: "number", description: "Release year" },
{ name: "rating", type: "number", description: "Score 0-10" },
];
const retriever = SelfQueryRetriever.fromLLM({
llm: new ChatOpenAI({ model: "azure/model-router" }),
vectorStore,
documentContents: "Brief film summary",
attributeInfo: metadata,
verbose: true,
});
const docs = await retriever.invoke(
"sci-fi films after 2015 rated above 8"
);
3Invoke and inspect
Call retriever.invoke(query) with the raw user string. With verbose: true Meridian logs the parsed query plan so you can verify the LLM picked the right operators. Iterate on the attribute descriptions until the filters land where you expect.