news 2026/10/3 5:38:36

用Claude辅助设计AI应用eval:从60分迭代到90分的实战指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
用Claude辅助设计AI应用eval:从60分迭代到90分的实战指南

1. 为什么我要用 Claude 来设计 eval,而不是手写测试用例

做 AI 应用开发的人都有一个共同的痛点:模型输出不稳定,今天跑得好好的 prompt,明天换个输入就崩了。你改了一版 prompt,感觉效果好了,但到底好了多少?说不清楚。更麻烦的是,你改好了 A 场景,结果 B 场景又退化了,而你根本不知道。

这就是 eval 存在的意义。eval 不是单元测试,它更像是一套“评分标准 + 自动化裁判”,让你每次改动之后能快速知道:分数涨了还是跌了,哪个维度涨了,哪个维度跌了。

但问题来了——写 eval 本身就是一件很痛苦的事。你得设计测试集、定义评分维度、写评分逻辑、处理边界情况。传统做法是人工写一堆规则或者正则,费时费力,而且覆盖不全。

我用 Claude 来做这件事,核心思路是:让 Claude 帮我生成 eval 的骨架和评分维度,我再基于实际 badcase 一轮轮迭代,把分数从 60 分推到 90 分以上。这个过程在圈子里叫 hillclimb,就是爬山——每一步都往高处走一点,最终爬到局部最优。

这篇文章适合谁看?如果你正在做 AI 应用(不管是对话、写作、代码生成还是 RAG),并且想让效果可量化、可迭代,那这套方法你可以直接抄作业。如果你还没开始做 eval,看完这篇你至少知道从哪下手。

2. 整体设计思路:先让 Claude 帮你把 eval 框架搭起来

2.1 eval 的本质是什么

很多人一上来就想写一个“完美的评分函数”,结果卡在第一步。我的经验是:eval 不是一次写完的,它是长出来的。

你一开始只需要一个粗糙的评分框架,能跑通就行。然后拿真实数据去跑,看哪些 case 得分低,分析为什么低,再补规则、补维度、补测试用例。每一轮迭代,eval 就更准一点,模型效果也更好一点。

Claude 在这个过程中的角色是:帮你快速生成第一版框架,帮你分析 badcase 的原因,帮你写评分逻辑的代码。它不是替你思考,而是替你省掉那些重复劳动。

2.2 为什么选 Claude 而不是别的模型

我试过几个模型来做这件事,最后选 Claude 的原因很实际:

  • 长上下文理解稳:eval 设计经常需要把一堆 badcase、评分标准、历史迭代记录一起丢进去,Claude 在长文本里抓重点的能力比较靠谱。
  • 代码生成质量高:评分函数很多时候就是一段 Python,Claude 写出来的代码结构清晰,边界处理也比较到位。
  • 指令遵循好:你让它“按这个格式输出评分维度”,它不会给你自由发挥。

当然,这不是说别的模型不行。核心是你要有一个能稳定输出结构化内容的模型来辅助你设计 eval,Claude 在我这里表现最好。

2.3 整体流程长什么样

我把整个流程拆成五步,后面会一步步展开:

  1. 定义评分维度:让 Claude 根据你的任务描述,生成 3-5 个核心评分维度。
  2. 生成测试集骨架:让 Claude 生成一批覆盖不同场景的测试输入。
  3. 写评分逻辑:让 Claude 生成评分函数的代码框架。
  4. 跑第一轮,收集 badcase:拿真实数据跑,看哪些 case 得分低。
  5. 迭代 hillclimb:分析 badcase,补规则、补维度、补测试用例,重复第 4 步。

这个流程看起来简单,但每一步都有坑。下面我逐个拆。

3. 核心细节解析:评分维度怎么定,测试集怎么造

3.1 评分维度的设计原则

评分维度是 eval 的灵魂。维度定错了,后面怎么迭代都是白费。

我一般遵循三个原则:

第一,维度要正交。比如你做的是客服对话,那“回答准确性”和“语气友好度”是两个独立维度,不要混在一起。混在一起的结果是,你不知道分数低是因为答错了还是因为语气差。

第二,维度要可判定。“回答得好不好”这种维度没法判定,因为太主观。你要拆成“是否包含关键信息点”、“是否出现事实错误”、“是否超出规定长度”这种可以明确判断的。

第三,维度不要超过 5 个。超过 5 个之后,权重分配会变得很纠结,而且迭代时很难定位问题。3-5 个是最舒服的区间。

我一般会让 Claude 先根据任务描述生成一版维度,然后我自己再调。比如我给它这样的 prompt:

我在做一个技术文档问答系统,用户问技术问题,系统从文档里找答案并生成回答。 请帮我设计 4 个评分维度,要求: 1. 每个维度可以独立打分(1-5 分) 2. 维度之间尽量正交 3. 每个维度给出明确的判定标准 4. 输出格式:维度名称 | 判定标准 | 1分示例 | 5分示例

Claude 返回的结果通常可以直接用,我只需要微调判定标准的措辞。

3.2 测试集怎么造才有效

测试集不是越多越好,而是越有代表性越好。我见过有人造了 500 条测试用例,结果 400 条都是同一个场景的变体,跑出来的分数根本没有区分度。

我的做法是:先按场景分类,每个场景造 5-10 条,覆盖正常 case、边界 case、badcase。

让 Claude 生成测试集的时候,我会给它一个场景列表,让它按场景生成。比如:

请为以下 5 个场景各生成 8 条测试输入: 1. 简单事实查询(答案在文档中直接能找到) 2. 需要跨段落推理的问题 3. 文档中没有答案的问题(应该拒答) 4. 问题有歧义,需要澄清 5. 用户输入包含错别字或口语化表达 输出格式:场景编号 | 测试输入 | 预期行为

这样造出来的测试集,覆盖度比随机生成高得多。

3.3 评分逻辑的代码框架

评分逻辑我一般分两种:规则评分和模型评分。

规则评分适合那些可以明确判断的维度,比如“是否包含关键信息点”、“是否超出长度限制”。模型评分适合那些需要理解的维度,比如“回答是否流畅”、“逻辑是否连贯”。

Claude 帮我写评分代码的时候,我会让它把两种评分分开:

def rule_based_score(response, expected_keywords, max_length): score = 0 # 关键信息点覆盖 covered = sum(1 for kw in expected_keywords if kw in response) score += (covered / len(expected_keywords)) * 3 # 长度合规 if len(response) <= max_length: score += 2 return score def model_based_score(response, question, client): prompt = f"请对以下回答的流畅度打分(1-5分):\n问题:{question}\n回答:{response}\n只输出分数。" result = client.messages.create( model="claude-sonnet-4-20250514", max_tokens=10, messages=[{"role": "user", "content": prompt}] ) return float(result.content[0].text.strip())

这个框架跑通之后,你就可以开始第一轮迭代了。

注意:模型评分会有波动,同一个回答跑两次可能分数不一样。我的做法是跑 3 次取平均,或者用 temperature=0 来降低波动。

4. 实操过程:从 60 分爬到 90 分的完整记录

4.1 第一轮:跑通流程,拿到基线分

第一轮的目标不是高分,而是跑通。我把测试集跑了一遍,得到每个维度的平均分:

维度平均分最低分场景
关键信息覆盖3.2跨段落推理
事实准确性3.8歧义问题
拒答合理性2.5无答案问题
回答流畅度4.1口语化输入

总分 60 分左右。这个分数很正常,第一轮能跑通就不错了。

关键是要看 badcase。我把得分低于 3 分的 case 全部拉出来,让 Claude 帮我分析原因:

以下是 10 条低分 case,请帮我归类,并指出每一类的主要问题是什么。 输出格式:问题类别 | 涉及 case 编号 | 主要原因 | 改进建议

Claude 返回的结果很有用。比如它指出“拒答合理性”低分的主要原因是:模型在文档中没有答案时,倾向于编造一个看起来合理的答案,而不是明确说“文档中没有相关信息”。

4.2 第二轮:针对 badcase 补规则

知道了原因,改起来就有方向了。我做了三件事:

第一,在 prompt 里加拒答指令。明确告诉模型:“如果文档中没有找到答案,必须回答‘根据现有文档无法回答该问题’,不要编造。”

第二,在评分逻辑里加惩罚项。如果模型编造了文档中不存在的信息,直接扣分。

第三,补充测试用例。针对“文档中没有答案”这个场景,我又加了 10 条测试输入,覆盖不同类型的无答案问题。

改完之后再跑一轮,分数变化:

维度第一轮第二轮变化
关键信息覆盖3.23.5+0.3
事实准确性3.84.0+0.2
拒答合理性2.53.8+1.3
回答流畅度4.14.10

总分从 60 涨到 72。拒答维度涨得最多,因为问题最明确。

4.3 第三轮:优化跨段落推理

第二轮之后,最低分变成了“跨段落推理”场景。这个场景的问题是:答案分散在文档的不同段落里,模型只找到了一部分。

我的改进方法是:

在 prompt 里加“先检索再回答”的步骤。让模型先把相关段落全部列出来,再基于这些段落生成回答。这样能减少遗漏。

在评分逻辑里加“信息点覆盖完整性”检查。对于跨段落问题,我手动标注了每个问题应该覆盖的信息点,评分时检查覆盖了几个。

这一轮改动比较大,我让 Claude 帮我重新生成了 prompt 模板:

你是一个技术文档问答助手。请按以下步骤回答: 第一步:从文档中找出所有与问题相关的段落,列出来。 第二步:基于这些段落,生成一个完整的回答。 第三步:检查回答是否覆盖了所有相关段落中的关键信息。 如果文档中没有相关段落,直接回答“根据现有文档无法回答该问题”。 问题:{question} 文档:{document}

再跑一轮,跨段落推理场景的分数从 2.8 涨到 4.2。总分到了 81。

4.4 第四轮:处理口语化和错别字

第三轮之后,剩下的低分 case 主要集中在口语化输入和错别字上。比如用户输入“这个咋弄啊”,模型有时候会理解偏差。

我的做法是:在预处理阶段加一层输入规范化。让 Claude 帮我把口语化输入转成标准问法,再走后面的流程。

这一步的评分逻辑也要调整:如果模型对口语化输入的回答和对标准问法的回答一致,就给高分。

这一轮涨分不多,从 81 涨到 85。但这一步很关键,因为真实用户输入就是口语化的,不处理的话线上效果会很差。

4.5 第五轮:微调评分权重

到第四轮之后,分数已经比较高了,但我觉得评分权重不太合理。比如“回答流畅度”占了 25% 的权重,但实际上这个维度对用户体验的影响没那么大。

我重新分配了权重:

维度原权重新权重理由
关键信息覆盖30%35%最重要
事实准确性25%30%第二重要
拒答合理性20%20%保持不变
回答流畅度25%15%降低权重

重新算分之后,总分到了 88。再补了几条边界 case,最终稳定在 91 分左右。

5. 常见问题与排查技巧实录

5.1 评分波动太大怎么办

这是最常见的问题。同一个回答,跑两次分数不一样。原因通常是模型评分那部分不稳定。

解决方法:

  • 固定随机种子:如果用的 API 支持,设置 temperature=0。
  • 多次取平均:跑 3 次取平均分,成本不高但效果明显。
  • 规则优先:能规则判定的维度尽量用规则,减少模型评分的比例。

5.2 分数涨了但线上效果没变好

这种情况通常是 eval 和真实场景脱节了。你的测试集不能代表真实用户输入。

解决方法:定期从线上日志里采样真实 case,补充到测试集里。我一般每周补 20 条,保持测试集的时效性。

5.3 Claude 生成的评分维度不适用

有时候 Claude 生成的维度太抽象,没法落地。比如它给你一个“回答质量”维度,你根本没法打分。

解决方法:在 prompt 里明确要求可判定。加上“每个维度必须能用 1-5 分明确判定,不能有主观模糊空间”这句话,效果会好很多。

5.4 迭代到后面涨不动了

这是 hillclimb 的典型问题:爬到局部最优了。分数卡在 85 左右,怎么改都不涨。

这时候有两个选择:

  • 换方向:不是继续优化 prompt,而是换模型、换检索策略、换预处理方式。
  • 接受现状:85 分可能已经够用了,继续投入产出比不高。

我的经验是,如果连续三轮迭代涨分不超过 2 分,就该考虑换方向了。

5.5 常见问题速查表

问题可能原因解决方法
评分波动大模型评分不稳定设 temperature=0,多次取平均
分数涨线上不涨测试集脱节从线上采样补充测试集
维度没法判定维度太抽象重新生成,要求可判定
迭代涨不动局部最优换方向或接受现状
拒答维度低分模型爱编造prompt 加拒答指令,评分加惩罚
跨段落漏信息检索不完整先检索再回答,分步执行

实操心得:每次迭代只改一个变量。如果你同时改了 prompt 和评分逻辑,分数涨了你不知道是哪个起的作用。一次只改一个,跑完看结果,再改下一个。

6. 工具选型与 Claude API 的实操配置

6.1 为什么我用 Claude API 而不是网页版

网页版适合探索,但 eval 迭代需要批量跑、需要程序化调用、需要记录每次的结果。这些网页版都做不了。

Claude API 的配置很简单,核心就是三行:

import anthropic client = anthropic.Anthropic(api_key="your-api-key") response = client.messages.create( model="claude-sonnet-4-20250514", max_tokens=1024, messages=[{"role": "user", "content": "你的 prompt"}] )

我一般会把评分逻辑封装成一个函数,输入是测试集,输出是每个 case 的分数和总分。这样每次迭代只需要改 prompt 或评分逻辑,然后重新跑一遍就行。

6.2 批量跑 eval 的脚本结构

我的脚本一般长这样:

import json from anthropic import Anthropic client = Anthropic(api_key="your-api-key") def load_test_cases(path): with open(path) as f: return json.load(f) def run_eval(test_cases, prompt_template): results = [] for case in test_cases: # 生成回答 prompt = prompt_template.format(question=case["question"], document=case["document"]) response = client.messages.create( model="claude-sonnet-4-20250514", max_tokens=1024, temperature=0, messages=[{"role": "user", "content": prompt}] ) answer = response.content[0].text # 评分 score = score_answer(answer, case) results.append({"case_id": case["id"], "answer": answer, "score": score}) return results def score_answer(answer, case): # 规则评分 + 模型评分 rule_score = rule_based_score(answer, case["expected_keywords"], case["max_length"]) model_score = model_based_score(answer, case["question"]) return rule_score * 0.6 + model_score * 0.4 if __name__ == "__main__": cases = load_test_cases("test_cases.json") results = run_eval(cases, PROMPT_TEMPLATE) total = sum(r["score"] for r in results) / len(results) print(f"总分:{total:.2f}") # 保存结果 with open("eval_results.json", "w") as f: json.dump(results, f, ensure_ascii=False, indent=2)

这个脚本跑一次大概几分钟,成本取决于测试集大小和模型选择。我一般用 Sonnet 跑 eval,性价比比较高。

6.3 成本控制的小技巧

eval 跑多了成本会上去。我的控制方法是:

  • 测试集控制在 100 条以内:太多没必要,100 条足够有代表性。
  • 评分用便宜模型:生成回答用 Sonnet,评分可以用 Haiku,成本低很多。
  • 缓存结果:同一个 case 跑过了就缓存,不要重复跑。

注意:评分模型和生成模型最好分开。用同一个模型评分会有偏差,因为它倾向于给自己生成的回答打高分。

7. 迭代过程中的经验与避坑指南

7.1 不要追求一步到位

我见过有人想一次性设计一个完美的 eval,结果花了两个月还没跑通第一轮。正确的做法是:先跑通,再优化。第一版 eval 哪怕只有 60 分,也比没有强。

7.2 badcase 要分类,不要逐个改

低分 case 可能有几十条,你不可能逐个改。正确做法是让 Claude 帮你归类,然后按类别改。改一类,跑一轮,看分数变化。

7.3 评分逻辑要可解释

如果你的评分逻辑是一个黑盒,分数涨了你不知道为什么涨,跌了也不知道为什么跌。我的做法是:每个维度单独输出分数,这样你能看到是哪个维度在变化。

7.4 定期回顾测试集

测试集会过时。三个月前的测试集可能已经不能代表现在的用户输入了。我一般每个月回顾一次,删掉过时的 case,补充新的 case。

7.5 记录每次迭代的变化

这个习惯很重要。我每次迭代都会记录:改了什么、分数变化、badcase 变化。这样回头看的时候,你能清楚地知道哪次改动最有效。

迭代轮次改动内容总分变化关键发现
第一轮跑通流程60拒答维度最低
第二轮加拒答指令72拒答涨 1.3 分
第三轮先检索再回答81跨段落涨 1.4 分
第四轮输入规范化85口语化场景改善
第五轮调整权重88分数更合理
补充边界 case91稳定在 91 左右

这个表格是我实际迭代的记录,你可以参考这个格式来记录自己的迭代过程。

7.6 一个容易被忽略的细节

评分的时候,不要只看平均分,要看分布。平均分 85 可能是所有 case 都在 85 左右,也可能是 50 条 100 分加 50 条 70 分。后者的问题更大,因为有一半的 case 效果很差。

我一般会看三个数:平均分、最低分、标准差。标准差太大说明效果不稳定,需要重点排查。

8. 后续可以怎么扩展

这套方法跑通之后,可以往几个方向扩展:

第一,自动化迭代。把“分析 badcase → 生成改进方案 → 跑 eval → 看分数”这个流程自动化,让 Claude 自己迭代。当然,关键决策还是要人来把关。

第二,多模型对比。同一套 eval,跑不同模型,看哪个模型在你的场景下效果最好。这个对比结果很有参考价值。

第三,eval 即文档。你的 eval 测试集和评分维度,其实就是你对“好回答”的定义。把它整理成文档,新加入的团队成员一看就懂。

第四,接入 CI/CD。每次改 prompt 或改模型,自动跑一遍 eval,分数跌了就报警。这样能防止退化。

我个人在实际操作中的体会是:eval 的价值不在于分数本身,而在于它强迫你把“什么是好”想清楚。你想不清楚,模型就更想不清楚。用 Claude 来辅助设计 eval,本质上是借它的语言能力帮你把模糊的标准具象化,然后你在这个基础上迭代。这个过程跑一轮下来,你对业务的理解会比之前深很多。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/3 5:38:34

SAP固定资产模块操作指南:资产卡片到采购收货全流程

简介&#xff1a;SAP固定资产&#xff08;FI-AA&#xff09;模块用户操作手册&#xff0c;面向企业财务人员、SAP系统管理员及实施顾问&#xff0c;也适合建筑地产、金融商贸等需长期资产管理背景的从业者。先从折旧表设置与资产类别管理讲起&#xff0c;系统讲解固定资产、无形…

作者头像 李华
网站建设 2026/10/3 5:38:31

小红书笔记合规解析方案:飞书+Coze零代码自动化流程

1. 这不是“爬虫”&#xff0c;而是小红书内容运营的合规新路径最近帮三个做美妆垂类的品牌方做内容复盘&#xff0c;他们共同卡在一个死结上&#xff1a;想批量分析自己账号下上百条笔记的标题风格、评论情绪、发布时间规律&#xff0c;甚至想看看竞品爆款图的构图共性——但所…

作者头像 李华
网站建设 2026/10/3 5:37:12

AI引用与搜索收录双轨核验:可复查台账与实操清单

1. 为什么“被AI引用”和“被搜索引擎收录”是两码事很多人第一次听到“AI引用”这个词&#xff0c;下意识会把它等同于“被搜索引擎收录”。我一开始也这么想&#xff0c;直到自己运营的一个技术博客出现了诡异现象&#xff1a;Google、Bing 搜品牌词都能搜到&#xff0c;收录…

作者头像 李华
网站建设 2026/10/3 5:36:27

Oracle数据库课程设计实战:从选题到答辩的完整指南

简介&#xff1a;这份资源是面向高校数据库课程学习者与IT专业学生的Oracle课程设计完整报告&#xff0c;以「学生考勤系统」为实践案例&#xff0c;帮助读者掌握从需求分析到数据库落地的全流程设计方法。压缩包内仅含1个doc文档&#xff0c;约227KB&#xff0c;内容涵盖背景分…

作者头像 李华
网站建设 2026/10/3 5:35:53

从“PDF聊天”到知识库治理:版本、分块、混合检索与引用实践

我最早做知识库的时候&#xff0c;跟大多数人一样&#xff0c;以为 RAG 就是把 PDF 传上去、问几个问题、拿到回答就完事了。等真正用了三个月&#xff0c;我发现这个“聊天”模式根本扛不住真实场景&#xff1a;文档更新了&#xff0c;老版本还在回答&#xff1b;一个完整方案…

作者头像 李华