Semantic vs Keyword BM25
POST /query is the unified retrieval endpoint. Two parameters decide what runs:
typepicks the collection:"knowledge"(Knowledge),"memory"(user-scoped Memories), or"all"(both, merged and re-ranked together).query_bypicks the retrieval method:"hybrid"(semantic + BM25, the default) or"text"(BM25 only, withoperator: "or" | "and" | "phrase").
Why Pure Semantic Search Breaks
Pure vector search can miss important production constraints:- Exact identifiers such as
E_AUTH_429orpayments-worker-v4may be generalized away. - A project name can collide with a normal word, like
strawberrythe project vs strawberry the fruit. - Old and new documents can look equally relevant without recency or metadata signals.
- Different users can need different context for the same query.
- Relationship questions need graph context, not only similar text chunks.
query_by: "hybrid" inside the unified /query endpoint rather than as a separate pure-vector mode.
The alpha Parameter
alpha controls the semantic-vs-keyword-bm25 blend when query_by: "hybrid". Higher values lean semantic. Lower values lean keyword bm25.
Start with the API default (
0.8) and tune from observed results. If users query for exact IDs and get loosely related content, lower alpha. If they ask broad conceptual questions and get sparse results, raise it. alpha applies only to query_by: "hybrid"; it is ignored for "text".
Query Request Example
metadata_filters are exact constraints that run before ranking and are re-checked after hydration. Use them whenever the query has a scope that should not be violated. Top-level keys match metadata; nest under additional_metadata to filter free-form per-document fields.
Practical Recipes
General Retrieval
Use the default semantic-leaning blend for natural-language questions over documents.Technical Lookup
Loweralpha when names, IDs, and literal strings matter.
Scoped Retrieval
Use metadata filters to keep retrieval inside a project, team, customer, data class, or source.Exact Phrase Query
Switch toquery_by: "text" with operator: "phrase" when a literal match is the point of the query.
Reading The Response
POST /query returns ranked chunks and source metadata, not an answer. A typical application flow is:
- Call
POST /querywith the righttypeandquery_byfor the query. - Keep the chunks that are relevant enough for your use case.
- Format
chunk_content, source titles, and graph context into a prompt. - Ask your LLM to answer using only that context.
Mental Model
Semantic search finds text that means the same thing. Keyword BM25 search finds text that says the same thing. Graph context finds connected entities. Metadata filters decide what is allowed to be queried.POST /query combines all four behind one endpoint via type, query_by, metadata_filters, and graph_context so your agents get context that is scoped, relevant, and explainable.
Related
- Query - full parameter reference and parallel query patterns
- Context Graphs - how graph context enriches retrieval
- Metadata - designing filterable schemas
- How to Use API Results - turning the response into an LLM prompt