Normalize sampler results between synthesis and no-synthesis paths - #15
Open
dan-s-w wants to merge 1 commit into
Open
Normalize sampler results between synthesis and no-synthesis paths#15dan-s-w wants to merge 1 commit into
dan-s-w wants to merge 1 commit into
Conversation
format_results is documented as returning either a list of search results or a single already-written answer, but the two downstream paths each require one specific shape and neither was enforced. parallel_pro and parallel_ultra hit this. ParallelTaskSampler.format_results returns a str while both configs leave needs_synthesis at its True default, so trim_results_to_model_limit iterated the answer one character at a time and rejoined it with a separator between every character: 'R\n---\ne\n---\nv\n---\ne\n---\nn\n---\nu\n---\ne ...' The synthesis model received that instead of the answer, at roughly seven times the token count. The mirror case also existed: exa_research_pro and tavily_research_pro return list[str] with needs_synthesis=False, so the grader received a Python list repr rather than the answer text. Fixed in the base class rather than in individual samplers, since the mismatch is a contract problem and any new sampler can reintroduce it. Samplers stay free to return whichever shape suits their provider. Note this changes what reaches the synthesis model and the grader for the four samplers above, so their scores are expected to move. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
eddy-nassif
approved these changes
Sep 1, 2026
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.
Problem
format_resultsis documented as returning either a list of search results or a single already-written answer. But the two downstream paths each require one specific shape, and neither was enforced.parallel_proandparallel_ultrahit this.ParallelTaskSampler.format_resultsreturns astr, while both configs leaveneeds_synthesisat itsTruedefault. Sotrim_results_to_model_limititerated the answer one character at a time and rejoined it with a separator between every character:That is what the synthesis model received instead of the answer — at roughly 7x the token count. It doesn't crash, which is why it went unnoticed; the model can still partially read it. Worth considering whether this depresses
parallel_pro's 34.45% on the FinSearchComp T2 table in the README.The mirror case also exists.
exa_research_proandtavily_research_proreturnlist[str]withneeds_synthesis=False, sogenerated_answerreaches the grader as a Python list repr (['the answer']) rather than the answer text.Approach
Fixed in the base class rather than in
ParallelTaskSampler, because the mismatch is a contract problem — any new sampler can reintroduce it, and two already had. Samplers stay free to return whichever shape is natural for their provider;normalize_formatted_resultscoerces to what the configured path needs.The abstract
format_resultssignature is corrected to-> str | list[str], which is what implementations were already doing.Heads up on scores
This changes what actually reaches the synthesis model and the grader for four samplers:
parallel_pro,parallel_ultra,exa_research_pro,tavily_research_pro. Their numbers are expected to move. I'd treat existing results for those four as not comparable to post-merge runs.Happy to split the no-synthesis half (the Exa/Tavily join) into its own PR if you'd rather land the two behaviour changes separately.
Tests
tests/test_result_normalization.py— pure function, no network. Includes a test asserting the synthesis-side join round-trips the text intact, which is the specific corruption above.🤖 Generated with Claude Code