- name
- hermesfusion-multi-model-panel
- description
- Run multi-model consensus panels (Lite or Heavy) with your own agent backends—no hosted middleware, your models, your rules.
- triggers
- ["set up a hermesfusion panel with multiple models","run a multi-model consensus check","configure hermesfusion lite or heavy mode","use hermesfusion to get second opinions from different models","set up a model panel for code review or architecture decisions","run hermesfusion with local and cloud models","create a fusion panel with custom agent backends","validate my hermesfusion configuration"]
# HermesFusion Multi-Model Panel
> Skill by [ara.so](https://ara.so) — Hermes Skills collection.
HermesFusion is a model-agnostic, provider-agnostic orchestration framework that runs consensus panels using multiple LLM backends. Inspired by OpenRouter's Fusion API, it lets you bring your own models (local via Ollama, cloud via OpenAI/Anthropic, or custom CLI agents) and run structured panels in two modes:
- **HF Lite**: 2 models in parallel → judge → synthesizer (~4 calls total)
- **HF Heavy**: 3 models in parallel → judge → synthesizer (~5 calls total)
Each panel member is just a configured shell command (`hermes`, `ollama run`, `openai chat`, or your own). No hosted middleware, no per-call markup. Use for code review, architecture decisions, security audits, or any task where you want multi-model consensus before shipping.
## Installation
```bash
pip install hermesfusion
```
Or from source:
```bash
git clone https://github.com/GiannoKlein9/HermesFusion.git
cd hermesfusion
pip install -e .
```
Requires Python 3.9+. You'll also need the CLIs/APIs for whichever models you wire up (e.g., `hermes`, `ollama`, `openai` CLI, etc.).
## Quick Start
### Interactive Setup
```bash
hermesfusion setup
```
The wizard will:
1. Ask for provider IDs (e.g., `fast`, `strong`, `local`)
2. Let you pick a recipe (`hermes`, `ollama`, `openai`, or `custom`)
3. Wire models into Lite and Heavy modes
4. Create `~/.hermesfusion/config.yaml`
Re-run any time to add more providers.
### Non-Interactive Setup (CI/Scripted)
```bash
hermesfusion setup --non-interactive \
--provider fast --recipe hermes --label "Fast" \
--hermes-provider openai --hermes-model gpt-4o-mini \
--provider strong --recipe hermes --label "Strong" \
--hermes-provider anthropic --hermes-model claude-3-5-sonnet \
--lite-participants fast,strong --lite-judge strong --lite-synthesizer strong \
--heavy-participants fast,strong --heavy-judge strong --heavy-synthesizer strong
```
### Manual Config
Create `~/.hermesfusion/config.yaml`:
```yaml
version: 1
providers:
fast:
label: Fast Analyst
provider: openai
model: gpt-4o-mini
role: Quick analyst providing rapid insights.
command:
- hermes
- -z
- "{prompt}"
- --provider
- openai
- --model
- gpt-4o-mini
timeout_seconds: 60
passthrough_env: true
strong:
label: Deep Thinker
provider: anthropic
model: claude-3-5-sonnet
role: Senior engineer with deep domain expertise.
command:
- hermes
- -z
- "{prompt}"
- --provider
- anthropic
- --model
- claude-3-5-sonnet
timeout_seconds: 120
passthrough_env: true
local:
label: Local Model
provider: ollama
model: llama3.1:8b
role: Local privacy-focused analyst.
command:
- ollama
- run
- llama3.1:8b
- "{prompt}"
timeout_seconds: 180
passthrough_env: false
modes:
lite:
display_name: HF Lite
max_participants: 2
max_calls_per_run: 4
participants: [fast, strong]
judge: strong
synthesizer: strong
heavy:
display_name: HF Heavy
max_participants: 3
max_calls_per_run: 5
participants: [fast, strong, local]
judge: strong
synthesizer: strong
```
Validate your config:
```bash
hermesfusion validate
hermesfusion show
```
## Core Commands
### Run a Panel
```bash
# Lite mode (2 models)
hermesfusion run --mode lite --prompt "Should we ship this feature on Friday?"
# Heavy mode (3 models)
hermesfusion run --mode heavy --prompt "Review this architecture for security issues"
# From file
hermesfusion run --mode lite --prompt-file ~/.hermesfusion/inputs/plan.md
# Dry run (see what would execute)
hermesfusion run --mode lite --prompt "..." --dry-run
# JSON output
hermesfusion run --mode heavy --prompt "..." --json
```
### Configuration Management
```bash
# Validate config
hermesfusion validate
# Show current config (obfuscates sensitive data)
hermesfusion show
# Check environment and dependencies
hermesfusion doctor
```
## Configuration Reference
### Provider Definition
```yaml
providers:
my_provider:
label: Human-Friendly Name # shown in output
provider: logical_name # used in 'disabled' map
model: gpt-4o-mini # free-form model ID
role: Quick analyst. # role description for prompt
command: # shell command array
- hermes
- -z
- "{prompt}" # {prompt} is substituted
- --provider
- openai
- --model
- gpt-4o-mini
timeout_seconds: 60 # per-call timeout
env: # extra env vars for this provider
CUSTOM_VAR: value
passthrough_env: true # inherit parent env (API keys)
```
### Mode Definition
```yaml
modes:
lite:
display_name: HF Lite
max_participants: 2 # hard cap
max_calls_per_run: 4 # hard cap (participants + judge + synthesizer)
participants: [fast, strong] # provider IDs
judge: strong # provider ID for judging
synthesizer: strong # provider ID for synthesis
```
### Safety & Execution Options
```yaml
output:
dir: ~/.hermesfusion/runs # where run artifacts are saved
keep_last_n: 50 # auto-prune old runs (future)
input:
allowed_roots_extra: [] # extra paths for --prompt-file sandbox
safety:
max_prompt_bytes: 200000 # refuse prompts bigger than this
max_child_output_chars: 50000 # truncate child output
allow_recursive: false # allow nested HermesFusion calls
execution:
parallel_participants: true # run participants in parallel
participant_timeout_seconds: 180 # fallback timeout
passthrough_env_keys: [] # specific keys to forward when passthrough_env: false
workdir: null # cwd for child processes (default: user home)
templates:
participant: null # override bundled participant template
judge: null # override bundled judge template
synthesizer: null # override bundled synthesizer template
```
### Disabling Providers
```yaml
disabled:
openai: "out of credits" # disable by logical provider name
ollama: "maintenance"
```
## Recipes
Built-in recipes for `hermesfusion setup`:
### Hermes Recipe
```yaml
command:
- hermes
- -z
- "{prompt}"
- --provider
- openai
- --model
- gpt-4o-mini
```
### Ollama Recipe
```yaml
command:
- ollama
- run
- llama3.1:8b
- "{prompt}"
```
### OpenAI CLI Recipe
```yaml
command:
- openai
- chat
- --model
- gpt-4o-mini
- "{prompt}"
```
### Custom Recipe
You provide the full command with `{prompt}` as a placeholder:
```yaml
command:
- python
- /path/to/my_agent.py
- --prompt
- "{prompt}"
- --output
- json
```
## Common Patterns
### Code Review Panel
```bash
# Create input file
mkdir -p ~/.hermesfusion/inputs
cat > ~/.hermesfusion/inputs/pr_review.md << 'EOF'
Review this PR for:
- Security issues
- Performance concerns
- Code style violations
- Missing tests
```diff
+ async def process_payment(amount: float, user_id: str):
+ await db.execute(f"INSERT INTO payments VALUES ({amount}, {user_id})")
```
EOF
# Run heavy panel
hermesfusion run --mode heavy --prompt-file ~/.hermesfusion/inputs/pr_review.md
```
### Architecture Decision Panel
```python
#!/usr/bin/env python3
"""Script to run architecture decisions through HermesFusion."""
import subprocess
import sys
def run_architecture_review(question: str, mode: str = "heavy"):
"""Run an architecture question through HermesFusion panel."""
result = subprocess.run(
["hermesfusion", "run", "--mode", mode, "--prompt", question, "--json"],
capture_output=True,
text=True,
check=False
)
if result.returncode != 0:
print(f"Error: {result.stderr}", file=sys.stderr)
return None
import json
return json.loads(result.stdout)
if __name__ == "__main__":
question = """
We're deciding between:
A) Monolithic PostgreSQL with careful sharding
B) Microservices with dedicated databases per service
Context:
- Team of 8 engineers
- Expected 10k users in year 1, 100k in year 2
- Budget for 2 full-time ops engineers
- Current stack: Python/FastAPI, React
Which approach should we choose and why?
"""
panel = run_architecture_review(question)
if panel:
print("\n=== SYNTHESIS ===")
print(panel["synthesis"]["output"])
```
### Hybrid Local + Cloud Setup
```yaml
providers:
local_fast:
label: Local Llama
provider: ollama
model: llama3.1:8b
role: Fast local model for privacy-sensitive content.
command: [ollama, run, llama3.1:8b, "{prompt}"]
timeout_seconds: 120
passthrough_env: false
cloud_strong:
label: Cloud GPT-4
provider: openai
model: gpt-4o
role: Strong cloud model for complex reasoning.
command: [hermes, -z, "{prompt}", --provider, openai, --model, gpt-4o]
timeout_seconds: 180
passthrough_env: true
env:
OPENAI_API_KEY: $OPENAI_API_KEY
modes:
lite:
participants: [local_fast, cloud_strong]
judge: cloud_strong
synthesizer: cloud_strong
```
### Custom Python Agent Integration
```yaml
providers:
custom_agent:
label: My Custom Agent
provider: custom
model: custom-v1
role: Custom business logic agent.
command:
- python
- /home/user/agents/my_agent.py
- --input
- "{prompt}"
- --format
- text
timeout_seconds: 300
passthrough_env: false
env:
AGENT_CONFIG: /home/user/agents/config.json
```
Corresponding agent:
```python
#!/usr/bin/env python3
"""my_agent.py - Custom agent compatible with HermesFusion."""
import argparse
import sys
import os
def main():
parser = argparse.ArgumentParser()
parser.add_argument("--input", required=True)
parser.add_argument("--format", default="text")
args = parser.parse_args()
# Detect if running inside HermesFusion
if os.getenv("HERMESFUSION_CHILD") == "1":
# Write to stdout only (HermesFusion captures this)
response = process_prompt(args.input)
print(response, end="")
else:
# Standalone mode
response = process_prompt(args.input)
print(response)
def process_prompt(prompt: str) -> str:
"""Your custom logic here."""
# Load config from env
config_path = os.getenv("AGENT_CONFIG")
# ... your agent logic ...
return f"Analysis of prompt: {prompt[:50]}..."
if __name__ == "__main__":
main()
```
## Output Artifacts
Every run saves to `~/.hermesfusion/runs/<timestamp>_<mode>.json`:
```json
{
"timestamp": "20260614T120000Z",
"mode": "lite",
"task": "Should we ship this on Friday?",
"participants": {
"fast": {
"provider_id": "fast",
"label": "Fast Analyst",
"model": "gpt-4o-mini",
"output": "I recommend shipping. The feature is...",
"duration_seconds": 2.3,
"exit_code": 0
},
"strong": {
"provider_id": "strong",
"label": "Deep Thinker",
"model": "claude-3-5-sonnet",
"output": "Caution advised. While the feature works...",
"duration_seconds": 4.1,
"exit_code": 0
}
},
"judge": {
"provider_id": "strong",
"output": "Participant 'strong' raises valid concerns about...",
"duration_seconds": 3.2
},
"synthesis": {
"provider_id": "strong",
"output": "**Recommendation**: Delay until Monday. While 'fast' is optimistic...",
"duration_seconds": 3.8
},
"total_duration_seconds": 13.4
}
```
Inspect with `jq`:
```bash
# Get synthesis
GitHub에서 보기