Skip to content

ComBEE parallel scan aggregation for scalable prompt learning#307

Open
nuglifeleoji wants to merge 17 commits into
gepa-ai:mainfrom
nuglifeleoji:main
Open

ComBEE parallel scan aggregation for scalable prompt learning#307
nuglifeleoji wants to merge 17 commits into
gepa-ai:mainfrom
nuglifeleoji:main

Conversation

@nuglifeleoji

@nuglifeleoji nuglifeleoji commented Apr 3, 2026

Copy link
Copy Markdown

Hi, this is a pr that implements this paper's algorithm on gepa, here are the overall summary and usage, feel free to ask questions and comment!

Summary

Adds aggregation_method parameter to support ComBEE (Combee: Scaling Prompt Learning for Self-Improving Language Model Agents), a Map-Shuffle-Reduce framework that prevents context overload when using large reflection batch sizes.

When aggregation_method="naive" (default), the existing code path is completely unchanged. When set to "combee", the reflection step applies:

  • Augmented shuffling (§3.2) — each reflection is duplicated p=2 times and the full set is shuffled, ensuring every reflection has multiple chances to be incorporated
  • Parallel scan aggregation (§3.1) — reflections are split into k = ⌊√n⌋ groups; Level-1 calls one reflection LM per group to produce k intermediate instructions; Level-2 aggregates those k instructions into a single final context update

This resolves the context overload problem where naive large-batch reflection degrades quality because the aggregator LLM defaults to retaining only generic patterns while discarding specific, high-value insights.

Usage

# gepa.optimize
result = gepa.optimize(
    ...,
    reflection_minibatch_size=40,   # this is n in the paper
    aggregation_method="combee",    # k = ⌊√40⌋ = 6 groups computed automatically
)

# optimize_anything
config = GEPAConfig(
    reflection=ReflectionConfig(
        reflection_minibatch_size=40,
        aggregation_method="combee",
    )
)

aggregation_method="naive" is the default — no behaviour change for existing users.

Implementation

  • src/gepa/strategies/instruction_proposal.py — added default_aggregation_prompt_template to InstructionProposalSignature, the Level-2 reduce prompt that synthesizes k intermediate instructions into one
  • src/gepa/proposer/reflective_mutation/reflective_mutation.py — added _propose_new_texts_combee() implementing the full Map-Shuffle-Reduce logic; propose() routes to it when aggregation_method="combee" and reflection_lm is set (falls back to naive otherwise)
  • src/gepa/api.pyaggregation_method exposed on gepa.optimize()
  • src/gepa/optimize_anything.pyaggregation_method added to ReflectionConfig with docstring

ComBEE is only active when reflection_lm is provided and no custom adapter proposer overrides the default LM-based reflection.

@semanticdiff-com

semanticdiff-com Bot commented Apr 3, 2026

Copy link
Copy Markdown

Review changes with  SemanticDiff

Changed Files
File Status
  src/gepa/proposer/reflective_mutation/reflective_mutation.py  4% smaller
  docs/docs/guides/combee.md Unsupported file format
  docs/mkdocs.yml  0% smaller
  src/gepa/api.py  0% smaller
  src/gepa/optimize_anything.py  0% smaller
  src/gepa/strategies/instruction_proposal.py  0% smaller

Comment thread uv.lock
Made-with: Cursor
@nuglifeleoji

nuglifeleoji commented Apr 6, 2026

Copy link
Copy Markdown
Author

Are there any other problems, I will be happy to fix that! @LakshyAAAgrawal Thanks for your response!

@Shangyint Shangyint left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a nice addition, with the following caveats:

  1. Can you add docs too, so this feature is not buried in the code?
  2. In the feature flag comment (i'd suggest change aggregation_method to use_combee, can you also either points to the docs or the paper? Naively, gepa's minibatch size is 3, so k=sqrt(3) does not make too much sense here. Ideally, people who want to use combee should know this and set minibatch to something larger.

Comment thread src/gepa/optimize_anything.py Outdated
Comment thread src/gepa/proposer/reflective_mutation/reflective_mutation.py Outdated
- rename aggregation_method -> use_combee: bool (clearer than string enum)
- add minibatch size guidance in comments and docs
- rename prompts local var to lm_prompts in _propose_new_texts_combee
- add docs/docs/guides/combee.md with usage and background
- add ComBEE guide to mkdocs.yml nav

Made-with: Cursor
Made-with: Cursor
@Shangyint Shangyint self-requested a review April 7, 2026 06:40
Shangyint
Shangyint previously approved these changes Apr 7, 2026

@Shangyint Shangyint left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@LakshyAAAgrawal

Copy link
Copy Markdown
Contributor

Can you resolve the conflicts?

…terion and callbacks

Keep both upstream changes (acceptance_criterion in api.py, callbacks in
optimize_anything.py) alongside our ComBEE additions (use_combee, rng).

Made-with: Cursor
@nuglifeleoji

nuglifeleoji commented Apr 7, 2026

Copy link
Copy Markdown
Author

I think all conflicts are resolved now! @LakshyAAAgrawal

# Requires reflection_minibatch_size to be set significantly larger than the
# default of 3; k = floor(sqrt(n)) groups are formed, so n >= 4 is needed
# for ComBEE to activate (n=3 gives k=1 and falls back to naive).
use_combee: bool = False,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think all of these should go into both api.py and optimize_anything. You can add another level of config in GEPAConfig in optimize_anything called ComBEEConfig inside reflective mutation config?

Comment thread src/gepa/proposer/reflective_mutation/reflective_mutation.py Outdated
Add nested ComBEEConfig to optimize_anything, expose the remaining ComBEE knobs
in gepa.optimize, and clarify paper references in the reflection proposer/docs.

Made-with: Cursor
Bring in the latest upstream changes, keep the new parallel proposal flow,
and preserve the ComBEE reflective mutation path on top of it.

Made-with: Cursor
@nuglifeleoji

Copy link
Copy Markdown
Author

Just fixed all the conflicts! @LakshyAAAgrawal

@nuglifeleoji

Copy link
Copy Markdown
Author

Thanks for this design @LakshyAAAgrawal, do I wait until Phase 1 and Phase 2 are completed?

Benzhang2004 added a commit that referenced this pull request Jun 6, 2026
…307)

ComBEE (arXiv:2604.04247) re-expressed as a ReflectionLM on top of the
vectorized pipeline, replacing #307's `use_combee` branch + bespoke
`_propose_new_texts_combee` method.

- ComBEEReflectionLM(StatelessReflectionLM): per (job, component) with n
  records, augmented-shuffle (duplicate p times) + split into k=floor(sqrt(n))
  groups, reflect per group (Level-1/Map), aggregate the k intermediates into
  one (Level-2/Reduce). k<=1 degrades to a single stateless reflection — i.e.
  it IS StatelessReflectionLM at small n.
- Both rounds are vectorized across the whole proposal batch via the shared
  _batch_complete primitive: all ~N*k Map calls go out as one
  litellm.batch_completion, all ~N Reduce calls as a second. So a batched
  ComBEE iteration is two batch_completion round-trips regardless of N — vs
  #307's N*k sequential calls.
- Stateless in memory (next_lm = self); the aggregation axis is orthogonal to
  the session/memory axis.
- Add InstructionProposalSignature.default_aggregation_prompt_template (the
  Level-2 reduce prompt, ported from #307).
- Wire through: ReflectiveMutationProposer(use_combee=..., duplication_factor,
  aggregation_prompt) swaps the ReflectionLM impl in __init__; exposed on
  optimize_anything ReflectionConfig (use_combee / combee_duplication_factor /
  combee_aggregation_prompt). No new engine branch.

Tests: two-round Map/Reduce batching, k<=1 naive fallback (== stateless),
balanced split, determinism under seed, and an end-to-end optimize_anything
run with use_combee=True. Full suite: 497 passed, 4 skipped.

Refs #329, #307.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Co-Authored-By: nuglifeleoji <204564520+nuglifeleoji@users.noreply.github.com>
@khram2003

Copy link
Copy Markdown

Hello! Our team at JetBrains Research is currently running experiments with GEPA, and ComBEE-style parallelization would significantly speed them up.

Could you please share when the relevant PRs are expected to be merged and ready for use?

Thanks in advance!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants