Two related findings from the retrieval work in PR #167. Recording rather than acting: both are product decisions.
1. Answer length has two levers; only one has been pulled
MAX_DOCUMENTS_PER_COLLECTION now caps the context at 40 documents (~6.3k tokens), down from ~222 (~32k). That helps, but src/retrievers/reactome/prompt.py independently instructs the model to be exhaustive over whatever it receives:
- "answer the user's questions comprehensively, mechanistically, and with precision"
- "Provide an information-rich narrative that explains not only what is happening but also how and why"
- "Comprehensiveness: Capture all mechanistically relevant details available in Reactome"
plus a mandatory de-duplicated Sources list on every answer.
Nothing in the prompt says how long an answer should be, or that the most relevant few matter more than covering everything supplied. So the model will still try to cover all 40 documents.
| lever |
state |
| documents reaching the model |
222 → 40 (done) |
| prompt telling it to be exhaustive |
unchanged |
The prompt is the more direct lever for length, and it does not cost retrieval recall — documents can stay in context for grounding and citation while the narrative covers fewer of them. Wording is a voice decision, so leaving it to whoever owns the prompt.
Observed in practice: "the answers provided by the chat are too long ... having the 11th pathway or reaction on a list is probably not useful at all. You would want to talk about the top ten or top five."
2. The document budget belongs to the caller, not the retriever
MAX_DOCUMENTS_PER_COLLECTION is currently a module constant, which assumes every consumer wants the same amount of context. That will not hold:
- Search-results integration — the search results are the comprehensive part, so the chat answer alongside them should draw on fewer documents.
- Chat — can afford more, being the primary surface.
- Analysis summarisation — different again; the input is a result set rather than a question.
Same retriever, different budget per caller. That is a per-request parameter, not a constant, and it is the same seam as the headless-API extraction: the caller states how much context it wants instead of the retriever deciding for everyone.
Worth building that way during the retriever rewrite rather than accreting a second constant afterwards.
Note
The current value of 10 per collection is a starting point matching what a single retriever returns, not a tuned number. It should be calibrated against answer quality — likely lower. See #171 and the ragas evaluation work.
🤖 Generated with Claude Code
Two related findings from the retrieval work in PR #167. Recording rather than acting: both are product decisions.
1. Answer length has two levers; only one has been pulled
MAX_DOCUMENTS_PER_COLLECTIONnow caps the context at 40 documents (~6.3k tokens), down from ~222 (~32k). That helps, butsrc/retrievers/reactome/prompt.pyindependently instructs the model to be exhaustive over whatever it receives:plus a mandatory de-duplicated Sources list on every answer.
Nothing in the prompt says how long an answer should be, or that the most relevant few matter more than covering everything supplied. So the model will still try to cover all 40 documents.
The prompt is the more direct lever for length, and it does not cost retrieval recall — documents can stay in context for grounding and citation while the narrative covers fewer of them. Wording is a voice decision, so leaving it to whoever owns the prompt.
Observed in practice: "the answers provided by the chat are too long ... having the 11th pathway or reaction on a list is probably not useful at all. You would want to talk about the top ten or top five."
2. The document budget belongs to the caller, not the retriever
MAX_DOCUMENTS_PER_COLLECTIONis currently a module constant, which assumes every consumer wants the same amount of context. That will not hold:Same retriever, different budget per caller. That is a per-request parameter, not a constant, and it is the same seam as the headless-API extraction: the caller states how much context it wants instead of the retriever deciding for everyone.
Worth building that way during the retriever rewrite rather than accreting a second constant afterwards.
Note
The current value of 10 per collection is a starting point matching what a single retriever returns, not a tuned number. It should be calibrated against answer quality — likely lower. See #171 and the ragas evaluation work.
🤖 Generated with Claude Code