In Weaviate's hybrid() query, what does the alpha parameter control?
answer
- one query, two retrievals
- a weight, not a filter
- 0 and 1 are the endpoints
- which half do you trust
- the client default leans vector
basics
~20 salpha weights the two halves of a Weaviate hybrid search: alpha=0 is pure BM25 keyword search, alpha=1 is pure vector search, and values in between blend them. The v4 Python client's default of 0.7 leans toward the vector side.
solid answer
~40 s`hybrid()` runs two searches for the same query string — a BM25 keyword search over the collection's text properties and a vector search using the query's embedding — then merges the two ranked lists into one. `alpha` is the weight given to the vector half when the two are combined: `alpha=0` collapses the query to pure keyword search, `alpha=1` to pure vector search, and `alpha=0.5` weights them evenly. The v4 Python client defaults `alpha` to 0.7, so an un-tuned hybrid query is already vector-leaning. Practically, you lower alpha for queries full of exact tokens — product codes, error strings, names — and raise it for natural-language questions where wording differs from the corpus. alpha is a per-request argument, so it can differ from call to call.
code
python · 17 linesimport weaviate
from weaviate.classes.query import MetadataQuery
client = weaviate.connect_to_local()
articles = client.collections.get("Article")
# Keyword-leaning: the query is mostly literal tokens
res = articles.query.hybrid(
query="ERR_CONN_REFUSED retry backoff",
alpha=0.25,
limit=5,
return_metadata=MetadataQuery(score=True),
)
for obj in res.objects:
print(obj.properties["title"], obj.metadata.score)
client.close()go deeper
Be able to say that hybrid runs both a keyword and a vector search and that alpha decides the mix, with 0 meaning keyword-only and 1 meaning vector-only. Knowing the direction of the scale is what is being checked.
Explain why the two halves fail differently — literal token matching versus paraphrase tolerance — and give a concrete case where you would push alpha down, such as searching product codes or error strings.
Show that you would verify each half in isolation before tuning alpha, since a silently empty keyword half looks exactly like a vector-only result. Talk about picking alpha from measured traffic rather than intuition.
Own the policy question: alpha is per-request, so the decision belongs to a retrieval layer that can route by query class and be re-tuned without redeploying every caller. Be clear that score values are not stable across tuning changes.
## What hybrid() actually runs A Weaviate hybrid query is not one search with a blended index. When you call `collection.query.hybrid(query="...")`, the server executes **two independent retrievals** over the same collection: 1. A **keyword (BM25) search** over the collection's searchable text properties, scoring objects on term overlap with the query string. 2. A **vector search** using an embedding of the query — produced by the collection's vectorizer module, or supplied directly via the `vector` argument — scoring objects by similarity to their stored vectors. Each retrieval returns its own ranked candidate list. Weaviate then **fuses** the two lists into a single ordered result set and returns the top `limit` objects. `alpha` is the knob that decides how much the vector list matters relative to the keyword list during that fusion step. ## The alpha scale - `alpha=0` — the vector half contributes nothing; the result is a pure BM25 keyword search. - `alpha=1` — the keyword half contributes nothing; the result is a pure vector search. - `0 < alpha < 1` — both contribute, with the vector side weighted `alpha` and the keyword side weighted `1 - alpha`. The v4 Python client's default is `alpha=0.7`, which is a deliberate lean toward semantics: most people reach for Weaviate because pure keyword search was not enough. It is still a default, not an answer for your corpus. A point that trips people up: alpha is a **weight applied during fusion**, not a filter and not a threshold. Setting `alpha=0.9` does not mean "only return results the vector search likes"; a document with an overwhelming keyword score can still surface, because the keyword contribution is scaled down, not zeroed. Only the exact endpoints 0 and 1 remove a side entirely. ## Why the two halves fail differently The reason to blend at all is that the two retrievals have complementary blind spots. **Keyword search** is literal. It finds an exact token — `ERR_CONN_REFUSED`, `SKU-4471`, a surname — even if that token appeared once in the corpus and the embedding model has no meaningful representation for it. It fails when the user's wording differs from the document's: "car" will not match a document that only says "automobile". **Vector search** is the mirror image. It handles paraphrase, synonymy and cross-lingual matching, but it is blurry about rare literal strings. Embedding models compress text into a few hundred dimensions; an identifier that carries no semantic content often lands near unrelated identifiers, so an exact match can rank below a topically similar but wrong document. Hybrid search exists so a single endpoint covers both query shapes. alpha is how you tell it which shape you expect. ## Choosing alpha There is no universal value, but there are useful priors: - **Exact-lookup-heavy traffic** (code search, catalogue SKUs, log messages, legal citations): alpha low, often 0.2–0.4. You mainly want keyword precision, with the vector half as a safety net for near-misses. - **Natural-language question traffic** (support search, RAG retrieval, documentation Q&A): alpha high, often 0.6–0.8. Wording varies wildly and semantic recall carries the query. - **Mixed traffic**: either pick a middle value and accept both tails degrade slightly, or classify the query in your application and pass a different alpha per class. Because `alpha` is a per-request parameter, the per-class approach costs nothing at the database level — the same collection serves both. ## What alpha does not do - It does not change which properties the keyword half searches. That is `query_properties`. - It does not change *how* the two score lists are mathematically combined — that is the fusion strategy, and the same alpha can produce different orderings under different fusion modes. - It does not affect filters. A `filters` argument on the hybrid call restricts the candidate set for both halves regardless of alpha. - It has no effect at all if one half returns nothing. If your keyword half matches zero objects (wrong property, tokenization mismatch, no searchable index on the property), the query behaves like a pure vector search no matter what alpha you set — and the scores will not obviously tell you that. Sanity-check by running the query at `alpha=0` and `alpha=1` separately and confirming both return sensible results. ## Reading the score Ask for the fused score explicitly with `return_metadata=MetadataQuery(score=True)`; `object.metadata.score` then holds the combined value. That number is not comparable across different alpha values, different fusion strategies, or different result-set sizes, so never hard-code an absolute score cutoff and expect it to survive a tuning change.
- If you set alpha=1, is that identical to calling near_text() with the same query?Effectively yes for ordering: alpha=1 removes the keyword contribution, so only the vector search decides the result. The practical differences are in the surrounding surface — you are still on the hybrid path, so hybrid-specific arguments such as query_properties and fusion_type stop mattering, and the returned metadata carries a fused score rather than a raw distance. If you genuinely want pure semantic search, a dedicated vector query is clearer to read.
- Your keyword half matches nothing for most queries. What would you check first?Whether the properties you expect to match are actually searchable and included. Confirm the query is hitting the properties you think it is, since by default the keyword half searches the collection's searchable text properties and an explicit query_properties list narrows that. Then check tokenization: a query token that never appears as an indexed token — because of casing, punctuation or a tokenizer split — scores zero. Run the query at alpha=0 in isolation to see the keyword half alone.
- Would you set one alpha for the whole application, or vary it?Vary it, but from one place. Different query classes have genuinely different optima — identifier lookups want a low alpha, natural-language questions a high one — so a single global value degrades one of them. Classify the query in your retrieval layer and pass the matching alpha, keeping the values in configuration rather than at call sites so they can be tuned without touching every caller.
saying these in an interview costs you the question
- Thinking alpha=0 disables hybrid search entirely rather than meaning keyword-only
- Believing higher alpha filters out weak vector matches instead of reweighting
- Assuming alpha changes which properties the keyword half searches
- Treating the fused score as an absolute, comparable relevance value
- Saying hybrid runs a single blended index rather than two retrievals