Repository navigation
refactor: remove unneeded DocumentJoiner in hybrid_rag_pipeline_with_breakpoints - #309
Merged
bilgeyucel merged 1 commit intoAug 3, 2026
Conversation
…breakpoints Since Haystack 2.24.0, Rankers deduplicate documents by id before ranking, and pipelines support connecting multiple list[T] outputs directly to a single list[T] input -- eliminating the need for a DocumentJoiner placed directly before a Ranker (release notes: "Rankers now deduplicate documents by id before ranking... eliminating the need for a DocumentJoiner after recent pipeline updates"). This notebook's doc_joiner is exactly that case: DocumentJoiner(sort_by_score=False) merging bm25_retriever and embedding_retriever, feeding straight into a SentenceTransformersSimilarityRanker with no other role (sort_by_score=False means it wasn't even doing meaningful reordering itself). Removed it and connected both retrievers directly to ranker.documents; answer_builder now receives its documents from ranker (the reranked/deduped top-k) instead of doc_joiner (the raw pre-rank union), which is both correct per the release notes' intent and consistent with what the notebook already uses for the prompt context. Verified the retrieval+ranking portion (no OpenAI key needed) end-to-end against a local script mirroring this notebook's indexing()/hybrid_retrieval() functions: the rewired pipeline connects without error and the top-ranked document for "Where does Mark live?" is still the Berlin document, matching this notebook's existing expected output.
|
Check out this pull request on See visual diffs & provide feedback on Jupyter Notebooks. Powered by ReviewNB |
bilgeyucel
approved these changes
Aug 3, 2026
Contributor
|
Thank you @mittalpk! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #275
What this does
Removes the
DocumentJoinerfromnotebooks/hybrid_rag_pipeline_with_breakpoints.ipynb, one of the 5 notebooks in the repo usingOutputAdapter/ListJoiner/DocumentJoiner. Since Haystack 2.24.0, Rankers deduplicate documents byidbefore ranking, and pipelines support connecting multiplelist[T]outputs directly to a singlelist[T]input — together eliminating the need for aDocumentJoinerplaced directly before a Ranker (see the 2.24.0 release notes).This notebook's
doc_joiner = DocumentJoiner(sort_by_score=False)is exactly that case: it mergesbm25_retrieverandembedding_retrieveroutput and feeds straight into aSentenceTransformersSimilarityRanker, with no other role (sort_by_score=Falsemeans it wasn't even doing meaningful reordering itself — a pure list-merge). Removed it and connected both retrievers directly toranker.documents.answer_buildernow receives its documents fromranker(the reranked/deduped top-k) instead ofdoc_joiner(the raw pre-rank union) — this is both the behavior the release notes intend and consistent with whatprompt_builderalready used for context.The other 4 notebooks in scope for #275 — surveyed, left unchanged, with reasons
The issue's linked search covers 5 notebooks total. I audited all 5 individually rather than blanket-removing every occurrence, since several use these components for genuine data-transformation logic that Haystack's new automatic type conversions don't cover:
async_pipeline.ipynb—DocumentJoiner(join_mode="reciprocal_rank_fusion")performs real reciprocal-rank-fusion scoring across two retrievers with no Ranker afterward. This is genuine algorithmic work the release notes' simplification doesn't apply to ("removes the need for... some joiners", not all) — removing it would lose the RRF ranking entirely.github_pr_creator_agent.ipynb— itsOutputAdapterconcatenatesissue_messages + [tool_call_result]via a custom Jinja filter into a newList[ChatMessage]. That's genuine list-construction logic, not a type-compatibility adapter Haystack's new auto-conversion (ChatMessage↔str,T↔list[T]) covers.information-extraction-gorilla.ipynb— looked like a trivial single-branch passthrough joiner from the.connect()graph alone, but it's actually a dual-source merge point:fetcher→converter→joiner(URL path) and directly-injectedDocumentobjects viaextract(text=...)both feedjoinerat pipeline-run time (see the"joiner":{"documents":documents}line in theextract()helper). Removing it would break thetext=code path, which the notebook actually exercises (the "Andean cock of the rock" example).using_hyde_for_improved_retrieval.ipynb— itsOutputAdapterusages construct newDocumentobjects from generated text (Document(content=d.text) for d in data), genuine data construction rather than type coercion. There's also a prior partial attempt here (refactor: replace OutputAdapter in using_hyde_for_improved_retrieval notebook #279, closed by a maintainer with "let me know when you want to continue" — an invitation, not a rejection) suggesting this one specifically warrants more careful, dedicated treatment than a mechanical sweep.Happy to take on any of these three as separate, focused PRs if useful — flagging the reasoning here rather than silently skipping them.
How was this tested?
No OpenAI API key available in my environment, so I couldn't execute the notebook's LLM cells end-to-end. Instead, I extracted this notebook's
indexing()/hybrid_retrieval()pipeline-building functions into a standalone script with the rewired topology and ran it directly (no API key needed for retrieval + reranking):PipelineConnectError(confirming the new topology is type-compatible).answer_builder/prompt_builderis still the Berlin document — matching this notebook's existing cached output ("Mark lives in Berlin.").I did not re-run the notebook itself (no API key), so the notebook's committed cell outputs are unchanged/stale relative to the new code — flagging this explicitly rather than leaving it implicit. The code change itself is a straightforward, verified rewire; happy to re-run and refresh outputs if a reviewer can supply a key, or a maintainer can do so on merge.