🧪 Llm Eval Router — 本地LLM模型云评估路由器

v1.2.2

该技能通过多评判员集成在本地对Ollama模型进行影子测试,相比云端基准模型。统计证明等效后自动提升模型,依据证据降低API成本。

0· 440·2 当前·2 累计
by @nissan (Nissan Dookeran)·MIT-0
下载技能包
License
MIT-0
最后更新
2026/4/12
0
安全扫描
VirusTotal
可疑
查看报告
OpenClaw
安全
high confidence
技能所请求的工具和凭证与其声明的目的相符(影子评估本地Ollama模型对云基准),虽然它会向云API发送提示并存储本地评分数据,但请求的内容与目的相称。
安全有层次,运行前请审查代码。

License

MIT-0

可自由使用、修改和再分发,无需署名。

运行时依赖

无特殊依赖

版本

latestv1.2.22026/2/26

添加安全注意事项:无遥测,所有API调用使用用户自己的密钥,本地Ollama永远不会向外部发送数据

可疑

安装命令

点击复制
官方npx clawhub@latest install llm-eval-router
🇨🇳 镜像加速npx clawhub@latest install llm-eval-router --registry https://cn.longxiaskill.com

技能文档

设置一个生产级别的影子评估管道,当本地 Ollama 模型在统计上证明其匹配云模型质量时自动升级 —— 用证据而非希望来降低推理成本。

核心理念

将每个任务同时通过您最好的本地模型(影子)和云基线(真实值)运行。轻量级评委集成对本地输出进行评分。经过 200+ 次运行后,如果本地模型达到 0.95 的平均分,则将其升级为在生产环境中处理该任务类型。如果质量下降,自动降级。

使用场景

  • 您正在为不需要那么高质量的任务支付 Claude/GPT API 费用
  • 您本地运行 Ollama 并使用有能力的模型(qwen2.5、phi4、mistral 等)
  • 您希望基于证据的成本降低,而不是盲目路由
  • 您有定义的任务类型:summarize(总结)、classify(分类)、extract(提取)、format(格式化)、analyze(分析)、RAG

不适用场景

  • 需要实时网络知识的任务(使用云)
  • 延迟要求严格 < 2 秒的任务(CPU 上的本地模型很慢)
  • 高安全风险的任务(始终使用带安全过滤器的云)
  • 您没有 Ollama 或具有足够 RAM 的 Mac/Linux 机器(每个模型 8GB+)

前提条件

  • Ollama 已安装并运行(ollama.com)
  • 至少一个有能力的模型:ollama pull qwen2.5ollama pull phi4
  • Python 3.10+
  • API 密钥:Anthropic(真实值)+ OpenAI(评委)—— Gemini 可选(平局打破者)
  • Langfuse 用于可观测性(自托管或云)—— 可选但强烈推荐

网络与隐私

本技能会向以下 API 发出出站调用:

  • Anthropic API — 生成真实值基线响应(每个累积周期)
  • OpenAI API — 评委评分(采样率为运行次数的 15%)
  • Google Gemini API — 仅作为平局打破者(当主要评委分歧 ≥0.20 时)

本地保留内容:

  • 所有 Ollama 模型推理完全在您的设备上运行
  • 评分运行数据存储在磁盘上的 data/scores/*.json
  • 无遥测、分析或任何形式的数据收集
  • 除上述显式 API 调用外,无任何数据发送到其他地方

Langfuse(可选)可以自托管或使用云版本。如果自托管,所有可观测性数据保留在您的网络中。

核心概念

6维度评估

每个响应在以下维度进行评分:

维度默认权重分析权重衡量内容
Structural(结构)25%10%格式合规性,必需键是否存在
Semantic(语义)25%40%与真实值的含义等价性
Factual(事实)20%25%无幻觉事实/数字/实体
Completion(完成度)15%18%任务完全解决
Tool use(工具使用)10%4%正确的工具/格式选择
Latency(延迟)5%3%在可接受范围内
重要: 使用每任务权重覆盖。默认的 25/25 分割将结构准确性与语义相似度同等对待 —— 这适用于提取/分类/格式化任务(其中精确格式很重要),但对于开放式分析则不正确。对同一问题的两个散文分析使用 difflib.SequenceMatcher 评分约为 0.29,即使它们在语义上是相同的。结构权重为 25% 时,仅此一项就将分析分数上限限制在 ~0.59。

# src/evaluator.py — 每任务权重配置
TASK_WEIGHT_OVERRIDES = {
    "analyze": {
        "structural_accuracy": 0.10,   # difflib 对散文没有意义
        "semantic_similarity": 0.40,   # 嵌入向量的余弦相似度捕获含义
        "factual_drift": 0.25,
        "task_completion": 0.18,
        "tool_correctness": 0.04,
        "latency_score": 0.03,
    },
    "code_transform": {
        "structural_accuracy": 0.15,
        "semantic_similarity": 0.35,
        "factual_drift": 0.20,
        "task_completion": 0.20,
        "tool_correctness": 0.07,
        "latency_score": 0.03,
    },
}

另外: 对于分析任务,通过 system_prompt 约束输出结构,使真实值和候选者产生格式相当的响应(Finding/Recommendation/Confidence/Reasoning)。这减少了第 2 层漂移并即使在权重降低的情况下也能提高 difflib 分数。

评委集成

  • 主要评委(15% 采样率):Claude Sonnet + gpt-4o-mini 独立评分
  • 平局打破者(仅当 |score_A - score_B| ≥ 0.20 时):Gemini 2.5-flash
  • 未采样运行(85%):仅第 1+2 层验证器(确定性,免费)
  • 升级门始终触发完整评委评估,无论采样率如何

第 1+2 层验证器(免费,确定性)

  • 第 1 层:JSON 有效性、必需键存在、禁止模式检查
  • 第 2 层:漂移检测 —— 真实值中不存在的新实体/数字/URL

这些在每个响应上零成本运行。评委仅在 L1+L2 通过且采样率触发时运行。

升级/降级

  • 升级:200+ 次运行,模型/任务对的滚动平均值 ≥ 0.95
  • 降级:滚动 7 天通过率 < 0.92
  • 控制底线:一个模型(phi4、granite4 或类似)作为测量底线 —— 任何评分低于它的模型都应被标记,而不是升级

实现步骤

步骤 1 — 定义任务类型

创建 config/task_types.yaml

tasks:
  - id: summarize
    description: "在 N 句话中总结文档"
    require_json: false
    judge_dimensions: [semantic, factual, completion]

- id: classify description: "将文本分类为 N 个类别之一" require_json: true # 响应必须是有效的 JSON judge_dimensions: [structural, semantic, completion]

API 端点

POST /run          — 通过最佳可用模型路由任务
GET  /health       — 服务状态 + 已升级模型 + Ollama 连接性
GET  /status       — 完整记分板(模型 × 任务 × 平均值 × n)
GET  /report       — 成本热图 + 效率分析

关键经验教训(来自 900+ 次生产运行)

有效方法:

  • phi4 作为控制底线:测量底线模型防止"因为其他人也很差所以升级"的错误。如果底线模型击败候选者,标记它 — 不要升级。
  • 思考令牌剥离:CoT 模型(deepseek-r1、带推理的 qwen2.5-coder)必须在评估前剥离 ... 块。否则第 2 层漂移检测会将推理链标记为幻觉内容。
  • None ≠ 0.0 对于未采样运行:没有评委评分的运行不是失败运行。存储 None,从平均值中排除。将 None 与 0.0 混合会污染平均值。
  • require_json: False 对于纯文本任务:返回格式化文本(不是 JSON 对象)的分类和提取任务如果需要 JSON 将在第 1 层失败。将"格式是否正确"检查与"是否为有效 JSON"分离。
  • 每任务权重覆盖:不要对所有任务类型使用一个权重配置文件。结构准确性(difflib)对于散文分析是错误的 — 对开放式任务使用语义相似度作为主要信号。这将分析平均值从 0.44-0.59 提升到 0.70。
  • 分析任务的结构化输出提示:添加指定精确输出格式(Finding/Recommendation/Confidence/Reasoning)的 system_prompt。真实值和候选者都遵循相同的模板,提高结构对齐并减少漂移惩罚。否则,第 2 层漂移会针对不同表述但正确的分析触发。
  • 用于智能体访问的 MCP 服务器:将 CP 作为 MCP 工具公开(run_taskget_statusget_championsget_promotion_timelineget_cost_heatmap)。允许 LLM 智能体查询评估状态而无需定制集成工作。

无效方法:

  • 大型模型(>9GB):gpt-oss:20b 及类似模型需要 39+ 秒推理 — 仅延迟维度就会降低综合分数。实际上限是 24GB 统一内存上的 ~9GB 模型,以避免 GPU 内存交换。
  • 100% 评委采样:每次运行都进行完整评委评估在评委 API 费用上的花费比本地路由节省的还要多。以 15% 采样。
  • Chroma 1.5.1 与 Python 3.14:Pydantic V1 BaseSettings 不兼容。改用 qdrant 或 numpy 余弦存储。
  • 一刀切的权重配置文件:在系统初始化时定义全局权重并且永远不在任务类型级别覆盖导致 112+ 次运行的所有分析评估静默失败。教训:尽早按任务类型评估评估器的分数 — 如果整个任务类型在可疑上限(例如 0.59)处封顶,度量标准是错误的,而不是模型。

预期时间线

使用 20 分钟累加器节奏和 9 个候选者 × 7 个任务类型:

  • 每个模型前 50 次运行:~5 小时
  • 首次升级(200 次运行):每个模型/任务对 ~1-2 天
  • 稳定路由层:1-2 周

成本估算

每个累积周期(一个任务,一个模型):

  • 真实值:~$0.002(Claude Sonnet,~500 输入 + 200 输出令牌)
  • 评委采样(15%):~$0.003(Sonnet + GPT-4o-mini)
  • 本地模型:$0(Ollama,设备上)

在 6 次运行/小时 × 24 小时:烧录期间 ~$0.70/天。 首次升级后:降至 ~$0.10/天(90%+ 的任务量在本地)。

数据来源:ClawHub ↗ · 中文优化:龙虾技能库