1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
//! Amortized coordination-topology selection for CAR.
//!
//! Implements the design of **"Codebook Agent: Amortized Topology Design for
//! LLM Multi-Agent Systems"** ([arXiv:2609.02264]) as a deterministic,
//! dependency-light core: pick which communication topology a multi-agent run
//! should use, from a short list, in one feed-forward pass, scored on
//! **measured** utility and **measured** tokens.
//!
//! [arXiv:2609.02264]: https://arxiv.org/abs/2609.02264
//!
//! # Why CAR wants this
//!
//! CAR already decides how to coordinate agents. `car_agents::coordinator::
//! Coordinator` spends a full LLM round trip on a hand-written prompt to pick
//! among four patterns, and nothing feeds back: a pattern that solved the task
//! for 3× the tokens is indistinguishable, to the next call, from one that
//! solved it cheaply. `car-multi` executes whichever pattern the caller names.
//!
//! This crate is the missing half — a selector fitted on what coordination runs
//! actually cost and actually achieved. It replaces an LLM call with a fold
//! over records CAR can already produce ([`TokenAccounting`] rides on every
//! `AgentOutput`), and it improves as records accumulate rather than as someone
//! rewrites a prompt.
//!
//! # The three measurements the design rests on
//!
//! The paper's argument is empirical, and all three claims are properties of a
//! *workload*, not theorems. [`diagnostics`] re-measures each on your own
//! records, and you should run it before trusting anything else here:
//!
//! | Claim | What the paper measured | Your check |
//! |---|---|---|
//! | The useful design space is a short list | Reward-surviving topologies collapse to ~6 distinct graphs even as codebook capacity grows 8 → 64 | [`diagnostics::design_space_collapse`] |
//! | The structural cost surrogate is inverted | Edge count correlates with measured tokens at `r ≈ -0.4`, so minimizing `\|E\|` *raises* the bill | [`diagnostics::edge_count_token_correlation`] |
//! | Message-passing scorers are topology-blind on homogeneous teams | With identical agent profiles every aggregator pools identical features, so every candidate scores the same | [`diagnostics::team_homogeneity`] |
//!
//! [`diagnose`] folds the first two into one [`DiagnosticsReport`] —
//! [`DiagnosticsReport::render`] for a terminal, [`DiagnosticsReport::headline`]
//! for a log line — and reports a [`Sufficiency`] alongside them, because a
//! sample below the paper's own collection protocol should not read like a
//! finding. The third claim needs the team's agent profiles, which an
//! [`ExecutionRecord`] does not carry, so it reads as unmeasured unless you call
//! [`diagnose_with_profiles`].
//!
//! The third is the one CAR should care about most, because CAR's teams are
//! usually homogeneous — four instances of the same agent spec, differing only
//! in the task text they are handed. On such a team a profile-node graph
//! network is not a weak ranker; it is a constant.
//!
//! # The pipeline
//!
//! ```text
//! offline, once fitted, no model calls per query
//! ┌────────────────┐ ┌──────────────────────┐ ┌──────────────┐
//! │ execute fixed │ │ Codebook (short │ │ predictor → │
//! │ topologies, │ ───► │ list) │ ───► │ top-M codes │
//! │ log (A,c,u,τ) │ │ CodePredictor (prior)│ │ → decode │
//! └────────────────┘ │ ExecutionProxy │ │ → 1 batched │
//! │ (û, ĉ) │ │ proxy call │
//! └──────────────────────┘ │ → argmax │
//! └──────────────┘
//! ```
//!
//! ```
//! use car_topology::{
//! CoordinationShape, ExecutionRecord, RecordSet, SelectorConfig, Topology,
//! TopologySelector,
//! };
//!
//! # fn main() -> Result<(), car_topology::TopologyError> {
//! // 1. Offline: execute each training task under the six fixed families and
//! // log what each run cost and achieved.
//! let mut records = Vec::new();
//! for task in 0..8 {
//! let query = vec![task as f32 / 8.0, 1.0 - task as f32 / 8.0];
//! for topology in Topology::collection_protocol(4)? {
//! // In production these come from a real run; here, a stand-in.
//! let tokens = 800 + 400 * topology.edge_count() as u64;
//! records.push(ExecutionRecord::new(
//! format!("task{task}"), query.clone(), topology, 1.0, tokens,
//! ));
//! }
//! }
//!
//! // 2. Fit. No LLM calls from here on.
//! let selector = TopologySelector::fit(
//! &RecordSet::new(records)?,
//! &SelectorConfig::default(),
//! )?;
//!
//! // 3. Per query: one pass, no search.
//! let selection = selector.select(&[0.5, 0.5])?;
//! assert!(selection.objective.is_finite());
//! # Ok(())
//! # }
//! ```
//!
//! # What this implementation is not
//!
//! The paper's three learned stages are a VQ autoencoder, an MLP prior, and an
//! MLP proxy with an auxiliary structure-token head. CAR has no autograd
//! framework in the workspace, and this crate is a deterministic leaf that must
//! stay one, so each stage is fitted in closed form instead:
//!
//! | Paper | Here | Consequence |
//! |---|---|---|
//! | VQ-VAE over `vec(A)`, EMA codebook, dead-code reset | Deterministic k-medoids over Hamming distance ([`Codebook`]) | Codes are topologies that were really executed; the fit is reproducible; it cannot emit a graph *between* two observed ones |
//! | MLP `p(k\|c)` under soft cross-entropy (Eq. 7) | Cosine-similarity kernel regression on the same reward-weighted soft targets ([`CodePredictor`]) | Same inputs, targets, and outputs; no generalization to query directions far from every training condition |
//! | MLP `[vec(A); c] → (û, ĉ)` (Eqs. 8–9) | Locally-weighted closed-form ridge on the same targets ([`ExecutionProxy`]) | Query conditioning moves from the features into the record weighting; still linear in the edges, so an edge-*pair* interaction is out of reach, and the fit keeps its training records rather than being a fixed-size model |
//! | Structure-token auxiliary loss (Eq. 10) | Dropped | It regularizes a shared hidden representation; ridge has none. The ridge penalty is the weaker substitute |
//!
//! Eq. (2) (per-task token normalization), Eq. (6) (reward-weighted soft
//! targets), and Eq. (11) (the one-pass selection rule) are reproduced exactly.
//!
//! **The paper's benchmark numbers are the paper's.** Its 84.6 average, 2.4 ms
//! generation, and 21.9–33.2% token reduction were measured on GSM8K / MATH /
//! MultiArith / SVAMP / MBPP / HumanEval with gpt-4o-mini and Qwen-3-8B, under
//! its own implementation. Nothing here has been evaluated against those
//! benchmarks, and the substitutions above mean this implementation should not
//! be assumed to reach them. What transfers without an experiment is the
//! *reasoning*: the three measurements, which [`diagnostics`] lets you make on
//! your own data.
//!
//! # Boundaries
//!
//! No model calls, no network, no clock, and no randomness that is not seeded.
//! Fitting and selection are pure functions of their inputs, so every stage
//! above is testable without a daemon, a model, or a filesystem.
//!
//! [`journal`] is the one module that touches disk — an append-only JSONL log
//! of execution records, kept separate for exactly that reason. It also carries
//! the guard that makes persisted records safe to reuse: every line names the
//! encoder that produced its query embedding, and a set can never be folded
//! across two of them. The pipeline compares queries by cosine similarity, so
//! mixing embedding spaces does not fail or look wrong — it answers from
//! arbitrary similarities.
//!
//! Record collection — the one step that costs real LLM calls — remains the
//! caller's, and [`Topology::collection_protocol`] is the protocol to collect
//! under.
//!
//! [`TokenAccounting`]: https://docs.rs/car-multi
pub use ;
pub use ;
pub use TopologyError;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;