用聚合 API 做多模型评测排行榜:一份代码给主流大模型打分排名
·
关键词:大模型评测、模型排行榜、LLM-as-judge、聚合 API、Python 实战
适用:已经做过一轮横评,想把「跑一遍」升级成「可复用的打分榜单」
一、为什么需要排行榜,而不是一次性横评
上一篇我们用一份代码把 Claude / GPT / DeepSeek / Qwen / Kimi 在同一道题上跑了一遍,看到的是「单次印象」。但真实选型要看多维度的稳定表现:代码写得对不对、推理准不准、长文本抓不抓得住重点、中文理解到不到位。
如果每次都靠人肉看输出,既慢又主观。本文在聚合 API 的基础上,加两样东西:
- LLM-as-judge:用一个强模型当「裁判」,给每个回答按维度打分;
- 自动校验:客观题(代码、数学)用程序直接验证对错。
最后把分数聚合成一张排行榜,模型换名字就能复跑,厂商更新模型后随时重排。
二、环境准备
pip install openai
登录 TokenPortal 控制台创建 API Key,只显示一次,存好。控制台入口与模型清单来我主页查看。base_url 指向平台网关(以控制台「API 文档」页为准,本文用 https://api.tokenportal.ai/v1 占位)。
三、核心思路
题库(多维度) ──▶ 候选模型逐题作答 ──▶ 两份结果
├─ 客观题:程序自动校验(对/错)
└─ 主观题:裁判模型 LLM-as-judge 打分
│
▼
聚合 → 排行榜(按维度 + 综合)
关键点:候选模型和裁判模型走同一个网关,换模型只改 model 一行,不需要再对接第二家 SDK。
四、核心代码
4.1 候选模型 + 题库
import time, json, re
from openai import OpenAI
client = OpenAI(api_key="你的_KEY", base_url="https://api.tokenportal.ai/v1")
# 想评谁往这里加——换模型只改名字
candidates = [
"anthropic/claude-opus-4.8",
"openai/gpt-5.5",
"deepseek/deepseek-v4-pro",
"qwen/qwen3.7-max",
"moonshotai/kimi-k3",
"zhipu/glm-5.2",
"google/gemini-3.1-pro-preview",
"minimax/minimax-m3",
"baidu/ernie-5.1",
]
# 裁判模型:单独走网关,挑一个综合强的
JUDGE = "openai/gpt-5.5"
# 题库:每题带 维度 与 客观校验方式
# check=None 走裁判打分;"code" 跑单元测试;"math:答案" 正则比对
tasks = [
{"dim": "代码", "prompt": "用 Python 写函数 is_palindrome(s),忽略大小写和非字母数字字符,返回布尔值。只给代码。", "check": "code"},
{"dim": "推理", "prompt": "鸡兔同笼:共 35 只,94 只脚。问鸡和兔各几只?只给最终答案:鸡X只,兔Y只。", "check": "math:23,12"},
{"dim": "长文本", "prompt": "请用 3 句话总结以下内容的核结论:(此处放一段长文)。", "check": None},
{"dim": "中文理解", "prompt": "『他差一点没赶上火车』与『他差一点赶上火车』意思相同吗?简要解释。", "check": None},
]
4.2 作答 + 客观校验
def ask(model, prompt):
t0 = time.time()
r = client.chat.completions.create(model=model, messages=[{"role": "user", "content": prompt}])
dt = time.time() - t0
return r.choices[0].message.content, r.usage, dt
def auto_check(kind, answer):
"""客观题自动校验,返回 1.0 / 0.0"""
if kind == "code":
# 抽出代码块,能定义函数且回文判断正确即给分
try:
m = re.search(r"def is_palindrome.*", answer, re.S)
if not m: return 0.0
ns = {}
exec(m.group(0), ns)
f = ns.get("is_palindrome")
ok = f and f("A man, a plan, a canal: Panama") is True and f("hello") is False
return 1.0 if ok else 0.0
except Exception:
return 0.0
if kind and kind.startswith("math:"):
want = kind.split(":", 1)[1]
return 1.0 if want.replace(" ", "") in answer.replace(" ", "") else 0.0
return None # 主观题,交给裁判
4.3 裁判模型打分(LLM-as-judge)
def judge_score(prompt, answer):
sys = ("你是严谨的评测裁判。请从准确性(0-5)、完整性(0-5)、表达清晰度(0-5)三项打分,"
"并给一句话理由。只输出 JSON:{\"acc\":0,\"comp\":0,\"clarity\":0,\"reason\":\"\"}")
r = client.chat.completions.create(
model=JUDGE,
messages=[{"role": "system", "content": sys},
{"role": "user", "content": f"题目:{prompt}\n回答:{answer}"}],
)
try:
j = json.loads(re.search(r"\{.*\}", r.choices[0].message.content, re.S).group(0))
return (j["acc"] + j["comp"] + j["clarity"]) / 15.0 # 归一化到 0-1
except Exception:
return 0.0
4.4 跑全流程,生成排行榜
board = {m: {"score": 0.0, "n": 0, "cost": 0, "latency": 0.0} for m in candidates}
for m in candidates:
for t in tasks:
ans, usage, dt = ask(m, t["prompt"])
auto = auto_check(t["check"], ans)
s = auto if auto is not None else judge_score(t["prompt"], ans)
board[m]["score"] += s
board[m]["n"] += 1
board[m]["cost"] += (usage.completion_tokens or 0)
board[m]["latency"] += dt
# 综合分 = 平均分;按分数降序排
ranking = sorted(
((m, round(v["score"] / v["n"], 3), v["cost"], round(v["latency"] / v["n"], 2))
for m, v in board.items()),
key=lambda x: x[1], reverse=True,
)
print(f"{'排名':<4}{'模型':<28}{'综合分':<8}{'用量(token)':<12}{'平均延迟(s)':<10}")
for i, (m, sc, c, lt) in enumerate(ranking, 1):
print(f"{i:<4}{m:<28}{sc:<8}{c:<12}{lt:<10}")
跑完你会得到一张类似这样的表(数值为示意):
排名 模型 综合分 用量(token) 平均延迟(s)
1 openai/gpt-5.5 0.91 1820 2.31
2 anthropic/claude-opus-4.8 0.89 2010 2.78
3 deepseek/deepseek-v4-pro 0.84 1540 1.96
...
五、进阶:按维度拆榜
综合分容易被「全能型」模型拉高,但很多团队只关心某一个场景。把 board 按 dim 分组统计,就能产出分场景榜单:
from collections import defaultdict
by_dim = defaultdict(lambda: defaultdict(float))
for m in candidates:
for t in tasks:
ans, _, _ = ask(m, t["prompt"])
auto = auto_check(t["check"], ans)
s = auto if auto is not None else judge_score(t["prompt"], ans)
by_dim[t["dim"]][m] += s
for dim, scores in by_dim.items():
print(f"\n【{dim}榜】")
for m, sc in sorted(scores.items(), key=lambda x: x[1], reverse=True):
print(f" {m:<28}{round(sc, 3)}")
这样你选型时就不是看一张总榜,而是「写代码看代码榜、做长文摘要看长文本榜」——更有指导意义。
六、小结
用聚合 API 做评测排行榜,优势很实在:
- 一个接口跑全部候选:换
model就换大脑,重排榜单只要改一行; - 裁判与候选同网关:LLM-as-judge 不用再单独接一家;
- 覆盖广:Anthropic、OpenAI、Google、DeepSeek、阿里通义、月之暗面、智谱、MiniMax、百度等主流厂商通吃;
- 有折扣:部分模型在平台上有折扣(如 Anthropic 系列低至 5 折),高频评测成本也压得住;
- 可开票、官方货源、稳定,做公司级选型报告也站得住脚。
更多推荐
所有评论(0)