From d6a846229de3b01a5838788a47e4fea5b9e96eec Mon Sep 17 00:00:00 2001 From: otiscuilei Date: Wed, 8 Jul 2026 23:04:17 +0800 Subject: [PATCH] fix: AnswerBuilder returned referenced documents in scrambled order The referenced document indices were kept in a set and iterated directly, so the returned documents came out in the set's hash-table order rather than ascending source-index order (e.g. citations [3] [10] [50] yielded documents ordered 10, 3, 50). This order was deterministic but did not match the source order. Iterate the indices sorted so documents follow ascending source index. --- haystack/components/builders/answer_builder.py | 2 +- .../fix-answer-builder-doc-order-f63c572cd6560bf4.yaml | 10 ++++++++++ test/components/builders/test_answer_builder.py | 10 ++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 releasenotes/notes/fix-answer-builder-doc-order-f63c572cd6560bf4.yaml diff --git a/haystack/components/builders/answer_builder.py b/haystack/components/builders/answer_builder.py index 78d3ed08d23..9e090d264aa 100644 --- a/haystack/components/builders/answer_builder.py +++ b/haystack/components/builders/answer_builder.py @@ -222,7 +222,7 @@ def run( else set(range(len(documents))) ) - for idx in doc_idxs: + for idx in sorted(doc_idxs): try: doc = documents[idx] except IndexError: diff --git a/releasenotes/notes/fix-answer-builder-doc-order-f63c572cd6560bf4.yaml b/releasenotes/notes/fix-answer-builder-doc-order-f63c572cd6560bf4.yaml new file mode 100644 index 00000000000..cb6d48b434e --- /dev/null +++ b/releasenotes/notes/fix-answer-builder-doc-order-f63c572cd6560bf4.yaml @@ -0,0 +1,10 @@ +--- +fixes: + - | + Fixed ``AnswerBuilder`` returning referenced documents in a scrambled order + instead of ascending source-index order. The referenced document indices + were collected in a ``set`` and iterated directly, so documents were emitted + in the set's internal hash-table order (e.g. citations [3] [10] [50] + yielded documents ordered 10, 3, 50). This order was deterministic but did + not match the intuitive source order. The referenced documents are now + returned sorted by their source index. diff --git a/test/components/builders/test_answer_builder.py b/test/components/builders/test_answer_builder.py index e5bc20d3d92..2dfd1ec1c3f 100644 --- a/test/components/builders/test_answer_builder.py +++ b/test/components/builders/test_answer_builder.py @@ -146,6 +146,16 @@ def test_run_with_documents_with_reference_pattern(self): assert answers[0].documents[0].meta["referenced"] is True assert answers[0].documents[0].meta["source_index"] == 2 + def test_run_returns_referenced_documents_in_source_order(self): + component = AnswerBuilder(reference_pattern="\\[(\\d+)\\]", return_only_referenced_documents=True) + output = component.run( + query="test query", + replies=["First [3], then [10], and finally [50]."], + documents=[Document(content=f"doc{i}") for i in range(1, 51)], + ) + source_indices = [doc.meta["source_index"] for doc in output["answers"][0].documents] + assert source_indices == [3, 10, 50] + def test_run_with_documents_with_reference_pattern_return_all_documents(self): component = AnswerBuilder(reference_pattern="\\[(\\d+)\\]", return_only_referenced_documents=False) output = component.run(