Proposed by Helia: drop SelfQueryRetriever, keep BM25 plus vector search. This records the evidence, because the measurement did not come out the way that would make it a free change.
The case for dropping it
- Cost.
SelfQueryRetriever makes one LLM call per collection per query variant to translate the question into a structured query. With 4 collections and 5 query variants (4 generated + the original) that is 20 LLM calls per user message, plus 1 for the expansion. A plain semantic retriever has no LLM in the loop.
- Upgrade risk. It depends on
lark and on structured-output behaviour that has moved across LangChain versions. It is the component most likely to break on 1.x, and it is one of five places HybridRetriever reaches into LangChain internals.
The case against assuming it is free
Measured with bin/retrieval_baseline, 20 questions, k=10, Release95.
Overlap between SelfQuery and plain vector search:
| collection |
mean overlap |
identical results |
| complexes |
0.33 |
0/20 |
| ewas |
0.46 |
3/20 |
| reactions |
0.60 |
4/20 |
| summations |
0.54 |
1/20 |
| overall |
0.48 |
|
Run-to-run stability, same code, same questions, two runs:
| retriever |
self-overlap |
byte-identical |
| bm25 |
1.00 |
80/80 |
| vector |
0.99 |
78/80 |
| selfquery |
1.00 |
78/80 |
SelfQuery is stable, not noisy. Its ~half-different results are real and repeatable, so removing it is a genuine retrieval change rather than dropping a source of churn. Note it does not only build a metadata filter — it also rewrites the query string before searching, which is likely part of the divergence.
What the difference looks like
"How does TP53 regulate PTEN transcription?" — top hit:
- selfquery:
PTEN gene transcription is stimulated by TP53
- vector:
TP53 binds the PTEN promoter
Both defensible. Set overlap cannot say which is better; that needs a quality eval (the ragas work), not a diff.
Suggested order
Settle #169 (duplicates consume half the top-k on reactions) and #170 (BM25 and vector are concatenated, not fused) first. Both change what the vector side returns, so measuring SelfQuery against a fixed baseline is more meaningful afterwards.
Reproduce:
./bin/retrieval_baseline capture --out c.json --with-selfquery
./bin/retrieval_baseline overlap c.json
🤖 Generated with Claude Code
Proposed by Helia: drop
SelfQueryRetriever, keep BM25 plus vector search. This records the evidence, because the measurement did not come out the way that would make it a free change.The case for dropping it
SelfQueryRetrievermakes one LLM call per collection per query variant to translate the question into a structured query. With 4 collections and 5 query variants (4 generated + the original) that is 20 LLM calls per user message, plus 1 for the expansion. A plain semantic retriever has no LLM in the loop.larkand on structured-output behaviour that has moved across LangChain versions. It is the component most likely to break on 1.x, and it is one of five placesHybridRetrieverreaches into LangChain internals.The case against assuming it is free
Measured with
bin/retrieval_baseline, 20 questions, k=10, Release95.Overlap between SelfQuery and plain vector search:
Run-to-run stability, same code, same questions, two runs:
SelfQuery is stable, not noisy. Its ~half-different results are real and repeatable, so removing it is a genuine retrieval change rather than dropping a source of churn. Note it does not only build a metadata filter — it also rewrites the query string before searching, which is likely part of the divergence.
What the difference looks like
"How does TP53 regulate PTEN transcription?" — top hit:
PTEN gene transcription is stimulated by TP53TP53 binds the PTEN promoterBoth defensible. Set overlap cannot say which is better; that needs a quality eval (the ragas work), not a diff.
Suggested order
Settle #169 (duplicates consume half the top-k on
reactions) and #170 (BM25 and vector are concatenated, not fused) first. Both change what the vector side returns, so measuring SelfQuery against a fixed baseline is more meaningful afterwards.Reproduce:
🤖 Generated with Claude Code