Tasks/Health & Medicine/Clinical QA & Routing

Design an efficient medical multi-agent workflow for MedAgentsBench

Design a multi-agent medical QA workflow under a call budget

medagents_workflow_design Health & Medicine Clinical QA & Routing
instruction.mdthis is what the agent is given

You inherit a reasoning-only medical-QA workflow that orchestrates a fixed base LLM (GPT-4o, injected as an llm proxy) under a tight per-question call/token budget. The starting point in /app/methods/main/ is a deliberately weak single-agent CoT — no stronger reference is shipped, and going weak→strong is the task. You submit an algorithm (the methods/main/ directory exposing answer_batch(examples, llm, budget)); a sealed verifier copies it into a clean box and re-runs it on a hidden MedAgentsBench hard subset (salted ids, shuffled options), scoring macro accuracy averaged per data source — so overfitting the visible split is useless. Optimize macro_accuracy_pct (higher is better).

Hard Constraints

  1. You may only edit code under /app/methods/main/; you may add sibling .py helper modules and import them from solver.py.
  2. No internet, no model downloads, no external API calls of your own. You may only use the llm proxy passed in by the judge.
  3. At most 4 LLM calls per question, at most 6000 total tokens per question, and at most 45s wall-clock per question.
  4. The llm proxy uses a fixed model version, fixed temperature=0, fixed seed, and fixed decoding parameters. Do not change these.
  5. The output must be exactly one option key per question, e.g. "A", "B", "C". Invalid output, empty output, multiple options, or explanatory text are all scored as wrong.
  6. You must not submit a precomputed answer table, look up answers by id / realidx / question hash, read hidden answers, or try to bypass the proxy's budget counting.
  7. Prompt search, role design, multi-agent debate, self-refine, answer verification, fallback selectors, and dataset-aware routing are all fair game — but it must generalize to the hidden set.

What You Have

  • Visible data (/app/data/): visible_train.jsonl, visible_dev.jsonl, visible_gold.jsonl. Each example has id (a salted id, not the original realidx), dataset (data-source name), question (the stem), options (e.g. {"A": "...", "B": "..."}), and answer_idx — the gold letter, present only in the visible files, stripped from the hidden set before your solver is called.
  • The editable baseline /app/methods/main/this directory is what gets graded. It is a weak single-agent CoT (solver.py + reusable prompt_utils.py). Improve it in place or rewrite it; multi-agent / self-refine / debate / selector / verifier designs are yours to build.
  • Your self-check surface (/app/selfcheck.py): python /app/selfcheck.py (optionally --split visible_dev and --method <dir>) runs on the visible set, calling the same fixed GPT-4o base the grader uses. Reusable, but each run costs real LLM calls — use a small split. Visible scores do not represent the hidden score.

What You Submit

Edit /app/methods/main/solver.py and keep this exact signature:

def answer_batch(examples, llm, budget):
    """
    examples: list[dict] — each has at least id, dataset, question, options
                           (hidden examples do NOT contain answer_idx).
    llm:      callable    — llm(messages, max_tokens=..., stop=...); messages is OpenAI-style
                           [{"role": "...", "content": "..."}]. The proxy forces temperature=0
                           and records tokens and call counts.
    budget:   dict        — max_llm_calls_per_question, max_total_tokens_per_question,
                           max_wall_time_per_question_sec, etc.
    returns:  list[str]   — same length as examples; each element an option key, e.g. "A".
    """

You may add other .py files inside /app/methods/main/ (e.g. router.py, agents.py, verifier.py, prompts.py, parser.py) and import them from solver.py, but the entrypoint function name and signature must stay unchanged. There is no submit step and no per-attempt feedback — work and self-check as long as your run window allows, then leave your best methods/main/ in place; it is graded once at the end on the hidden test set.

How It Is Judged

A sealed verifier copies your methods/main/ into a clean box and runs it on the hidden MedAgentsBench hard subset. It imports solver.answer_batch, passes hidden examples and a controlled llm proxy, and collects the predicted options. The raw metric is:

macro_accuracy_pct = 100 * mean_over_datasets(correct / total)

— per data source first, then averaged across sources, so no single source's sample count dominates. If the budget is exceeded, the signature is wrong, the output length is wrong, the output is an invalid option, or the code tries to read hidden answers / reach the internet directly, the submission is treated as invalid and scored 0. The score is anchored baseline (single-agent CoT) -> 0, reference (AFlow paper SOTA landmark) -> 0.5, upper_bound (perfect accuracy) -> 1; the normalized reward is not shown to you. Beat the baseline and push toward (and ideally past) the SOTA landmark.

Metric

macro accuracy on the hidden MedAgentsBench hard subset · higher is better

Mean of nine per-source accuracies over 540 hidden questions; fixed GPT-4o, 4 calls / 6000 tok / 45 s per question

anchorheld-outreward
Binherited single-agent CoT baseline27.220.00
RAFlow paper SOTA landmark30.10.50
Uperfect macro accuracy100.01.00
normalisation
m <= B0
B < m <= R0.5 * (m - B) / (R - B)
R < m <= U0.5 + 0.5 * (m - R) / (U - R)
m > U1

m = this run's held-out metric  ·  B = inherited single-agent CoT baseline  ·  R = AFlow paper SOTA landmark  ·  U = perfect macro accuracy

B/R/U = 27.22 / 30.1 / 100 (task.toml). Sources averaged first, then mapped. Budget breach, forbidden snippet or >10% infra errors -> 0.

Rollouts

110 minwall clock
$14.88spend
17.3Mtokens
7versions, 5 kept
24 28 32 36 40 44 $0 $2.5 $5 $7.5 $10 cumulative spend on the run tuning-set macro accuracy on 90 visible items, higher better v0 v1 v1_tmp v2 v3 v4 v5
keptrevertedno scoreturning point
  1. v0Inherited single-agent CoT: one call, 422 tokens per question27.781 min · $0.47
  2. v1MedXpert stem sanitisation, text-anchored parsing, verbose direct CoT plan25.5616 min · $2.77
  3. v1_tmpCopy of main created and deleted inside one shell commandnot a real version$2.73
  4. v2Trap-aware single call: name the instinct, hunt the detail it ignores, re-decideTen diverse prompts agreeing are only 33% correct on this split, so voting cannot help; only unseating the instinct can.44.4416 min · $2.69
  5. v3Permutation ensemble: the trap prompt over three relabelled option orders, votedSpend leftover calls on variance reduction, not more reasoning. Wrong axis, but built the vote, tie rules and guards v5 kept.43.3329 min · $5.81
  6. v4Fourth vote unless the first three agree; budget clamped to the proxy's own left43.3340 min · $9.08
  7. v5Repetition ensemble at the as-given order: the identical trap call 3x, majorityAn 8-sample replay cache showed the backend is nondeterministic and the as-given order beats every permutation by 5-12 points.41.2548 min · $10.65

Single draws carry about +-6: nine replays of one method spanned 34.4-51.1 and drift with the clock. v5's 41.25 is a paired mean over 8 rotations.

On the hidden set

held-out metricreward
inherited single-agent CoT baseline27.220.00
AFlow paper SOTA landmark30.10.50
perfect macro accuracy100.01.00
this run37.780.5549
84 minwall clock
$19.35spend
28.6Mtokens
15versions, 13 kept
25 30 35 40 45 50 $0 $4 $8 $12 $16 cumulative spend on the run visible_train macro accuracy on 45 items, higher better v0 v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14
keptrevertedno scoreturning point
  1. v0Inherited one-call 512-token generic chain-of-thought baseline26.671 min · $0.35
  2. v1Cleaned single call: de-duplicated option blocks, explicit labels, safer parsing31.1111 min · $1.37
  3. v2Three calls: independent solver, adversarial examiner, evidence-aware adjudicatorOne call cannot audit itself, so add an independent examiner and let an adjudicator weigh both answers.33.3314 min · $1.73
  4. v3Parser reads Markdown keys and short option text; neutralised a rejected vignetteparser fix, no rerun23 min · $3.06
  5. v4Four roles: solver, answer-aware reviewer, reversed-order specialist, chair18-item slice 38.8927 min · $3.59
  6. v5Dataset router: PubMedQA evidence flow, MedBullets specialist, v3 panel elsewhereThe nine sources fail in different ways, so route each to its own workflow instead of one panel for all.4039 min · $6.36
  7. v6Dropped generic guidance from routed prompts, normalised the PubMedQA triggerrouted items only41 min · $6.84
  8. v7MedQA route: broad solver plus a coverage-ledger reviewer with sanity checks44.4450 min · $8.87
  9. v8PubMedQA safeguard: answer no only when primary sensitivity is reported unchanged46.6752 min · $9.75
  10. v9MedBullets guard against inventing findings from an unavailable ECG figure48.8953 min · $10.14
  11. v10Hybrid: routed MedQA/PubMedQA, panels for MedExQA and R, one-call control elsewhereHeld-out dev showed panels hurting five sources; keep workflow only where it generalised, restore the control elsewhere.visible_gold 35.5666 min · $12.88
  12. v11Reliability pass: marker normalisation, short-text answer lines, dead code removedPubMedQA probe only67 min · $13.50
  13. v12MedBullets: basic answer plus one general syndrome and management-sequence reviewerMedBullets probe only72 min · $14.99
  14. v13Adaptive adjudication: chair only on disagreement for MedExQA, R and unknownMedExQA/R probe only76 min · $16.33
  15. v14PubMedQA fallback when a named primary outcome never recurs in the results bodyvisible_gold 36.6779 min · $17.57

v7-v9 macros are composed from per-source probes, not full reruns; v10-v14 self-checked on the 90-item visible_gold instead.

On the hidden set

held-out metricreward
inherited single-agent CoT baseline27.220.00
AFlow paper SOTA landmark30.10.50
perfect macro accuracy100.01.00
this run30.740.5046
54 minwall clock
-spend
-tokens
9versions, 7 kept
33 36 39 42 45 48 0 20 40 60 80 agent step (this harness reports no tokens or timestamps) visible_train macro accuracy on 45 items, higher better v0 v1 v2 v3 v4 v5 v6 v7 v9
keptrevertedno scoreturning point
  1. v0Inherited one-call 512-token brief chain-of-thought, no stem cleaning33.33
  2. v1Stem cleaning, two letter-shifted agents and a judge9-item smoke 33.3
  3. v2Three unlike agents, majority vote with chair; content-filter retry keeps votesDiversify the reasoning rather than the answer: three unlike prompts, majority vote, chair only when they split.37.78
  4. v3Dropped letter shuffling; primary solver, conservative critic, judge37.78
  5. v4One call under six options; elimination on 10-option, conclusion-first PubMedQA35.56
  6. v5Route by question shape: brief CoT, clinical vignette, PubMedQA bar, fact-then-matchThe nine sources fail differently, so pick the prompt from the question's own shape, letting unknown sources fall through.46.67
  7. v6Baseline-like simple prompt everywhere; 10-option branch split by stem length44.44
  8. v7v5 routing with v6's simple prompt and its length-split 10-option branchTied train scores are noise, so decide on the untouched hold-out, where this beat the inherited baseline 31.1 to 17.8.46.67
  9. v9Deleted unused critic and elimination helpers; behaviour identical to v7identical to v7

One visible item moves macro by 2.2, so the v2/v3 and v5/v7 ties are noise; v1 was scored on a 9-item smoke, not the full 45.

On the hidden set

held-out metricreward
inherited single-agent CoT baseline27.220.00
AFlow paper SOTA landmark30.10.50
perfect macro accuracy100.01.00
this run28.330.1933