CalcGuide · 技术博客主页 / 一页纸学习计划
🔥极高

LLM 评测与运维:从质量指标到灰度控制

分类:数据与人工智能 · 路径:docs/topics/llm-eval-and-ops/README.md

#llm-eval#monitoring#cost#canary

建立人工、A/B、LLM-as-judge 评测与可观测、成本、灰度体系

父主题

大语言模型应用:从 Prompt 到 RAG 与 Agent 的工程实践

子主题(0)

LLM 评测与运维:从质量指标到灰度控制

0. 元信息

1. 学习路线

评测集与标注规范
  → 人工评测
  → A/B 测试与 LLM-as-judge
  → 质量/延迟/错误监控
  → Token 成本控制
  → 灰度、门槛与回滚

2. 阶段周数分配(1~2 周,每天 1.5~2 小时)

阶段1 周方案2 周方案备注
1. 评测设计0.25 周0.5 周任务定义、样本、rubric
2. 多方法评测0.25 周0.5 周人工 / A/B / LLM-as-judge
3. 监控0.25 周0.5 周质量、延迟、错误指标
4. 成本与灰度0.25 周0.5 周预算、canary、回滚

分阶段概述

1 周方案每天 2 小时;2 周方案每天 1.5 小时,多留 2 天做灰度方案与回滚演练。先建评测集再谈上线——没有评测集的灰度是盲飞。

3. 阶段表

阶段核心知识实践产出可观察学会标准
1. 评测设计任务定义、样本、标签、人工 rubric30 条评测集每条样本有期望行为和判定理由
2. 多方法评测人工、A/B、LLM-as-judge、偏差校准评测脚本与报告能解释三种方法的适用边界,人工抽样校准 judge
3. 监控质量、成功率、P50/P95、首 token、上下文、拒答指标面板和告警能从 trace 定位失败阶段
4. 成本与灰度token 预算、缓存、路由、采样、canary、回滚成本表与灰度方案超门槛自动停止,能复现回滚决策

4. 第一周(每天 1.5~2 小时)

环境约定:本子主题统一使用 Python 3.11+ 与 python -m venv .venv;评测集与 trace 用 JSONL 保存(datasets/eval.jsonl / traces/<date>.jsonl);指标聚合用纯 Python(参考 §9.7.1);面板用 Grafana / Prometheus 或本地 Streamlit。API key 通过 export ANTHROPIC_API_KEY=... 共享 .env 模板:父主题 attachments/.env.example 含 Anthropic / OpenAI / Voyage / Qdrant / Ollama / OTel / Langfuse 全套变量;本地 cp ../../attachments/.env.example .env 后填值,.env 加入 .gitignore,加载用 python-dotenv禁止把真实 key 提交到仓库或写入 trace / 日志。 注入。

任务当天交付自检
Day 1写 10 条评测样本(覆盖 happy / 拒答 / 长尾 / 越权 4 类),含 input / expected / rubric / tags 字段datasets/eval.jsonl(10 行)每条样本能用一句话说清”期望行为”与”判定理由”
Day 2跑评测脚本:把线上 / 本地模型回答写入 runs/<run_id>/answers.jsonl,按 rubric 算成功率notes/eval/day2.md + eval/runner.py10 条样本跑完;成功率按任务分桶统计
Day 3引入 LLM-as-judge:用 claude-sonnet-4-5 做盲评(隐藏模型名),输出 factuality / completeness / reasonnotes/eval/day3.md + judge promptjudge 输出的 JSON 可解析;reason 不为空;与人工 rubric 对比差异 ≤ 2 条
Day 4加 A/B 测试:同一评测集跑两个 prompt / 两个模型,记录 run_id / arm / score;按用户分桶notes/eval/day4.md + 一组 A/B 结果两个 arm 样本量均衡;分流固定可复现;指标差异可解释
Day 5建监控:记录 latency_ms / tokens / error_typetraces/<date>.jsonl;写 LatencyWatch(P50/P95/P99)notes/ops/day5.md + metrics/latency.py200 条样本聚合后 P50/P95/P99 数字合理;长尾样本未被平均掩盖
Day 6加成本监控:CostGuard 按分钟 / 按请求记录 spend,超阈值熔断;写 notes/cost/<date>.mdnotes/ops/day6.md + metrics/cost.py模拟流量把单位成本推到阈值之上时,CostGuard.charge() 返回 False
Day 7评测 + 监控 + 成本综合跑:把前 6 天产物串成一条流水线,输出 report.md;做一次失败注入(模型 5xx / 延迟飙升 / 成本超限)notes/ops/day7.md + report.md失败注入时监控告警可见;超成本时 CostGuard 拒收新请求;trace 可定位失败阶段

第一周复盘要求

每日把样本、prompt、judge 结果、监控指标写到 notes/eval/notes/ops/ 对应日期的 md;Week 1 结束前用 30 分钟复盘:哪些 rubric 容易和 judge 偏差?哪些指标其实没区分度?

5. 阶段通用验收

  1. 不看答案独立重写评测集 schema 与指标聚合脚本;
  2. 用自己的话解释人工 rubric、A/B、LLM-as-judge 的适用边界与偏差来源;
  3. 画出”评测 → 指标 → 灰度 → 回滚”四阶段的依赖图;
  4. 测试样本不足、模型 5xx、judge 输出非法、P95 飙升、成本超限 5 类边界;
  5. 准备至少 3 组 A/B 实验并贴出实际报告;
  6. 记录成功率、P50/P95/P99、首 token、token 用量、单位请求成本;
  7. 能修改已有评测(加 rubric / 加指标 / 改告警阈值)并复现失败注入。

交付存放:第 3 项的图、第 5 项的报告、第 6 项的指标统一存到 notes/eval/ / notes/ops/ 或 README 对应章节,便于复盘与综合项目引用。

6. 最终验收(学完 1~2 周后)

API key 配置与回退方案

7. 综合项目

首选:LLM 应用质量门禁(必做:评测集 + 多方法评测 + 监控面板 + 成本限流 + canary / 自动回滚)。

备选:A/B 测试平台原型(必做:用户分桶 + 多 arm 路由 + 指标聚合 + 报告生成)。

任何综合项目都必须包含:

  1. 需求说明:要解决的运维问题、用户故事、输入输出约定(含超阈值自动回滚分支);
  2. 数据流与模型选择理由:为什么选这套评测 / 监控 / 灰度方案;记录权衡;
  3. 算法与策略说明:rubric 设计、A/B 分桶、canary 阈值、回滚触发条件;
  4. 模块化源码eval/ / metrics/ / cost/ / canary.py 等职责单一;
  5. 边界与安全测试:模型 5xx、judge 失败、P95 飙升、成本超限、阈值误判;
  6. 运行说明make run 或清晰 python -m ... 命令,注明环境变量与依赖;
  7. README:项目介绍、运行步骤、目录结构、复盘(踩过的坑、可改进点);
  8. 评测与复盘记录notes/retrospective.md(用时、难点、收获、下一步)。

notes/ 与 README 存放规范

所有”画图(依赖图 / 灰度流程)“和”贴报告”类交付物统一存放在项目根目录的 notes/ 子目录或 README 的对应章节;提交时一并带上,避免散落在聊天或临时文件里。综合项目的 notes/ 至少包含:

本主题贡献(Loop 6-D · llm-applications / llm-eval-and-ops)

本主题把”评测 rubric、A/B 与 canary、LLM-as-judge、成本与延迟 trace”四条独立工程线拧成一条验收闭环,输出可被父主题与下游子主题直接复用的评测管线。

3 项核心职责

4 项交付物

  1. rubric + 评测集源码eval/rubric.yaml(维度 × 等级 × 权重)+ eval/dataset.jsonl(gold 输入 / 输出 / 期望维度分),用 LLM-as-judge + 人工抽检双轨打分。
  2. A/B + canary 控制器canary.py(按 bucket_id 分流 + 阈值告警 + 自动回滚),配 metrics/(P50 / P95 / 错误率 / 成本)+ cost/(按模型 + token 单价聚合)。
  3. trace + 监控配置tracing.py(opentelemetry 风格 trace)+ Prometheus / Langfuse 接入,每次推理写入 prompt / completion / latency / tokens / cost。
  4. 边界测试 + 必读交付:模型 5xx / judge 失败 / P95 飙升 / 成本超限 / 阈值误判 5 类各 1 例,配 notes/design.md(rubric + 聚合逻辑 + canary 策略)+ notes/retrospective.md

3 个验收指标

8. 推荐开源资料(按角色分工,避免堆链接)

阶段角色资料链接用法
1评测设计Anthropic Building Evalshttps://docs.anthropic.com/en/docs/build-with-claude/develop-tests评测集与 rubric 写法参考
1评测设计OpenAI Evals 框架https://github.com/openai/evals看评测结构;不要直接当生产评测
2LLM-as-judgeAnthropic Constitutional AIhttps://www.anthropic.com/researchjudge prompt 与偏差校准背景
2A/B 测试《Trustworthy Online Controlled Experiments》https://experimentguide.com/实验设计、样本量、分桶原则
3可观测性OpenTelemetry Pythonhttps://opentelemetry.io/docs/languages/python/trace / span / metric 接入;评测系统的工程基础
3监控面板Grafana 文档https://grafana.com/docs/grafana/latest/仪表盘与告警配置
3监控采集Prometheus 文档https://prometheus.io/docs/counter / histogram / summary 选型
4成本与限流OpenAI Rate Limitshttps://platform.openai.com/docs/guides/rate-limits限流策略参考;不绑定供应商
4灰度发布《Continuous Delivery》https://continuous.com/canary / blue-green / 回滚原则;书籍说明,引用即可
5评测指标Ragas 文档https://docs.ragas.io/faithfulness / answer_relevancy 等指标;必须配合人工抽样
通识API 查阅Anthropic API 文档https://docs.anthropic.com/en/api/overview查参数、token、限制与价格
通识模型查阅Hugging Face Hubhttps://huggingface.co/docs查模型卡、tokenizer、推理参数

许可证提示:复制或参考 OpenAI Evals / Ragas 等开源仓库代码前,先打开 LICENSE 确认。OpenAI Evals 采用 MIT 许可证;Ragas 采用 Apache-2.0。默认做法是读思路后自己重写,而不是复制粘贴;GPL 类代码用于商业 / 闭源项目前请逐条阅读。

API key 安全:示例代码统一使用 os.environ["ANTHROPIC_API_KEY"] 或等价方式;不要把 key 提交到仓库;本地用 .env(加入 .gitignore)+ python-dotenv 加载;CI 上用 secret 注入。trace 中的 input / expected 可能含敏感字段,记录前脱敏。

默认使用顺序:先用 Anthropic Building Evals / OpenAI Evals 看评测结构 → 自己写评测集 schema + 指标聚合 → 引入 LLM-as-judge 并人工校准 → 接入 OpenTelemetry + Prometheus + Grafana 做监控 → 加 CostGuard 与 canary / 回滚 → 引入 Ragas 做辅助评测 → 跑失败注入 + 复盘到 notes/retrospective.md

9. 学习资料汇聚(v0.3 自包含)

9.1 背景与动机

LLM 输出具有概率性,传统“接口返回 200”无法代表业务成功。评测把质量变成可比较数据,运维把质量、延迟、错误和成本变成持续反馈,灰度则把上线风险控制在小范围内。

9.2 概念地图

flowchart LR
  Dataset[评测集] --> Human[人工 rubric]
  Dataset --> AB[A/B 测试]
  Dataset --> Judge[LLM-as-judge]
  Human --> Gate[质量门槛]
  AB --> Gate
  Judge --> Gate
  App[应用 trace] --> Metrics[质量/延迟/错误/成本指标]
  Metrics --> Canary[灰度]
  Gate --> Canary
  Canary --> Rollback[回滚]

9.3 基础知识讲解

主推 OpenTelemetry 文档(日志、指标、trace)和项目自身的标注 rubric;备查 Ragas 等 RAG 评测工具。LLM-as-judge 只能作为辅助信号,必须保留人工校准样本和评测版本。

9.4 经典问题与经典案例

问题最简答案
评测集过于简单增加真实失败、拒答和长上下文样本
judge 偏爱长答案盲化模型名,加入长度和引用控制项
平均值掩盖尾延迟同时看 P50/P95/P99 和首 token
成本突然升高记录 input/output token、模型路由和预算
A/B 混入不同流量固定分流、用户分桶和实验窗口
灰度没有回滚上线前定义质量、错误率和成本阈值

9.5 学习难点

9.6 技术标准与接口

Entity

Dataset/version、rubric、judge score、trace/span、counter、histogram、cost budget、canary cohort。

Scope

指标描述系统表现,不能代替安全审查、人工责任或业务验收;灰度控制发布暴露面,不修复根因。

Structure

掌握成功率、引用正确率、faithfulness、P50/P95、首 token、错误分类、token usage、单位请求成本和回滚阈值。

Ecosystem

OpenTelemetry 是观测基础;Prometheus/Grafana 等负责采集展示;Ragas 等负责部分评测计算。具体命名和采样策略需在项目中固定。

Depth Tiers

L0 知道指标存在;L1 看懂评测报告;L2 能建立评测集和面板;L3 能定位回归并执行灰度;L4 能设计跨版本质量门禁。本子主题要求 L3。

Source

OpenTelemetry、Prometheus、Grafana、Ragas 官方文档;版本快照日期:2026-07-28。

9.7 关键代码

9.7.1 评测集 + 指标聚合

# 9.7.1 评测集与 recall@k、MRR、引用命中率
from collections import defaultdict
from statistics import mean

def recall_at_k(retrieved: list[str], gold: list[str], k: int) -> float:
    return 1.0 if any(d in gold for d in retrieved[:k]) else 0.0

def mrr(retrieved: list[str], gold: list[str]) -> float:
    for i, d in enumerate(retrieved, start=1):
        if d in gold:
            return 1.0 / i
    return 0.0

def citation_hit(citations: list[str], gold_source_ids: list[str]) -> float:
    return 1.0 if any(c in gold_source_ids for c in citations) else 0.0

def aggregate(samples: list[dict]) -> dict:
    bucket = defaultdict(list)
    for s in samples:
        bucket[s["task"]].append({
            "recall@5": recall_at_k(s["retrieved"], s["gold"], 5),
            "mrr": mrr(s["retrieved"], s["gold"]),
            "cite": citation_hit(s["citations"], s["gold_source_ids"]),
        })
    return {t: {k: mean(v) for k, v in m.items()} for t, m in bucket.items()}

if __name__ == "__main__":
    samples = [
        {"task": "qa", "retrieved": ["c1", "c2"], "gold": ["c1"],
         "citations": ["c1"], "gold_source_ids": ["c1"]},
        {"task": "qa", "retrieved": ["c9", "c2"], "gold": ["c2"],
         "citations": [], "gold_source_ids": ["c2"]},
    ]
    print(aggregate(samples))  # {'qa': {'recall@5': 1.0, 'mrr': 1.0, 'cite': 0.5}}

9.7.2 P50/P95 延迟监控 + 成本限流

# 9.7.2 延迟分桶、成本预算与超限熔断
import time
from collections import deque
from threading import Lock

class LatencyWatch:
    def __init__(self, window: int = 200) -> None:
        self.samples: deque[float] = deque(maxlen=window)
        self.lock = Lock()

    def record(self, latency_ms: float) -> None:
        with self.lock:
            self.samples.append(latency_ms)

    def percentile(self, p: float) -> float:
        if not self.samples:
            return 0.0
        s = sorted(self.samples)
        idx = int(round((p / 100.0) * (len(s) - 1)))
        return s[idx]

class CostGuard:
    def __init__(self, budget_usd_per_min: float, input_per_1k: float, output_per_1k: float) -> None:
        self.budget = budget_usd_per_min
        self.input_rate = input_per_1k
        self.output_rate = output_per_1k
        self.spend = 0.0
        self.window_start = time.time()

    def charge(self, in_tok: int, out_tok: int) -> bool:
        now = time.time()
        if now - self.window_start >= 60:
            self.spend = 0.0
            self.window_start = now
        cost = in_tok / 1000 * self.input_rate + out_tok / 1000 * self.output_rate
        self.spend += cost
        return self.spend <= self.budget

if __name__ == "__main__":
    w = LatencyWatch()
    for x in [80, 90, 100, 200, 1200, 110]:
        w.record(x)
    print(f"P50={w.percentile(50):.0f}ms P95={w.percentile(95):.0f}ms")

9.7.3 真实可运行:Anthropic SDK 跑一个 LLM-as-judge 评分

# 9.7.3 用 Anthropic SDK 做一次 LLM-as-judge 盲评
# 运行:export ANTHROPIC_API_KEY=...; python judge_anthropic.py
import os
import json
import anthropic

client = anthropic.Anthropic()
ANSWER = "RAG 是检索增强生成。"
REFERENCE = "检索增强生成(Retrieval-Augmented Generation)"

prompt = (
    "你是评分员,对候选答案相对于参考答案的事实性与完整性打分 0~5 整数。"
    "若候选答案与参考答案矛盾,扣到 0;只输出 JSON:"
    "{\"factuality\": 0..5, \"completeness\": 0..5, \"reason\": str}\n"
    f"参考答案:{REFERENCE}\n候选答案:{ANSWER}"
)

resp = client.messages.create(
    model="claude-haiku-4-5",
    max_tokens=128,
    messages=[{"role": "user", "content": prompt}],
)
score = json.loads(resp.content[0].text.strip())
print(score)

10. 常见误区

11. 所有知识点分类(统一规则)

  1. 编程语言
  2. 数据结构与算法
  3. 计算机基础
  4. 工程技术
  5. Web 与后端
  6. 前端与客户端
  7. 数据与人工智能
  8. 项目与职业能力

本计划归属:数据与人工智能 主 + 工程技术 辅。


直接依赖(0)

查看知识图谱 · 热度 🔥极高