最近在各种AI编程社区里面逛,发现一个很有意思的现象——大家都在疯狂地折腾怎么省Token。
有人搞Prompt缓存,有人换便宜模型,甚至还有人专门写了一个省Token.skill,让大模型在回复的时候尽量精简。更夸张的是,有人为了省钱,把Claude换成了各种开源小模型,然后抱怨说效果变差了。
这些操作,怎么说呢,就像你家水龙头在哗哗漏水,你不去修水龙头,反而跑去超市买打折的矿泉水。
其实真正吃掉你Token的大头,不是大模型的回复太长,也不是你的Prompt写多了。是Skill本身。
先给不太熟悉的同学解释一下。Skill就是一段预定义的指令,告诉大模型应该怎么一步一步完成一个任务。比如你可以写一个Skill,让大模型帮你操作浏览器,上某个网站搜东西,然后把结果整理出来。
听起来很方便对吧?问题出在哪呢?
我们来看一个具体的例子。假设我要让AI帮我做这么一件事:
打开浏览器,访问Amazon,搜索”牛仔裤”,从第一页的搜索结果里找到最便宜的那条,把商品名称和链接返回给我。
这个需求很简单,对人来说,打开网页点几下就搞定了。我们用Skill来实现它。
我写了一个Skill,核心逻辑大概是这样的:
Steps 1. 使用浏览器工具,导航到 https://www.amazon.com 2. 找到搜索框,输入"牛仔裤"并搜索 3. 等待搜索结果加载 4. 获取页面快照,分析第一页所有商品的名称和价格 5. 比较所有价格,找出最便宜的商品 6. 返回该商品的名称、价格和链接
看起来清晰明了。我直接在Claude Code里面运行这个Skill,模型用的是Opus 4.6——没办法,要驱动浏览器工具做这种多步骤操作,小模型根本搞不定。
运行这个Skill,我足足等了12分钟。
跑完以后我去OpenRouter后台看了一下这次任务的消耗:

看到没有?几十次API调用,每次都携带将近10万tokens的上下文。最后一算总账,这个看似简单的任务消耗了我将近10美元。
我仔细看了一下每次API调用的内容,发现了一个非常离谱的事情:
大模型在用”智力”做不需要智力的事情。
举几个例子:
- 导航到Amazon首页 —— 大模型需要”思考”应该调用browser_navigate工具,传入URL。就这么一个简单的操作,一轮对话下来,系统提示词、工具定义、Skill内容、对话历史全部打包发送,直接吃掉将近10万tokens。
- 找搜索框并输入关键词 —— 大模型需要先调用snapshot获取页面结构,然后”思考”哪个元素是搜索框,再调用type输入文字。两轮对话,又是将近20万tokens。
- 点击搜索按钮 —— 又是一轮对话,大模型需要分析页面快照,找到搜索按钮的ref ID,然后调用click。又是10万tokens。
- 分析搜索结果 —— 这里是最夸张的。大模型需要获取整个页面的快照,这个快照本身就很长,然后它需要从里面找到所有商品的价格信息,进行比较。又是10万tokens。
你看出问题了吗?
打开一个URL,在搜索框里输入文字,点击按钮——这些操作需要大模型来”思考”吗?这就好比你请了一个数学教授来帮你按计算器,教授每按一个键之前都要在脑子里推演一遍偏微分方程。
几十次API调用里面,真正需要大模型”智力”的,其实只有一步:从搜索结果中判断哪个商品最便宜。 其他全是确定性的操作——打开网页、输入文字、点击按钮、提取文本——这些操作写几行Python就能搞定,根本不需要大模型参与。
想明白了这一点,我让Claude Code把这个Skill改造成Python脚本。原则很简单:
所有确定性的、不需要智力判断的环节,用代码实现。只有需要智力判断的环节,才调用大模型。
改造后的代码核心逻辑是这样的:
from playwright.sync_api import sync_playwright import openai def find_cheapest_jeans(): # ===== 第一部分:纯代码,不需要大模型 ===== with sync_playwright() as p: browser = p.chromium.launch(headless=True) page = browser.new_page() # 1. 导航到Amazon(确定性操作,不需要AI) page.goto("https://www.amazon.com") # 2. 搜索牛仔裤(确定性操作,不需要AI) page.fill('input[name="field-keywords"]', '牛仔裤') page.press('input[name="field-keywords"]', 'Enter') page.wait_for_load_state('networkidle') # 3. 提取搜索结果(确定性操作,不需要AI) results = page.query_selector_all('div[data-component-type="s-search-result"]') products = [] for result in results[:20]: # 只取前20个 title_el = result.query_selector('h2 span') price_el = result.query_selector('.a-price .a-offscreen') link_el = result.query_selector('h2 a') if title_el and price_el and link_el: products.append() browser.close() # ===== 第二部分:需要大模型的智力判断 ===== # 为什么这里要用大模型?因为价格格式可能不统一 # 有的写 $29.99,有的写 $29.99 - $35.99,有的有优惠券 # 还有的价格是"See price in cart",这些需要AI来理解 client = openai.OpenAI( base_url="https://openrouter.ai/api/v1", api_key="your-key" ) product_text = " ".join( f"[{i+1}] {p['title']} | {p['price']}" for i, p in enumerate(products) ) response = client.chat.completions.create( model="minimax/minimax-m1", messages=[{ "role": "user", "content": f"下面是Amazon搜索牛仔裤的结果,请找出最便宜的一条。" f"只返回序号数字,不要其他内容。 {product_text}" }] ) idx = int(response.choices[0].message.content.strip()) - 1 cheapest = products[idx] return cheapest result = find_cheapest_jeans() print(f"最便宜的牛仔裤:{result['title']}") print(f"价格:{result['price']}") print(f"链接:{result['url']}")
注意看代码的结构——我用注释把它分成了两部分。第一部分是纯代码操作:打开浏览器、输入搜索词、提取商品信息。这些操作100%确定性,不需要大模型参与。第二部分才是调用大模型:让它从一堆商品里面判断哪个最便宜。
你可能会问,比较价格为什么还需要大模型?直接用代码排序不就行了?
因为Amazon的价格格式乱七八糟。有的商品显示$29.99,有的显示$29.99 - $45.99(价格区间),有的写See price in cart,还有的价格旁边带一个with coupon。要把这些情况全部用代码处理,你光写正则表达式就得写半天。但对大模型来说,理解这些格式是它的强项。
运行改造后的代码,17秒跑完,结果直接打印在终端里。
去OpenRouter后台一看——API调用次数:1次。Token消耗:约2.1K tokens。费用:$0.004。
我把两次运行的数据放在一起对比:
没有看错,费用从10美元降到了不到半美分,降了99%以上。运行时间从12分钟降到17秒,快了40多倍。
很多人没有意识到一个问题:大模型每做一次工具调用,都需要携带完整的上下文。
第一次调用,大模型需要接收系统提示词+工具定义+用户消息。光Claude Code的系统提示词和工具定义就有好几万tokens,加上Skill的内容,第一轮就将近10万tokens了。它返回一个工具调用,然后你把工具执行结果发回去。第二次调用,大模型需要接收之前所有的内容+第一次的助手消息+第一次的工具结果+……
看出来了吗?每多一轮工具调用,上下文就膨胀一次。 几十轮下来,累积的tokens量是天文数字。而这些历史消息里面,绝大部分是浏览器页面快照——那些密密麻麻的HTML元素和ref ID。
这就是为什么工具调用密集型的Skill特别费Token。不是大模型话多,是它每次说话之前,都要把之前所有的对话重新”读”一遍。
而改造成代码以后,浏览器操作全部由Playwright完成,大模型只需要在最后被调用一次。它接收到的输入就是一个简单的商品列表文本,2K tokens搞定。
上面的例子我用的是OpenRouter + Opus 4.6。但如果你有Claude Pro或Team订阅,还有一个更狠的玩法。
先说一个现实:Claude的官方API价格确实不便宜。Sonnet 4每百万输入Token 3美元,输出15美元。Opus就更不用说了。如果你用API来跑上面这种工具调用密集型任务,几十轮对话下来,光API费用就够你心疼的。
但订阅用户有一个巨大的优势——Anthropic提供了一个叫Claude Agent SDK的东西。这个SDK可以直接调用你本地的Claude Code,走的是你的订阅额度,不需要额外提供任何大模型API Key。
什么意思呢?就是说你每个月付的那20美元订阅费,本来就包含了5小时的Claude Code使用时间。现在你可以通过Agent SDK,在自己的Python脚本里直接调用Claude Code来完成那个”需要智力判断”的环节。不需要OpenRouter,不需要API Key,不需要额外花一分钱。
我们来看看改造后的代码:
import anyio from playwright.async_api import async_playwright from claude_agent_sdk import query, ClaudeAgentOptions, AssistantMessage, TextBlock async def find_cheapest_jeans(): # ===== 第一部分:纯代码,不需要大模型 ===== async with async_playwright() as p: browser = await p.chromium.launch(headless=True) page = await browser.new_page() await page.goto("https://www.amazon.com") await page.fill('input[name="field-keywords"]', '牛仔裤') await page.press('input[name="field-keywords"]', 'Enter') await page.wait_for_load_state('networkidle') results = await page.query_selector_all( 'div[data-component-type="s-search-result"]' ) products = [] for result in results[:20]: title_el = await result.query_selector('h2 span') price_el = await result.query_selector('.a-price .a-offscreen') link_el = await result.query_selector('h2 a') if title_el and price_el and link_el: products.append() await browser.close() # ===== 第二部分:调用Claude Code,走订阅额度 ===== product_text = " ".join( f"[{i+1}] {p['title']} | {p['price']}" for i, p in enumerate(products) ) prompt = ( f"下面是Amazon搜索牛仔裤的结果,请找出最便宜的一条。" f"只返回序号数字,不要其他内容。 {product_text}" ) result_text = "" async for message in query( prompt=prompt, options=ClaudeAgentOptions( system_prompt="你是一个价格比较助手,只返回数字。", max_turns=1 ) ): if isinstance(message, AssistantMessage): for block in message.content: if isinstance(block, TextBlock): result_text += block.text idx = int(result_text.strip()) - 1 cheapest = products[idx] return cheapest result = anyio.run(find_cheapest_jeans) print(f"最便宜的牛仔裤:{result['title']}") print(f"价格:{result['price']}") print(f"链接:{result['url']}")
核心变化就一个——把OpenRouter的API调用换成了claude_agent_sdk的query函数。安装也很简单:
pip install claude-agent-sdk
这个SDK会自动调用你本地装好的Claude Code。只要你登录了Claude订阅账号,它就直接走你的订阅额度,不走API计费。
这意味着什么?上面那个”需要智力判断”的步骤,从花钱变成了花$0。对,零额外费用。你唯一消耗的,是5小时额度里面的几秒钟而已。
而且还有一个隐藏的好处——既然大模型调用的部分已经不花钱了,你甚至可以在脚本里多调几次Claude。比如让它先判断哪些搜索结果是真正的牛仔裤(排除广告和配件),再从里面找最便宜的。之前用API的时候,多调一次就多花一次钱,你会下意识地省着用。现在走订阅额度,心理负担一下就没了。
所以最终的方案就是:Playwright负责干活,Claude负责动脑,订阅负责买单。 三者各司其职,效率拉满,额外开销为零。
这里我要特别强调一点,因为我知道肯定有同学会搞混。
我说的”把Skill改成代码”,不是让你在Skill的Markdown里面嵌入代码片段。类似这样:
Steps 1. 运行以下Python代码来打开浏览器并搜索: python from playwright.sync_api import sync_playwright # ...一堆代码... 2. 分析返回的结果,找出最便宜的商品
这种写法,本质上还是Skill。大模型读到这段Skill以后,它还是会一步一步地调用工具——调用终端执行你写的代码片段,然后读取输出,然后”思考”下一步该干什么。每一步照样携带完整上下文,该膨胀的Token一个都不会少。你只是把浏览器操作从browser工具调用换成了terminal工具调用,换汤不换药。
我说的是,把整个任务逻辑写成一个真正的.py文件。比如find_cheapest_jeans.py,保存在你的电脑上。这个脚本从头到尾自己跑,中间需要大模型判断的地方,通过Agent SDK自己调用Claude,最后把结果打印出来。
下次你想用的时候,在Claude Code里面说一句:
帮我运行 find_cheapest_jeans.py
就完事了。Claude Code收到这句话,调用一次终端执行python find_cheapest_jeans.py,脚本自己跑完,结果直接打印出来。整个过程对Claude Code来说,就是一次工具调用——执行一个命令,返回输出。
对比一下:
- Skill方式: Claude Code读取Skill → 思考第一步 → 调用工具 → 读取结果 → 思考第二步 → 调用工具 → …… → 几十轮对话,烧掉10美元
- .py文件方式: Claude Code执行一条命令 → 脚本自己跑完 → 返回结果。1轮对话,不到1K tokens
看到没有?连之前那2.1K tokens都省了。因为脚本内部调用Agent SDK时,走的是一次独立的Claude会话,不会叠加到Claude Code的主对话上下文里。
所以记住:Skill是给大模型看的说明书,.py文件是给Python解释器跑的程序。 一个要烧Token,一个不用。别搞混了。
我上面举的这个例子可能不是特别好,有人可能会说,如果我不仅仅要爬亚马逊,还要爬虾皮,淘宝,小红书这些呢?每一个网站都手动写代码吗?
其实你可以第一次运行的时候让大模型操作浏览器走完全程,并生成playwright的代码,后面从第二次开始,所有操作都通过代码进行。
除此之外,你日常使用的很多Skill,是完全固定的,毫无变化的流程,例如自动发送小红书帖子。就一个网站,同一个流程,这种就非常适合写代码。
其实道理很简单,你日常用的很多Skill,仔细想想就会发现——大部分步骤都是确定性的操作。
比如:
- 打开某个网站 → 代码搞定
- 在搜索框输入关键词 → 代码搞定
- 点击按钮 → 代码搞定
- 提取页面上的文字 → 代码搞定
- 读取文件内容 → 代码搞定
- 调用某个API → 代码搞定
- 格式化输出结果 → 代码搞定
真正需要大模型的,往往只有中间那一小步”判断”或”理解”的环节。
所以下次当你觉得Token花得太多的时候,不要急着去折腾缓存、换模型、写省Token.skill。先看看你的Skill,问自己一个问题:
这个Skill里面,有多少步骤其实不需要大模型?
然后让大模型帮你把那些确定性的步骤改写成Python代码。保留需要智力的部分给大模型,把不需要智力的部分还给代码。
这才是真正的降本增效——不是逼大模型少说话,而是别让大模型做不该它做的事。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/271813.html