Do E5 and BGE embedding models need query and passage prefixes?
Yes for E5: keep
query: on queries and passage: on documents. For BGE v1.5 the query instruction is optional on short queries and helps on question-style queries. The costly mistake is the wrong prefix. We scored three small embedding models on three BEIR datasets with and without their prefixes. Dropping E5's prefixes changed nDCG@10 by between +0.6 and -1.6 points, and the loss was largest on FiQA, where short finance questions are matched against long forum answers. Putting passage: in front of E5 queries cost 5.3 points on SciFact and 22.1 points on FiQA, where nDCG@10 fell from 0.373 to 0.151.Use the prefix on the side the model card documents, use the same prefixes at index time and query time, and never add prefixes to a model that was trained without them.
What did we measure?
nDCG@10 with each model's documented setup, and the change in points for each other setup (95% confidence interval in brackets).
| Model and setup | SciFact | NFCorpus | FiQA |
|---|---|---|---|
e5-small-v2, documented: query: and passage: | 0.671 | 0.324 | 0.373 |
| e5-small-v2, no prefixes | +0.6 (-1.5 to +2.7) | -0.3 (-1.1 to +0.4) | -1.6 (-2.7 to -0.6) |
e5-small-v2, query: on queries, nothing on documents | +1.0 (0.0 to +2.2) | -0.1 (-0.7 to +0.4) | -0.9 (-1.7 to -0.1) |
e5-small-v2, passage: on both sides | -5.3 (-7.6 to -3.1) | -2.9 (-3.9 to -2.0) | -22.1 (-24.4 to -19.9) |
| bge-small-en-v1.5, documented: instruction on queries only | 0.708 | 0.342 | 0.401 |
| bge-small-en-v1.5, no instruction | +1.7 (+0.3 to +3.0) | +0.1 (-0.7 to +0.8) | -1.7 (-2.6 to -0.7) |
| bge-small-en-v1.5, instruction on both sides | +0.3 (-0.6 to +1.2) | +0.6 (0.0 to +1.2) | -1.1 (-1.9 to -0.2) |
| all-MiniLM-L6-v2, documented: no prefixes | 0.648 | 0.319 | 0.369 |
| all-MiniLM-L6-v2, E5-style prefixes added | +0.2 (-1.1 to +1.4) | -1.2 (-2.0 to -0.5) | -1.5 (-2.4 to -0.6) |
The datasets are the BEIR test sets: SciFact (300 scientific claims, 5,183 abstracts), NFCorpus (323 nutrition questions, 3,633 medical documents) and FiQA (648 finance questions, 57,638 forum answers). Every query was searched against the whole corpus by exact cosine similarity. The confidence intervals come from a paired bootstrap over queries, so they compare the same query under two setups. The documented setups land within 0.6 points of each model's published MTEB score on five of the six model and dataset pairs (e5-small-v2 on SciFact is 1.8 points under), which is a check that the evaluation is sound.
The raw results are at /measurements/2026-11-05-embedding-query-prefixes.json and the script is at /measurements/2026-11-05-embedding-query-prefixes.py. It runs on a laptop in about 30 minutes.
Why do the prefixes matter more on some datasets?
The prefixes tell an asymmetric model which side of the search a text is on. E5 was trained on pairs where the query side always started with
query: and the document side with passage: , so it learned to place a question and its answer near each other even though they look different. When the query and the answer already look alike, as with SciFact's claims and the abstracts that support them, the model can match them without the hint, and the prefixes made no measurable difference. FiQA's questions look nothing like the long, informal answers that answer them, and that is where dropping the prefixes cost the most.Writing
passage: in front of a query does more damage than leaving it bare, because it tells the model the question is a document. The query lands among documents that resemble questions, and the documents that answer it fall out of the top ten. On FiQA, recall@10 fell by more than half, from 0.447 to 0.196.BGE v1.5 behaves differently because BAAI trained it to work without the instruction. Its model card says v1.5 improves "retrieval ability without instruction" and that no instruction is needed on passages. Our numbers agree on SciFact and NFCorpus. On FiQA's questions the instruction still added 1.7 points, which fits the card's advice to add it for short queries and to keep whichever setting scores better on your own task.
How do I set the prefixes in code?
from sentence_transformers import SentenceTransformer
e5 = SentenceTransformer("intfloat/e5-small-v2")
doc_vecs = e5.encode(["passage: " + d for d in documents], normalize_embeddings=True)
query_vec = e5.encode("query: " + user_query, normalize_embeddings=True)
bge = SentenceTransformer("BAAI/bge-small-en-v1.5")
doc_vecs = bge.encode(documents, normalize_embeddings=True) # no instruction on documents
query_vec = bge.encode(
"Represent this sentence for searching relevant passages: " + user_query,
normalize_embeddings=True,
)prompts={"query": "query: ", "passage": "passage: "}), and you pass prompt_name="query" at encode time. Newer models document their prefixes the same way: Nomic embed uses search_query: and search_document: , and instruction-tuned models such as multilingual-e5-large-instruct take a task description on the query. Check the model card, and check what your embedding service sends, before you index.What if my documents are already indexed without prefixes?
You do not have to re-embed today. In our test, adding
query: to E5 queries against documents embedded without passage: recovered about half of the FiQA loss (-0.9 against -1.6 points) and was even with the documented setup on the other two datasets. Re-embed with the documented prefixes when you next rebuild the index, and score both on held-out queries from your own data first, since the gap depends on how different your queries look from your documents.How does this fit a Mixpeek pipeline?
Mixpeek's text extractor runs multilingual-e5-large-instruct and adds
passage: to every document it indexes by default, and a retriever adds query: when it embeds the search, so the two sides always match. If you embed on your side, upsert the vectors into a bring-your-own-vectors collection in an MVS namespace and store the model name and prefix setting with each document, so a later re-embed can run beside the old index. For task prompts in instruction-tuned models, see instruction-tuned embeddings.Frequently Asked Questions
Do I need the "query: " prefix for E5 embeddings?
Yes. On FiQA, dropping both of E5's prefixes cost 1.6 points of nDCG@10 (95% CI -2.7 to -0.6). On SciFact and NFCorpus the difference was within noise. The prefix costs nothing to add, and the model card says the model was trained with it.
What happens if I use "passage: " on queries by mistake?
Search quality drops sharply. With e5-small-v2, nDCG@10 fell by 5.3 points on SciFact, 2.9 on NFCorpus and 22.1 on FiQA (0.373 to 0.151), and recall@10 on FiQA fell from 0.447 to 0.196. It is the worst of every setup we tested.
Do I need the BGE query instruction?
For bge-*-v1.5 it is optional. Without it, nDCG@10 rose 1.7 points on SciFact, did not change on NFCorpus and fell 1.7 points on FiQA's question-style queries. BAAI recommends it for short queries; keep whichever setting scores better on held-out queries from your own data. Never add it to documents.
Should I add prefixes to every embedding model?
No. Add only the prefixes the model card documents. all-MiniLM-L6-v2 was trained without prefixes, and adding E5-style ones lowered nDCG@10 by 1.2 points on NFCorpus and 1.5 on FiQA.
Do I have to re-embed my documents if I indexed them without "passage: "?
Not immediately. Adding
query: to queries against unprefixed E5 documents scored 0.9 points under the documented setup on FiQA and matched it on SciFact and NFCorpus. Re-embed with the correct prefix on your next rebuild.