AI TOOLS

EP02. "Prompt 评测工作流:从直觉判断到客观打分"

首页 › AI 工具 › Claude · Developer and Platform · Google Vertex AI · EP02
约 17 分钟· #EP02#Claude#Google Vertex AI
🔒 登录后可标记已读
  • Prompt engineering(怎么写好一个 prompt)跟 prompt evaluation(怎么客观量出这个 prompt 到底好不好)是两件事——写完一个 prompt 只手动测个一两次就上线,是最常见也最危险的做法,因为真实用户的提问方式远比你手动测的那几条更不可预测
  • 完整的评测流程有 5 步:写 prompt 草稿 → 准备一份测试数据集 → 把每条数据丢给 Claude 跑一遍 → 用 grader 给每个回答打分(1-10 分)→ 改 prompt 再跑一次、比较平均分——分数从 v1 的 7.66 涨到 v2 的 8.7,就是「这次修改真的有用」的客观证据,不是凭感觉
  • 测试数据集不用全靠手写,可以让 Claude(用 Haiku 这类快模型)自动生成,省下大量人工造数据的时间
  • Grader(打分器)分三种:Code Grader(程序化检查格式/语法)、Model Grader(再调一次 API 让 Claude 评分)、Human Grader(人工审核,最灵活但最花时间)——实务上常把 Code Grader 和 Model Grader 的分数平均起来用
  • 前置知识:EP01 的 chat()/messages 基础调用、prefill + stop sequence 拿干净 JSON 的手法

重点内容


为什么不能只靠手动测一两次

Prompt 写完之后,一般会走三条路:

做法风险
只测一次就假设没问题上线后大概率翻车,生产环境风险最高
针对几个已知边界情况多测几次还是覆盖不到真实用户会怎么问
系统化跑评测 pipeline、拿客观分数前期投入更多,但能确定改动是真的有进步,不是运气

前两种是最容易掉进去的陷阱——自己测的那几条问题永远不够代表真实用户会怎么提问。第三种虽然要多花功夫搭 pipeline,但拿到的是可以量化比较的客观数据,能让 prompt 真正做到「production-ready」。


完整评测流程:5 步

Step 1:写一个 prompt 草稿

prompt = f"""
Please answer the user's question:

{question}
"""

Step 2:准备一份评测数据集

准备一组有代表性的测试输入,例如「2+2 等于多少」「怎么煮燕麦粥」「月球有多远」这三条问题。

Step 3:把每条数据丢给 Claude 跑一遍

把数据集里每一题套进 prompt 模板发给 Claude,收集「问题 - 回答」这组配对。

Step 4:用 grader 给每个回答打分

一般用 1-10 分制,例如「10 分 = 完美答案,没有改进空间」「4 分 = 及格但明显有改进空间」,然后把所有回答的分数取平均,得到一个客观的整体分数。

Step 5:改 prompt、重跑一次

例如把 prompt 改成多加一句「回答要有足够的细节」,重新跑一次评测流程。

📌 两次评测的平均分可以直接比较——课程示范里 v1 拿到 7.66 分,加了一句「回答要更详细」的 v2 拿到 8.7 分,这个分数差距就是「这次修改确实有效」的客观证据,不用靠直觉猜。


准备测试数据集:让 Claude 帮你自动生成

数据集可以手写,也可以让 Claude 自动生成——用 Haiku 这类速度快的模型来生成测试数据比较划算。

以「生成 AWS 相关的 Python 代码 / JSON 配置 / 正则表达式」这个场景为例,先定义目标 prompt:

prompt = f"""
Please provide a solution to the following task:
{task}
"""

再写一个专门生成数据集的函数,让 Claude 输出一组 JSON 格式的任务描述:

def generate_dataset():
    prompt = """
    Generate an evaluation dataset for a prompt evaluation. The dataset will be used to evaluate prompts
    that generate Python, JSON, or Regex specifically for AWS-related tasks. Generate an array of objects,
    each representing task that requires Python, JSON, or a Regex to complete.

    Example output:

[ { "task": "Description of task", }, ...additional ]

* Focus on tasks that can be solved by writing a single Python function, a single JSON object, or a single regex
* Focus on tasks that do not require writing much code

Please generate 3 objects.
"""

messages = []
add_user_message(messages, prompt)
add_assistant_message(messages, "```json")
text = chat(messages, stop_sequences=["```"])
return json.loads(text)

💡 这里又是 EP01 那招「prefill \\\json + stop sequence \\\`」——生成数据集本身也要拿干净的 JSON,不要让 Claude 多加解释文字。

存成文件,之后每次评测直接读这份数据,不用每次重新生成:

dataset = generate_dataset()

with open('dataset.json', 'w') as f:
    json.dump(dataset, f, indent=2)

跑评测 Pipeline:三个核心函数

run_prompt:把 prompt 模板和测试数据的输入合并,发给 Claude,拿回结果。

run_test_case:单条测试的执行入口,调用 run_prompt 拿输出、再交给 grader 打分——课程在还没实现真正的 grader 前,先用写死的 10 分当占位。

run_eval:读取整份数据集,对每一条都调用 run_test_case,把所有结果收集成一个列表。

结果的结构是每条测试案例对应一个对象,包含三个字段:

{
    "output": "Claude 的完整回答",
    "test_case": "原始测试输入",
    "score": "评分"
}

📌 即使用速度快的 Haiku,跑完一整份数据集大概也要 30 秒左右——数据集越大、评测就越花时间,这是要考虑的实际成本。这个阶段因为还没给 prompt 加任何格式要求,Claude 的回答会偏冗长,这个问题会在后面的 grading 实现里一并处理。


三种打分方式怎么选

Grader 收到模型的输出后,返回一个可衡量的分数(通常 1-10 分,10 分代表高质量,1 分代表低质量):


方法怎么选

方法适合场景备注
Code Grader格式/语法能被程序判断对错的场景检查长度、关键字、JSON/Python/正则语法是否合法、可读性
Model Grader需要判断「答得好不好」这种主观质量的场景多花一次 API 调用,能评估是否遵循指令、内容完不完整、有没有帮助、安不安全
Human Grader前两者都判断不了、需要人工经验的场景最灵活,但最花时间,不适合大批量跑

在动手写 grader 之前,先定清楚评分标准——针对生成代码这类任务,通常看三件事:格式对不对、语法合不合法、内容是否真的解决了这个任务。


Model Grader:再叫一次 Claude 来评分

Model grader 的核心思路是另外写一个评分用的 prompt,让 Claude 针对「这个回答有没有达标」给出结构化的评分结果:

def grade_by_model(test_case, output):
    messages = []
    add_user_message(messages, eval_prompt)
    add_assistant_message(messages, "```json")
    eval_text = chat(messages, stop_sequences=["```"])
    return json.loads(eval_text)

📌 课程页面没有完整展示 eval_prompt 这段评分提示词的具体文字,只讲了它该包含的内容方向:把测试案例和 Claude 的输出都交代清楚,要求 Claude 给出结构化的 JSON(至少包含分数和理由)。

💡 让 Model Grader 除了给分数,也要给出理由(strengths / weaknesses / reasoning)——只要一个数字,Claude 评分容易缩在中间值敷衍了事,要求写理由能逼它认真判断。

接进完整的评测流程:

def run_test_case(test_case):
    output = run_prompt(test_case)
    model_grade = grade_by_model(test_case, output)
    score = model_grade["score"]
    reasoning = model_grade["reasoning"]

    return {
        "output": output,
        "test_case": test_case,
        "score": score,
        "reasoning": reasoning
    }

from statistics import mean

def run_eval(dataset):
    results = []
    for test_case in dataset:
        result = run_test_case(test_case)
        results.append(result)

    average_score = mean([result["score"] for result in results])
    print(f"Average score: {average_score}")

    return results

Code Grader:用程序检查格式对不对

针对代码生成类任务,Code Grader 验证两件事:格式(Format)和语法是否合法(Valid Syntax),再搭配 Model Grader 判断内容是否真的解决了任务。

Python / JSON / 正则各自的语法校验函数:

def validate_json(text):
    try:
        json.loads(text.strip())
        return 10
    except json.JSONDecodeError:
        return 0

def validate_python(text):
    try:
        ast.parse(text.strip())
        return 10
    except SyntaxError:
        return 0

def validate_regex(text):
    try:
        re.compile(text.strip())
        return 10
    except re.error:
        return 0

语法合法给 10 分,解析失败给 0 分。

测试数据集的每条案例要额外标注期望的输出格式(task + format 两个字段),程序才知道该用哪个校验函数。


合并两种分数

最后把 Code Grader 和 Model Grader 的分数取平均,让「内容质量」和「技术正确性」各占一半权重——权重也可以按实际需求调整,不是一定要对半分。

📌 有了 Code Grading 提供的这个量化基线分数,改 prompt 前后的进步幅度才有客观数字可以比较,不用只靠主观感觉判断「这次改动好像有帮助」。

Sources

官方文档:

  1. Claude with Google Cloud's Vertex AI(Claude Academy 课程)— https://academy.claude.com/courses/claude-with-google-cloud-s-vertex-ai