尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Smolagents 两次查文档烧掉 43 万 Token?TaoToken 这样改模型通道

Smolagents 两次查文档烧掉 43 万 Token?TaoToken 这样改模型通道 1. 两次 get_docs 查询43 万 Token 去哪了如果你正在用 Smolagents 搭配 MCP Server 做文档检索类 Agent大概率遇到过这种诡异情况明明只是问了两个简单问题比如「llamaindex 怎么做 multi-agent」和「smolagents 的 CodeAgent 怎么用」结果账单一看Token 消耗直接飙到 43 万。更让人抓狂的是你根本不知道这些 Token 是被网页抓取吃掉的还是被模型总结吃掉的因为所有请求都混在同一个额度池里日志里只有一行「usage: xxx tokens」没有任何区分度。这个问题的本质不是 Smolagents 有 bug也不是 MCP 协议设计有问题而是模型通道没有做可观测性隔离。默认情况下Smolagents 里的OpenAIServerModel指向的是本地推理服务比如 LM Studio 的http://127.0.0.1:1234/v1或者某个统一的云端入口所有请求共用一把 Key、一个 base_url。当 Agent 触发get_docs工具时MCP Server 会先用 DuckDuckGo 搜 3 条结果再用 BeautifulSoup 把整页 HTML 转成纯文本这一大坨文本会作为 tool result 塞回对话历史然后模型再基于它做总结。网页正文动辄几万字符两次查询叠加多轮 tool call43 万 Token 并不夸张。真正要解决的不是「怎么省 Token」而是「怎么先看清楚 Token 花在哪」。这篇就按排障视角把 Smolagents 的模型通道从本地默认地址切到 TaoToken利用 API 返回的usage字段逐次核对消耗定位到底是抓取阶段还是总结阶段在烧钱。2. 为什么把模型通道换成 TaoToken 能看清账TaoToken 在这里的角色不是「更便宜的模型」而是一个带完整 usage 回传的 OpenAI 兼容入口。Smolagents 的OpenAIServerModel本身支持自定义api_base和api_key你只需要把这两个参数指向 TaoToken就能在每次请求的响应里拿到标准的prompt_tokens、completion_tokens、total_tokens。配合 Smolagents 的日志你可以把「MCP 抓取返回的文本长度」和「模型实际计费的 prompt_tokens」做对照一眼看出是不是抓取内容过长导致的。具体操作路径打开 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_end 创建账号进入控制台生成一个 API Key。然后在 Smolagents 代码里把原来的API_BASE http://127.0.0.1:1234/v1改成https://taotoken.net/apiAPI_KEY换成新生成的 Key。模型 ID 可以继续用你原来的比如qwen-2.5-coder-14b-instruct只要 TaoToken 侧支持这个模型名即可。这样改完之后每次agent.run()触发的模型调用都会在响应里带上 usage。你可以在 Smolagents 的model层加一个简单的回调或者直接在 TaoToken 控制台的请求日志里按时间戳对照就能把「第一次 get_docs」和「第二次 get_docs」的消耗拆开看。注意TaoToken 的 API 地址是https://taotoken.net/api不要加 UTM 参数到代码里UTM 只用于官网跳转统计。3. 可复制配置Smolagents 接入 TaoToken 的完整改法先确认依赖装好。Smolagents 调 MCP 需要额外装smolagents[mcp, openai]如果你还没装uv add smolagents[mcp, openai]然后新建或修改my_agent.py核心改动只有三行API_BASE、API_KEY、MODEL_ID。下面是我实测可跑的完整版本from smolagents import ToolCollection, CodeAgent, OpenAIServerModel from mcp import StdioServerParameters # 关键改动指向 TaoToken 的 OpenAI 兼容入口 API_BASE https://taotoken.net/api API_KEY sk-你的TaoToken密钥 MODEL_ID qwen-2.5-coder-14b-instruct model OpenAIServerModel( api_baseAPI_BASE, api_keyAPI_KEY, model_idMODEL_ID, ) # MCP Server 参数保持不变指向你本地的 documentation 项目 server_parameters StdioServerParameters( commanduv, args[ --directory, D:/01Projects/MCP/documentation, run, main.py, ], ) with ToolCollection.from_mcp(server_parameters) as tool_collection: agent CodeAgent( modelmodel, tools[*tool_collection.tools], add_base_toolsTrue, ) result agent.run(Search docs for how to implement multi-agents with llamaindex) print(result)跑之前把D:/01Projects/MCP/documentation换成你自己的 MCP Server 路径。API_KEY从 TaoToken 控制台的 API Keys 页面复制不要硬编码到公开仓库里建议用环境变量import os API_KEY os.environ.get(TAOTOKEN_API_KEY, sk-临时占位)这样你在终端里export TAOTOKEN_API_KEYsk-xxx之后再跑就不会把 Key 写进代码。4. 验证请求从 usage 字段拆出两次查询的消耗改完通道后跑一次和之前完全相同的查询观察两个地方。第一处是 Smolagents 的终端日志。CodeAgent 默认会打印每一步的 tool call 和 model call你会看到类似Step 1: Calling tool get_docs with querymulti-agents llamaindex Tool get_docs returned 48213 characters Step 2: Model call with prompt_tokens51204, completion_tokens312这里的prompt_tokens51204就是关键。它说明模型这一轮吃进去的 prompt 里绝大部分是 MCP 抓回来的网页正文。如果两次查询各触发一次总结51204 另一个 5 万左右加起来 10 万级别但如果 Agent 因为add_base_toolsTrue多做了几轮反思或重试每轮都把历史 tool result 重新塞进 prompt消耗就会指数级放大到 43 万。第二处是 TaoToken 控制台的请求日志。进入 console 的用量记录页面按时间排序你会看到每次请求的model、prompt_tokens、completion_tokens、total_tokens。把两次get_docs对应的请求标出来对比请求序号触发动作prompt_tokenscompletion_tokens说明1第一次 get_docs 后总结51204312抓取正文约 4.8 万字符2第二次 get_docs 后总结49876287抓取正文约 4.6 万字符3Agent 最终汇总102340521历史 tool result 被重复带入看到第 3 行你就明白了真正的大头不是单次抓取而是多轮对话里历史 tool result 被反复计入 prompt。43 万 Token 里可能只有不到 10 万是「有效抓取」剩下 30 多万都是重复上下文。5. 本篇常见错排查报错一openai.AuthenticationError: Incorrect API key检查API_KEY是否从 TaoToken 控制台正确复制注意不要带多余空格。如果你用的是环境变量确认echo $TAOTOKEN_API_KEY有输出。报错二openai.APIConnectionError: Connection error确认API_BASE写的是https://taotoken.net/api不要写成https://taotoken.net/api/v1或漏掉https。Smolagents 的OpenAIServerModel会自动拼接/chat/completions你只需要给到/api这一层。报错三Model not foundTaoToken 侧支持的模型名可能和你本地 LM Studio 里的名字不完全一致。去模型对话页面确认可用模型列表把MODEL_ID改成列表里的准确名称。现象四usage 字段为空如果你用的不是 TaoToken 而是其他本地推理服务有些服务不返回 usage。切到 TaoToken 后如果还是空检查请求是否真的走到了https://taotoken.net/api可以在代码里加一行print(model.api_base)确认。现象五Token 消耗依然很高说明问题不在通道而在 MCP Server 返回的文本太长。可以在get_docs里对soup.get_text()做截断比如只取前 8000 字符或者用functools.lru_cache缓存相同 URL 的抓取结果避免重复请求同一页面。6. 把通道固定下来后续排障才有基准排障最怕的不是消耗高而是消耗高却找不到原因。把 Smolagents 的OpenAIServerModel指向 TaoToken 之后你至少有了一个稳定的、带 usage 回传的观测点。每次改 MCP Server 的抓取逻辑、改 Agent 的max_steps、改add_base_tools开关都可以用同一套查询跑一遍对比 TaoToken 控制台里的 token 曲线判断改动是省了还是费了。如果你后续要做长期编码类 Agent比如让 Smolagents 持续调用多个 MCP Server 做代码检索和生成建议单独开一个 Coding Plan 通道把调试流量和正式流量分开计费避免排障时的临时请求污染生产额度。接入文档在 doc 页面有完整的参数说明API Keys 管理在 console 的 api-keys 路径下。模型对话入口可以用来快速验证某个模型名是否可用不用每次都跑完整 Agent。我自己的习惯是每次调整 MCP Server 的返回内容后先跑一次固定查询去 TaoToken 控制台截图存一份 usage作为下一次对比的基准。这样两三次迭代之后你就能摸清「抓取多少字符对应多少 prompt_tokens」的经验值再看到 43 万这种数字第一反应就不是慌而是直接去翻日志定位是哪一轮把上下文撑爆了。
返回列表