news 2026/9/3 13:56:13

AgentScope 令牌计数:覆写 1 个方法,看懂账单

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
AgentScope 令牌计数:覆写 1 个方法,看懂账单

AgentScope 令牌计数:覆写 1 个方法,看懂账单

【免费下载链接】agentscopeBuild and run agents you can see, understand and trust.项目地址: https://gitcode.com/GitHub_Trending/ag/agentscope

AgentScope 的模型计费不靠猜。它的令牌计数器只有一个入口:ChatModelBase.count_tokens。本文讲清这个方法的契约、默认估算算法,以及自定义 token 计数的写法,让你控制上下文压缩的触发时机,管住账单。

复现场景:压缩晚触发一步,整次请求作废

你跑一个长任务 agent,上下文越滚越大,压缩本应提前介入。但估算值偏低,压缩没触发,下一次请求撞上服务商的上下文硬限,整轮推理和工具结果全部作废。反过来,估算偏高会过早压缩,有用历史被换成摘要,你还为摘要多付一次调用费。

⚠️ 两个问题都归到一个返回值:await self.model.count_tokens(...)

打开 _base.py:count_tokens 的契约与默认算法

打开 src/agentscope/model/_base.py,第 369 行附近的签名长这样:

async def count_tokens( self, messages: list[Msg], tools: list[dict] | None, ) -> int: ...

默认实现做的事很直白:

  • 遍历每条消息的内容块,把TextBlock、思考块、工具调用的 input、工具结果文本全部拼进一个字符串;
  • 文本 token 数 = UTF-8 字节数除以 4,四舍五入;
  • 每个DataBlock(图片、文件)按固定 2000 计,常量叫_MULTIMODAL_DATA_BLOCK_TOKEN_ESTIMATE
  • tools参数先json.dumps,并入文本一起算。

中文一个字符占 3 字节,除以 4 后约等于 1 字符 1 token,默认值日常够用。但它和各家真实分词器有偏差,要精确的模型计费,就覆写它。

盘点 src/agentscope/model/:9 个子类都能挂计数器

打开src/agentscope/model/目录,__init__.py里导出 9 个具体类:AnthropicChatModelDashScopeChatModelDeepSeekChatModelGeminiChatModelMoonshotChatModelOllamaChatModelOpenAIChatModelOpenAIResponseModelXAIChatModel。每个类都在同名子包的_model.py里,继承ChatModelBase

扩展点就在基类 docstring 里写明的一句话:子类可覆写count_tokens,换上针对自家分词器的实现。你的模型落在 9 家之一,继承对应类即可,格式化、重试逻辑原样保留;全新服务商,则直接继承ChatModelBase

在你的项目里覆写 count_tokens

在你自己的项目里新建一个模型类,仓库本身是只读的。以 OpenAI 系为例,核心就这几行:

import json import tiktoken from agentscope.model import OpenAIChatModel enc = tiktoken.encoding_for_model("gpt-4o") class MyOpenAIModel(OpenAIChatModel): async def count_tokens(self, messages, tools=None) -> int: texts = [] for msg in messages: for block in msg.get_content_blocks(): texts.append(getattr(block, "text", "") or str(block)) if tools: texts.append(json.dumps(tools, ensure_ascii=False)) return len(enc.encode("".join(texts)))

注意两点:get_content_blocks()是基类遍历消息用的同一个入口,块结构别自己另起炉灶;tools的计法保持和基类一致,这样压缩前后的数字可比。多模态消息里,DataBlock你可以沿用每块 2000 的扁平估算,也可以按服务商的图片计价公式细化。

这个数字的去向:context_size 与工具结果切分

谁在消费这个数字?打开src/agentscope/agent/_agent.py,调用点有十几处,关键的两处:

  • 压缩判定:estimated_tokens < trigger_ratio * context_size就跳过。ContextConfigtrigger_ratio默认 0.8、上限 0.9,context_size默认 32768,所以默认触发线约 26214;
  • 工具结果切分:_split_tool_result_for_compression用一个单块反复调用count_tokens,找到不超过tool_result_limit的切分点。单条巨型工具结果会触发多次计数,精确但慢的分词器在这里成本会放大,超大型工具输出可以考虑缓存。

估算准不准,直接决定压缩在 26214 这条线附近是「刚刚好」还是「差一截」。

写断言:照抄 model_count_tokens_test.py 的写法

tests/model_count_tokens_test.py 给了现成范式:40 万字符的 base64 图片加上 "hi",断言总数等于 2001;再断言 base64 与 URL 两种来源的DataBlock估算一致,都是 2000。测试用的MockModeltests/utils.py

照这个风格给你的计数器写一条:

class MyCounterTest(IsolatedAsyncioTestCase): async def test_count_matches_tokenizer(self): model = MyOpenAIModel() # 构造参数按你的凭据填 msg = UserMsg(name="u", content=TextBlock(text="hello")) n = await model.count_tokens([msg], None) self.assertEqual(n, 1)

再补一条 DataBlock 断言,确认图片不会被当成 base64 文本按字节计费,验证就齐了。

计数只是估算,分词器才是账单——把count_tokens覆写成官方分词器,压缩时机、工具切分、模型计费这三件事就对齐了。

【免费下载链接】agentscopeBuild and run agents you can see, understand and trust.项目地址: https://gitcode.com/GitHub_Trending/ag/agentscope

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/3 13:54:44

半导体制造中的蚀刻工艺:从干湿法原理到生产实践全解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/3 13:52:52

SaaS产品宣传片文字标题动画:AE/PR模板使用与实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/3 13:51:11

从屏幕里跑出来:破屏视频合成的三条技术路线与实战拆解

最近刷到“劈叉舞的初音&#xff0c;但是真从屏幕里跑出来了”这类标题时&#xff0c;我第一反应并不是“初音这个动作好不好看”&#xff0c;而是“这到底是怎么做出来的”。因为要让观众相信一个二维或 3D 角色真的从屏幕平面里钻出来&#xff0c;不是一个滤镜就能解释的事。…

作者头像 李华
网站建设 2026/9/3 13:50:35

3步给Rust桌面应用加3D:Iced矩阵变换与3D渲染速成

3步给Rust桌面应用加3D&#xff1a;Iced矩阵变换与3D渲染速成 【免费下载链接】iced A cross-platform GUI library for Rust, inspired by Elm 项目地址: https://gitcode.com/GitHub_Trending/ic/iced 界面还是一片平&#xff1f;Iced 是一个受 Elm 启发的跨平台 Rust…

作者头像 李华
网站建设 2026/9/3 13:50:34

小鹏G9L七重试炼背后:智能电动车三电安全与整车极限验证逻辑

小鹏G9L的“水陆空七重试炼”&#xff0c;如果只看成一次营销表演&#xff0c;那确实容易错过重点。这套测试真正想讲的&#xff0c;并不是一台车能不能冲过水池、碾过烂路、扛住冲击那么简单&#xff0c;而是把三电系统、底盘结构、传感器感知、车身密封和整车控制器放在一起验…

作者头像 李华