资讯动态

用Claude设计eval并hillclimb:从人工打分到自动化评分迭代

发布时间:2026/10/3 5:38:50 来源:尧图企业网站定制
1. 为什么我选择用 Claude 来做 eval 而不是人工打分第一次接触 eval 这个概念是在做一个垂直领域的问答助手时。当时团队里三个人轮流看模型输出每人每天看两百条看完还要在表格里打分、写评语。坚持了不到一周所有人都开始敷衍——同一类错误早上打 2 分下午可能就打 3 分因为看麻了。更麻烦的是当我把模型从 A 版本换到 B 版本想对比到底有没有变好发现两批评分的人不一样、标准也不一样数据根本没法比。这就是我后来转向用 Claude 来设计 eval 的直接原因。eval 的本质不是打分而是把什么叫好这件事变成一套可重复执行的判定逻辑。人工打分最大的问题是不可复现而 Claude 这类模型恰好擅长做给定标准、逐条判断的活。你只要把评分标准写清楚它能以几乎一致的口径跑几千条还能把判断理由写出来方便你回头审计。需要先说清楚的是我这里说的 eval 不是指跑个 benchmark 看个准确率数字就完事。那种做法在真实项目里价值有限因为公开 benchmark 和你的业务场景往往差得很远。我关心的是针对自己业务场景的定制化 eval输入是你真实的用户 query输出是模型回答判定标准是你自己定义的好答案长什么样。这套东西搭起来之后你才能做后面那件更有意思的事——hillclimb也就是一轮一轮把分数往上爬。hillclimb 这个词直译是爬坡在模型优化语境里指的是拿到一个基线分数后通过改 prompt、改检索、改后处理、换模型等手段每次只动一个变量看分数有没有涨涨了就保留没涨就回退如此反复迭代。它听起来很朴素但真正做起来难点全在分数这两个字上——如果你的 eval 本身不可靠那 hillclimb 就是在爬一座会移动的山越爬越迷茫。所以这篇东西的定位很明确给那些已经在用 Claude 做实际项目、想系统化提升输出质量的人看。不管你是做客服机器人、内容生成、代码助手还是数据分析只要你的产出质量可以被打分这套先设计 eval、再 hillclimb的方法就能用。我会把每一步为什么这么做、参数怎么定、坑在哪里都讲透你可以直接抄作业。2. 用 Claude 设计 eval 的整体思路拆解2.1 先想清楚 eval 要回答什么问题很多人一上来就写评分 prompt结果写出来的东西自己都说不清在评什么。我的经验是动手之前先回答三个问题这个 eval 是用来做绝对判断还是相对比较绝对判断是这条回答够不够好相对比较是A 版本和 B 版本哪个更好。前者适合设阈值卡质量后者适合 hillclimb 时判断改动是否有效。我通常两个都做但分开跑。评分维度有几个能不能拆开一条回答可能同时涉及准确性、完整性、语气、格式。如果揉成一个总分你只知道变差了不知道差在哪。拆成多个维度分别打分hillclimb 时才能精准定位。判定标准能不能用自然语言描述清楚这是能不能交给 Claude 的关键。如果标准是感觉对就行那 Claude 也帮不了你。你必须能写出如果回答里出现了未经检索支持的具体数字准确性扣分这种可执行的规则。我一般会把 eval 拆成 3 到 5 个维度每个维度 1 到 5 分最后加权成总分。维度太多会让 Claude 的判断变模糊太少又定位不到问题。三个维度是我最常用的起点准确性、完整性、表达质量。2.2 为什么用 Claude 当裁判而不是规则脚本有人会问既然标准能写成规则为什么不直接写正则或者关键词匹配答案是真实回答的多样性远超规则能覆盖的范围。比如判断回答是否切题关键词匹配只能看有没有出现某些词但一条回答可能把所有关键词都堆上了却答非所问。这种语义层面的判断规则脚本做不了Claude 可以。另一个原因是 Claude 能输出判断理由。这一点在调试时极其重要。当分数掉了你不只知道掉了还能看到 Claude 说这条回答在完整性上扣了 2 分因为没有覆盖用户问的第二个子问题。这种可解释性让 hillclimb 从盲猜变成了有方向的调整。当然用模型当裁判也有代价它本身会有波动会有偏见比如偏好更长的回答。这些后面会专门讲怎么压制。2.3 eval 和 hillclimb 的关系先有尺子再量身高我见过太多人反过来做先疯狂调 prompt调到自己觉得差不多了再想怎么评估。结果就是没有基线不知道到底比原来好了还是差了。正确的顺序是先把尺子造出来再量身高。具体来说收集一批有代表性的真实输入我一般用 50 到 200 条太少不具统计意义太多跑起来慢。用 Claude 设计评分逻辑在这批数据上跑出基线分数。人工抽查一部分评分结果确认 Claude 的判断和你的直觉一致。确认尺子靠谱后才开始 hillclimb。这个顺序不能乱。尺子不准后面所有迭代都是白费。2.4 数据集怎么选才有代表性数据集的选择直接决定 eval 有没有用。我的做法是从真实日志里采样而不是自己编。编出来的 case 往往太干净、太典型跑出来的高分在真实场景里根本复现不了。采样时我会刻意覆盖几类高频常规 case占大头反映日常表现。边界 case比如超长输入、空输入、多语言混杂。已知难点 case之前人工发现模型容易翻车的那类。对抗 case故意设计来诱导模型出错的输入。这四类按大概 6:1:2:1 的比例混。高频 case 保证分数反映整体水平难点和对抗 case 保证 eval 有区分度——如果全是简单 case所有版本都满分hillclimb 就没意义了。3. 核心细节解析与实操要点3.1 评分 prompt 的写法把标准写成可执行的规则评分 prompt 是整个 eval 的心脏。我踩过的最大坑是一开始写得太笼统比如请判断这个回答好不好结果 Claude 给分非常随机。后来我总结出一套结构稳定很多你是一个严格的评审。请根据以下标准给回答打分。 【用户问题】 {question} 【模型回答】 {answer} 【评分维度】 1. 准确性1-5分 - 5分所有事实陈述都有依据无编造 - 3分主体正确但有1处细节存疑 - 1分存在明显事实错误或编造 2. 完整性1-5分 - 5分覆盖了问题的所有子问题 - 3分覆盖了主要部分遗漏次要内容 - 1分答非所问或严重遗漏 3. 表达质量1-5分 - 5分结构清晰无冗余 - 3分能读懂但有啰嗦或结构混乱 - 1分难以理解 【输出格式】 先逐维度给出分数和理由最后给出总分三个维度平均。几个关键点每个分数档都要有具体描述不能只写很好一般。Claude 需要锚点才能稳定判断。要求先写理由再给分。这个顺序很重要如果先给分再写理由Claude 容易先定分再找理由判断质量下降。输出格式固定方便后面用脚本解析。我一般让它输出 JSON解析起来最省事。3.2 用 JSON 输出让结果可解析自然语言的评分结果没法直接算平均分所以我会强制 Claude 输出结构化格式{ accuracy: {score: 4, reason: ...}, completeness: {score: 3, reason: ...}, expression: {score: 5, reason: ...}, total: 4.0 }实测下来只要在 prompt 里给一个明确的 JSON 模板Claude 的格式遵循率能到 95% 以上。偶尔有跑偏的加一句只输出 JSON不要有其他文字基本能压住。解析时我会加一层容错遇到解析失败的就重跑一次还失败就标记出来人工看。3.3 温度参数怎么设裁判要稳不要活这是很多人忽略的一点。当裁判的 Claude 应该用低温度我一般设 0 到 0.2。温度高了同一条回答两次评分可能差一分那你的 eval 就不可靠了。我做过对比测试温度 0.7 时同一批数据跑两遍总分平均差 0.4 分温度 0 时平均差 0.1 分以内。对于 hillclimb 来说0.4 分的波动足以淹没你辛苦调出来的真实提升所以低温度是必须的。另外如果预算允许我会对同一条数据跑 3 次取平均进一步降低波动。虽然成本翻三倍但在关键决策点上值得。3.4 压制裁判偏见长度偏见和位置偏见Claude 当裁判有两个已知偏见必须主动压制长度偏见它倾向于给更长的回答更高分哪怕长回答里全是废话。压制方法是在评分标准里明确写冗长但无信息量的内容应在表达质量上扣分并且在完整性维度里强调覆盖子问题而不是字数多。位置偏见做 A/B 对比时如果总是把 A 放前面Claude 会略微偏好 A。压制方法是交换顺序跑两遍A 在前跑一次B 在前跑一次两次结果综合。如果两次结论矛盾说明这两个版本差异不大别急着下结论。3.5 人工校准别让裁判自己说了算Claude 的评分再稳也得定期和人工对齐。我的做法是每周抽 20 条自己先盲评再和 Claude 的评分对比。如果某个维度上分歧超过 20%说明评分标准写得不够清楚要回去改 prompt。这个校准环节是很多人省掉的但它恰恰是 eval 可信度的来源。没有校准你永远不知道 Claude 的 4 分到底等于你心里的几分。4. 实操过程与核心环节实现4.1 搭一个最小可用的 eval 脚本下面是我常用的骨架用 Python 写调 Claude 的 API。这里只讲结构具体 key 用你自己的。import json import anthropic client anthropic.Anthropic() def score_one(question, answer): prompt f你是一个严格的评审...评分标准 resp client.messages.create( modelclaude-sonnet-4-5, max_tokens1024, temperature0, messages[{role: user, content: prompt}] ) text resp.content[0].text try: return json.loads(text) except json.JSONDecodeError: return None # 标记失败后面重跑 def run_eval(dataset): results [] for item in dataset: r score_one(item[question], item[answer]) if r is None: r score_one(item[question], item[answer]) # 重试一次 results.append(r) return results跑完之后算平均分就是你的基线。我一般会把每条明细存成 CSV方便后面分析。4.2 基线分数怎么读拿到基线分数后别急着看总分。先看分布。如果所有维度都是 4 到 5 分说明你的数据集太简单没有区分度得加难点 case。如果某个维度普遍低那就是明确的优化方向。我还会看方差。如果同一维度上分数忽高忽低说明模型表现不稳定可能对某类输入特别敏感。这时候要去看那些低分 case 有什么共性。4.3 hillclimb 的迭代节奏有了基线就可以开始爬坡了。我的节奏是这样的一次只改一个变量。改 prompt 就只改 prompt别同时换模型。否则分数变了你不知道是谁的功劳。每次改动跑完整 eval。不要只看几条 case 就下结论样本量不够会被噪声骗。记录每次改动和分数。我用一个表格记列是版本号、改动内容、各维度分数、总分。这样回头看能发现哪些改动真的有效。涨了就保留没涨就回退。听起来简单但很多人舍不得回退自己辛苦写的 prompt结果越堆越乱。4.4 一个真实的迭代记录拿我之前做的一个问答助手举例基线总分 3.2版本改动准确性完整性表达总分v0基线3.52.83.33.2v1prompt 里加了先列要点再展开3.53.43.53.5v2检索结果里加了来源标注3.93.43.53.6v3加了不确定就说不确定的指令4.13.33.43.6v4后处理去掉重复句4.13.33.83.7可以看到v1 主要提完整性v2 主要提准确性v3 准确性涨了但完整性略降因为模型更保守了v4 只动后处理就提了表达。每一步都能对应到具体维度这就是拆维度评分的好处。4.5 什么时候该停hillclimb 不是无限爬的。当连续两三次改动总分提升都小于 0.1 分时我就停了。这时候边际收益已经很低继续调不如去优化别的环节。另外如果某个维度已经接近满分比如 4.8再往上抠意义不大把精力放在低分维度上更划算。5. 常见问题与排查技巧实录5.1 评分结果波动大怎么办症状同一批数据跑两遍总分差 0.3 以上。排查顺序先确认温度是不是设成了 0。这是最常见的原因。检查评分标准里有没有模糊表述比如回答得好这种。有就改成具体规则。看是不是某些 case 本身就有歧义导致 Claude 每次理解不同。这类 case 要么删掉要么把标准写得更细。如果以上都排除了考虑跑 3 次取平均。5.2 Claude 总是给高分区分度不够症状所有版本都是 4 分以上看不出差异。原因评分标准太宽松或者数据集太简单。解决把每个维度的 5 分标准写得更苛刻比如5 分要求无任何可改进之处。同时往数据集里加对抗 case。我还会在 prompt 里加一句请严格打分不要因为回答整体不错就忽略细节问题实测能压下来 0.3 到 0.5 分。5.3 解析 JSON 老失败症状跑一批数据有 10% 以上解析不出来。解决prompt 里给完整的 JSON 模板包括字段名和嵌套结构。加一句只输出 JSON不要 markdown 代码块不要解释。解析前先做清洗去掉可能的前后文字。实在不行用正则从文本里抠出 JSON 部分。我现在的做法是解析失败就重跑一次重跑还失败就记下来人工处理。一般重跑能救回大半。5.4 分数涨了但实际体验没变好症状eval 分数从 3.2 涨到 3.8但用户反馈还是差不多。原因eval 数据集和真实分布不一致或者评分维度和用户真正在意的点不匹配。解决回去看真实日志找出用户抱怨最多的那类 case看它们在 eval 里占多少。如果占比很低说明数据集采样有偏。另外重新审视评分维度——也许用户在意的是响应速度或格式而你只评了内容质量。5.5 常见问题速查表问题可能原因快速排查分数波动大温度高/标准模糊温度设 0细化标准分数普遍偏高标准松/数据简单加严标准加对抗 caseJSON 解析失败格式约束不够给模板加只输出 JSON分数涨体验没变数据有偏/维度错位对齐真实日志重审维度某维度一直低该环节确实弱针对性改 prompt 或检索5.6 几个我踩过的坑坑一一开始就想做完美 eval。我花了三天设计了一套十几个维度的评分体系结果跑起来又慢又乱最后砍到三个维度反而好用。eval 要的是够用不是完备。坑二用同一个模型既生成又评分。这会有自我偏好模型倾向于给自己的输出高分。如果条件允许生成和评分用不同模型或者至少不同版本。坑三忽略成本。跑一次 eval 如果几百条数据、每条跑三次token 消耗不小。我一般先用小样本20 条快速验证改动方向方向对了再跑全量。坑四改了 prompt 不记录。有次我调了一周回头想复现最好的那版发现没记清楚改了啥。从那以后我每次改动都写进版本表包括改动的原文。6. 把 eval 和 hillclimb 变成日常习惯这套方法跑顺之后我把它变成了固定流程每周一跑基线周中做两三次迭代周五看一周的分数曲线。分数曲线比单次分数更有信息量——如果它整体向上说明方向对如果忽上忽下说明改动太随意或者 eval 不稳。有个细节值得说别把 eval 分数当成唯一目标。我见过有人为了刷分把 prompt 调得特别针对 eval 数据集结果真实场景反而变差。eval 是尺子不是终点。每次分数涨了我都会抽几条真实 case 人工看一眼确认不是应试涨分。另外eval 本身也要迭代。业务变了、用户关注点变了评分维度和数据集都得跟着更新。我大概每个月会重新采样一次数据集把过时的 case 换掉。尺子用久了会钝得定期磨。最后分享一个我常用的小技巧把每次 hillclimb 的改动和分数做成一张折线图横轴是版本纵轴是总分和各维度分。看着曲线往上爬比看一堆数字有成就感得多也更容易发现哪个维度是瓶颈。这个图我一般用 matplotlib 几行代码就画出来了跑完 eval 顺手生成复盘的时候特别直观。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑