Files
open-multi-agent/package.json
T
Jack Chen 16562ed894 feat(bench): add a reproducible A/B harness for multi-agent orchestration (#547)
bench/ measures a multi-agent run against a single-agent baseline pursuing the
identical goal, on tokens, wall-clock, cost and judge-scored quality. Three
groups per task: A runs runTasks() with deterministic model routing and a token
budget, while B and C run one agent on the strong and the cheap tier, bracketing
A from both sides so an effect that holds against both is attributable to the
orchestration rather than to the model mix. Two tasks ship with it, both from
packages/core/examples/cookbook/: a four-role contract review DAG and a
single-pass meeting report.

Role prompts are read out of the example source at load time rather than
restated in the harness, so what gets measured cannot drift from what the
examples say. Token counts come off each provider response through a loopback
recording proxy, because TokenUsage carries no cache field and no per-model
split and so cannot price a group A run that deliberately mixes two tiers. The
framework's own counts are recorded alongside, and any disagreement lands in the
row's notes instead of being reconciled silently.

Quality is judge-scored, blind, and run in both presentation orders so position
preference cancels. A is judged once per challenger and each of those scores is
kept separately: A's score against B and its score against C are two
measurements taken under two different contrasts, and only the first belongs in
an A-minus-B comparison.

The report states only what it computed. Whether the token budget bound is read
off budget_exceeded. What dropping cache-contaminated repetitions would do to
the headline is recomputed and printed, including whether any comparison
reverses direction. Which rate schedule the invocation was billed on is checked
against the manifest's UTC window rather than assumed, because the configured
prices are peak rates and a run that happened off-peak was billed half of what
the cost column says. Vendor-specific facts are emitted only for the vendor that
actually ran, and a missing manifest is an error rather than a report whose
models and controlled variables all read unknown.

bench/ is not an npm workspace, so it is reached through explicit root scripts:
npm run lint ends with lint:bench, and npm test ends with bench:ab:test. Both
run in CI, the tests across Node 20, 22 and 24. npm run bench:ab:mock drives the
full pipeline against an offline stand-in upstream, so the wiring is checkable
without a key or a provider call.

Results (bench/REPORT.md, bench/results-*.csv, bench/runs/) are gitignored.
2026-08-22 21:20:27 +08:00

43 lines
1.8 KiB
JSON

{
"name": "open-multi-agent",
"version": "0.0.0",
"private": true,
"description": "Private workspace root for the open-multi-agent monorepo. The published package is @open-multi-agent/core in packages/core.",
"workspaces": [
"packages/*"
],
"scripts": {
"build": "npm run build --workspaces --if-present",
"dev": "npm run dev -w @open-multi-agent/core",
"pretest": "npm run test:example-catalog",
"test": "npm run test --workspaces --if-present && npm run bench:ab:test",
"test:example-catalog": "node --test scripts/example-catalog.test.mjs && node scripts/validate-example-catalog.mjs",
"test:watch": "npm run test:watch -w @open-multi-agent/core",
"test:coverage": "npm run test:coverage -w @open-multi-agent/core",
"test:e2e": "npm run test:e2e -w @open-multi-agent/core",
"bench:observability:ci": "node scripts/observability-benchmark-ci.mjs",
"bench:ab": "tsx bench/src/run-bench.mts",
"bench:ab:mock": "tsx bench/src/run-bench.mts --mock --label mock",
"bench:ab:report": "tsx bench/src/report.mts",
"bench:ab:test": "tsx --test bench/src/bench.test.mts",
"test:eval-examples": "node scripts/eval-example-smoke.mjs",
"test:observability-examples": "node scripts/observability-example-smoke.mjs",
"test:observability-pack": "node scripts/observability-tarball-smoke.mjs",
"test:scaffold": "npm run test:scaffold --workspaces --if-present",
"lint": "npm run lint --workspaces --if-present && npm run lint:bench",
"lint:bench": "tsc --noEmit -p bench/tsconfig.json"
},
"license": "MIT",
"repository": {
"type": "git",
"url": "git+https://github.com/open-multi-agent/open-multi-agent.git"
},
"engines": {
"node": ">=20.0.0"
},
"devDependencies": {
"tsx": "^4.21.0",
"typescript": "^5.6.0"
}
}