mcpField
V
Volante

Volante

本地服务
github.com/ribato22AI 与智能体111 周前更新

关于 Volante

Volante 是由用户掌控的模型路由与编排命令行工具,依据硬性能力和可解释证据,从已配置模型中选择。任务可通过单次调用或可选工具循环执行,并可用沙箱检查验证结果。

主要功能

  1. 01按所需能力筛选模型
  2. 02依据可解释证据排列合格模型
  3. 03在已配置的提供方间路由任务
  4. 04通过单次调用或 Agent 工具循环运行任务
  5. 05用沙箱断言验证结果
  6. 06流式显示运行过程并跟踪估算成本

适用场景

  1. 01为任务选择已配置的模型
  2. 02借助工具访问执行多步骤工作
  3. 03用目标生成的断言检查结果
  4. 04查看模型路由与运行成本

MCP 相关

可选的 `volante[mcp]` 安装包含供 IDE 使用的 MCP 服务。README 未说明其公开的工具。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"ribato22-volante": {
"command": "uvx",
"args": [
"volante"
],
"env": {
"ANTHROPIC_API_KEY": "<ANTHROPIC_API_KEY>",
"ANTHROPIC_MODELS": "<ANTHROPIC_MODELS>",
"ANTHROPIC_NAMES": "<ANTHROPIC_NAMES>",
"ANTHROPIC_STRENGTHS": "<ANTHROPIC_STRENGTHS>",
"ANTHROPIC_CONTEXT": "<ANTHROPIC_CONTEXT>",
"ANTHROPIC_MAX_OUTPUT": "<ANTHROPIC_MAX_OUTPUT>",
"ANTHROPIC_TOOLS": "<ANTHROPIC_TOOLS>",
"ANTHROPIC_COST_IN": "<ANTHROPIC_COST_IN>",
"ANTHROPIC_COST_OUT": "<ANTHROPIC_COST_OUT>",
"ANTHROPIC_TIER": "<ANTHROPIC_TIER>",
"MOONSHOT_API_KEY": "<MOONSHOT_API_KEY>",
"MOONSHOT_BASE_URL": "<MOONSHOT_BASE_URL>",
"MOONSHOT_MODELS": "<MOONSHOT_MODELS>",
"MOONSHOT_NAMES": "<MOONSHOT_NAMES>",
"MOONSHOT_STRENGTHS": "<MOONSHOT_STRENGTHS>",
"MOONSHOT_CONTEXT": "<MOONSHOT_CONTEXT>",
"MOONSHOT_MAX_OUTPUT": "<MOONSHOT_MAX_OUTPUT>",
"MOONSHOT_TOOLS": "<MOONSHOT_TOOLS>",
"MOONSHOT_COST_IN": "<MOONSHOT_COST_IN>",
"MOONSHOT_COST_OUT": "<MOONSHOT_COST_OUT>",
"MOONSHOT_TIER": "<MOONSHOT_TIER>",
"OLLAMA_BASE_URL": "<OLLAMA_BASE_URL>",
"OLLAMA_API_KEY": "<OLLAMA_API_KEY>",
"OLLAMA_MODELS": "<OLLAMA_MODELS>",
"OLLAMA_NAMES": "<OLLAMA_NAMES>",
"OLLAMA_STRENGTHS": "<OLLAMA_STRENGTHS>",
"OLLAMA_CONTEXT": "<OLLAMA_CONTEXT>",
"OLLAMA_MAX_OUTPUT": "<OLLAMA_MAX_OUTPUT>",
"OLLAMA_TOOLS": "<OLLAMA_TOOLS>",
"OLLAMA_COST_IN": "<OLLAMA_COST_IN>",
"OLLAMA_COST_OUT": "<OLLAMA_COST_OUT>",
"OLLAMA_TIER": "<OLLAMA_TIER>",
"CLAUDE_CODE_ENABLED": "<CLAUDE_CODE_ENABLED>",
"CLAUDE_CODE_MODELS": "<CLAUDE_CODE_MODELS>",
"CLAUDE_CODE_TIER": "<CLAUDE_CODE_TIER>",
"CLAUDE_CODE_MAX_OUTPUT": "<CLAUDE_CODE_MAX_OUTPUT>",
"CLAUDE_CODE_TIMEOUT": "<CLAUDE_CODE_TIMEOUT>",
"CLAUDE_CODE_SYSTEM_PROMPT_MODE": "<CLAUDE_CODE_SYSTEM_PROMPT_MODE>",
"CODEX_ENABLED": "<CODEX_ENABLED>",
"CODEX_MODELS": "<CODEX_MODELS>",
"CODEX_TIER": "<CODEX_TIER>",
"CODEX_CONTEXT": "<CODEX_CONTEXT>",
"CODEX_MAX_OUTPUT": "<CODEX_MAX_OUTPUT>",
"CODEX_COST_IN": "<CODEX_COST_IN>",
"CODEX_COST_OUT": "<CODEX_COST_OUT>",
"CODEX_TIMEOUT": "<CODEX_TIMEOUT>",
"OPENAI_COMPAT_BASE_URL": "<OPENAI_COMPAT_BASE_URL>",
"OPENAI_COMPAT_KEY": "<OPENAI_COMPAT_KEY>",
"OPENAI_COMPAT_MODEL": "<OPENAI_COMPAT_MODEL>",
"OPENAI_COMPAT_NAME": "<OPENAI_COMPAT_NAME>",
"OPENAI_COMPAT_STRENGTHS": "<OPENAI_COMPAT_STRENGTHS>",
"OPENAI_COMPAT_CONTEXT": "<OPENAI_COMPAT_CONTEXT>",
"OPENAI_COMPAT_MAX_OUTPUT": "<OPENAI_COMPAT_MAX_OUTPUT>",
"OPENAI_COMPAT_TOOLS": "<OPENAI_COMPAT_TOOLS>",
"OPENAI_COMPAT_COST_IN": "<OPENAI_COMPAT_COST_IN>",
"OPENAI_COMPAT_COST_OUT": "<OPENAI_COMPAT_COST_OUT>",
"OPENAI_COMPAT_TIER": "<OPENAI_COMPAT_TIER>",
"OPENAI_COMPAT_2_BASE_URL": "<OPENAI_COMPAT_2_BASE_URL>",
"OPENAI_COMPAT_2_KEY": "<OPENAI_COMPAT_2_KEY>",
"OPENAI_COMPAT_2_MODEL": "<OPENAI_COMPAT_2_MODEL>",
"OPENAI_COMPAT_2_NAME": "<OPENAI_COMPAT_2_NAME>",
"OPENAI_COMPAT_2_STRENGTHS": "<OPENAI_COMPAT_2_STRENGTHS>",
"OPENAI_COMPAT_2_CONTEXT": "<OPENAI_COMPAT_2_CONTEXT>",
"OPENAI_COMPAT_2_MAX_OUTPUT": "<OPENAI_COMPAT_2_MAX_OUTPUT>",
"OPENAI_COMPAT_2_TOOLS": "<OPENAI_COMPAT_2_TOOLS>",
"OPENAI_COMPAT_2_COST_IN": "<OPENAI_COMPAT_2_COST_IN>",
"OPENAI_COMPAT_2_COST_OUT": "<OPENAI_COMPAT_2_COST_OUT>",
"OPENAI_COMPAT_2_TIER": "<OPENAI_COMPAT_2_TIER>",
"OPENAI_COMPAT_3_BASE_URL": "<OPENAI_COMPAT_3_BASE_URL>",
"OPENAI_COMPAT_3_KEY": "<OPENAI_COMPAT_3_KEY>",
"OPENAI_COMPAT_3_MODEL": "<OPENAI_COMPAT_3_MODEL>",
"OPENAI_COMPAT_3_NAME": "<OPENAI_COMPAT_3_NAME>",
"OPENAI_COMPAT_3_STRENGTHS": "<OPENAI_COMPAT_3_STRENGTHS>",
"OPENAI_COMPAT_3_CONTEXT": "<OPENAI_COMPAT_3_CONTEXT>",
"OPENAI_COMPAT_3_MAX_OUTPUT": "<OPENAI_COMPAT_3_MAX_OUTPUT>",
"OPENAI_COMPAT_3_TOOLS": "<OPENAI_COMPAT_3_TOOLS>",
"OPENAI_COMPAT_3_COST_IN": "<OPENAI_COMPAT_3_COST_IN>",
"OPENAI_COMPAT_3_COST_OUT": "<OPENAI_COMPAT_3_COST_OUT>",
"OPENAI_COMPAT_3_TIER": "<OPENAI_COMPAT_3_TIER>",
"VOLANTE_QUALITY_PROFILES_FILE": "<VOLANTE_QUALITY_PROFILES_FILE>",
"VOLANTE_MODEL_OVERRIDES_FILE": "<VOLANTE_MODEL_OVERRIDES_FILE>",
"VOLANTE_FETCH_ALLOWLIST": "<VOLANTE_FETCH_ALLOWLIST>",
"VOLANTE_READ_ROOT": "<VOLANTE_READ_ROOT>",
"VOLANTE_SANDBOX": "<VOLANTE_SANDBOX>",
"VOLANTE_MAX_SUBSCRIPTION_CALLS": "<VOLANTE_MAX_SUBSCRIPTION_CALLS>"
}
}
}
}
启动命令uvx volante
需要配置的环境变量
ANTHROPIC_API_KEY密钥Anthropic API key.
ANTHROPIC_MODELSComma-separated Anthropic wire model ids.
ANTHROPIC_NAMESOptional comma-separated canonical model ids.
ANTHROPIC_STRENGTHSShared comma-separated routing strengths.
ANTHROPIC_CONTEXTShared context-window tokens.
ANTHROPIC_MAX_OUTPUTShared maximum output tokens.
ANTHROPIC_TOOLSDeclare tool-call support (1 or 0).
ANTHROPIC_COST_INShared USD per 1k input tokens.
ANTHROPIC_COST_OUTShared USD per 1k output tokens.
ANTHROPIC_TIERShared capability tier from 1 to 4.
MOONSHOT_API_KEY密钥Moonshot API key.
MOONSHOT_BASE_URLMoonshot OpenAI-compatible base URL.
MOONSHOT_MODELSComma-separated Moonshot wire model ids.
MOONSHOT_NAMESOptional comma-separated canonical model ids.
MOONSHOT_STRENGTHSShared comma-separated routing strengths.
MOONSHOT_CONTEXTShared context-window tokens.
MOONSHOT_MAX_OUTPUTShared maximum output tokens.
MOONSHOT_TOOLSDeclare tool-call support (1 or 0).
MOONSHOT_COST_INShared USD per 1k input tokens.
MOONSHOT_COST_OUTShared USD per 1k output tokens.
MOONSHOT_TIERShared capability tier from 1 to 4.
OLLAMA_BASE_URLLocal Ollama OpenAI-compatible base URL.
OLLAMA_API_KEY密钥Optional credential for the Ollama endpoint.
OLLAMA_MODELSComma-separated Ollama wire model ids.
OLLAMA_NAMESOptional comma-separated canonical model ids.
OLLAMA_STRENGTHSShared comma-separated routing strengths.
OLLAMA_CONTEXTShared context-window tokens.
OLLAMA_MAX_OUTPUTShared maximum output tokens.
OLLAMA_TOOLSDeclare tool-call support (1 or 0).
OLLAMA_COST_INShared USD per 1k input tokens.
OLLAMA_COST_OUTShared USD per 1k output tokens.
OLLAMA_TIERShared capability tier from 1 to 4.
CLAUDE_CODE_ENABLEDSet to 1 to enable the logged-in Claude Code CLI.
CLAUDE_CODE_MODELSComma-separated Claude Code model ids.
CLAUDE_CODE_TIERShared capability tier from 1 to 4.
CLAUDE_CODE_MAX_OUTPUTShared maximum output tokens.
CLAUDE_CODE_TIMEOUTPer-call timeout in seconds.
CLAUDE_CODE_SYSTEM_PROMPT_MODESystem-prompt mode: replace or append.
CODEX_ENABLEDSet to 1 to enable the logged-in Codex CLI.
CODEX_MODELSComma-separated Codex model ids.
CODEX_TIERRequired capability tier from 1 to 4 when enabled.
CODEX_CONTEXTShared context-window tokens.
CODEX_MAX_OUTPUTShared maximum output tokens.
CODEX_COST_INShared API-equivalent input valuation.
CODEX_COST_OUTShared API-equivalent output valuation.
CODEX_TIMEOUTPer-call timeout in seconds.
OPENAI_COMPAT_BASE_URLCompatible slot 1 base URL.
OPENAI_COMPAT_KEY密钥Compatible slot 1 API key.
OPENAI_COMPAT_MODELCompatible slot 1 wire model id.
OPENAI_COMPAT_NAMECompatible slot 1 canonical model id.
OPENAI_COMPAT_STRENGTHSCompatible slot 1 comma-separated strengths.
OPENAI_COMPAT_CONTEXTCompatible slot 1 context-window tokens.
OPENAI_COMPAT_MAX_OUTPUTCompatible slot 1 maximum output tokens.
OPENAI_COMPAT_TOOLSCompatible slot 1 tool-call support (1 or 0).
OPENAI_COMPAT_COST_INCompatible slot 1 input cost.
OPENAI_COMPAT_COST_OUTCompatible slot 1 output cost.
OPENAI_COMPAT_TIERCompatible slot 1 capability tier.
OPENAI_COMPAT_2_BASE_URLCompatible slot 2 base URL.
OPENAI_COMPAT_2_KEY密钥Compatible slot 2 API key.
OPENAI_COMPAT_2_MODELCompatible slot 2 wire model id.
OPENAI_COMPAT_2_NAMECompatible slot 2 canonical model id.
OPENAI_COMPAT_2_STRENGTHSCompatible slot 2 comma-separated strengths.
OPENAI_COMPAT_2_CONTEXTCompatible slot 2 context-window tokens.
OPENAI_COMPAT_2_MAX_OUTPUTCompatible slot 2 maximum output tokens.
OPENAI_COMPAT_2_TOOLSCompatible slot 2 tool-call support (1 or 0).
OPENAI_COMPAT_2_COST_INCompatible slot 2 input cost.
OPENAI_COMPAT_2_COST_OUTCompatible slot 2 output cost.
OPENAI_COMPAT_2_TIERCompatible slot 2 capability tier.
OPENAI_COMPAT_3_BASE_URLCompatible slot 3 base URL.
OPENAI_COMPAT_3_KEY密钥Compatible slot 3 API key.
OPENAI_COMPAT_3_MODELCompatible slot 3 wire model id.
OPENAI_COMPAT_3_NAMECompatible slot 3 canonical model id.
OPENAI_COMPAT_3_STRENGTHSCompatible slot 3 comma-separated strengths.
OPENAI_COMPAT_3_CONTEXTCompatible slot 3 context-window tokens.
OPENAI_COMPAT_3_MAX_OUTPUTCompatible slot 3 maximum output tokens.
OPENAI_COMPAT_3_TOOLSCompatible slot 3 tool-call support (1 or 0).
OPENAI_COMPAT_3_COST_INCompatible slot 3 input cost.
OPENAI_COMPAT_3_COST_OUTCompatible slot 3 output cost.
OPENAI_COMPAT_3_TIERCompatible slot 3 capability tier.
VOLANTE_QUALITY_PROFILES_FILELocal strict-JSON quality-evidence file.
VOLANTE_MODEL_OVERRIDES_FILELocal strict-JSON per-model metadata override file.
VOLANTE_FETCH_ALLOWLISTComma-separated domains that enable fetch_url.
VOLANTE_READ_ROOTRoot directory that enables confined read_file.
VOLANTE_SANDBOXAgentic execution sandbox. Unset auto-selects docker when available and otherwise disables code execution; subprocess opts in to unisolated execution.
VOLANTE_MAX_SUBSCRIPTION_CALLSPhysical subscription calls allowed per run.

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
pypivolante0.10.0

工具

1

收录的工具列表 · 更新于 3 周前

参数类型必填说明
goalstring是
preferany否
verifyboolean否

详细介绍

Volante

CI License: MIT Python 3.11+ PyPI MCP Registry Ruff

透明、由用户掌控的模型路由器,能够检查自己的答案(alpha)。 Volante 会将目标路由到你配置的模型,并优先满足硬性能力要求,再根据可解释的元数据和评估证据为其余模型排序;随后还可以通过实际运行来验证结果:根据你的目标推导断言,在沙箱中执行,并逐项报告检查结果。模型清单、策略、凭据和决策追踪都保留在你的机器上。默认情况下,它通过一次调用给出答案——在 72 组配对运行中,规划和综合的得分为 -0.047,而 [95% CI -0.135, +0.041] 的成本是其 8.8 倍,因此该区间表明其最佳情况接近 +0.04。使用 --orchestrate 可重新启用任务 DAG,处理确实需要工具循环、而一次调用无法完成的工作。

测量结果如实呈现,包括那些不利的部分。 本项目对自身进行了三组对照评估,并公布了失利结果。编排并不能可靠地胜过单个强大模型:本 README 的早期版本曾声称达到 +0.289、p<0.005,但该结果未能复现;在专门为分解留出发挥空间的目标上,同一系列中更强的模型单独得分为 0.958。四种预测门控、一次修复流程和一项模型升级策略都曾构建并测量,最终均被舍弃。经受住所有测试的成果范围更窄,但真实有效——路由器、可靠性改进(无法解析的输出从 8 次运行中的 2 次降至 8 次中的 0 次),以及验证器。完整数据、方法和更正见:eval/artifacts/README.md。

选择质量是一种基于证据的预测,并非宣称存在普遍适用的赢家。Volante 尚未发布具有代表性的跨提供商基准测试,也未实现自动分数校准。本项目未使用编排框架构建(不依赖 LangChain / CrewAI / LiteLLM)。

volante 在足球比赛中掌控全局:这位后置中场球员纵观全场,把球送到最有利的位置——然后再把球夺回来。一个头脑,众多球员。


亮点

  • Supervisor + 可解释的路由。 大模型会规划经过验证的无环任务 DAG;路由器会评估所有已配置的模型,排除不满足硬性能力要求的模型,对符合条件的模型进行评分,并记录完整的决策轨迹。可选的、基于评估得出的质量配置文件可用实证取代粗略元数据。quality、local、cheap 和 cash_protect_quota 是不同的路由目标。
  • 由用户掌控、跨服务提供商的控制平面。 AnthropicProvider 和通用的 OpenAICompatProvider 可连接 Anthropic、Google AI Studio(Gemini)、Groq、OpenRouter、DeepSeek、Moonshot(Kimi)、本地 Ollama,以及任何其他兼容 OpenAI 的端点。模型清单和凭据都保留在用户的环境中。
  • 有范围限制的服务提供商故障转移。 模型/部署、服务提供商身份验证/端点、重试耗尽及超时故障都会被记录,并可将工作转交给排名靠后的下一位合格候选项,包括规划器/综合器的备用候选项。格式错误或语义无效的请求仍会快速失败,不会向多个服务提供商重复发送请求。
  • 混合式单次调用 / Agent 式运行。 任务可以通过单次调用运行,也可以采用模型↔工具循环(有守护进程时,在 Docker 隔离的沙箱中运行 run_python;没有守护进程时则禁用该工具;另有由主机中介的 fetch_url / read_file)。
  • 共享上下文。 仅追加的黑板会保留来源信息;每个任务都会获得一个有范围限制、预算封顶的投影,其中只包含它所需的依赖产物。
  • 全程流式传输。 流式传输实时 Token 会贯穿 supervisor、工作器和综合器;并行为工作器显示任务标签,并支持协作式提前停止。
  • 可选的 Web UI。 一个轻量的 FastAPI + SSE 应用可在浏览器中实时流式显示运行过程(规划 → 每个任务的工作器输出 → 综合 → 结果);既可使用真实服务提供商运行,也可通过无密钥演示运行。
  • 可核验的答案。 volante --verify 会根据你的目标生成 assert 语句,在沙箱中针对结果运行这些语句,并打印哪些通过、哪些失败——同时显示检查文本,而非徽章,因为检查失败往往是检查本身有误,只有文本行才能说明这一点。它会报告三种状态;如果你的目标未说明预期结果,还会报告“证据不足”。测量结果:针对一个粗略缺陷,在 8 个目标上误报和漏报均为 0;针对仿照编辑操作设计的缺陷,6 个中检出 5 个。报告干净能提供证据,但并非保证。
  • 成本与诚实性。 CostMeter 会统计每个模型的用量和成本;如果服务提供商未返回用量数据,还会传递估算值标记。
  • 抗伪造的评估,并报告自身效力。 三组评估(基线 vs. 编排 vs. 单 Agent)使用评分器,在进程 + 文件系统隔离环境下运行不可信的解决方案代码,防止模型伪造通过的分数。各组采用成对比较,每份报告都会显示置信区间和本次运行能够检测到的最小效应——此前公布的三个数字都必须下调更正,它们全是来自样本量不足以支撑结论的设计的点估计,因此加入了这一做法。
  • 经过测试。 1200+ 项测试,默认不联网(FakeProvider + 本地子进程),通过 ruff 检查,且通过 mypy 检查。

架构

flowchart TD
    goal(["goal"]) --> S["Supervisor<br/>plan → validated task DAG<br/>(acyclic · typed · one_shot | agentic)"]
    S --> R["Router<br/>best predicted fit per task<br/>(hard constraints → explainable score)"]
    R --> P
    subgraph wave["wave execution · asyncio fan-out · fail-fast"]
        direction TB
        P["Projector<br/>scoped, budget-capped request<br/>(system + task + deps)"]
        P --> W["Worker<br/>one-shot"]
        P --> AW["AgenticWorker<br/>model ↔ tool loop<br/>(run_python · fetch_url · read_file)"]
    end
    W --> BB[("Blackboard<br/>append-only · provenance · latest-wins")]
    AW --> BB
    BB --> SY["Synthesizer<br/>combine artifacts → final answer"]
    SY --> result(["result<br/>+ CostMeter totals · usage · duration"])

    classDef io stroke:#8b5cf6,stroke-width:2px;
    classDef store stroke:#f59e0b,stroke-width:2px;
    class goal,result io;
    class BB store;
文本版本(可在任何地方渲染,例如 PyPI 或终端)
                    ┌──────────────┐
   goal ──────────► │  Supervisor  │  plan → validated task DAG (acyclic, typed, one_shot|agentic)
                    └──────┬───────┘
                           ▼
                    ┌──────────────┐   per task: hard-capability filter, then rank the
                    │    Router    │   predicted fit from configured evidence
                    └──────┬───────┘
                           ▼
        ┌───────────── wave execution (asyncio, fan-out cap, fail-fast) ─────────────┐
        │   ┌───────────┐   scoped, budget-capped request (system + task + deps)      │
        │   │ Projector │──────────────────────────────────────────────────────────► │
        │   └───────────┘                                                             │
        │        ▼                              ▼                                      │
        │   ┌─────────┐  one-shot          ┌───────────────┐  model↔tool loop         │
        │   │ Worker  │                    │ AgenticWorker │  (run_python sandbox,     │
        │   └────┬────┘                    └───────┬───────┘   fetch_url, read_file)   │
        │        └──────────────┬──────────────────┘                                   │
        └───────────────────────┼───────────────────────────────────────────────────┘
                                 ▼
                    ┌──────────────────────┐   append-only, provenance, latest-wins
                    │  Blackboard          │◄──────────────────────────────────────
                    └──────────┬───────────┘
                               ▼
                    ┌──────────────┐
                    │ Synthesizer  │  combine artifacts → final answer
                    └──────┬───────┘
                           ▼
                        result  (+ CostMeter totals, usage, duration)
组件文件职责
Supervisorsrc/volante/supervisor.py将目标分解为经过验证的任务 DAG
Routersrc/volante/router.py完整清单 → 符合条件的候选项 → 可解释的排序
Projectorsrc/volante/projector.py根据黑板产物生成范围受限、预算封顶的请求
Workersrc/volante/worker.py单次模型调用
AgenticWorkersrc/volante/agent.py模型↔工具循环,并记录每轮信息
Blackboardsrc/volante/blackboard.py追加式共享状态,并保留来源信息
Synthesizersrc/volante/synthesizer.py将产物转化为最终答案
Runtimesrc/volante/runtime.py编排:规划 → 波次 → 综合(流式、快速失败)
Providerssrc/volante/providers/Anthropic + OpenAI 兼容适配器(完成/流式/工具)
Toolssrc/volante/tools/Sandbox / DockerSandbox、run_python、fetch_url、read_file
Evaleval/7 个目标(5 个 kata + 2 个多部分任务)、三臂对比、防伪造评分器

快速开始

需要 Python 3.11.10+(最低版本是安全边界——见 Providers)。

安装:

pip install volante          # the CLI and the library
pip install "volante[mcp]"   # ...plus the MCP server, for IDE use
volante --version
volante --list-models        # what your environment currently offers, offline

volante 至少需要配置一个提供商才能运行目标——有关两行配置方法,请见 Providers。在此之前,--list-models 和 --help 可以正常使用,其他命令则会提示缺少什么。

**或者参与开发:**克隆仓库后即可使用测试、Web UI 和一个无需密钥的演示;这些内容不会随 wheel 一同发布。

git clone https://github.com/ribato22/volante
cd volante
uv sync --dev            # install deps + dev tools
uv run pytest            # 1200+ tests, no network
uv run ruff check .      # lint

# See it orchestrate end-to-end with ZERO API keys (FakeProvider demo):
uv run python examples/fake_provider.py

然后至少配置一个真实提供商(见 Providers),并运行演示:

cp .env.example .env     # fill in one provider, then `set -a; . .env; set +a`

uv run python demo.py               # show detected providers
uv run python demo.py orchestrate   # full supervisor → workers → synth, streamed live
uv run python demo.py agentic       # one cross-provider agentic coding task (run_python loop)
uv run python demo.py eval          # 3-arm eval suite
示例输出

demo.py orchestrate 会实时流式输出每个阶段,然后打印结果(仅供示意):

Orchestrate demo — planner/synth model=openai/gpt-4o-mini

(planning + workers + synthesis stream live)
[haiku] Threads run as one— / tasks bloom in parallel time, / the join gathers all.

STATUS: success

FINAL:
Threads run as one—
tasks bloom in parallel time,
the join gathers all.

cost: $0.001834

demo.py eval 会打印三臂表格(format_report)。以下是上一次完整运行时的实际输出:

GOAL            WINNER          BASE   ORCH   AGEN
--------------------------------------------------
slugify         baseline        1.00   1.00   0.67
roman           baseline        1.00   1.00   0.70
calc            orchestration   0.96   1.00   0.27
csv_stats       baseline        1.00   1.00   0.57
json_flatten    baseline        1.00   1.00   0.70
textkit         baseline        1.00   1.00   0.47
ledger          baseline        1.00   1.00   0.80
toolbelt        baseline        1.00   1.00   0.70
debug_gauntlet  baseline        0.98   0.98   0.63
--------------------------------------------------
wins: baseline=8  orchestration=1  agentic=0  ties=0
totals: baseline $0.018108  orchestration $0.139354  agentic $0.099910
VERDICT: BASELINE

openai/gpt-4o-mini,9 个目标 x 3 个臂 x k=3 = 81 次针对 Docker 沙箱的真实运行,数据读取自 results-0.4.2-corrected.json——每次运行都会写入的自描述产物(模型、k、每个目标的分数、成本)。

“VERDICT: BASELINE”是成本平局判定,不是质量结论。编排在八个目标上与基线持平,在一个目标上胜过基线;基线在那八个目标上胜出,是因为它以低 7.7 倍的成本取得相同分数。就质量而言,这套测试在上限处打成平局:基线为 0.993,编排为 0.997。

早期版本在此处公布的编排分数为 0.919,四个目标完全落败。这主要是我们的评分错误,已在 cd94390 中修复:评分器遇到第一个 ``` 就会关闭围栏代码块,即使它位于字符串字面量内。因此,模型即使在自己的模块中嵌入了所需 README,代码也能正常运行,却会得到 0.000 分。这惩罚了单个自包含代码块的答案——也就是综合阶段生成的形式——因此对编排臂的影响远大于基线臂。该提交之前公布的所有编排分数都是下限。

复现此结果——需要你的密钥,而且会产生实际费用:

uv run python -m eval.run --k 5 --json results.json

**阅读此表时请牢记其局限性,因为这些局限性很大。**现在两个臂在这套测试中都已达到上限——基线 0.993,编排 0.997——因此它已完全无法区分二者。1.00 的平局并不能证明二者等效;它只能说明这些目标太容易,无法衡量出差异。这九个目标所能证明的是:“在单个模型已能通过单轮解决的任务上,编排不会落后”。这一点值得了解,但并非该理念所依据的主张。

要验证这一主张,需要一个有提升空间的目标。resolve(位于 eval/tasks_depth.py,使用 --suite depth 运行)就是一个:实现由七条相互重叠的优先级规则约束的单个函数,并在 48 个测试用例上评分,每种答案均衡分布 12 个,因此恒定回答恰好得分 0.25。同一模型,温度为 0,n=8:

分组汇总运行次数平均值各批次平均值
基线250.4940.414 · 0.492 · 0.708 · 0.497
编排250.6530.742 · 0.721 · 0.656 · 0.476

请看最后一列,而不是平均值。 本 README 的早期版本曾报告 +0.289,Welch t=3.54,p<0.005,结果来自一批 8 次运行。该结果未能复现。合并四批数据后,差距为 +0.159,而最近一批的结果则反转了:编排为 0.476,基线为 0.497。在这一目标上,批次间的波动大于所测效果,因此,目前本项目没有证据表明编排优于单次调用,即使是在专为发挥编排优势而设计的目标上也没有。

更不利于这一论断的是,后来发现所谓的优势空间源自模型能力不足。在同一批次中,用同系列的更强模型运行相同目标,每组 n=6:

模型基线编排编排成本
openai/gpt-4o-mini0.4970.4762.2x
openai/gpt-4o0.958(标准差 0.000)0.9417.6x

gpt-4o 单独调用即可稳定解决问题,而编排的效果略差,成本却是 7.6x。因此,在 resolve 上发挥作用的任务拆解,弥补的是更好的模型本就不存在的差距。这是关于该引擎的一项真实结果,我们在此公布它是因为它属实,而不是因为它有利。

仍然成立的是:可靠性方面的改进不受影响,且本身就有价值——无法解析的输出从 8 次运行中出现 2 次降至 0 次;在 22 次测量运行中,--verify 从未批准过错误答案。这些都是引擎本身的特性,与两组之间的比较无关。

以上结果都只涉及一种模型和一类小型编码任务,而且编排成本是基线的 7.7x。如果编排没有带来收益,--prefer cheap 现在可以节省这部分成本:它会要求规划器只在拆分有帮助时才进行拆分。实测结果,每组 n=5 —

目标基线--prefer quality--prefer cheap
slugify(基线已达满分)1.000 · $0.000461.000 · 10.6x1.000 · 4.7x
resolve(有提升空间)0.708 · $0.000930.721 · 4.8x0.525 · 4.6x

对于一个模型已经能轻松满分的目标,该选项在输出完全相同的情况下,将费用减半。对于有提升空间的目标,它会损失 0.20 分,却没有节省任何成本——这正是该标志所代表的取舍,也是它采用可选启用而非默认启用的原因。

它采用可选启用,是有实测依据的:自动选择行不通。我们尝试了三种信号,结果全部失败。规划器自己的难度标签将 resolve 与 csv_stats 归为同一配置(medium:2, easy:1),而 csv_stats 的基线得分已达 1.00。即使告知它,简单目标可以只返回一个任务,它也从不放弃拆分。给它看自己的答案并要求检查是否符合目标时,它会对得分仅为 0.417 的结果回复 OK。在这一层级上没有可用的信号,因此选择权应交给了解任务价值的人。它是否能为更强的模型、更大型的任务,或确实超出单个上下文窗口的工作带来收益,尚未测量,本项目也不对此作出声称。 Agentic 组的 27 次运行中仍有 2 次失败。

到目前为止,基准测试最有价值的产出并非分数。它发现了三个真实的引擎错误——Agentic 循环中存在确定性活锁;一个评估组会因模型正确作答但未调用工具而判其失败;以及一个停滞保护机制在第一次警告后便放弃,而第二次警告本可以让运行恢复——修复这些问题后,Agentic 运行的终端失败率从 79% 降至 7%。它还推翻了作者自己的两个假设(扩大目标范围会打破天花板效应;提高迭代上限会有所帮助)。这正是这套测试的用途。

用法

Volante 提供三种使用方式:一条命令即可运行的 CLI(主要入口)、可选的 Web UI,以及可导入的 库。三者都至少需要配置一个提供商——参见提供商——否则(仅限 Web UI)会回退到免密钥演示模式。

CLI(主要方式)
uv run volante "write a haiku about concurrency, then explain the metaphor"

volante 会实时流式输出计划、每个并行工作器的输出(按任务标注)和综合结果, 随后打印摘要。标志(volante --help):

标志说明
--prefer {quality,cash_protect_quota,local,cheap}路由目标。quality(默认)按预测的任务匹配度排序;cash_protect_quota 保留订阅配额;local 优先选择符合条件的本地模型;cheap 优先选择已配置的经济成本
--provider NAME / -P NAME将规划器/综合器的基线限制为此提供方
--model ID覆盖规划器/综合器的 model_id
--list-models打印完整的已配置/检测到的路由清单并退出;与 --json 搭配可输出机器可读内容
--usage打印近期使用记录(~/.volante/usage.jsonl)——包括通过 MCP 从 IDE 委派的运行——并退出;可与 --json 搭配使用
--json将运行摘要打印为一行可解析的 JSON;禁用流式输出
--no-stream禁用计划/工作器/综合文本的实时流式输出
--version打印已安装的版本并退出

退出码:0 成功,1 运行失败,2 配置错误(例如未配置提供方),130 Ctrl-C(打印截至中断时已流式输出的内容——绝不会输出原始回溯)。

摘要会报告 billed_usd(实际现金支出)与 credit_usd(订阅/套餐 API 等值金额,并非现金)、实际的 subscription_calls,以及每项任务的路由跟踪。JSON 模式还会包含所有符合条件/被拒绝的候选项、评分组成部分、所选模型,以及发生任何回退后实际执行的模型。

Web UI
uv sync --extra ui
uv run python -m webui          # then open http://127.0.0.1:8000

一个小型 FastAPI + Server-Sent-Events 应用,可在浏览器中实时流式输出运行内容——计划、每个并行工作器的输出(按任务标注)、综合结果,以及包含成本和模型路由的最终结果。 它使用已配置的提供方运行;若未配置,则使用内置的 FakeProvider 演示(无需 API 密钥)。这是源码检出版本的功能——webui/ 不会随构建后的 wheel/PyPI 包一起发布。

VOLANTE_UI_HOST / VOLANTE_UI_PORT 可覆盖绑定地址。除非设置了 VOLANTE_UI_AUTH_TOKEN,否则 Volante 会拒绝非回环主机;同时也会拒绝通过普通 HTTP 传输该令牌:设置 VOLANTE_UI_TLS_CERT + VOLANTE_UI_TLS_KEY 可直接提供 TLS 服务;如果前面有终止 TLS 的反向代理,则设置 VOLANTE_UI_TRUST_PROXY=1。 远程访问时,还要将 VOLANTE_UI_ALLOWED_HOSTS 设置为客户端将使用的逗号分隔主机名。VOLANTE_UI_MAX_GOAL_CHARS(默认值为 20000)和 VOLANTE_UI_MAX_CONCURRENT_RUNS(默认值为 2)用于限制输入长度和并发数。页面仅通过 textContent 插入所有模型输出(绝不使用原始 HTML),因此流式文本无法注入标记。/usage 页面(由页眉链接,且受同一 VOLANTE_UI_AUTH_TOKEN 保护)会显示下方的使用记录。

监控使用情况

CLI、Web UI 和 MCP 服务的每次运行都会尽力向使用记录追加一行 JSON——默认路径为 ~/.volante/usage.jsonl(可通过 VOLANTE_USAGE_LOG 更改位置,设置为空则禁用)——记录状态、现金与套餐额度、实际订阅调用次数、耗时、所用模型以及截断后的目标。这是当 IDE Agent 通过 MCP 委派目标时,监控 Volante 的方式:

uv run volante --usage            # recent runs + totals, newest first
uv run volante --usage --json     # the same as one JSON object

Web UI 的 /usage 仪表板会读取同一份记录(摘要卡片 + 近期运行表格)。设置 VOLANTE_LOG=debug(或 info/warning/error)可提高 stderr 上的引擎诊断信息级别——对于 MCP 服务,这些信息会显示在客户端的服务输出窗格中(例如 VS Code 的输出 → Volante MCP 服务);默认保持静默,且绝不会写入 stdout。

库
import asyncio
import volante


async def main() -> None:
    registry, providers, model_id = volante.build_providers_from_env()
    factory = await volante.make_verified_runtime_factory(
        registry, providers, model_id
    )
    runtime = factory()
    result = await runtime.aexecute("your goal")
    print(result.status, result.billed_usd, result.credit_usd, result.cost_estimated)


asyncio.run(main())

Runtime 是一次性使用的:它运行一个目标,其记账、路由轨迹和规划器都仅属于本次运行。每个目标都要再次调用 factory()(在同一个实例上第二次或重叠调用 aexecute 会被拒绝,并抛出 RuntimeError,而不是悄悄混淆两次运行的数字)。请同时查看 result.cost_estimated 和各项金额——当提供方至少有一次调用未报告 Token 数量时,该值为 True,这意味着部分数字是根据配置的费率推算得出的,而非由提供方报告。

顶层 volante 包重新导出了常用的库 API(Runtime、Registry、Router、RoutingDecision、ModelQualityProfile、清单辅助工具、build_providers_from_env、make_verified_runtime_factory、RunResult、ModelInfo、Task、LLMProvider、ProviderError——请参阅 volante.__all__),因此你无需访问子模块。

可运行的脚本请参阅 examples/——其中包括完全无需 API 密钥的 examples/fake_provider.py。如需了解硬编码目标的演示,请运行演示脚本: uv run python demo.py orchestrate|agentic|eval(快速入门中有详细介绍)。

使用你的 Claude / ChatGPT 订阅(无需 API 密钥)

Volante 可以驱动你已登录的官方无头 CLI,以替代(或搭配)需要绑定银行卡的 API 密钥:

export CLAUDE_CODE_ENABLED=1               # needs `claude` installed and logged in
# CLAUDE_CODE_SYSTEM_PROMPT_MODE=replace is the default — makes `claude -p` behave as a
# raw completion; `append` breaks strict-JSON planning, so leave it unset unless you know why.
export CODEX_ENABLED=1 CODEX_TIER=3         # needs `codex login`
uv run volante "your goal"

⚠️ 订阅运行不产生现金费用,但会消耗你的交互式 Claude Code / Codex 配额—— 也就是你的交互式编码会话使用的同一配额池。繁重的编排运行可能会触发速率限制暂停。默认的 quality 目标会优先为每项任务选择预测适配度最高的模型,因此可能会大量使用订阅模型。传入 --prefer cash_protect_quota 可缓解这一情况——它会将批量/简单任务交给更便宜的本地/免费层级模型,只为困难任务保留订阅模型。 建议使用按量计费、免费层级或本地模型作为规划器:订阅 CLI 会忽略 temperature,因此 Volante 会通过自我纠正重试规划,并可在将 claude -p 用作规划器之前执行实时解析计划检查(只有确认它能输出有效的计划 JSON 时才会进行规划)。

这会驱动你已登录的官方无头 CLI(claude -p、codex exec)——绝不会驱动 claude.ai / ChatGPT 网页应用。尚未实现抓取这些网页应用的功能(因为这会违反其服务条款)。

在 IDE(VSCode)和 MCP 中使用

Volante 是一款 CLI 优先的工具,因此它已能在任何编辑器的集成终端中运行(uv run volante "…")。VSCode 还提供两项便利功能:

1. 一键执行任务。 此仓库附带 .vscode/tasks.json。打开 终端 → 运行任务…(或按 ⌘/Ctrl+Shift+B),然后选择:

任务功能
Volante:运行目标提示输入目标并对其进行编排(依次流式输出计划 → 工作器 → 综合结果)。
Volante:Web UI在 http://127.0.0.1:8000 提供实时 Web UI。
Volante:MCP 服务(stdio)运行 MCP 服务,供 AI Agent 集成使用(见下文)。
Volante:测试/Lint对项目运行 pytest / ruff。

2. MCP 服务——让编辑器内的 AI 调用 Volante。 Volante 附带一个 MCP 服务(volante_mcp/),提供一个工具: volante_run(goal, prefer?)。该工具会规划 → 路由 → 执行 → 综合,并返回最终答案 以及如实列出的现金费用/计划额度。任何支持 MCP 的助手(Claude Code、Cursor、VS Code Copilot Agent 模式、Windsurf)都可以将完整目标委托给 Volante。

建议无需克隆即可安装,也可以从源码检出目录安装:

# clone-free — uv fetches the published package + the `mcp` extra on demand:
uvx --from "volante[mcp]==0.9.0" volante-mcp

# or install it and run the console script:
pip install "volante[mcp]==0.9.0"   # then:
volante-mcp

# or from a source checkout:
uv sync --extra mcp && uv run --extra mcp python -m volante_mcp

在你的客户端中注册它。Claude Code——运行一条命令:

claude mcp add volante -- uvx --from "volante[mcp]==0.9.0" volante-mcp

Cursor / VS Code / Windsurf——将其添加到客户端的 MCP 配置中(例如 .cursor/mcp.json,或 VS Code 的 .vscode/mcp.json 中 "servers" 键下):

{
  "mcpServers": {
    "volante": {
      "command": "uvx",
      "args": ["--from", "volante[mcp]==0.9.0", "volante-mcp"]
    }
  }
}

服务器与 CLI 一样,直接从环境变量读取提供方(包括 CLAUDE_CODE_ENABLED / CODEX_ENABLED),因此请先配置至少一个提供方——它不会 回退到演示模式。项目有意不提供完整品牌化的 VSCode 扩展;CLI、 任务和 MCP 服务涵盖了相同的功能。

已加入官方 MCP 注册表。 Volante 已作为 io.github.ribato22/volante 发布到 官方 MCP 注册表 (包含经过验证的 server.json 清单,以及一个会在每次发布时通过 OIDC 重新发布的 publish-mcp.yml GitHub Actions 工作流)。mcp.so、 PulseMCP 和 Glama 等目录会从中索引。

作为 Claude Code 插件。 此仓库也兼作插件市场——只需一条命令,即可将 MCP 服务和 /volante:run 斜杠命令接入 Claude Code:

/plugin marketplace add ribato22/volante
/plugin install volante@volante

需要将 uv 添加到 PATH(插件使用 uvx 启动服务)。请参阅 plugins/volante/。

其他 MCP 客户端(Codex、Cursor、Windsurf、Gemini CLI、Cline)。 这些客户端没有插件 市场——它们通过配置使用 MCP 服务。将它们指向相同的启动命令:

  • OpenAI Codex CLI — codex mcp add volante -- uvx --from "volante[mcp]==0.9.0" volante-mcp (会在 ~/.codex/config.toml 中写入一个 [mcp_servers.volante] 配置块;可通过重复使用 --env KEY=VALUE 添加提供方)。

  • Gemini CLI — gemini mcp add volante uvx -- --from "volante[mcp]==0.9.0" volante-mcp (必须使用 --,因为 Volante 的第一个参数是 --from)。

  • Cursor / Windsurf / Cline / Roo — 在客户端的 MCP 配置中添加标准的 mcpServers 条目 (配置文件为 ~/.cursor/mcp.json、~/.codeium/windsurf/mcp_config.json 或 Cline 设置):

    { "mcpServers": { "volante": {
        "command": "uvx",
        "args": ["--from", "volante[mcp]==0.9.0", "volante-mcp"],
        "env": { "CLAUDE_CODE_ENABLED": "1", "ANTHROPIC_API_KEY": "sk-ant-..." }
    } } }
    

在每个客户端的 env 配置块中设置提供方(CLAUDE_CODE_ENABLED、CODEX_ENABLED、 ANTHROPIC_API_KEY、OPENAI_COMPAT_*)。

Claude Desktop 和 Smithery — MCPB 捆绑包。 每个 发布版本都会附带一个单文件 MCPB 捆绑包,文件名为 volante-<version>.mcpb。在 Claude Desktop 中打开它即可一键安装(它会显示提供方配置界面)。也可以将其发布到 Smithery 作为本地服务——由于 Volante 使用 stdio(而非托管的 HTTPS 端点),因此应使用 CLI 捆绑包方式,而不是“发布 URL”网页表单:

# download volante-<version>.mcpb from the release, then (needs a Smithery API key):
npx -y @smithery/cli mcp publish ./volante-<version>.mcpb -n <your-namespace>/volante

该捆绑包封装了 uvx --from "volante[mcp]==0.9.0" volante-mcp,因此会在本地运行,你的 订阅 CLI 和 API 密钥也可以照常使用(需要将 uv 添加到 PATH)。

提供方

可为任意子集设置环境变量。每个已配置的模型都会加入用户的模型清单,供路由器 选择;Anthropic > OpenAI-compat > Kimi > Ollama 的优先级仅用于选择默认规划器/综合器。 完整列表请参阅 .env.example。

提供方环境变量使用方式
Anthropic(Claude)ANTHROPIC_API_KEY付费 API(console.anthropic.com)
通用 OpenAI 兼容服务OPENAI_COMPAT_BASE_URL、OPENAI_COMPAT_MODEL(以及 +_KEY/_NAME/_CONTEXT/…)任意 OpenAI 兼容端点
Moonshot / KimiMOONSHOT_API_KEY付费 API
OllamaOLLAMA_BASE_URL本地且免费
模型清单和质量证据

Volante 绝不会猜测某个账户拥有哪些远程模型。提供方目录和权限 API 并不统一, 可能需要额外权限,也无法证明某个模型当前可用。 因此,路由清单是明确且可审计的:

# Comma-separated lists; the singular forms remain backward compatible.
export ANTHROPIC_MODELS=claude-opus-4-8,claude-sonnet-4-5
export ANTHROPIC_NAMES=anthropic/opus,anthropic/sonnet
export MOONSHOT_MODELS=kimi-k3,kimi-k2.6
export OLLAMA_MODELS=qwen2.5-coder:14b,llama3.2
export CLAUDE_CODE_MODELS=opus,sonnet
export CODEX_MODELS=gpt-5-codex,gpt-5-codex-mini

uv run volante --list-models
uv run volante --list-models --json

*_NAMES 是可选的;如果提供,则每个线上的模型都必须有且只有一个规范 ID。 所有已配置的模型都会注册;不会悄悄添加默认种子。清单命令为离线命令:“已配置/已检测到”不代表拥有实时使用权限、配额或服务可用性。 执行时,明确的模型/部署不存在错误或模型访问被拒绝,只会将相应候选模型标记为不可用。常规身份验证或端点错误则会将提供商标记为不可用。Volante 会记录这两类回退事件,并可尝试排名中的下一个模型;格式错误或语义无效的请求仍会快速失败,而不会盲目调用所有提供商。

在没有实测证据时,quality 有意作为一种预测,依据声明的优势、层级、上下文/输出余量和任务难度得出。Volante 不会虚增该预测:对于每个符合条件的模型都给出相同结果的评分组件(未声明专长优势时的 task_fit,未配置任何画像时的 reliability)会被赋予零权重,其占比会分配给实际包含信息的组件。路由追踪会列出被舍弃的组件,因此由层级决定的排名会如实呈现,而不会用 45 分的“任务适配度”常量来掩饰。

有两种方法可以重新启用这些组件。

1. 声明模型的实际优势。 除了任务类型所需的优势(code 对应 coding,其余类型对应 reasoning)之外,这些可选标签也会提高 task_fit,并帮助区分同一层级的模型:

任务类型可提高适配度的可选优势标签
codesoftware_engineering、debugging、instruction_following
researchresearch、grounding、long_context
writewriting、creativity、instruction_following
analyzeanalysis、math、long_context

使用 *_STRENGTHS 环境变量按提供商槽位设置(例如 ANTHROPIC_STRENGTHS=coding,reasoning,software_engineering,debugging),或在 覆盖文件中按模型设置。这些是你作出的声明,并非 Volante 内置的供应商说法。

2. 根据你掌握的测量结果进行校准。 将你实际观察到的分数转换为严格的 profiles 文件——无需调用提供商,因此不产生任何费用:

# measurements.json — one entry per observed run, each naming the goal it came from;
# a null score means "produced nothing usable":
#   {"anthropic/opus": {"code": [{"goal": "slugify", "score": 1.0},
#                                {"goal": "roman",   "score": 0.8}],
#                       "write": [{"goal": "incident_note", "score": 0.9}]},
#    "ollama/qwen":    {"code": [{"goal": "slugify", "score": 0.4},
#                                {"goal": "roman",   "score": null}]}}
uv run volante --calibrate measurements.json --calibrate-out quality-profiles.json
export VOLANTE_QUALITY_PROFILES_FILE=$PWD/quality-profiles.json

每条记录都要注明目标。confidence 统计的是不同目标,而非运行次数,因为画像要描述的是某种任务类型,而目标是这项描述能够泛化的单位——实测中,同一目标运行五次都返回了相同分数,因此第二至第五次运行并未带来任何信息,却将置信度从 0.25 提高到了 0.625。手动编写的文件仍可使用单个数字,但以这种方式记录的任务类型,其覆盖广度无法验证:它仍采用旧的运行次数置信度,且 --calibrate 会警告该值可能偏高。 --calibrate 按任务类型计算平均值。只有测量覆盖了所有任务类型时,它才会输出 overall_score,因为路由器会将该字段应用于每种任务类型——包括测量从未涉及的类型。若根据不完整的样本推导该值,就会让编码方面的证据冒充未经考察的研究能力。覆盖不完整时,该字段会被省略,路由器会回退到较粗略的已声明等级,并在追踪记录中说明这一点,而不是引用一份从未考察过相关能力的配置文件。覆盖完整时,它会对各类型的均值进行宏平均,因此不均衡的样本(30 次 code 运行、一次 write 运行)描述的是模型,而不是你的抽样方式。confidence 取样本量最少的任务类型的值,且上限低于 1.0——路由器会将同一个置信度应用于所有任务类型,因此无关的运行不应让单次观察显得确定无疑。其计算公式为 goals/(goals+3),因此扩大覆盖范围会提高该值,而重复运行相同目标不会。只有记录过 null 运行时,才会输出 reliability_score:如果从低分推导该值,可靠性指标就会变成质量指标的翻版。模型 ID 必须存在于你配置的清单中(加载器会严格校验),且输出会替换而非合并,因此请在一个文件中校准所有你关心的模型。

这些测量数据从何而来。 eval/calibrate_models.py 会运行评测套件的基线组——一个模型、一次调用、不做编排——针对多个模型进行测量,并为你写入测量文件。这会产生实际费用(models x goals x k 次调用):

uv run python -m eval.calibrate_models --models gpt-4.1-nano,gpt-4o-mini,gpt-4.1 --k 3
uv run volante --calibrate measurements.json --calibrate-out quality-profiles.json

本仓库中的 measurements.json 和 quality-profiles.json 是一次完全按照上述方式进行的真实运行结果(2026-07-29,共 81 次调用)。请将它们视为完整示例,而非默认配置:它们描述了三个你可能没有的 OpenAI 模型,而且路由器只会加载你指定的配置文件。它们生成于 goal 字段加入之前,因此 --calibrate 会警告其覆盖广度无法验证,并保留原有的运行次数置信度——当时没有记录每次运行的目标,现在补造目标分配会伪造这些文件旨在保留的来源信息。如果想查看当前格式的真实数据,可参阅 eval/artifacts/measurements-k5.json,其中包含完整标注的运行数据。

这些测量结果说明了什么。 三个 OpenAI 模型在 code 上呈现出清晰、单调的梯度——gpt-4.1-nano 为 0.951,gpt-4o-mini 为 0.990,gpt-4.1 为 1.000——这与路由器原先采用的等级顺序一致,因此在同一家族内进行校准,验证了这一启发式规则,而非推翻它。测量第二个模型家族才改变了整体情况:

模型codeanalyze
openai/gpt-4.11.0000.417
openai/gpt-4o-mini0.9900.167
openai/gpt-4.1-nano0.9510.183
glm/glm-4.5-flash0.7040.389

glm-4.5-flash 在代码方面排名末位,在分析方面则排名第二;gpt-4o-mini 在代码方面几乎最佳,在分析方面却最差——一种任务类型上差了 0.29,另一种上则反而高出 0.22;而同一家族内 0.016 的波动只是噪声。

这些结果有多大分量,直说如下。 code 的分数来自每个模型 9 个目标,每个目标 k=3 次运行。analyze 的分数则只来自一个目标——目前 eval/tasks_text.py 只有一个条目——每个目标 k=3 到 5 次运行,而且所有分数都落在该评分标准区间的下半段。单个条目上出现如此幅度的差异,值得关注,但尚不足以确立结论;请把它视为测量你自己的模型清单的理由,而非可以引用的结果。不同实验室的模型是否确实各有所长,是按任务路由所依赖的假设;这是目前这里首次出现支持该假设的证据——但只来自一个目标。 加载这些证据并排除最强模型后,路由器会为 code 选择 gpt-4o-mini,为 analyze 选择 glm-4.5-flash——针对不同工作选择不同模型,依据的是测量结果, 而不是层级常量。最强模型可用时,它仍会在两项任务中胜出,因为它确实两方面都最强;模型替换 发生在它以下的所有模型中,而成本或配额目标实际需要做出的选择也正是这些模型。

在信任自己的配置文件之前,有两点限制值得了解:

  • 测试套件已达饱和。 gpt-4.1 获得了 27/27 的满分,因此无法测量比它更强的模型, 分数梯度也被压缩到了最上方的 5%。在 k=1 时,最弱模型碰巧得到了 1.000 的满分; 只有 k=3 才能区分它们。请使用 k>=3 进行校准,并注意:如果所有模型都能通过某个任务集, 它就无法提供任何信息。
  • 四种任务类型中只有一种有任务覆盖。 编码套件中的每个目标都是编码任务,因此仅运行编码测试 只能测量 code。过去这会造成信息泄漏:overall_score 根据已测量的内容得出,然后应用于所有 任务类型,因此编码证据会悄然变成对研究能力的断言。现在已不再如此——一般性断言现在需要完整覆盖—— 这一点也体现在分数中:加载仅包含 code 的配置文件时,research 的排名与完全不加载配置文件时 完全相同,而 code 的排名则会变化。eval/tasks_text.py 为其他类型添加了目标。

配置文件格式与手动编写时相同:

{
  "anthropic/opus": {
    "task_scores": {"code": 0.96, "research": 0.94, "write": 0.91, "analyze": 0.95},
    "overall_score": 0.95,
    "reliability_score": 0.98,
    "confidence": 0.9,
    "source": "team-eval-2026-07"
  },
  "ollama/qwen2.5-coder:14b": {
    "task_scores": {"code": 0.78},
    "overall_score": 0.70,
    "reliability_score": 0.86,
    "is_local": true,
    "confidence": 0.8,
    "source": "team-eval-2026-07"
  }
}

请将此严格 JSON 文件保存在版本控制之外,并设置 VOLANTE_QUALITY_PROFILES_FILE=/absolute/path/to/quality-profiles.json。分数已归一化至 0..1;支持的任务键为 code、research、write 和 analyze。未知模型 ID、 未知字段、重复的 JSON 键、无效或非有限分数,以及类似凭据的额外字段都会导致操作失败并拒绝使用。 决策跟踪记录会注明证据来源和注意事项,而不会声称某个模型在经验上普遍胜出。

代码库包含一个三组评估框架,但 Volante 尚未发布具有代表性的跨提供商实证基准测试结果,也不会自动 校准质量配置文件。请将配置的分数视为由用户持有的证据,根据你自己的任务分布进行验证,并在模型或 端点发生变化时重新校准。

复数形式的系列设置会共享其提供商级默认值。如果同一系列中的两个模型在硬性能力、限制、价格或层级上 有所不同,请在第二个严格 JSON 文件中按规范模型 ID 分别声明这些设置:

{
  "anthropic/haiku": {
    "strengths": ["reasoning"],
    "context_window": 200000,
    "max_output_tokens": 64000,
    "supports_tools": true,
    "cost_per_1k_in": 0.001,
    "cost_per_1k_out": 0.005,
    "tier": 2
  },
  "anthropic/opus": {
    "strengths": ["coding", "reasoning", "long_context"],
    "context_window": 1000000,
    "max_output_tokens": 128000,
    "supports_tools": true,
    "cost_per_1k_in": 0.005,
    "cost_per_1k_out": 0.025,
    "tier": 4
  }
}

设置 VOLANTE_MODEL_OVERRIDES_FILE=/absolute/path/to/model-overrides.json。覆盖项只能包含上述 七个字段;模型 ID 必须已存在于配置清单中。质量配置文件包含软性的、源自评估的证据,而模型覆盖项包含 用于资格判定、预测、路由和核算的硬性或经济性元数据。两个文件都不接受机密信息。

Agent 工具的可用性也有明确规定。只有在有隔离沙箱可用时才会提供 run_python(请参见 安全性与限制(坦诚说明));设置 VOLANTE_FETCH_ALLOWLIST=example.com,docs.python.org 可启用 fetch_url,设置 VOLANTE_READ_ROOT=/absolute/path/to/trusted/files 可启用 read_file。监督器会为每项 Agent 任务声明 required_tools,如果这些工具未启用或实际上从未调用,Volante 会拒绝计划或执行。主机名允许列表 无法完全防御 DNS 重绑定或私有地址解析;VOLANTE_READ_ROOT 应指向可信目录树,且该目录树不应遭遇恶意的 并发符号链接变更。

订阅 CLI Agent 需主动启用,并会消耗交互额度。 不会抓取 claude.ai / ChatGPT(违反服务条款、脆弱且有封号风险)。Volante 可以驱动你已经登录的官方无头 CLI: Claude Code(claude -p)和 Codex(codex exec),无需 API 密钥。 此功能默认关闭(需设置 CLAUDE_CODE_ENABLED=1 / CODEX_ENABLED=1,并安装相应 CLI), 且 eval 绝不会使用它。坦诚说明:目前,claude -p 和 codex exec 消耗的额度来自与聊天应用 相同的交互式订阅额度池(不是单独计量的额度池),因此一次完整的编排运行——尤其是 3 臂 eval——可能 耗尽你的 Claude Code / Codex 额度,并触发运行期间的硬暂停。Volante 会将 credit_usd(消耗的订阅价值) 与 billed_usd(现金费用)分开报告,只将高难度/高档位任务分配给订阅服务(批量工作交给 本地/免费档),并限制每次运行中实际发起的订阅调用次数 (VOLANTE_MAX_SUBSCRIPTION_CALLS,默认值为 16,包括订阅规划器兼容性预检、规划、重试、工作器/Agent 调用以及综合)。 在默认的 quality 目标下,任何符合条件的订阅模型都可能被选中;只有使用 --prefer cash_protect_quota 时, 才会采用高难度任务预留机制。

计费方式可能变化——请重新核实后再采信。 claude -p 的费用是从 订阅额度池扣除,还是从按用量计费的 API 额度池扣除,几个月内已多次变化 (于 2026-06-15 宣布变更,随后暂停;截至 2026-07-22 仍处于暂停状态)。Anthropic 下次宣布计费变更时, 请重新执行 docs/claude-code-live-gate.md 中的在线检查,并再次查看帮助中心横幅,然后更新该文档中记录的“已验证”日期。

免费且智能程度高的选项——通过通用槽位使用 Google AI Studio(Gemini Flash):

export OPENAI_COMPAT_BASE_URL=https://generativelanguage.googleapis.com/v1beta/openai/
export OPENAI_COMPAT_KEY=<ai-studio-key>       # aistudio.google.com/apikey
export OPENAI_COMPAT_MODEL=gemini-flash-latest # pick a current model from the endpoint's /models
export OPENAI_COMPAT_NAME=google/gemini-flash
uv run python demo.py orchestrate

通用槽位默认上下文长度为 128k、输出长度为 8k、工具支持关闭,费用为 0。只有在确认支持函数调用后, 才设置 OPENAI_COMPAT_TOOLS=true,并填写提供商的实际费用/档位/优势;Volante 会注册该 ModelInfo, 使路由和费用核算使用已声明的元数据,而非隐藏的默认值。

同时使用多个模型/提供商——添加 OPENAI_COMPAT_2_*、OPENAI_COMPAT_3_*,……(每个槽位都要有各自的 model_id/价格/上下文),或者使用上文针对 Anthropic、Moonshot、Ollama、Claude Code 和 Codex 的复数模型列表。 槽位可以指向不同的提供商,也可以指向同一兼容端点上的多个模型。例如,配置 Gemini 和 Groq,让监督器 使用 Gemini 制定计划,同时由 Groq 模型运行并行工作器。请参阅 .env.example。

评估

demo.py eval 会针对 5 个复合编码目标执行三臂对比:基线(一个强模型,单次尝试)、编排(完整引擎), 以及 agentic-single(一个模型 + 一个 run_python 循环,不进行任务分解)。每个目标都由隐藏的参考测试评分。

评分器会在子进程中运行模型生成的 solution.py,并进行进程隔离和文件系统隔离:受信任的运行器会在单独的 进程中运行不受信任的解决方案,且该进程无法看到预期输出(通过 nonce 认证的 RPC),因此解决方案必须实际计算出正确答案—— 不能伪造通过评分。

请结合测试框架发出的警告来解读判定结果:

  • WARNING: some costs are estimated … — 提供商未返回用量信息;费用对比仅供参考。
  • WARNING: agentic arm failed N run(s) … — 0.0 可能是基础设施/提供商故障,而非能力不足。
  • WARNING: goal(s) […] produced NO trusted result … — 参考运行器本身发生故障;这些分数是测试框架产物,并非真正的零分。

安全性与局限性(如实说明)

Volante 仍处于 alpha 阶段;其隔离保障经过有意界定,并有明确文档说明。

  • 代码执行默认安全,失败时会拒绝执行。 未设置 VOLANTE_SANDBOX 时,Volante 会探测是否有正在运行的 Docker 守护进程:如果有响应,run_python 会在容器中执行(--network none、根目录只读、移除功能、设置 cgroup 限制)。如果没有响应,则完全不提供 run_python——规划器会获知其无法执行代码——而不会悄悄运行模型编写的代码并让其访问你的文件和网络。子进程 Sandbox 防范的是意外,而非恶意攻击者(主机网络和磁盘仍可访问),因此现在必须显式选择启用:VOLANTE_SANDBOX=subprocess,每次启动时都会打印警告。遇到未知的 VOLANTE_SANDBOX 值时会拒绝运行,而不会悄悄降级。
  • 外部工具由主机代为执行。 fetch_url(主机名允许列表、禁止重定向、限制响应正文大小)和 read_file(检查解析后的路径是否位于根目录内、限制读取大小)由可信的编排器运行,因此沙箱中的代码无法访问网络。允许列表无法防止 DNS 重绑定或解析到私有地址,根目录检查也无法防止恶意符号链接被交换时发生竞态;请使用可信域名和可信的本地目录树。只有在 Docker 下才能保证阻止提示词注入。
  • 评测评分可抵御伪造,但仅在尽力而为的 POSIX 环境下有效。 进程与文件系统隔离可阻止解答伪造分数;调用 setsid() 的解答仍可能逃离 killpg 进程组(但运行时间仍受墙钟超时限制)。这是进程隔离,而不是用于任意恶意代码的安全沙箱。
  • 切勿将机密放入模型上下文。 应将允许列表和文件读取根目录视为明确的暴露控制措施,而非通用的恶意攻击防护沙箱。

项目布局

src/volante/     # engine (importable package: `volante`)
  providers/          # Anthropic + OpenAI-compatible adapters, FakeProvider
  tools/              # Sandbox, DockerSandbox, run_python, fetch_url, read_file
eval/                 # goals, 3-arm harness, forgery-resistant scorer, runner
examples/             # small runnable library-API scripts (incl. a no-key FakeProvider demo)
webui/                # optional FastAPI + SSE web UI (uv run python -m webui)
tests/                # 1200+ tests (unit + opt-in integration)
docs/                 # internal design/build records — see docs/README.md; not user docs
demo.py               # end-to-end demo (orchestrate | agentic | eval)

开发

  • 测试驱动,默认不访问网络。 uv run pytest 使用 FakeProvider 和本地子进程;会访问网络或 Docker 的集成测试标记为 integration,默认跳过(使用 uv run pytest -m integration 可选择运行)。
  • Lint: uv run ruff check .(行长度 100;E,F,I,UP,B)。
  • 欢迎贡献 — 请参阅 CONTRIBUTING.md 和我们的 行为准则。 安全问题报告:SECURITY.md。发行说明: CHANGELOG.md。

项目状态与非目标

Volante 是一个 alpha 阶段、透明、由用户拥有的模型路由与编排控制平面。用户可通过 CLI、库、Web UI 和 MCP 服务使用它,管理用户明确配置的模型清单和提供商。它不是托管式模型网关、自动发现权限的服务,也不保证其预测的适配度在实证上达到最优。接口仍可能演进。

用于生产环境时,请使用有代表性的工作负载验证 Volante 的路由,为其提供并维护自己的质量证据,根据威胁模型选择文档说明的隔离模式,并保留应用层恢复路径。刻意采用不依赖框架的实现:监督器、路由器、投影器和黑板的行为都便于检查,而不是隐藏在 LangChain、LiteLLM 或 CrewAI 的抽象之下。

路线图

  • 发布具有代表性的跨提供商三臂基准测试结果,并分析编排是否优于单个模型。
  • 根据有代表性的用户评估,自动校准特定任务的质量配置。
  • 异步生成器/背压流式 API。
  • Ollama 工具调用/流式集成覆盖。

许可证

MIT © 2026 ribato。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。