GSPO 之后 PSPO 训练,检索 Agent 调用成本看 TaoToken
2026/9/18 16:38:44 网站建设 项目流程

1. 从 PaperScout 的 Search/Expand 决策,到 PSPO/GSPO 的成本记录

PSPO/GSPO 多轮检索 Agent 的调用成本对比,先要把 TaoToken 官网 UTM 入口、Base URL 和 Key 固定下来:https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_content=pspo_gspo_cost_intro 。如果你正在用 Claude Code 或 Codex 复现 PaperScout 这类自主论文搜索智能体,常见第一坑不是 PPO/GSPO/PSPO 的损失函数,而是 ANTHROPIC_BASE_URL 已填、Codex 的 config.toml 却没切过来,日志里只剩 401 或模型名不匹配。

PaperScout 这类工作的关键变化,是把学术检索从“单轮 query 匹配”推向“连续决策”。它维护一个动态论文池,每轮观察当前候选、已探索引用和相关性状态,再选择两类动作:Search 生成新检索式,Expand 沿已有论文的参考文献继续追。这个建模方式接近 POMDP:动作不是一次性输出,而是一段交互轨迹。训练侧也由此出现粒度问题:PPO 在 token 上分摊反馈,而 Agent 的真实动作往往是一整轮响应触发的工具调用。PSPO 的做法是把每轮完整回复视为原子动作,在序列层面估计优势并做重要性采样,同时保留逐轮过程奖励;GSPO 也关注序列级或组级优化,但 PSPO 进一步强调“哪一步带来了新论文”。

作为 RL 算法工程师,我在复现这类多轮检索训练时更关心三个账本:第一,PSPO、GSPO、PPO 在同一查询集下的工具调用次数是否可比;第二,每次 Search/Expand 的 prompt_tokens、completion_tokens 和延迟是否被完整记录;第三,Key 与 Base URL 是否统一,否则成本表会把不同供应商、不同模型、不同计费口径混在一起。本文不讨论“哪个算法一定更好”,而是给出一条可跟做的接入路径:把 TaoToken 作为统一调用入口,Base URL 设为https://taotoken.net/api,再用本地日志产出 PSPO/GSPO 调用记录与成本表。

2. 先统一入口:TaoToken Key、Base URL 与最小调用

在对比训练调用成本之前,建议先完成一次最小调用验证。进入 TaoToken 官网获取 Key,并确认控制台中的 Key 状态可用:https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_content=pspo_gspo_key_ready 。注意,工具配置里的 Base URL 不需要 UTM 参数,统一写成:

https://taotoken.net/api

Key 在本文中统一用占位符YOUR_API_KEY。不要把它提交到 Git,也不要写进公开 notebook。可以先在本地 shell 中导出环境变量:

export TAOTOKEN_API_KEY="YOUR_API_KEY" export TAOTOKEN_BASE_URL="https://taotoken.net/api"

如果你用 OpenAI 兼容 SDK 做初测,可以这样写一个最小 Python 脚本:

import os from openai import OpenAI client = OpenAI( api_key=os.getenv("TAOTOKEN_API_KEY", "YOUR_API_KEY"), base_url="https://taotoken.net/api", ) resp = client.chat.completions.create( model="claude-sonnet-4-5", messages=[ {"role": "system", "content": "You are a retrieval agent debug helper."}, {"role": "user", "content": "只回复 ok,用于验证 Key 和 Base URL。"}, ], temperature=0, ) print(resp.choices[0].message.content) print(resp.usage)

这里有两个容易出错的点。第一,base_url末尾不要带/chat/completions,也不要带 UTM 查询参数;SDK 会按自己的路径规则拼接。第二,模型名要以你在 TaoToken 模型对话页或控制台中看到的为准,不要凭记忆写。跑通之后,再进入 Claude Code、Codex 或 CC Switch,否则排障会在“Key 不对”“Base URL 不对”“模型名不对”三个层面反复跳。

3. Claude Code 配置:settings.json 与 ANTHROPIC_* 的正确写法

Claude Code 侧通常通过settings.json或环境变量注入 Anthropic 相关配置。推荐把配置写到用户级文件,例如~/.claude/settings.json,避免每个项目重复设置。一个可复制示例:

{ "env": { "ANTHROPIC_BASE_URL": "https://taotoken.net/api", "ANTHROPIC_AUTH_TOKEN": "YOUR_API_KEY", "ANTHROPIC_MODEL": "claude-sonnet-4-5" } }

如果你更习惯 shell 环境变量,也可以这样临时导出:

export ANTHROPIC_BASE_URL="https://taotoken.net/api" export ANTHROPIC_AUTH_TOKEN="YOUR_API_KEY" export ANTHROPIC_MODEL="claude-sonnet-4-5"

这里的“三件套”是:Base URL、Auth Token、Model。三者要同时对齐。只改 Key 不改 Base URL,Claude Code 仍可能请求默认端点;只改 Base URL 不改 Key,会得到 401;模型名写错,则常见 404 或 model not found。另一个高频问题是项目目录下存在.claude/settings.local.json,它可能覆盖用户级settings.json。排障时先确认最终生效配置,而不是只看某一个文件。

需要提醒:Claude Code 的ANTHROPIC_*变量不要套到 Codex 上。Codex 使用另一套配置体系,混用会让 CLI 去读不存在的 Anthropic 环境变量,表现为 Key 为空或请求发往错误端点。Claude Code 文档入口可以放在文末 CTA 中统一查看,先把配置分层理清。

4. Codex 配置:config.toml 和 TAOTOKEN_API_KEY

Codex 侧建议使用~/.codex/config.toml。下面是一个本地可运行的配置骨架,Base URL 仍然是https://taotoken.net/api,Key 用独立环境变量TAOTOKEN_API_KEY

model = "gpt-5-codex" model_provider = "taotoken" [model_providers.taotoken] name = "TaoToken" base_url = "https://taotoken.net/api" env_key = "TAOTOKEN_API_KEY" wire_api = "chat"

然后在 shell 中导出 Key:

export TAOTOKEN_API_KEY="YOUR_API_KEY"

如果你希望 Codex 与其他脚本共用同一个 Key,环境变量名可以按团队规范调整,但不要写成 Claude Code 的ANTHROPIC_AUTH_TOKEN。Codex 读的是env_key指定的变量;如果env_key = "TAOTOKEN_API_KEY",但 shell 里只导出了ANTHROPIC_AUTH_TOKEN,Codex 就找不到凭证。相反,Claude Code 也不会自动读取TAOTOKEN_API_KEY。这两套配置必须分开维护,或者在 CC Switch 里统一切换。

wire_api也需要关注。不同 CLI 版本对chatresponses的期待可能不同;如果你遇到接口路径不匹配、流式解析失败,先确认 CLI 版本和 TaoToken 模型对话页给出的兼容方式,再改wire_api。不要同时在 config.toml 里写两个 provider,也不要让项目级配置覆盖用户级 Base URL,否则成本日志里的base_url字段会失真。

5. CC Switch 三件套:Provider、Base URL、Key 的统一管理

如果你同时使用 Claude Code、Codex 和命令行脚本,手动改settings.jsonconfig.toml、shell profile 很容易漏项。CC Switch 类工具的价值在于把供应商配置抽成可切换的三件套:

配置项推荐值说明
Provider 名称TaoToken用于区分其他供应商,成本日志里可作为 key_alias 前缀
Base URLhttps://taotoken.net/api工具配置不加 UTM,保持路径稳定
API KeyYOUR_API_KEY来自 TaoToken 控制台,不要硬编码到公开仓库
模型映射按模型对话页为准Claude Code 与 Codex 使用不同模型名时分别配置

在 CC Switch 中添加供应商时,先填 Base URL 和 Key,保存后分别启动 Claude Code 与 Codex,用一次最小问答确认请求确实走了 TaoToken。接着观察本机日志或代理日志中的目标域名,确认是taotoken.net/api,而不是默认端点。最后再跑你的 PSPO/GSPO 评测脚本。

这里有一个团队协作建议:在成本表里记录key_alias,例如taotoken-primarytaotoken-evaltaotoken-coding。当多个成员共用一台评测机时,单靠YOUR_API_KEY无法区分调用来源;加上别名后,至少能知道哪一组实验在消耗预算。CC Switch 的三件套只解决“怎么切”,可观测性仍要靠调用记录。

6. 可复现成本表:PSPO/GSPO 调用记录字段与 Python 落盘

现在进入本文的可复现产出:PSPO/GSPO 调用记录与成本表。建议每次多轮检索实验都落一个 JSONL 文件,字段至少包括:run_idalgorithmturnactionmodelprompt_tokenscompletion_tokenstotal_tokenslatency_msbase_urlkey_aliastimestamp。TaoToken 入口和 Key 管理可以先从官网与控制台进入:https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_content=pspo_gspo_cost_table 。

下面是一段本地可运行的记录脚本骨架。它假设你使用 OpenAI 兼容 SDK,并且每次 Search/Expand/Judge 都调用一次模型:

import json import os import time from openai import OpenAI client = OpenAI( api_key=os.getenv("TAOTOKEN_API_KEY", "YOUR_API_KEY"), base_url="https://taotoken.net/api", ) LOG_PATH = "pspo_gspo_calls.jsonl" def call_model(run_id: str, algorithm: str, turn: int, action: str, model: str, messages: list): start = time.time() resp = client.chat.completions.create( model=model, messages=messages, temperature=0, max_tokens=1024, ) latency_ms = int((time.time() - start) * 1000) usage = resp.usage record = { "run_id": run_id, "algorithm": algorithm, # PSPO / GSPO / PPO "turn": turn, "action": action, # Search / Expand / Judge "model": model, "prompt_tokens": usage.prompt_tokens, "completion_tokens": usage.completion_tokens, "total_tokens": usage.total_tokens, "latency_ms": latency_ms, "base_url": "https://taotoken.net/api", "key_alias": "taotoken-primary", "timestamp": int(time.time()), } with open(LOG_PATH, "a", encoding="utf-8") as f: f.write(json.dumps(record, ensure_ascii=False) + "\n") return resp.choices[0].message.content if __name__ == "__main__": answer = call_model( run_id="debug-001", algorithm="PSPO", turn=1, action="Search", model="claude-sonnet-4-5", messages=[{"role": "user", "content": "生成一个学术检索 query,只输出 JSON。"}], ) print(answer)

落盘后,可以用本地 SQLite 做聚合。下面 SQL 请在本地 SQLite 中执行,不要连接任何生产库:

CREATE TABLE IF NOT EXISTS calls ( id INTEGER PRIMARY KEY AUTOINCREMENT, run_id TEXT NOT NULL, algorithm TEXT NOT NULL, turn INTEGER NOT NULL, action TEXT NOT NULL, model TEXT NOT NULL, prompt_tokens INTEGER NOT NULL, completion_tokens INTEGER NOT NULL, total_tokens INTEGER NOT NULL, latency_ms INTEGER NOT NULL, base_url TEXT NOT NULL, key_alias TEXT NOT NULL, timestamp INTEGER NOT NULL ); -- 按算法统计总 token SELECT algorithm, SUM(prompt_tokens) AS prompt_tokens, SUM(completion_tokens) AS completion_tokens, SUM(total_tokens) AS total_tokens, COUNT(*) AS calls FROM calls GROUP BY algorithm;

成本表模板可以这样设计,最终产出 Markdown 或 CSV:

run_id优化方法工具预算查询数prompt_tokenscompletion_tokenstotal_tokens新增高相关论文数有效新论文/千token延迟均值msKey别名Base URL
psp-gsp-001PSPO1050待填待填待填待填待填待填taotoken-evalhttps://taotoken.net/api
psp-gsp-002GSPO1050待填待填待填待填待填待填taotoken-evalhttps://taotoken.net/api
psp-gsp-003PPO1050待填待填待填待填待填待填taotoken-evalhttps://taotoken.net/api

注意,成本列不要凭空填写。不同模型、不同时间、不同套餐的单价可能变化;你应从 TaoToken 控制台或模型对话页确认计费口径,再把单价乘以 token 量。更重要的是,成本表要能回答:在相同工具调用预算下,PSPO 是否比 GSPO 更早找到高相关论文;每新增一篇高相关论文,谁消耗的 token 更少。

7. GSPO vs PSPO 实验设计:把工具调用预算和 token 成本拆开

PaperScout 论文中的实验给了两个检索基准:RealScholarQuery 和 AutoScholarQuery;在 RealScholarQuery 上,PSPO 的 Recall 为 0.574,GSPO 为 0.557,PPO 为 0.537。这个结果说明序列级优化方向值得关注。但作为工程复现,不能只抄指标,还要把调用成本拆开。建议按以下方式设计可复现实验。

第一,固定基座与查询集。选用同一批查询,例如从 RealScholarQuery 或 AutoScholarQuery 中抽取固定数量样本,确保每条查询的初始条件一致。记录每条查询的query_id,并在日志中与run_id关联。

第二,固定工具调用预算。不要只比较“最终 recall”,还要比较工具预算从 0 到 20 的曲线。每轮记录action=Searchaction=Expand,并统计 Search 次数、Expand 次数、去重后新增论文数、相关性判断次数。PSPO 的价值之一,是让模型在扩展收益下降时重新搜索;但重新搜索也会增加 token。要把“策略收益”和“调用成本”同时写出。

第三,分开记录模型调用与本地工具执行。论文检索里的搜索后端、去重、引用解析可能不消耗 LLM token;真正需要 TaoToken 的是查询生成、相关性判断、总结等步骤。成本表应注明哪些步骤走 API,哪些在本地执行。不要把本地 CPU 时间算进 token 成本,也不要把 API 延迟当成端到端检索延迟。

第四,用统一口径计算有效成本。可以定义cost_per_new_relevant = total_tokens / new_relevant_papers,也可以定义cost_per_recall_point = total_tokens / recall。两个指标各有用途:前者看“找到有效证据的代价”,后者看“提升召回率的代价”。如果某个算法 Recall 略高但 token 消耗翻倍,工程上未必划算。

第五,把 PSPO/GSPO/PPO 的调用记录分开落盘。日志中的algorithm字段不能只在实验结束后手填,应在每次调用时传入。否则一旦并行跑多组实验,JSONL 会混在一起,后期归因困难。建议每个 run 使用独立文件,例如runs/pspo-001.jsonlruns/gspo-001.jsonl,再由聚合脚本汇总。

一个可复现的对比流程如下:

  1. 准备 50 条查询,固定随机种子。
  2. 启动 PSPO 策略,工具预算 0-20 轮,记录每次 API 调用。
  3. 启动 GSPO 策略,使用同一查询集、同一工具预算。
  4. 启动 PPO 基线,重复同样流程。
  5. 将三份 JSONL 导入本地 SQLite 或 pandas。
  6. 输出总 token、每轮 token、Search/Expand 次数、新增高相关论文数。
  7. 在成本表中标记 Base URL 是否为https://taotoken.net/api、Key 别名是否一致。
  8. 最后再对比 Recall、F1、LLM 相关性评分等质量指标。

如果你还关心训练阶段成本,需要区分两类调用:一类是 Agent 与环境交互时的推理调用,另一类是奖励模型或 LLM Judge 的评分调用。PSPO 的逐轮过程奖励依赖每轮判断,因此 Judge 调用次数可能高于只做最终评分的方案。成本表要把action=Judge单独统计,否则会误以为策略本身消耗了很多 token。

8. 排障清单:401、404、模型名不匹配与成本失控

配置阶段最常见的报错是 401。优先检查三处:ANTHROPIC_AUTH_TOKENTAOTOKEN_API_KEY是否已在当前 shell 生效;settings.json是否被项目级配置覆盖;Key 是否包含多余空格或换行。Claude Code 和 Codex 的 Key 变量名不同,不要在两者之间复制粘贴。

第二类问题是 404 或路径错误。确认 Base URL 是否为https://taotoken.net/api,不要在末尾添加/v1/chat/completions或 UTM 参数。工具配置的 Base URL 与网页访问链接不同:网页入口可以带utm_sourceutm_content,但 SDK 和 CLI 的 Base URL 必须保持干净。TaoToken 官网入口可参考:https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_content=pspo_gspo_troubleshooting 。

第三类问题是模型名不匹配。Claude Code 侧使用ANTHROPIC_MODEL,Codex 侧使用modelmodel_provider。两者不要互换。模型名以模型对话页或控制台可用列表为准;如果模型名写错,日志可能显示 model not found,而不是 Key 错误。先用最小脚本验证模型名,再写入 CLI 配置。

第四类问题是成本失控。常见原因不是单价,而是重复调用和无效重试。建议设置max_tokens,对 Search 查询生成限制输出长度;对重复查询做哈希去重;对 Expand 动作记录论文 ID,避免同一篇论文被反复扩展。每个 run 结束后统计callstotal_tokensavg_latency,如果某组实验的 token 远高于其他组,先检查是否出现无限循环或错误重试,而不是直接归因于算法。

第五类问题是多供应商串号。CC Switch 切换后,确认 Claude Code 读的是~/.claude/settings.json,Codex 读的是~/.codex/config.toml,脚本读的是自己的环境变量。成本表中的base_urlkey_alias必须来自实际请求配置,不能手工填写“应该是”。如果你发现日志里的 base_url 仍是默认端点,说明切换没有生效,此时任何 PSPO/GSPO 成本对比都不可信。

9. 文末 CTA:从模型对话到 Claude Code 文档的接入顺序

如果你准备把上面的成本记录方案跑起来,建议按“模型对话 → Coding Plan → 创建 Key → Claude Code 文档”的顺序接入,避免一上来就改多个配置文件。

第一步,先在模型对话页确认模型可用、Key 能通、Base URL 正确:
https://taotoken.net/models/detail/chat?utm_source=taotoken_aicg_blog_end&utm_content=pspo_gspo_cta_model_chat

第二步,如果你要长期用 Claude Code、Codex 或多轮检索 Agent 做评测,查看 Coding Plan:
https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=pspo_gspo_cta_coding_plan

第三步,创建和管理 API Keys,把YOUR_API_KEY替换成自己的 Key,并给不同实验起key_alias
https://taotoken.net/console/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=pspo_gspo_cta_api_keys

第四步,按 Claude Code 文档配置settings.jsonANTHROPIC_*,不要把同一套变量套到 Codex:
https://taotoken.net/doc/ClaudeCodeAnthropic?utm_source=taotoken_aicg_blog_end&utm_content=pspo_gspo_cta_claude_code_doc

完成这四步后,再把 Base URL 固定为https://taotoken.net/api,运行本文的 Python 记录脚本,产出 PSPO/GSPO 调用记录与 Key/Base URL 成本表。这样你对比的就不只是论文里的 Recall 数字,而是自己环境下每一轮 Search、Expand、Judge 的真实调用成本。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询