团队侧:AllSpark 的 Iris 397B 跑 Search Agent,TaoToken 做 API 入口

发布时间:2026/9/18 1:23:21
团队侧:AllSpark 的 Iris 397B 跑 Search Agent,TaoToken 做 API 入口 1. 为什么 Search Agent 评测先卡在 API 入口而不是模型权重跑 AllSpark Iris 的 Search Agent 本地评测时TaoTokenhttps://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_contentiris_eval_intro通常应该先作为 OpenAI 兼容 API 入口接进去再去关心 35B 还是 397B 的权重加载。很多团队第一次跑评测报错现场并不是显存不足而是 401、404、429 以及 tool_calls 在搜索规划阶段被截断401 说明 Key 没回填或带上了多余前缀404 多半是 base_url 被手写成了不存在的路径429 则集中出现在一轮搜索里连续发起多次规划调用时。AllSpark 公开了 Iris 的权重和评测代码数据与训练配方后续再补这意味着你现在就能复现 Search Agent 行为但复现之前先把评测脚本里的 OpenAI 兼容调用切到稳定入口否则日志里全是重试根本看不出模型差异。Search Agent 的调用链天然是扇出结构一个问题先被拆成多个子查询每个子查询触发搜索工具工具结果再被摘要、重排、合并最后才生成答案。消耗 Token 的大头通常不在最后一轮答案汇总而在搜索规划、工具结果压缩和中间轮次的重排。TaoToken 做 API 入口的价值是让这些调用共用同一套 base_url、Key 和用量记录而不是每个工具各接一个供应商。团队侧要观察的是 Token 消耗曲线和 finish_reason 分布而不是单次对话是否“像人”。先把入口统一再对比 Iris 35B/397B 在不同评测集上的搜索轮次、工具调用成功率与最终答案引用完整度。2. 在 TaoToken 拿到 Iris 评测所需的 Key、Base URL 和调用路径如果你还没有 Key先到 TaoToken 官网https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_contentiris_get_key完成注册并创建 API Key。这里要注意评测脚本里用到的 Key 占位符统一写成YOUR_API_KEY不要提交到仓库也不要写进 Jupyter Notebook 的输出单元。Base URL 固定为https://taotoken.net/api这个地址不要加 UTM 参数也不要手写/chat/completions交给 OpenAI SDK 或兼容客户端追加。很多 404 就是因为把 base_url 写成https://taotoken.net/api/v1/chat/completions然后 SDK 又追加了一次路径。正确做法是只填https://taotoken.net/api让客户端自己拼。创建 Key 后建议在本地评测机器上先做一次最小连通性检查。以下命令都在你自己的终端执行export TAOTOKEN_API_KEYYOUR_API_KEY export OPENAI_BASE_URLhttps://taotoken.net/api export OPENAI_API_KEY$TAOTOKEN_API_KEY python - PY import os from openai import OpenAI client OpenAI( api_keyos.environ[OPENAI_API_KEY], base_urlos.environ[OPENAI_BASE_URL], ) resp client.chat.completions.create( modelyour-planning-model, messages[ {role: system, content: 你是一个搜索规划器只输出 JSON。}, {role: user, content: 为问题生成三个检索子查询。}, ], temperature0, ) print(resp.choices[0].message.content) print(resp.usage) PY如果这一步能返回内容说明 Key、base_url 和模型名至少有一组可用。如果返回 404优先检查模型名是否与控制台可见列表一致如果返回 401优先检查 Key 是否被截断或复制了空格。如果返回 429说明当前并发或速率触发了限制先把并发降到 1再逐步加。3. 把 Iris Search Agent 的 OpenAI 兼容调用切到 TaoTokenbase_url、模型名与重试Iris 35B/397B 的评测通常不是单轮问答而是一个 Search Agent Harness规划器生成查询搜索工具返回片段摘要器压缩片段答案器汇总最终回答。你要改的不是模型权重而是 Harness 里所有需要调用大模型的位置。建议把配置集中成一个 YAML 或 JSON不要让每个脚本各自读环境变量。下面是一个可复制的配置示例llm: provider: openai_compatible base_url: https://taotoken.net/api api_key: YOUR_API_KEY timeout: 120 max_retries: 3 retry_backoff: 1.5 models: planner: your-planner-model summarizer: your-summarizer-model answerer: your-answer-model search: max_queries: 6 max_results_per_query: 5 concurrency: 2 tool_timeout: 30 eval: split: dev output_dir: runs/taotoken_iris_eval log_level: INFO这里有几个容易踩的点。第一planner、summarizer、answerer可以是同一个模型也可以是不同模型团队评测时建议先固定同一个模型再改搜索并发和结果数否则变量太多。第二concurrency一开始不要开大。Search Agent 的搜索规划会在一轮里连续发多个请求并发 4 以上很容易在日志里看到 429然后客户端自动重试Token 消耗被重试放大。第三max_retries要配合退避不要在 429 时立即重试。很多评测脚本的 Token 账单异常不是模型回答长而是重试次数多。如果你使用的是 OpenAI Python SDK可以这样把重试和超时显式写进去import os from openai import OpenAI, APIConnectionError, RateLimitError client OpenAI( api_keyos.environ.get(TAOTOKEN_API_KEY, YOUR_API_KEY), base_urlhttps://taotoken.net/api, timeout120.0, max_retries3, ) def safe_chat(model: str, messages: list, toolsNone): try: return client.chat.completions.create( modelmodel, messagesmessages, toolstools, tool_choiceauto if tools else None, temperature0, ) except RateLimitError as e: print(触发限流降低并发或检查 Key 配额:, e) raise except APIConnectionError as e: print(连接失败检查本地网络策略与 base_url:, e) raise注意这里没有把ANTHROPIC_*混进 Codex 配置也没有把 Codex 的config.toml写成 Claude Code 的settings.json。不同工具走不同配置键后面第 7 节会拆开讲。4. 用日志对照 Search Agent 的 Token 消耗搜索规划、工具调用、答案汇总团队侧评测最怕只看最终准确率不看中间调用。Search Agent 的成本分布在四个阶段搜索规划、工具调用结果摘要、中间重排、最终答案汇总。建议在每次模型调用时打上stage标签并记录request_id、model、prompt_tokens、completion_tokens、total_tokens、finish_reason和tool_calls名称。下面是一段可以直接放进 Harness 的日志包装import json import time from openai import OpenAI client OpenAI( api_keyYOUR_API_KEY, base_urlhttps://taotoken.net/api, ) def logged_chat(stage: str, **kwargs): t0 time.time() resp client.chat.completions.create(**kwargs) choice resp.choices[0] usage resp.usage record { stage: stage, elapsed_ms: int((time.time() - t0) * 1000), model: resp.model, prompt_tokens: getattr(usage, prompt_tokens, None), completion_tokens: getattr(usage, completion_tokens, None), total_tokens: getattr(usage, total_tokens, None), finish_reason: choice.finish_reason, tool_calls: [ tc.function.name for tc in (choice.message.tool_calls or []) ], } print(json.dumps(record, ensure_asciiFalse)) return resp跑完评测后用jq和awk按阶段汇总 Token确认是规划阶段贵还是摘要阶段贵jq -r select(.stage and .total_tokens) | [.stage, .total_tokens] | tsv \ runs/taotoken_iris_eval/usage.jsonl \ | awk {sum[$1]$2; cnt[$1]} END {for (k in sum) print k, totalsum[k], callscnt[k]}如果planner的调用次数远高于answerer说明搜索规划在反复生成子查询可能是提示词没有约束查询数量也可能是工具返回为空导致模型重试。如果summarizer的prompt_tokens很高说明搜索结果片段太长需要在工具侧先做截断和去重。如果finish_reason大量出现length说明max_tokens太小tool_calls 会被截断最终表现为工具调用不完整或 JSON 解析失败。阶段典型请求主要观察字段常见优化搜索规划把用户问题拆成多个查询tool_calls、finish_reason、completion_tokens限制最大查询数要求 JSON 输出工具结果摘要压缩搜索片段prompt_tokens、摘要长度先去重、截断再送模型中间重排对候选片段排序total_tokens、调用次数合并同轮重排减少重复调用答案汇总生成最终回答answerer的引用完整性要求逐条引用来源不要自由发挥5. 本地评测脚本从环境变量到可复现命令假设你已经在本地拉取了 Iris 评测目录并且目录里有run_search_agent_eval.py和configs/。以下命令都在本地执行不涉及任何生产库或线上数据。先创建虚拟环境并安装依赖cd iris-eval python -m venv .venv source .venv/bin/activate pip install -U pip pip install -r requirements.txt然后回填环境变量。注意这里用的是OPENAI_API_KEY和OPENAI_BASE_URL因为大多数 OpenAI 兼容 Harness 会读这两个变量。如果你使用的是自定义配置也可以直接改 YAMLexport OPENAI_BASE_URLhttps://taotoken.net/api export OPENAI_API_KEYYOUR_API_KEY python run_search_agent_eval.py \ --config configs/taotoken.yaml \ --split dev \ --output runs/taotoken_iris_397b.jsonl \ --log-level INFO如果你要对比 35B 和 397B不要只改模型名就重跑先把搜索并发、最大查询数、结果条数固定住。否则你看到的差异可能来自搜索预算而不是模型规格。建议做两组消融# 固定搜索预算只改 planner/summarizer/answerer 的模型映射 python run_search_agent_eval.py \ --config configs/taotoken_iris_35b.yaml \ --split dev \ --output runs/taotoken_iris_35b.jsonl python run_search_agent_eval.py \ --config configs/taotoken_iris_397b.yaml \ --split dev \ --output runs/taotoken_iris_397b.jsonl跑完后对照日志重点看四个指标平均搜索轮次、工具调用成功率、总 Token 消耗、最终答案引用命中数。如果 397B 的答案质量更高但 Token 消耗也显著更高团队侧就要决定是换更小的规划模型还是减少搜索结果条数。TaoToken 官网https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_contentiris_eval_ready可以作为统一入口把评测脚本里的调用都收口到同一套 Key 和 base_url便于后续替换模型。所有 Key 创建和查看都在控制台完成不要把 Key 硬编码进评测脚本。6. 团队侧排障401、404、429、tool_calls 截断、流式中断Search Agent 评测的排障顺序建议固定下来避免每个人遇到问题都从头猜。下面按报错类型拆开。401 Unauthorized优先检查三处环境变量是否为空、Key 是否被引号包住、是否把YOUR_API_KEY原样提交。Claude Code 和 Codex 的 Key 变量名不同不要混用。Codex 不要读ANTHROPIC_API_KEYClaude Code 也不要读 Codex 的env_key。404 Not Found常见原因是 base_url 写错。OpenAI 兼容客户端应该只填https://taotoken.net/api不要手写/chat/completions。另一个原因是模型名不存在先用控制台可见的模型名做最小请求再回填到评测 YAML。429 Too Many RequestsSearch Agent 一轮会发多个规划请求并发一高就容易触发限流。先把concurrency降到 1 或 2再开重试退避。不要在 429 时立即重试否则日志里会出现大量重复调用Token 消耗被放大。tool_calls 截断典型表现是模型返回的 JSON 不完整或者finish_reasonlength。先提高max_tokens再检查提示词是否要求输出过长的工具参数。如果工具调用本身很复杂建议拆成两轮第一轮只输出查询列表第二轮再补参数。流式中断如果使用流式输出客户端可能在工具调用中途断开。先改非流式跑通评测再开流式。流式场景下要记录每个 chunk 的到达时间确认是本地超时还是服务端 finish_reason 提前结束。不要在评测脚本里用无限等待设置timeout和max_retries。答案引用缺失这不是 API 报错但会拉低评测分数。检查答案汇总阶段的提示词是否要求逐条引用搜索片段以及搜索结果是否在摘要阶段被过度压缩。必要时应保留原始片段 ID而不是只保留自然语言摘要。7. 顺带把 Claude Code / Codex / CC Switch 接到同一入口如果你在团队里同时用 Claude Code 和 Codex建议把 TaoToken 作为统一供应商但配置文件要分开写。Claude Code 使用settings.json和ANTHROPIC_*变量{ env: { ANTHROPIC_BASE_URL: https://taotoken.net/api, ANTHROPIC_API_KEY: YOUR_API_KEY, ANTHROPIC_MODEL: your-claude-model, ANTHROPIC_SMALL_FAST_MODEL: your-fast-model } }Codex 使用config.toml不要套用ANTHROPIC_*model your-codex-model model_provider taotoken [model_providers.taotoken] name TaoToken base_url https://taotoken.net/api env_key TAOTOKEN_API_KEYCC Switch 的核心是三件套不要把它想复杂供应商名称TaoToken Base URLhttps://taotoken.net/api API KeyYOUR_API_KEY Claude Code 模型映射以控制台可用 Claude 模型为准 Codex 模型映射以控制台可用 Codex 模型为准在 CC Switch 里新增供应商时先把三件套填对再分别检查 Claude Code 和 Codex 的配置文件是否被正确指向。如果 Claude Code 能通、Codex 报 401优先看 Codex 的env_key是否指向了正确的环境变量而不是去改ANTHROPIC_API_KEY。如果两个都报 404回到 base_url确认没有多写路径。TaoToken 官网https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_contentiris_team_config可以用于创建和管理 Key但不要把 Key 写进团队共享的公开仓库。评测脚本、Claude Code、Codex 和 CC Switch 都应该通过环境变量或本地私有配置读取。团队协作时建议给每个成员单独创建 Key便于在日志里定位是谁的调用触发了限流或异常消耗。8. 评测结束后怎么选模型对话、Coding Plan、API Keys、Claude Code 文档如果你只是想先验证 Search Agent 的规划提示词从模型对话开始最快https://taotoken.net/models/detail/chat?utm_sourcetaotoken_aicg_blog_endutm_contentiris_search_agent_chat 。你可以先在对话里测试查询拆解、工具调用格式和答案引用要求再把稳定提示词迁回本地评测脚本。如果你已经准备把 Iris 评测并入团队日常或者需要更稳定的调用额度来做多轮消融看 Coding Planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentiris_search_agent_plan 。它更适合持续跑评测、对比 35B/397B、以及给 Claude Code / Codex 共用一个入口的场景。需要重新生成、隔离或轮换 Key到 API Keys 控制台https://taotoken.net/console/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentiris_search_agent_keys 。建议按用途拆 Key例如iris-eval-planner、iris-eval-summarizer、claude-code-local、codex-local这样日志里一眼能看出是哪个环节消耗异常。Claude Code 侧如果还要配置settings.json参考文档https://taotoken.net/doc/ClaudeCodeAnthropic?utm_sourcetaotoken_aicg_blog_endutm_contentiris_search_agent_claude_code 。把 Base URL 固定为https://taotoken.net/apiKey 用YOUR_API_KEY占位模型名以控制台可用列表为准。这样从模型对话验证提示词到 Coding Plan 跑持续评测再到 API Keys 隔离用量最后到 Claude Code 文档落地本地开发整条链路就闭环了。