ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

评估 Elo-per-token 收益递减,TaoToken Key 记录 LLM Agent 每轮 Token

2026/9/18 5:30:58 拓冰建站 浏览量
评估 Elo-per-token 收益递减,TaoToken Key 记录 LLM Agent 每轮 Token 1. TaoToken 接入与 Elo-per-token 复现Key、base_url 和每轮 token 账本跑 LLM Agent 评测时先把 TaoToken 官网 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_contentelo_per_token_intro 放进流程创建 Key并把客户端 base_url 固定为https://taotoken.net/api。真正让 Elo-per-token 分析失真的往往不是 Bradley-Terry 的迭代而是 API Key 入口不统一、base_url 一会儿默认一会儿兼容路径以及每轮 token usage 没落盘。Elo-per-token 想回答的问题很具体同一批任务中增加测试时算力后跨任务 Elo 还能涨多少每 1000 token 买到多少 Elo。如果成本分母不稳定后面所有收益递减曲线都会失去解释力。这类分析通常先把同一任务内的 Agent 输出排序转成两两比较再用 Bradley-Terry 模型估计每个策略的全局能力参数最后换算成跨任务 Elo。测试时算力策略可以是单轮、CoT、self-consistency、多轮 debate、verifier rerank也可以是不同采样温度或候选数。关键不是策略名字而是你能不能在每次调用后拿到input_tokens、output_tokens、total_tokens并把它们和任务 ID、轮次、策略名、模型名写在同一行 JSONL 里。本文实验记录来源标记为csdn_ugc。建议目录结构如下agent-elo-token/ ├── configs/ │ ├── claude.settings.json │ ├── codex.config.toml │ └── cc-switch.txt ├── runs/ │ └── csdn_ugc_eloper_token.jsonl ├── scripts/ │ ├── agent_runner.py │ ├── bt_elo.py │ └── summarize_tokens.py └── reports/ ├── elo_table.csv └── eloper_token.csv每一轮调用至少落这些字段{ run_id: csdn_ugc_eloper_token_001, source_platform: csdn_ugc, task_id: task_017, strategy: cot, round: 1, model: YOUR_MODEL, input_tokens: 1820, output_tokens: 640, total_tokens: 2460, latency_ms: 8342, winner: null, opponent: null, content: Agent final answer... }这里winner和opponent可以等评测器打分后回填。Elo-per-token 的分子来自 Bradley-Terry 聚合后的跨任务 Elo分母来自同一策略在全部任务上的平均总 token。为了让收益递减可观察你还需要记录同一策略在不同算力档位下的版本例如sc_k3、sc_k5、sc_k10否则只能看到单点成本看不到边际变化。Bradley-Terry 的基本假设是策略 (i) 战胜策略 (j) 的概率由两者能力差决定[ P(i \succ j)\frac{e^{\theta_i}}{e^{\theta_i}e^{\theta_j}} ]估计出 (\theta) 后常用 Elo 换算为[ \text{Elo}_i 1000 \frac{400}{\ln 10}\theta_i ]Elo-per-1K-token 可以定义为[ \text{EloPer1K}_s \frac{\text{Elo}_s}{\text{AvgToken}_s / 1000} ]从策略 (s) 增加到 (s) 时边际收益为[ \text{MarginalEloPer1K}{s\to s} \frac{\text{Elo}{s}-\text{Elo}s} {(\text{AvgToken}{s}-\text{AvgToken}_s)/1000} ]当边际 Elo-per-1K-token 明显下降时就说明测试时算力进入了收益递减区间。下面从 Key、base_url、客户端配置、token 统计到 Elo 对照表逐步落地。2. 在 TaoToken 创建 Key并把 base_url 固定为 https://taotoken.net/api先到 TaoToken 官网 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_contentelo_per_token_setup 创建账号并进入控制台。创建 API Key 后不要把它写进代码仓库放到本地环境变量或密钥管理文件。本文所有配置统一使用占位符YOUR_API_KEY。本地先导出两个变量export TAOTOKEN_API_KEYYOUR_API_KEY export TAOTOKEN_BASE_URLhttps://taotoken.net/api注意TAOTOKEN_BASE_URL不要带 UTM也不要写成站外中转地址。工具配置里的 Base URL 就是https://taotoken.net/api如果你使用 OpenAI 兼容 SDK可以这样初始化import os from openai import OpenAI client OpenAI( api_keyos.environ[TAOTOKEN_API_KEY], base_urlos.environ.get(TAOTOKEN_BASE_URL, https://taotoken.net/api), )先用一个很小的请求验证连通性。下面的模型名用YOUR_MODEL占位请替换成你在 TaoToken 控制台或模型对话页面看到的可用模型resp client.chat.completions.create( modelYOUR_MODEL, messages[{role: user, content: 只回复 pong}], max_tokens8, ) print(resp.choices[0].message.content) print(resp.usage)如果返回 401优先检查Authorization头或 SDK 的api_key是否真的拿到了YOUR_API_KEY对应的值。如果返回 404大概率是 base_url 被写成了别的路径例如多了/v1、少了/api或者环境变量里混入了旧配置。排查时直接打印echo $TAOTOKEN_BASE_URL它应该输出https://taotoken.net/api如果返回 429不要立刻并发重试先用指数退避并记录失败轮次。评测 Agent 时失败请求不应计入 token 成功账本否则平均成本会被低估。建议在 JSONL 中增加status字段{ status: ok, error: null }失败时写{ status: error, error: 429 rate limit }后续统计只对status ok的行求平均这样 Elo-per-token 的分母才干净。3. Claude Code、Codex、CC Switch 三套配置避免 ANTHROPIC_* 错配Claude Code 走settings.json和ANTHROPIC_*环境变量。可以在用户级~/.claude/settings.json也可以在项目级.claude/settings.json中配置。示例{ env: { ANTHROPIC_BASE_URL: https://taotoken.net/api, ANTHROPIC_AUTH_TOKEN: YOUR_API_KEY, ANTHROPIC_MODEL: YOUR_CLAUDE_MODEL, ANTHROPIC_SMALL_FAST_MODEL: YOUR_CLAUDE_FAST_MODEL } }这里的ANTHROPIC_BASE_URL同样指向https://taotoken.net/api不要加 UTM。ANTHROPIC_AUTH_TOKEN使用你的 TaoToken Key。模型字段按你实际可用模型替换。Codex 不要套用ANTHROPIC_*。Codex 走config.toml常见位置是~/.codex/config.toml。示例model YOUR_CODEX_MODEL model_provider taotoken [model_providers.taotoken] name TaoToken base_url https://taotoken.net/api env_key TAOTOKEN_API_KEY wire_api chat然后在 shell 中设置export TAOTOKEN_API_KEYYOUR_API_KEY验证codex --version codex 用一句话说明当前模型提供方名称如果你把ANTHROPIC_API_KEY或ANTHROPIC_BASE_URL配到 CodexCodex 不会按 Claude Code 的逻辑读取容易出现认证失败或模型不存在。记住两条线Claude CodeANTHROPIC_BASE_URLANTHROPIC_AUTH_TOKENCodexconfig.tomlTAOTOKEN_API_KEYCC Switch 可以理解为多套客户端配置的切换器。新建供应商时先填三件套供应商名称TaoToken Base URLhttps://taotoken.net/api API KeyYOUR_API_KEY然后把三件套同步到三个地方Claude Code - settings.json 中的 ANTHROPIC_BASE_URL / ANTHROPIC_AUTH_TOKEN Codex - config.toml 中的 model_provider.base_url / env_key Shell - TAOTOKEN_API_KEY / TAOTOKEN_BASE_URL切回旧供应商后如果 Claude Code 仍然请求旧地址检查 shell 环境变量是否覆盖了settings.json。很多客户端的优先级是进程环境变量 用户级配置 项目级配置。可以用env | grep -E ANTHROPIC|TAOTOKEN|OPENAI确认没有残留变量。4. 让 Agent 每轮上报 token本地 JSONL 账本与统计命令Elo-per-token 的复现核心是每轮调用都有 token 记录。下面是一个最小可运行的 Python 包装器把每轮输出追加到runs/csdn_ugc_eloper_token.jsonl。所有命令都在本地实验目录执行不连接外部生产库。# scripts/agent_runner.py import json import os import time from openai import OpenAI client OpenAI( api_keyos.environ[TAOTOKEN_API_KEY], base_urlos.environ.get(TAOTOKEN_BASE_URL, https://taotoken.net/api), ) LOG_PATH runs/csdn_ugc_eloper_token.jsonl def run_round(task_id, strategy, round_id, prompt, model): started time.time() status ok error None content usage None try: resp client.chat.completions.create( modelmodel, messages[{role: user, content: prompt}], temperature0.2, ) content resp.choices[0].message.content or usage resp.usage except Exception as exc: status error error str(exc) row { run_id: os.environ.get(RUN_ID, csdn_ugc_eloper_token), source_platform: csdn_ugc, task_id: task_id, strategy: strategy, round: round_id, model: model, input_tokens: getattr(usage, prompt_tokens, None) if usage else None, output_tokens: getattr(usage, completion_tokens, None) if usage else None, total_tokens: getattr(usage, total_tokens, None) if usage else None, latency_ms: int((time.time() - started) * 1000), status: status, error: error, content: content, } os.makedirs(os.path.dirname(LOG_PATH), exist_okTrue) with open(LOG_PATH, a, encodingutf-8) as f: f.write(json.dumps(row, ensure_asciiFalse) \n) return row if __name__ __main__: run_round( task_idtask_001, strategycot, round_id1, prompt计算 17*23并只输出结果。, modelYOUR_MODEL, )运行export TAOTOKEN_API_KEYYOUR_API_KEY export TAOTOKEN_BASE_URLhttps://taotoken.net/api python scripts/agent_runner.py cat runs/csdn_ugc_eloper_token.jsonl | tail -n 1统计每个任务、每个策略的总 tokenjq -s map(select(.status ok)) | group_by(.task_id, .strategy) | map({ task_id: .[0].task_id, strategy: .[0].strategy, rounds: length, input_tokens: (map(.input_tokens) | add), output_tokens: (map(.output_tokens) | add), total_tokens: (map(.total_tokens) | add), avg_total_tokens: ((map(.total_tokens) | add) / length) }) runs/csdn_ugc_eloper_token.jsonl查看每轮 token 明细jq -r select(.status ok) | [.task_id, .strategy, .round, .input_tokens, .output_tokens, .total_tokens] | tsv runs/csdn_ugc_eloper_token.jsonl | column -t按策略汇总平均 tokenjq -s map(select(.status ok)) | group_by(.strategy) | map({ strategy: .[0].strategy, runs: length, avg_input_tokens: ((map(.input_tokens) | add) / length), avg_output_tokens: ((map(.output_tokens) | add) / length), avg_total_tokens: ((map(.total_tokens) | add) / length) }) runs/csdn_ugc_eloper_token.jsonl如果usage为空先检查是否使用了流式响应但没取最后一块 usage或者 SDK 版本过旧。另一个常见原因是请求失败后仍然写了日志但usage为null。统计时用select(.status ok)过滤即可。5. Bradley-Terry 聚合跨任务 Elo从任务内排序到全局评分有了 token 账本还不够Elo 需要比较关系。每个任务内你可以让裁判模型、规则评测器或人工对同一任务下的多个策略输出排序。排序可以转成两两比较第 1 名胜第 2 名第 1 名胜第 3 名第 2 名胜第 3 名依此类推。然后把这些比较对交给 Bradley-Terry 拟合。假设比较表comparisons.csv长这样task_id,winner,loser task_001,cot,baseline task_001,sc_k3,cot task_001,sc_k5,sc_k3 task_002,sc_k3,baseline task_002,sc_k5,sc_k3用 Python 拟合全局 Elo# scripts/bt_elo.py import math import pandas as pd import numpy as np from scipy.optimize import minimize def bt_nll(theta, winners, losers): diff theta[winners] - theta[losers] return -np.sum(diff - np.log1p(np.exp(diff))) def fit_bt(strategies, comparisons): idx {s: i for i, s in enumerate(strategies)} winners np.array([idx[w] for w in comparisons[winner]], dtypeint) losers np.array([idx[l] for l in comparisons[loser]], dtypeint) def objective(t): return bt_nll(t, winners, losers) init np.zeros(len(strategies)) res minimize(objective, init, methodBFGS) theta dict(zip(strategies, res.x)) scale 400 / math.log(10) elo {k: 1000 scale * v for k, v in theta.items()} return elo if __name__ __main__: df pd.read_csv(comparisons.csv) strategies sorted(set(df[winner]) | set(df[loser])) elo fit_bt(strategies, df) for k, v in sorted(elo.items(), keylambda x: -x[1]): print(k, round(v, 2))如果比较对很少或者任务内排序存在大量循环BT 参数可能不稳定。可以加入 L2 正则def bt_nll_reg(theta, winners, losers, lam0.01): diff theta[winners] - theta[losers] nll -np.sum(diff - np.log1p(np.exp(diff))) return nll lam * np.sum(theta ** 2)跨任务聚合时不要让某个任务因为比较对特别多而主导全局 Elo。可以按任务归一化或者给每个任务相同权重。一个简单做法是先算任务内 Elo再对任务内 Elo 做加权平均最后用全局 BT 校准。更严谨的做法是用分层 Bradley-Terry把任务 ID 作为随机效应或分组变量。对多数工程评测先用任务等权 比较对裁剪已经足够观察收益递减。把 Elo 结果和 token 汇总合并import pandas as pd elo_df pd.DataFrame([ {strategy: baseline, elo: 1000.0}, {strategy: cot, elo: 1035.2}, {strategy: sc_k3, elo: 1068.7}, {strategy: sc_k5, elo: 1081.4}, {strategy: sc_k10, elo: 1086.9}, ]) token_df pd.read_csv(reports/strategy_tokens.csv) out elo_df.merge(token_df, onstrategy, howleft) out[elo_per_1k] out[elo] / (out[avg_total_tokens] / 1000.0) out out.sort_values(avg_total_tokens) out[marginal_elo_per_1k] out[elo].diff() / (out[avg_total_tokens].diff() / 1000.0) out.to_csv(reports/eloper_token.csv, indexFalse) print(out)上面的 Elo 数值只是格式示例实际请用你的runs/csdn_ugc_eloper_token.jsonl拟合结果替换。6. Elo-per-token 与收益递减对照表怎么计算、怎么读收益递减不是“token 越多越差”而是“每增加一档算力新增 Elo 的斜率下降”。你需要同时看三列平均总 token、跨任务 Elo、边际 Elo/1K token。第一列是成本第二列是效果第三列才是扩展规律。建议生成如下 Markdown 表策略成功轮数平均总 Token跨任务 EloElo/1K Token边际 Elo/1K Token判断baseline待填待填待填待填—成本基线cot待填待填待填待填待填看是否高于基线sc_k3待填待填待填待填待填第一次扩展sc_k5待填待填待填待填待填观察斜率sc_k10待填待填待填待填待填边际可能下降debate_2待填待填待填待填待填高成本档verifier_rerank待填待填待填待填待填可能局部有效生成 CSV 后可以用命令行快速算python scripts/bt_elo.py reports/elo.txt再导出 token 汇总jq -s map(select(.status ok)) | group_by(.strategy) | map({ strategy: .[0].strategy, avg_total_tokens: ((map(.total_tokens) | add) / length), runs: length }) runs/csdn_ugc_eloper_token.jsonl reports/strategy_tokens.json如果你用 Python 读 JSONLimport json from collections import defaultdict agg defaultdict(lambda: {tokens: 0, runs: 0}) with open(runs/csdn_ugc_eloper_token.jsonl, r, encodingutf-8) as f: for line in f: row json.loads(line) if row.get(status) ! ok: continue key row[strategy] agg[key][tokens] row[total_tokens] agg[key][runs] 1 for strategy, item in agg.items(): avg item[tokens] / item[runs] print(strategy, round(avg, 2), item[runs])怎么读这张表如果cot的 Elo 比baseline高但Elo/1K Token反而更低说明 CoT 提升了效果但成本涨得更快。如果sc_k3到sc_k5的边际 Elo/1K Token 为正且较大说明这一档算力仍值得加。如果sc_k5到sc_k10的边际 Elo/1K Token 接近 0甚至为负说明在这个任务集上继续加采样数已经进入收益递减区间。如果debate_2的 Elo 只比sc_k5高一点但平均 token 翻倍优先选择sc_k5。阈值可以自定义。例如团队规定“新增 1K token 至少换 2 Elo 才上线”那么低于该值的档位就只保留在离线实验里。为了让曲线更稳把 token 分桶而不是只看平均值。例如按 0-2K、2-5K、5-10K、10K 分桶每桶计算平均 Elo。分桶后如果 Elo 增量明显放缓就说明扩展规律不是线性的。7. 跨任务 Elo 实验的排障清单401、404、usage 为空与 CC Switch 切换401 Unauthorized检查 Claude Code 是否用了ANTHROPIC_AUTH_TOKENCodex 是否用了TAOTOKEN_API_KEY。如果同一个 shell 里既有旧 Key 又有新 Key先清理unset ANTHROPIC_API_KEY unset OPENAI_API_KEY export TAOTOKEN_API_KEYYOUR_API_KEY404 Not Found优先检查 base_url。工具配置里统一写https://taotoken.net/api不要额外拼/v1也不要在 URL 后面追加 UTM。UTM 只用于官网链接统计不用于 API 请求。模型不存在模型名区分供应商和版本。Claude Code 的ANTHROPIC_MODEL、Codex 的model、Python 脚本里的model参数都要替换成当前可用模型。不要把一个平台的模型名硬套到另一个平台。usage 为空检查 SDK 版本、是否流式输出、是否在异常分支写入日志。统计命令中始终加select(.status ok)。Elo 不收敛比较对太少、任务内排序冲突太多、某些策略从未获胜都会导致 BT 参数漂移。增加比较对、按任务等权、加 L2 正则。CC Switch 切换后仍请求旧地址先看进程环境变量env | grep -E ANTHROPIC|TAOTOKEN|OPENAI再检查settings.json和config.toml是否被正确写入。Claude Code 和 Codex 的配置不要混用。Token 统计和账单对不上确认只统计成功请求确认重试请求单独记录确认输入输出 token 没有被截断。对于 Agent 多轮调用把每一轮都写入 JSONL而不是只写最终答案。8. 把 Elo-per-token 跑成可复现实验从 Key 到收益递减表现在可以把流程串起来在 TaoToken 创建 Key把 base_url 固定为https://taotoken.net/api用 Claude Code 或 Codex 跑任务用 Python 包装器记录每轮 token用 Bradley-Terry 聚合跨任务 Elo最后生成 Elo-per-token 和边际收益表。这样得到的结论不是“某个策略感觉更强”而是“在 csdn_ugc 这批任务上某策略每 1000 token 换到多少 Elo继续加算力是否还划算”。如果你还在准备实验环境可以按下面顺序进入 TaoToken先打开模型对话确认可用模型和返回格式https://taotoken.net/models/detail/chat?utm_sourcetaotoken_aicg_blog_endutm_contentelo_per_token_chat如果要用 Codex / Claude Code 做批量评测看 Coding Planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentelo_per_token_plan创建或管理 API Keyhttps://taotoken.net/console/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentelo_per_token_keysClaude Code 接入细节看文档https://taotoken.net/doc/ClaudeCodeAnthropic?utm_sourcetaotoken_aicg_blog_endutm_contentelo_per_token_doc官网入口也放在这里方便统一拿 Key 和核对控制台配置https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_contentelo_per_token_cta。先把 Key、base_url、token 账本三件事固定下来再去比较不同测试时算力策略的跨任务 Elo收益递减曲线才有工程意义。