website/docs/user-guide/features/mixture-of-agents.md
Mixture of Agents is a virtual model provider. Each named MoA preset appears as a selectable model under the moa provider.
When you select a MoA preset, the preset's aggregator is the acting model. It is the model that writes the assistant response and emits tool calls. Reference models run first and provide analysis for the aggregator to use.
Use MoA when a hard task benefits from multiple model perspectives but still needs Hermes' normal agent loop: tool calls, follow-up iterations, interrupts, transcript persistence, and the same session context as any other message.
You can select a preset through the normal model picker surfaces:
/model default --provider moa
/model review --provider moa
MoA presets are selectable on every Hermes surface, because MoA is a normal provider in the model system:
/model — /model <preset> --provider moa, or /model --provider moa for the default preset. A bare /model <preset> also works when the name exactly matches a configured preset.hermes model and the Dashboard model picker — a Mixture of Agents provider row appears with your preset names as its models.MoA presets section; selecting one (MoA: <preset>) switches the active model to that preset. The Desktop settings panel also creates and edits presets.Configured presets therefore show up wherever you would pick any other model.
/moa is one-shot convenience sugar. It runs a single prompt through the default MoA preset, then restores whatever model you were on:
/moa design and implement a migration plan for this flaky test cluster
Hermes temporarily switches to the default MoA preset for that one turn, sends the prompt, then restores your previous model afterward. The whole argument is the prompt — /moa no longer interprets it as a preset name.
/moa
Bare /moa (no prompt) just prints usage.
To switch to a MoA preset for the rest of the session, select it from the model picker — MoA presets appear under a Mixture of Agents provider in every model-selection surface (see above). /moa is deliberately not a model switch, so a normal prompt can never accidentally change your model.
For each main model call when provider moa is selected, Hermes:
Because MoA is selected through the normal model system, it composes automatically with /goal, gateway sessions, TUI sessions, and Desktop chat.
You can configure named MoA presets from:
hermes moa configure [name]config.yamlThe config stores explicit provider/model pairs, so you can mix providers and use multiple models from the same provider:
moa:
default_preset: default
presets:
default:
reference_models:
- provider: openai-codex
model: gpt-5.5
- provider: openrouter
model: deepseek/deepseek-v4-pro
aggregator:
provider: openrouter
model: anthropic/claude-opus-4.8
# Optional: pin sampling temperatures. When omitted (the default),
# temperature is NOT sent and each model uses its provider default —
# the same behavior as a single-model Hermes agent.
# reference_temperature: 0.6
# aggregator_temperature: 0.4
max_tokens: 4096
enabled: true
Default preset:
openai-codex:gpt-5.5openrouter:deepseek/deepseek-v4-proopenrouter:anthropic/claude-opus-4.8reference_max_tokensEach turn, MoA runs the reference models (advisors) in parallel and then the
aggregator acts. Advisor generation is the dominant per-turn latency — turn
wall time correlates strongly with how many tokens the advisors emit, because
the turn waits for the slowest advisor to finish writing. By default advisors
are uncapped (reference_max_tokens unset), so they may write long,
essay-length advice.
Set reference_max_tokens on a preset to cap advisor output and give concise
advice instead. The aggregator only needs the gist of each advisor's
judgement, so a cap (e.g. 600) measurably cuts per-turn wall time with little
quality impact. It caps advisors only — the acting aggregator's output (the
user-visible answer) is never capped.
moa:
presets:
fast:
reference_models:
- provider: openrouter
model: anthropic/claude-opus-4.8
- provider: openrouter
model: openai/gpt-5.5
aggregator:
provider: openrouter
model: anthropic/claude-opus-4.8
reference_max_tokens: 600 # concise advice → faster turns
Leave it unset (or 0/blank) to keep the prior uncapped behavior.
fanoutBy default the advisors run once per user turn (fanout: user_turn) —
they synthesize plan-level advice on the first message of the turn, then the
acting aggregator works through the rest of the tool loop alone. This is the
cheapest cadence: advisor cost does not multiply with the number of tool
calls in a turn. Two alternative cadences trade cost for advice freshness:
fanout: per_iteration — advisors re-run on every tool iteration, so
their advice always tracks the latest tool results — at the cost of
multiplying advisor latency and spend by the number of tool calls in a
turn.fanout: every_n:3 — the middle ground: advisors run on the first
iteration of each user turn and then every 3rd tool iteration (any
N >= 2 works). Iterations in between reuse the cached guidance from the
last advisor run, so the aggregator still gets advice on every step — it is
just refreshed every N steps instead of every step. The counter resets on
each new user message, so every turn starts with fresh advice. The mapping
form fanout: {mode: every_n, n: 3} is also accepted and normalized to
the string form.moa:
presets:
fresh:
reference_models:
- provider: openrouter
model: anthropic/claude-opus-4.8
aggregator:
provider: openrouter
model: openai/gpt-5.5
fanout: per_iteration # advisors refresh on every tool iteration
Unknown or malformed values fall back to user_turn.
:::note Default change
Prior to July 2026 the default cadence was per_iteration. The default is
now user_turn — the cheapest, lowest-impact cadence — until per-mode
benchmarks justify a costlier default. Presets that want per-step advising
back set fanout: per_iteration explicitly.
:::
Advisor outputs can echo sensitive data from the conversation — emails,
formatted phone numbers, API keys, JWTs — into the reference blocks shown in
the UI, saved MoA traces, and the aggregator prompt. moa.privacy_filter
(off by default) redacts those surfaces:
moa:
privacy_filter: display # or: full
display — redacts user-visible surfaces only: the labelled reference
blocks rendered in the UI and the records written by save_traces. The
aggregator still receives the raw advisor text, so answer quality is
unaffected.full — additionally redacts the advisor text injected into the
aggregator prompt (and the one-shot /moa synthesis input).Credential shapes (API-key prefixes, JWTs, private keys, DB connection
strings) are masked by Hermes' central secret redactor; the MoA filter adds
email and clearly formatted phone-number redaction on top. Patterns are
deliberately conservative for code-review-style advice: bare digit runs, line
numbers, timestamps, git SHAs, and IP addresses are never touched — only
delimited phone formats like (555) 123-4567 or 555-123-4567 match.
Reference and aggregator slots may also set reasoning_effort. Use this when
you want the same model to contribute at different depths, or when the
aggregator should think harder than the advisory references. Valid values match
Hermes' normal reasoning controls: none, minimal, low, medium, high,
xhigh, max, and ultra.
moa:
presets:
deep_review:
reference_models:
- provider: openai-codex
model: gpt-5.6-sol
reasoning_effort: low
- provider: openai-codex
model: gpt-5.6-sol
reasoning_effort: xhigh
- provider: xai-oauth
model: grok-4.5
aggregator:
provider: openai-codex
model: gpt-5.6-sol
reasoning_effort: high
Omit reasoning_effort to use the provider/Hermes default for that slot.
hermes moa list
hermes moa configure # update the default preset
hermes moa configure review # create or update a named preset
hermes moa delete review
On HermesBench, a two-model MoA preset — claude-opus-4.8 aggregating over a gpt-5.5 reference — outscores either model run on its own:
| Model | HermesBench score |
|---|---|
| Opus aggregator (opus-4.8 + gpt-5.5 reference) — MoA | 0.8202 |
anthropic/claude-opus-4.8 | 0.7607 |
openai/gpt-5.5 | 0.7412 |
The MoA configuration beats its strongest component (opus-4.8) by ~6 points, confirming that aggregating a second perspective lifts quality on hard tasks rather than just averaging the two.
MoA is built so the main conversation's prompt cache is never broken. Selecting a MoA preset is a normal model selection: it does not mutate past context, swap toolsets, or rebuild the system prompt mid-conversation. Your conversation history, system prompt, and tool schema stay byte-stable, so the cached prefix every other model relies on is preserved exactly as it would be for a plain model. Switching to or away from a MoA preset costs the same cache invalidation as any other /model switch — no more.
Both internal call types cache normally:
So MoA does not sacrifice prompt caching on either call type. Its only real cost is the extra reference calls per iteration — you pay for multiple model perspectives, not for broken caches. The long-lived conversation prefix shared with the rest of Hermes is fully intact.
hermes tools; there is no moa toolset to enable.enabled: false on a preset disables the reference fan-out for that preset: the aggregator acts alone, exactly as if you selected it as a plain model. This is the per-preset off switch surfaced in the dashboard and desktop settings.