本文最后更新于 2026-07-30,文章内容可能已经过时。

别急着切新模型:先用20个历史任务,做一轮真正有效的影子测试

新模型上线当天,最容易发生的误判是:榜单更高、单价更低,于是默认模型直接切换。

但真实业务最怕的,从来不是模型在某个公开基准上少拿几分,而是原本稳定运行的任务突然开始漏字段、改格式、忘条件。输出看起来甚至更流畅,直到下游程序报错,团队才发现这次“升级”其实是一次生产风险。

新模型不是普通的软件更新。换模型,更像给一支已经配合成熟的团队换了一名新同事:简历可能更漂亮,但能不能接住你的具体工作,必须试岗。

这篇文章只解决两个问题:

1. 旧任务的质量有没有回退?

2. 完成同样任务,实际要花多少钱?

不讨论跑分、上下文窗口等外围指标,也不拿公开榜单替你做业务决策。

需要先说明:由于本文没有绑定某一组可公开验证的模型调用日志,下面不会虚构胜负数量、Token费用和成功率。文中的20任务清单、评分表和成本表,是一套可以直接填入真实结果的测试模板;示例输出仅用于解释判分规则,不代表任何具体模型的真实表现。

一、为什么榜单和标价都不能直接回答“该不该切”

公开基准通常测试的是标准化能力,而你的业务可能关心完全不同的细节。

例如,一项内容抽取任务要求:

  • 只能输出合法 JSON
  • 固定包含6个字段
  • 缺失信息必须填写 null
  • 禁止根据常识补全
  • 日期统一转换为 YYYY-MM-DD

新模型可能写得更自然、分析得更充分,却擅自增加解释文字,或者把不知道的日期“合理推测”出来。站在聊天体验的角度,它似乎更聪明;站在生产系统的角度,这就是一次失败。

价格也一样。

供应商展示的通常是输入、输出Token单价,但业务真正承担的是:

单任务有效成本 = 首次调用成本 + 重试成本 + 修复调用成本

如果新模型输出更长,或者格式失败后需要重新调用,那么“单价更低”不一定意味着“任务成本更低”。

因此,模型切换不能从价格表开始,而应该从过去真正完成过的任务开始。

二、如何搭建20个历史任务的影子测试集

所谓影子测试,就是让新旧模型在相同条件下并行执行任务,但新模型的结果暂时不返回给线上用户。

测试时至少固定以下变量:

  • 完全相同的提示词与上下文
  • 相同的温度、最大输出长度
  • 相同的工具权限与系统提示词
  • 相同的提示词版本
  • 尽量接近的测试时间
  • 接口支持时固定 Seed
  • 波动较大的任务,每个模型重复运行3次

最关键的一点是:不要为了测试新模型而临时出题。

临时题很容易无意中偏向某个模型。更可靠的方法,是从近期真实请求中抽取20个已经完成、并且知道合格答案长什么样的任务。

20个任务抽样清单

下表不是虚构的模型成绩,而是一份抽样配额。实际使用时,应将“输入长度”替换为接口返回的真实输入Token数,并补充脱敏后的历史请求编号。

| 编号 | 任务类型 | 难度 | 建议输入长度 | 输出要求 | 硬格式约束 | 选择原因 | |---|---|---:|---:|---|---|---| | T01 | 信息提取 | 简单 | 500—1000 Token | 提取姓名、日期、金额 | 是 | 检查基础字段完整性 | | T02 | 信息提取 | 中等 | 1000—3000 Token | 多实体关系抽取 | 是 | 检查实体混淆 | | T03 | 信息提取 | 困难 | 3000 Token以上 | 跨段落证据归并 | 是 | 检查长文本遗漏 | | T04 | 内容总结 | 简单 | 1000—2000 Token | 生成5条要点 | 否 | 检查压缩能力 | | T05 | 内容总结 | 中等 | 3000 Token以上 | 按主题分组总结 | 是 | 检查结构遵循 | | T06 | 内容总结 | 困难 | 5000 Token以上 | 保留结论与风险项 | 是 | 检查关键信息召回 | | T07 | 改写润色 | 简单 | 500 Token以内 | 调整为专业语气 | 否 | 检查语言质量 | | T08 | 改写润色 | 中等 | 1000 Token左右 | 保留事实与专有名词 | 是 | 检查是否擅自改写事实 | | T09 | 结构化输出 | 简单 | 500—1000 Token | 输出固定JSON | 是 | 检查语法合法性 | | T10 | 结构化输出 | 中等 | 2000 Token左右 | 输出嵌套JSON | 是 | 检查字段与类型 | | T11 | 结构化输出 | 困难 | 3000 Token以上 | 多对象数组与空值处理 | 是 | 检查复杂Schema遵循 | | T12 | 复杂指令 | 中等 | 1000—2000 Token | 同时满足6项限制 | 是 | 检查约束遗漏 | | T13 | 复杂指令 | 困难 | 3000 Token以上 | 条件分支与例外规则 | 是 | 检查规则冲突处理 | | T14 | 推理分析 | 简单 | 500—1000 Token | 给出结论与依据 | 否 | 检查基础推理 | | T15 | 推理分析 | 中等 | 2000 Token左右 | 对比多个方案 | 是 | 检查证据对应关系 | | T16 | 推理分析 | 困难 | 3000 Token以上 | 多条件决策 | 是 | 检查隐藏假设 | | T17 | 代码生成 | 简单 | 500 Token以内 | 编写独立函数 | 是 | 检查可执行性 | | T18 | 代码生成 | 中等 | 1000—2000 Token | 调用指定接口 | 是 | 检查接口约束 | | T19 | 代码修复 | 困难 | 2000 Token以上 | 定位并修复错误 | 是 | 检查改动范围 | | T20 | 综合任务 | 困难 | 3000 Token以上 | 分析、生成并结构化输出 | 是 | 检查端到端稳定性 |

这20个任务不需要完美代表全部业务,但至少要同时覆盖:

  • 高频任务
  • 高价值任务
  • 容错率极低的关键任务
  • 曾经发生过事故的任务
  • 简单、中等、困难三个层级

尤其不要用20个相似的总结任务充数。任务类型的多样性,比样本数量看起来整齐更重要。

三、质量评测:先查硬伤,再谈“谁写得更好”

模型输出的质量,应分成两层。

第一层:硬指标

硬指标通常可以直接判定通过或失败:

  • JSON是否可以解析
  • 字段是否齐全
  • 数据类型是否正确
  • 是否遗漏明确条件
  • 是否出现无来源事实
  • 代码是否可以运行
  • 是否违反长度、格式或禁用词要求

第二层:软评分

只有硬指标通过后,才比较:

  • 表达是否清晰
  • 结构是否合理
  • 逻辑是否完整
  • 是否简洁
  • 风格是否符合业务要求

如果一个输出文字更漂亮,却漏掉关键字段,就不应该通过平均分“补回来”。

新旧模型质量记录表

| 任务 | 旧模型得分 | 新模型得分 | 旧模型硬指标 | 新模型硬指标 | 盲评胜负 | 回退原因 | 关键业务 | |---|---:|---:|---|---|---|---|---| | T01 | 待实测 | 待实测 | 待填 | 待填 | 待评 | 待记录 | 否 | | T02 | 待实测 | 待实测 | 待填 | 待填 | 待评 | 待记录 | 是 | | T03 | 待实测 | 待实测 | 待填 | 待填 | 待评 | 待记录 | 是 | | T04—T08 | 分任务填写 | 分任务填写 | 分任务填写 | 分任务填写 | 盲评 | 记录具体原因 | 按业务标记 | | T09—T13 | 分任务填写 | 分任务填写 | 分任务填写 | 分任务填写 | 盲评 | 重点检查格式和约束 | 通常是 | | T14—T20 | 分任务填写 | 分任务填写 | 分任务填写 | 分任务填写 | 盲评 | 检查推理、代码与综合能力 | 按业务标记 |
不要只计算平均分。最终报告必须同时展示:新模型回退任务数、硬指标失败数,以及关键业务任务失败数。

三类最值得关注的输出

以下案例用于说明判分方式,不归因于任何具体模型。

#### 案例一:新模型确实带来了实际价值

完整提示词:

请根据下面的会议记录生成决策摘要。

要求:

1. 只保留已经确定的决策,不写讨论过程;

2. 每条包含负责人、截止时间和交付物;

3. 未明确的信息写“待确认”,不得自行补充;

4. 使用Markdown表格输出。

会议记录:

项目首页本周开始改版。李明负责整理新版信息架构,

周五前提供第一版。视觉稿由设计组接手,但会上没有确定具体负责人。

数据埋点方案需要产品和研发下周一再次确认。

一个更好的输出,不只是语言顺滑,而是能准确区分“已确定决策”和“仍待讨论事项”,并把未确定的负责人写成“待确认”。

这种提升能够减少人工整理时间,属于真实业务价值。

#### 案例二:看起来更漂亮,实际发生隐性回退

完整提示词:

从以下文本提取订单信息,只输出JSON,不要添加解释。

Schema:

{

"order_id": "string",

"amount": "number|null",

"currency": "CNY|USD|null",

"delivery_date": "YYYY-MM-DD|null"

}

规则:

  • 文本没有出现的信息必须填null;
  • 禁止推测日期;
  • 金额字段不能包含货币符号。

文本:

订单编号A-1024,总价暂未确认,客户希望下个月第一周交付。

不合格输出示例:

{

"order_id": "A-1024",

"amount": null,

"currency": "CNY",

"delivery_date": "2026-04-01"

}

这段输出形式正确,甚至显得很“聪明”,但它推测了币种和日期,违反了两条硬规则。正确结果应将对应字段写为 null

这类错误最容易被“整体可读性不错”掩盖,因此必须单独统计硬指标失败。

#### 案例三:标价降低,有效成本却可能上升

假设同一任务中,新模型倾向于先解释思路,再输出JSON。第一次调用因为存在额外文本而无法被程序解析,随后需要重试;如果第二次仍缺字段,还要增加一次修复调用。

此时不能只计算第一次调用:

新模型有效成本

= 第一次调用成本

+ 格式重试成本

+ 缺失字段修复成本

即使新模型Token单价更低,只要输出明显变长或重试次数增加,最终完成一次合格任务的成本仍可能更高。

四、成本对比:不要被每百万Token单价骗了

成本记录必须落到每个任务,而不是只抄价格表。

| 任务 | 模型 | 输入Token | 输出Token | 首次调用成本 | 重试次数 | 修复成本 | 最终有效成本 | 相比旧模型 | |---|---|---:|---:|---:|---:|---:|---:|---:| | T01 | 旧模型 | 实测填写 | 实测填写 | 按单价计算 | 实测填写 | 实测填写 | 自动汇总 | 基准 | | T01 | 新模型 | 实测填写 | 实测填写 | 按单价计算 | 实测填写 | 实测填写 | 自动汇总 | 自动计算 | | T02—T20 | 新旧分别记录 | 接口用量 | 接口用量 | 实际计费 | 实际次数 | 实际计费 | 三项相加 | 对比旧模型 |

建议最终至少汇总三个指标:

1. 20个任务总有效成本;

2. 单任务有效成本的中位数;

3. 成功完成一次任务的成本。

计算之前,应先确认模型实际的输入、输出计费标准。可前往 api.884819.xyz 查看当前可用模型与价格,再将实际单价填入成本模板。价格和模型可用情况均应以站内实时信息为准。

五、一个最小可复用的影子测试脚本

下面使用兼容OpenAI风格的Python客户端演示。实际运行时,请按所用服务的接口文档配置 BASE_URL、密钥和模型名称。

import json

import os

from datetime import datetime, timezone

from openai import OpenAI

BASE_URL = os.environ["BASE_URL"]

API_KEY = os.environ["API_KEY"]

OLD_MODEL = os.environ["OLD_MODEL"]

NEW_MODEL = os.environ["NEW_MODEL"]

TEMPERATURE = 0

MAX_TOKENS = 2000

PROMPT_VERSION = "shadow-test-v1"

client = OpenAI(

base_url=BASE_URL,

api_key=API_KEY

)

def call_model(model, task):

response = client.chat.completions.create(

model=model,

temperature=TEMPERATURE,

max_tokens=MAX_TOKENS,

messages=[

{"role": "system", "content": task["system_prompt"]},

{"role": "user", "content": task["user_prompt"]}

]

# 如果接口支持,可增加 seed=固定值

)

return {

"output": response.choices[0].message.content,

"usage": {

"input_tokens": response.usage.prompt_tokens,

"output_tokens": response.usage.completion_tokens,

"total_tokens": response.usage.total_tokens

}

}

def save_result(record):

with open("shadow_results.jsonl", "a", encoding="utf-8") as f:

f.write(json.dumps(record, ensure_ascii=False) + "\n")

with open("historical_tasks.json", encoding="utf-8") as f:

historical_tasks = json.load(f)

test_time = datetime.now(timezone.utc).isoformat()

for task in historical_tasks:

old_result = call_model(OLD_MODEL, task)

new_result = call_model(NEW_MODEL, task)

save_result({

"task_id": task["id"],

"prompt_version": PROMPT_VERSION,

"test_time": test_time,

"temperature": TEMPERATURE,

"max_tokens": MAX_TOKENS,

"old_output": old_result["output"],

"new_output": new_result["output"],

"old_usage": old_result["usage"],

"new_usage": new_result["usage"]

})

成本计算可以单独封装:

def calculate_effective_cost(

first_call_cost,

retry_cost,

repair_call_cost

):

return (

first_call_cost

+ retry_cost

+ repair_call_cost

)

old_effective_cost = calculate_effective_cost(

old_first_call_cost,

old_retry_cost,

old_repair_cost

)

new_effective_cost = calculate_effective_cost(

new_first_call_cost,

new_retry_cost,

new_repair_cost

)

cost_change = (

new_effective_cost - old_effective_cost

) / old_effective_cost

对于创作、推理等波动较大的任务,建议每个模型运行3次,分别记录最好、最差和中位表现。不要只挑一次最满意的结果作为结论。

评审时还应将模型名称替换为 模型A模型B,随机交换展示顺序,避免评审者因为知道哪个是新模型而下意识加分。

六、什么时候全量切,什么时候只切一部分

模型迁移不必强行二选一。

| 质量变化 | 成本变化 | 建议 | | 无明显回退或提升 | 下降 | 进入小流量灰度,验证后再扩大 | | 明显提升 | 上涨 | 优先用于高价值任务 | | 关键任务回退 | 下降 | 只路由到低风险场景 | | 质量回退 | 成本上涨 | 不切换,继续观察 | | 不同任务各有胜负 | 不确定 | 按任务类型进行模型路由 |

一个常见且更成熟的方案是:

  • 旧模型继续处理 JSON、字段抽取和强约束任务;
  • 新模型承担总结、创作和开放式分析;
  • 关键任务保留人工抽检;
  • 将本轮20个任务固定为后续回归测试集。

最终决策汇总表

| 指标 | 实测结果 | | 新模型胜出任务数 | 待盲评汇总 | | 持平任务数 | 待盲评汇总 | | 回退任务数 | 待盲评汇总 | | 硬指标失败数 | 待规则检测汇总 | | 硬指标通过率 | 通过任务数 ÷ 总任务数 | | 关键业务回退数 | 待汇总 | | 20个任务总成本 | 待按实际价格计算 | | 单次成功任务成本 | 总有效成本 ÷ 成功任务数 | | 最终建议 | 全量切换/部分路由/继续观察/不切换 |

建议为报告配套制作以下图片,所有图表都应直接读取测试脚本生成的数据,避免手工改数:

  • 新旧模型并行请求的调用记录截图;
  • 隐藏模型身份后的输出并排截图;
  • 20个任务胜出、持平、回退分布柱状图;
  • 各任务类型质量回退热力图;
  • 标价成本与有效成本对比图;
  • “质量变化—成本变化”四象限图。

七、真正值得保留的,不是结论,而是流程

一次影子测试的最终结论,可能是切换,也可能是不切换,甚至可能是只迁移一半任务。

但比结论更重要的是,你从此拥有了一套可以反复执行的流程:

1. 抽取20个真实历史任务;

2. 固定参数并行双跑;

3. 隐藏模型身份进行盲评;

4. 先检查硬性质量回退;

5. 再计算包含重试和修复的有效成本;

6. 最后决定全量切换、分任务路由或暂缓升级。

不要只看模型榜单决定是否切换。你可以先整理最近完成过的20个真实任务,用本文的表格和脚本做一次新旧模型双跑。

需要调用不同模型进行对照时,可前往 api.884819.xyz 查看当前可用模型与价格。8848AI平台使用用户名和密码即可注册,不需要邮箱验证;平台内置AI对话功能,注册后可以直接使用。国产模型如Deepseek、千问等完全免费,其他模型没有月租和订阅,按量付费。

新用户注册即送体验token。

20个任务手工测试一次并不难,难的是每次模型更新都重新测。下一篇,我会把这套影子测试改造成自动回归流程:提示词或模型版本一变化,就自动双跑、评分、计算成本,并在质量回退时发出提醒。

本文由8848AI原创,转载请注明出处。关注8848AI,带你从零开始学AI。

#AI模型 #模型评测 #影子测试 #人工智能 #AI教程 #8848AI #Prompt工程