运行时依赖
版本
添加安全注意事项:无遥测,所有API调用使用用户自己的密钥,本地Ollama永远不会向外部发送数据
安装命令
点击复制技能文档
设置一个生产级别的影子评估管道,当本地 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.5或ollama 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% | 在可接受范围内 |
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_task、get_status、get_champions、get_promotion_timeline、get_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%+ 的任务量在本地)。