# 腾讯 Hy4 工具调用接微博热搜、B站和抖音：工具定义、参数类型和 token 账

> Hy4 正式版权重未公开，自托管只能用 preview；3 个工具占 506 token，抖音 10 条原样 12,902 token，裁剪后剩 8.6%。

- Canonical page: https://everyinfra.com/blog/tencent-hy4-function-calling-social-data
- Published: 2026-11-12T01:15:00+08:00 · Fact-checked: 2026-11-12T01:10:00+08:00

腾讯在 2026 年 11 月 4 日发布了 Hy4 正式版，但到 11 月 11 日凌晨我们查 Hugging Face 时，能下载的权重仍然只有 8 月 27 日上传的 Hy4 preview，所以「自己部署 Hy4 再接实时数据」今天能落地的是 preview，正式版只能经腾讯云和 OpenRouter 托管调用。我们没有运行 Hy4，模型一侧都写成配置示例；实测的是我们的数据接口，11 月 11 日三个时刻共真调 18 次。token 数则用 Hy4 preview 自带的对话模板和分词器在本机算出来：3 个工具定义占 506 个 token，一次抖音搜索的 10 条结果原样塞回去是 12,902 个 token，只留模型用得上的字段后是 1,110 个，只剩 8.6%。另一个更容易踩的坑在参数类型上：vLLM 的 Hy4 解析器只按工具定义里写的类型转换参数，`limit` 没写成 integer 时会以字符串 "10" 交给你的代码，我们的接口会回 422 并且不扣费，但你的循环就白跑了一轮。

> **本文要点**
>
> - Hy4 正式版 2026 年 11 月 4 日发布，权重和系统卡写的是「近期」公开；11 月 11 日 Hugging Face 上只有 Hy4 preview（770B 总参数、49B 激活、Apache 2.0），FP8 版权重 813.8 GB。
> - Hy4 的工具调用在模型这一层不是 JSON，而是 `<tool_call>` 加 `<arg_key>`、`<arg_value>` 的标签格式；vLLM 用 `--tool-call-parser hy_v4` 把它转回 OpenAI 的 `tool_calls`，参数按你给的类型转换。
> - 按 Hy4 分词器计：3 个专用工具定义占 506 token，照抄长说明翻到 939；微博热搜 20 条、B 站搜索 10 条、抖音搜索 10 条原样共约 19,400 token，裁字段后约 2,500。
> - 一轮三次取数的接口费是 $0.009445；三轮对话的模型输入按 OpenRouter 价不裁字段约 $0.0102，裁剪后约 $0.0020。
> - 11 月 11 日三个时刻各测一轮：抖音按 24 小时过滤，每次给的都是 24 小时内的视频；B 站按综合排序，10 条里只有 1 到 2 条是新的；热搜 18 小时后前 20 条全换了。

这篇要回答的问题很具体：你已经有一台自己部署的开源模型，或者打算用 Hy4 这种权重开放的模型，因为数据不想出内网、想自己控成本或想微调；现在要让它回答「今天微博在热议什么、B 站和抖音上相关视频怎么样」这类问题。模型自己不知道今天的事，所以要给它一组工具，让它在需要时发出调用，由你的程序去取数，再把结果交回模型。下面每一步都标清楚哪些是我们真调、真算的，哪些是照官方文档写的配置示例。

## 先把名字和版本说清楚：tencent hy4 正式版、preview 和「开源」

写这篇之前我们先把版本对了一遍，因为网上的说法混在一起。腾讯 11 月 4 日的[新闻稿](https://www.tencent.com/tencent-launches-hy4-joining-the-ranks-of-the-worlds-leading-open-source-ai-models/)写的是 Hy4 正式版发布，新增视觉理解和电脑操作，并说会在「coming days」公开模型权重和系统卡；同一天的[混元研究页](https://hy.tencent.ai/research/hy4)和[中文版](https://hunyuan.tencent.com/research/hy4)写法一致。我们在 2026 年 11 月 11 日 00:2x（新加坡时间）用 Hugging Face 的公开接口查了腾讯账号下名字带 Hy4 的模型，只有两个：`tencent/Hy4-preview` 和 `tencent/Hy4-preview-FP8`，都是 8 月 27 日创建、8 月 28 日最后更新；直接访问 `tencent/Hy4` 返回 404。2026 年 11 月 12 日 01:10（新加坡时间）发稿前我们又查了一次，结果相同：仍只有这两个 preview 仓库，模型接口查 `tencent/Hy4` 返回 401，这是仓库不存在或未公开时的回法。也就是说，「开源」今天只对 preview 成立。

preview 的基本信息以[模型卡](https://huggingface.co/tencent/Hy4-preview)和 [GitHub 仓库](https://github.com/Tencent-Hunyuan/Hy4-preview)为准：MoE 结构，770B 总参数、每个 token 激活 49B，78 层，每层 256 个路由专家取前 8 个加 1 个共享专家，另带一个 10B 参数的 MTP 层用于投机解码；上下文 1M；许可证是 [Apache 2.0](https://www.apache.org/licenses/LICENSE-2.0)。我们用 Hugging Face 的文件列表把权重大小加了一遍：BF16 版 131 个分片共 1,560.0 GB，FP8 版 130 个分片共 813.8 GB。官方给的部署命令都是 8 卡张量并行，这决定了后面算账时自托管的门槛。

正式版目前能用的入口是托管接口。我们在 11 月 11 日 00:16（新加坡时间）读了 [OpenRouter 的模型列表接口](https://openrouter.ai/api/v1/models)：`tencent/hy4` 创建于 11 月 4 日，上下文 1,048,576，唯一的服务方是腾讯，量化标为 fp4，单次最多输出 65,536 个 token，支持的参数里有 `tools`。腾讯云开发者社区的[发布文章](https://developer.cloud.tencent.com/article/2776227)写了国内价：输入每百万 token 6 元、输出 18 元、缓存命中 0.3 元，和 preview 相同，TokenHub 到 12 月 31 日打五折。

| 版本 | 发布日期 | 权重 | 怎么调用 | 工具调用 |
| --- | --- | --- | --- | --- |
| Hy4 preview | 2026-08-27 上传，08-28 更新 | 已公开，Apache 2.0；BF16 1,560.0 GB，FP8 813.8 GB | 自己用 vLLM 或 SGLang 部署；托管也有 | 有，模板和解析器都公开 |
| Hy4 正式版 | 2026-11-04 | 写的是「近期」公开；11-11 查不到 | 腾讯云 TokenHub、OpenRouter、WorkBuddy 等 | 托管接口支持 `tools` |
| Hy4 Flash | 新闻稿写「即将发布」 | 未知 | 未上线 | 未知 |

这张表决定了本文的写法：协议细节、模板、分词器、解析器都来自 preview 的公开文件，可以在本机逐字核对；正式版的工具调用我们只能引用托管方的参数说明。正式版权重公开后，模板和解析器如果有变化，本文的 token 数需要重算，这一点写在文末的边界里。

## 为什么要给开源模型接实时社媒数据

开源模型的知识停在训练截止那天。Hy4 研究页提到它做了「时效检索、多源信息整合、事实一致性校验」方面的专项优化，并给出幻觉率下降的数字，但这些能力的前提是有人把新鲜的材料交给它。腾讯自家产品里，这部分由 WorkBuddy、元宝这些产品的搜索和连接器完成；你自己部署的模型没有这些，问它「今天微博热搜第一是什么」，它只能编，或者老实说不知道。

腾讯公布的幻觉率降幅在[新闻稿](https://www.tencent.com/tencent-launches-hy4-joining-the-ranks-of-the-worlds-leading-open-source-ai-models/)和[研究页](https://hy.tencent.ai/research/hy4)里写法不一，而且都是内部评测，我们没有复现，引用时请带上出处。

工具调用解决的就是「把新鲜材料交给模型」这一步。模型不直接上网，它只输出一段结构化的请求，例如「调用 weibo_trending，limit=20」；你的程序收到后去调真正的数据接口，把结果作为一条 `tool` 消息塞回对话，模型再接着推理。这个分工的好处是取数这件事完全在你手里：调哪个接口、带什么鉴权、结果裁掉哪些字段、一分钟最多调几次，都由你的执行器决定，模型只负责判断什么时候要数据、要什么数据。

![示意插图：一个透明漏斗形的筛子，上方倒进一大堆揉皱的纸、图片小方块、头像圆片和长纸条，代表接口原样返回的大量字段；筛子下方只流出三根整齐的青绿细条，滑进右边一个黑色小盒子的窄缝里，代表模型有限的上下文；旁边的灰色纸篓接住筛下来的多余纸张。](https://everyinfra.com/articles/tencent-hy4-function-calling-social-data/img-explain.webp)

工具结果先在执行器里裁字段，再交给模型：模型的上下文按 token 计费，也有上限。

我们选微博热搜、B 站搜索和抖音搜索三个能力，是因为它们正好代表了三种常见的数据形状。[微博热搜](/weibo-api/trending)是一张短表，每行只有排名、标题、热度；[B 站搜索](/bilibili-api/search)返回视频列表，字段多但每条不长；[抖音搜索](/douyin-api/search)返回的每条视频带作者资料、话题、音乐、多档码率的视频地址，一条就很长。三种形状对模型的上下文压力差别很大，后面的实测会看到差了一个数量级。三个平台的总览页分别在[微博](/weibo-api)、[B 站](/bilibili-api)和[抖音](/douyin-api)。

## hy4 function calling 在协议层长什么样

大多数开发者接触 hy4 function calling 时看到的是 OpenAI 兼容接口：请求里带 `tools` 数组，响应里拿到 `tool_calls`，和 [OpenAI 的函数调用指南](https://platform.openai.com/docs/guides/function-calling)写的一样。但模型本身输出的不是这个 JSON。我们下载了 preview 的 [chat_template.jinja](https://huggingface.co/tencent/Hy4-preview/blob/main/chat_template.jinja)，它定义了模型实际看到和写出的文本：工具清单放在系统消息开头的 `<tools></tools>` 里，每个工具一行 JSON；模型发起调用时先写 `<tool_calls:opensource>`，每个调用写成 `<tool_call:opensource>函数名`，后面跟成对的 `<arg_key>` 和 `<arg_value>` 标签，最后再闭合。下面是我们用这个模板在本机渲染出来的一段，内容是第 1 轮的真实热搜返回（裁剪后）：

```text
<tool_calls:opensource><tool_call:opensource>weibo_trending<arg_key:opensource>limit</arg_key:opensource><arg_value:opensource>20</arg_value:opensource></tool_call:opensource></tool_calls:opensource><｜hy_end:opensource｜><｜hy_start:opensource｜>tool<｜hy_middle:opensource｜><tool_response:opensource>[{"rank":1,"title":"金鸡奖获奖名单","hot_value":1323824,"category":"电影"},{"rank":2,"title":"拼多多送货上门新规11月13日生效","hot_value":856784, ...
```

这个格式有三个直接后果。第一，参数值在模型那一层全是文本，`20` 和 `"20"` 长得一样，要靠服务端的解析器按工具定义把它转回整数，所以工具定义里的类型不能省。第二，模板在把工具定义写进 prompt 时会删掉 `strict` 和 `defer_loading` 两个键（模板里 `tool_to_json` 宏的写法），我们渲染后的 prompt 里确实找不到 "strict"，模型看不到你是否要求了严格模式；`additionalProperties` 则原样保留。第三，带工具的对话默认 `preserved_thinking` 为真，上一轮的思考内容会留在后续 prompt 里，推理模式默认是 `high`，可以用 `reasoning_effort: "no_think"` 关掉，这两点都会影响 token 用量。

把这段文本转回 `tool_calls` 的是推理框架。[vLLM 的 Hy4 部署说明](https://recipes.vllm.ai/tencent/Hy4-preview)要求加 `--tool-call-parser hy_v4 --reasoning-parser hy_v4 --enable-auto-tool-choice`；[SGLang 的说明](https://lmsysorg.mintlify.app/cookbook/autoregressive/Tencent/Hy4-Preview)用 `--tool-call-parser auto`。我们读了 vLLM 主干上的 [hy_v4_tool_parser.py](https://github.com/vllm-project/vllm/blob/main/vllm/tool_parsers/hy_v4_tool_parser.py)，它的 `_parse_value` 函数按工具定义里该参数的类型依次尝试布尔、整数、数字、JSON，最后才退回字符串。这个文件最近一次功能改动是 10 月 31 日合并的 [PR #61542](https://github.com/vllm-project/vllm/pull/61542)，修的是参数名里的空白被吃掉的问题；如果你的 vLLM 版本早于这次合并，参数名带空格的工具会出错。

```bash
# 配置示例（照 vLLM 官方 Hy4 部署说明，本机未运行）：8 卡 FP8，打开工具调用
vllm serve tencent/Hy4-preview-FP8 \
  --tensor-parallel-size 8 \
  --speculative-config '{"num_speculative_tokens":3,"method":"mtp"}' \
  --attention-backend FLASHMLA_SPARSE \
  --tool-call-parser hy_v4 --reasoning-parser hy_v4 \
  --enable-auto-tool-choice \
  --tool-strict-level function \
  --served-model-name hy4-preview --port 8000
```

上面最后加的 `--tool-strict-level function` 不在腾讯的部署说明里，是 vLLM 在 9 月 18 日通过 [PR #56268](https://github.com/vllm-project/vllm/pull/56268) 加的服务端开关。这个 PR 的说明里给了一组很说明问题的数：作者统计了一个线上部署的 9,500 次请求，没有一次带 `tool_choice`，17,476 个工具定义里 `strict` 全是 false，因为常见的 SDK 和智能体框架默认就这么发；结果是服务端没法约束模型输出的调用格式，模型写坏了标签，解析器也救不回来。开关有三档：`auto` 是旧行为，只有标了 strict 的工具才受约束；`function` 约束调用的外壳和函数名；`parameter` 再把参数也按工具定义约束住。自托管时这个开关在你手里，托管接口上则取决于服务方。

## 官方评测里的工具调用分数

模型会不会在该调工具的时候调、参数写得对不对，我们本机没法测。能引用的是腾讯在 preview 模型卡附录里公布的分数。和工具调用最直接相关的两项是 MCP-Atlas（公开集）和 Toolathlon-Verified：Hy4 preview 分别是 83.7 和 74.1，上一代 Hy3 是 75.0 和 56.2。同一张表里，GLM 5.3 是 81.9 和 73.0，Kimi K3 是 84.2 和 76.5，Claude Opus 5 是 85.7 和 76.5；这些对手的分数在表里都带星号，表示是腾讯引用的其他来源。Toolathlon 的任务和评分方法见它的 [GitHub 仓库](https://github.com/hkust-nlp/Toolathlon)；Hugging Face 上把这项分数登记成社区评测结果的方式见[评测结果说明](https://huggingface.co/docs/hub/eval-results)。

![截图：Hy4-preview 模型卡附录评测表的一段，表头是 Hy3、Hy4 preview、DeepSeek V4 Pro 0813、Qwen 3.8 Max、GLM 5.3、Kimi K3、GPT 5.6 Sol、Claude Opus 5；青绿框标出两行，MCP-Atlas（public）一行 Hy4 preview 是 83.7，Toolathlon-Verified 一行是 74.1，上下两行是 OfficeQA Pro 和 APEX-Agents。](https://everyinfra.com/articles/tencent-hy4-function-calling-social-data/img-shot-hy4-card-tool-bench.webp)

Hy4-preview 模型卡附录里的工具调用两项（截图，2026-11-11 读取） [Hugging Face 上的 Hy4-preview 模型卡](https://huggingface.co/tencent/Hy4-preview)

这组数说明两件事，也有两个边界。说明的是：从 Hy3 到 Hy4 preview，工具调用类评测提升明显，Toolathlon 涨了 17.9 分；在同代开源模型里它处在中间偏上，不是最高。边界一：这是 preview 的分数，正式版研究页给的总表我们没有找到这两项的单独数字，正式版的系统卡公布后才能对上。边界二：这些评测里的工具大多是通用的文件、网页、代码类工具，和「按关键词搜 B 站」这种具体接口不完全是一回事，所以下面我们不去猜模型会不会调错，而是把调错之后会发生什么测清楚。

![横向分组条形图，横轴 50 到 90 分。八个模型各两根条，MCP-Atlas 公开集和 Toolathlon-Verified：Hy3 75.0 和 56.2；Hy4 preview 83.7 和 74.1（青绿高亮）；DeepSeek V4 Pro 0813 82.5 和 74.1；Qwen 3.8 Max 81.9 和 72.5；GLM 5.3 81.9 和 73.0；Kimi K3 84.2 和 76.5；GPT 5.6 Sol 82.5 和 73.2；Claude Opus 5 85.7 和 76.5。标题：Hy4 preview 比 Hy3 高 8.7 和 17.9 分，和同代开源模型差不多。](https://everyinfra.com/articles/tencent-hy4-function-calling-social-data/fig-05-tool-bench-bar.zh.light.svg)

## 工具定义怎么写：一个通用工具还是三个专用工具

接 EveryInfra 这类有几百项能力的数据接口，第一反应往往是只定义一个通用工具，参数是平台、能力名和一个 `params` 对象，让模型自己去填。我们把这种写法和「每个能力一个专用工具」都写了出来，用 preview 的模板渲染、分词器计数，比较它们各自往 prompt 里加了多少 token。对照组是同样的系统消息和用户问题、不带工具，共 71 个 token。

```text
[
  {"type": "function", "function": {
    "name": "weibo_trending",
    "description": "Weibo hot search list right now: rank, title, hot_value, category, label.",
    "parameters": {"type": "object", "additionalProperties": false, "required": [],
      "properties": {"limit": {"type": "integer", "minimum": 1, "maximum": 200}}},
    "strict": true}},
  {"type": "function", "function": {
    "name": "bilibili_search",
    "description": "Search Bilibili videos by keyword. Returns title, url, posted_at, view/like/comment/danmaku counts.",
    "parameters": {"type": "object", "additionalProperties": false, "required": ["keyword"],
      "properties": {"keyword": {"type": "string"},
        "sort": {"type": "string", "enum": ["most_commented", "most_liked", "most_viewed", "newest", "relevance"]},
        "limit": {"type": "integer", "minimum": 1, "maximum": 50}}},
    "strict": true}},
  {"type": "function", "function": {
    "name": "douyin_search",
    "description": "Search Douyin videos by keyword. Returns text, url, posted_at, like/comment/share counts, author.",
    "parameters": {"type": "object", "additionalProperties": false, "required": ["keyword"],
      "properties": {"keyword": {"type": "string"},
        "publish_time": {"type": "string", "enum": ["half_year", "one_day", "one_week", "unlimited"]},
        "sort": {"type": "string", "enum": ["most_liked", "newest", "relevance"]},
        "limit": {"type": "integer", "minimum": 1, "maximum": 50}}},
    "strict": true}}
]
```

上面三个专用工具的枚举值都是从我们的[公开目录](https://api.everyinfra.com/api/v1/social/catalog)里原样取的，目录同时给出每个参数的中文说明、默认条数和上限。四种写法的结果如下表。

| 写法 | 工具数 | 工具定义 JSON 字节 | 加进 prompt 的 token |
| --- | --- | --- | --- |
| 1 个通用工具，`params` 是嵌套对象 | 1 | 525 | 256 |
| 3 个专用工具，扁平参数、短英文说明 | 3 | 1,415 | 506 |
| 3 个专用工具，照抄目录里的中文参数说明 | 3 | 3,237 | 939 |
| 10 个专用工具，扁平参数、短英文说明 | 10 | 3,675 | 1,090 |

![横向条形图：工具定义加进 prompt 的 token 数。1 个通用工具 256；3 个专用工具短说明 506（青绿高亮）；3 个专用工具照抄目录中文说明 939；10 个专用工具 1,090。副标题注明不带工具时同一段对话是 71 token，每一轮都会重复带上。](https://everyinfra.com/articles/tencent-hy4-function-calling-social-data/fig-03-tool-defs-tokens-bar.zh.light.svg)

通用工具最省 token，但它把难题推给了模型：模型得记住几百个平台和能力的名字，还得知道每个能力的参数名和允许值；写错时只能靠我们接口返回的 422 去改。更要紧的是上一节说的类型问题，`params` 是一个对象，模型在标签格式里会把它写成一段 JSON 文本，只有当工具定义里写明 `"type": "object"` 时，vLLM 的解析器才会把它解析回对象。专用工具多花两三百个 token，换来的是每个参数都有类型、枚举和上下限，解析器和服务端的约束都能起作用。照抄目录中文说明会让 token 数几乎翻倍，而多出来的大多是给人看的细节，例如分页令牌的有效期；模型做决定用不到这么多，我们的建议是说明写一句话，细节留在执行器里处理。

还要注意这部分开销是每一轮都付的：工具清单在系统消息里，模型每次被调用都要重新读一遍。一次「查热搜再搜两个平台」的任务至少三轮，工具定义就被计费三次。10 个工具时每轮 1,090 token，按 OpenRouter 的输入价 $0.417/百万 token 算，三轮约 $0.0014，单看不多，但如果你的智能体一天跑上千次，这笔钱会比你想的大。

## 参数类型：integer 不写清楚，"10" 就会变成字符串

这一节是本文最实用的发现，而且可以完全在模型以外核对。我们把 vLLM 解析器里负责转换参数值的几个函数原样抽出来，在本机喂给它同一段文本 `10`，只改工具定义里 `limit` 的写法，看它交给你的代码的是什么；然后把这两种结果真的发给我们的接口。

| 工具定义里 limit 的写法 | 解析器交出的值 | 发给 EveryInfra 的结果 |
| --- | --- | --- |
| `{"type": "integer"}` | 10（整数） | 正常返回 |
| `{"type": "string"}` | "10"（字符串） | 422：`limit` must be an integer from 1 to 50 (got '10')，不扣费 |
| 不写 type | "10"（字符串） | 同上 |
| 工具定义里没有这个参数 | "10"（字符串） | 同上 |
| 通用工具里 `params` 写成 object | 对象 | 正常返回 |
| 通用工具里 `params` 不写 type | 一整段字符串 | 422：params: Input should be a valid dictionary，不扣费 |

表里两次 422 都是 2026 年 11 月 11 日 00:22（新加坡时间）真调的结果，响应原文如下图。我们的接口在参数错时会写明哪个参数、期望什么、你发了什么，并在 `next_steps` 里写「Nothing was charged」，这段文字是专门写给模型看的：把它原样作为 `tool` 消息交回去，大多数模型能自己改正再调一次。但这一来一回又多了一轮推理和一轮 prompt，Hy4 默认还开着深度思考，代价不是零。最省事的办法是在工具定义里把每个参数的类型写全，再在执行器里做一次转换：遇到 `"10"` 这种纯数字字符串，按工具定义转成整数再发。类型怎么写，照 [JSON Schema 的 type 说明](https://json-schema.org/understanding-json-schema/reference/type)即可；OpenAI 的[结构化输出文档](https://platform.openai.com/docs/guides/structured-outputs)对严格模式下哪些写法受支持列得更细，比如每个属性都要列进 `required`、`additionalProperties` 必须是 false，这些要求放到自托管的 Hy4 上同样是好习惯。

![截图：终端风格的真实请求和返回。请求是 2026-11-11 00:22:45 新加坡时间发出的 bilibili/search，params 里 limit 是字符串 "10"；返回 HTTP 422，耗时 0.12 秒，error.code 为 invalid_value，青绿框标出 message 一行「limit must be an integer from 1 to 50 (got '10')」和 next_steps 里「Change only limit to a value in allowed, then resend. Nothing was charged.」。](https://everyinfra.com/articles/tencent-hy4-function-calling-social-data/img-shot-ei-limit-422.webp)

limit 写成字符串时我们接口的真实返回：说清哪里错、不扣费 [EveryInfra 接口真实返回](https://api.everyinfra.com/api/v1/social)

同一时段我们还故意把 B 站搜索的 `sort` 写成不存在的 `hot`（00:20 新加坡时间）。返回同样是 422，并给出全部允许值和两个最接近的候选 `most_liked`、`most_viewed`，同样不扣费。对智能体来说，这种「错了也告诉你怎么改」的返回比一句 Bad Request 有用得多；对你的账单来说，错误请求不扣钱，意味着让模型自己试错的成本只有模型那一侧的 token。

## 执行器这一侧的完整往返：手写的模型调用和我们的真实返回

下面从执行器这一侧把一次完整的往返串起来。用户问：「现在微博热搜第一是什么？去 B 站和抖音各找 10 条相关视频，告诉我哪边讨论更新鲜。」模型一侧是配置示例，我们没有运行 Hy4，模型发出的调用是按这个问题手写的；我们这一侧的三次调用都是 11 月 11 日凌晨真调的，返回的内容和计费都来自原始响应。

![流程动画：上排三个方框从左到右是「Hy4（vLLM / SGLang），tool-call-parser hy_v4」「tool_calls，weibo_trending · bilibili_search」「你的执行器：白名单、校验类型、限速」（青绿边框）；向下箭头到「EveryInfra，POST /api/v1/social」；下排从右到左是「裁字段：只留标题、时间、计数、链接」（青绿边框）和「role: tool，回到下一轮 prompt」，再向上回到模型。灰色圆点沿整个环循环，一个青绿小点表示裁剪后的结果回到模型。图下两根横条：原样塞回 20,096 token，裁剪后 3,177 token。](https://everyinfra.com/articles/tencent-hy4-function-calling-social-data/fig-02-tool-roundtrip-flow.zh.light.svg)

第一轮，模型读到问题和工具清单，发出 `weibo_trending(limit=20)`。我们的执行器把它翻译成对 EveryInfra 的请求，00:19:46（新加坡时间）发出，0.81 秒返回 20 条热搜，扣费 $0.000556。排在第一的是「金鸡奖获奖名单」，热度 1,323,824，分类是电影；第二是「拼多多送货上门新规11月13日生效」。第二轮，模型拿热搜第一条当关键词，同时发出 `bilibili_search` 和 `douyin_search` 两个调用，抖音那边加了 `publish_time=one_day`。B 站搜索 00:21:05 返回 10 条，用时 1.7 秒，扣费 $0.000556；抖音搜索 00:21:20 返回 10 条，用时 5.97 秒，扣费 $0.008333。测试用 Key 限速每分钟 10 次，连发时撞上两次 429，返回里写明 6 秒后重试、不扣费，后面「错误、限速和扣费」一节再细说。

```text
# 执行器：把模型发出的 tool_calls 翻译成 EveryInfra 请求，裁字段后交回模型
# 模型一侧为配置示例（OpenAI 兼容客户端连自己部署的 vLLM）；EveryInfra 一侧与本文真调一致
import json, os, requests
from openai import OpenAI

llm = OpenAI(base_url="http://127.0.0.1:8000/v1", api_key="EMPTY")
EI = "https://api.everyinfra.com/api/v1/social"
HEAD = {"Authorization": f"Bearer {os.environ['EVERYINFRA_API_KEY']}"}
ROUTE = {"weibo_trending": ("weibo", "trending"),
         "bilibili_search": ("bilibili", "search"),
         "douyin_search": ("douyin", "search")}
KEEP = {"weibo_trending": ["rank", "title", "hot_value", "category"],
        "bilibili_search": ["title", "url", "posted_at", "view_count", "comment_count", "danmaku_count"],
        "douyin_search": ["text", "url", "posted_at", "like_count", "comment_count", "author_name"]}

def run_tool(name, args, schema):
    if name not in ROUTE:                       # 白名单：模型编出来的工具名不发
        return {"error": f"unknown tool {name}"}
    for k, v in list(args.items()):             # 按工具定义补救类型："10" -> 10
        if schema.get(k, {}).get("type") == "integer" and isinstance(v, str) and v.isdigit():
            args[k] = int(v)
    platform, action = ROUTE[name]
    r = requests.post(EI, headers=HEAD, timeout=90,
                      json={"platform": platform, "action": action, "params": args})
    body = r.json()
    if r.status_code != 200:                    # 422 / 429 原样交回，模型能读懂 next_steps
        return body.get("error", body)
    rows = [{k: row.get(k) for k in KEEP[name] if row.get(k) is not None}
            for row in body.get("results", [])]
    for row in rows:
        if "text" in row:
            row["text"] = row["text"][:80]
    return {"count": len(rows), "results": rows, "charged_usd": body["billing"]["charged_usd"]}
```

模型拿到三条 `tool` 消息之后的回答，我们不替它写；能确定的是它会看到什么。B 站的 10 条是按综合排序取的，发布时间多在 2026 年 11 月 9 日到 11 月 10 日夜里，最早一条是 2026 年 10 月 19 日的提名争议视频，只有 1 条是在请求前 24 小时内发的，内容多是颁奖前的预测；抖音按最近 24 小时过滤，10 条全是 11 月 10 日晚上颁奖之后的发布，作者多是搜狐娱乐、厦门广电、1905电影网、央视文艺这类机构号，最新一条距请求只有 0.6 小时。所以对「哪边讨论更新鲜」这个问题，正确答案取决于你给 B 站传了什么排序，这正是工具定义里要把 `sort` 的枚举列清楚的原因。

## 没跑模型，token 是怎么量的

本文里所有 token 数都不是估算，而是用 Hy4 preview 自己的文件在本机算出来的，方法很简单，你也可以照做。第一步，从 Hugging Face 下载 `chat_template.jinja` 和 `tokenizer.json` 两个文件，前者 14,674 字节，后者约 9.4 MB，不需要下载任何权重。第二步，用 [Jinja](https://github.com/pallets/jinja) 的沙箱环境加载模板，补上 Transformers 渲染模板时提供的两个函数：`raise_exception` 和带 `ensure_ascii` 参数的 `tojson`（[Transformers 的对话模板文档](https://huggingface.co/docs/transformers/main/en/chat_templating)写了这套约定）。第三步，把系统消息、用户问题、工具清单、模型的调用和工具返回按 OpenAI 的消息格式喂给模板，得到模型真正读到的那段文本；再用 [tokenizers](https://huggingface.co/docs/tokenizers/index) 库加载分词器计数。

| 步骤 | 文件或工具 | 大小或版本 | 得到什么 |
| --- | --- | --- | --- |
| 1 | `chat_template.jinja` | 14,674 字节 | 工具清单、调用和工具返回在 prompt 里的原文 |
| 2 | `tokenizer.json` | 约 9.4 MB | 和模型一致的 token 计数 |
| 3 | Jinja 沙箱 + `tojson` + `raise_exception` | 用 uv 临时装 jinja2、tokenizers | 和 Transformers 一样的渲染结果 |
| 4 | OpenAI 格式的消息 | 第 1 轮的真实返回 | 每一轮 prompt 的大小，原样和裁剪后各一份 |

这样量出来的数有两个好处。一是它和推理框架实际送进模型的 prompt 一致，因为 vLLM 和 SGLang 用的就是同一个模板；二是它可以反复做对照实验，改一个字段、加一个工具，马上能看到 token 的变化，不用租 8 张卡。局限也要说清：分词器只告诉你输入有多少 token，模型会输出多少思考内容、调用写得有多长，这些只能真跑才知道；托管接口背后的模板如果和公开文件不同，账单上的 token 数也会不同。我们在 2026 年 11 月 11 日的测量里，不带工具的基准对话是 71 个 token，这个数可以拿来检查你自己的渲染是否和我们一致。

输出这一侧虽然量不了，结构上可以先想清楚。Hy4 默认打开深度思考，vLLM 启动时加了 `--reasoning-parser hy_v4`，它会把思考内容从正文里分出来，放进响应的单独字段（vLLM 的 [Reasoning Outputs 文档](https://docs.vllm.ai/en/latest/features/reasoning_outputs.html)写了这个字段怎么取）；工具调用则由 `--tool-call-parser` 放进 `tool_calls`。两者都走 vLLM 的 [OpenAI 兼容服务](https://docs.vllm.ai/en/latest/serving/openai_compatible_server.html)，所以你的执行器只需要读标准字段。要注意的是前面说过的 `preserved_thinking`：带工具时思考内容会留在下一轮 prompt 里，三轮对话的输入 token 会比我们上面量出的数更多，多多少取决于模型每轮想了多少。想压低这部分，可以在不需要推理的取数轮把 `reasoning_effort` 设成 `no_think`，到最后汇总时再打开。

## 工具结果要先裁字段

原样把接口返回塞给模型最省事，也最贵。我们把第 1 轮三次真调的返回分别用 Hy4 分词器计数，再按执行器里的裁剪规则只留模型做判断要用的字段，结果如下。

| 能力 | 条数 | 原样字节 | 原样 token | 裁剪后 token | 留下比例 |
| --- | --- | --- | --- | --- | --- |
| `weibo/trending` | 20 | 7,276 | 3,287 | 545 | 16.6% |
| `bilibili/search` | 10 | 8,949 | 3,227 | 842 | 26.1% |
| `douyin/search` | 10 | 29,001 | 12,902 | 1,110 | 8.6% |

![横向分组条形图，按 Hy4 分词器计 token。weibo/trending 20 条：原样 3,287，裁剪后 545；bilibili/search 10 条：原样 3,227，裁剪后 842；douyin/search 10 条：原样 12,902，裁剪后 1,110（青绿）。标题：抖音搜索 10 条原样是 12,902 token，裁到 1,110（8.6%）。](https://everyinfra.com/articles/tencent-hy4-function-calling-social-data/fig-04-result-tokens-bar.zh.light.svg)

抖音那一项特别大，原因在字段：目录里 `douyin/search` 的 `response_fields` 有 55 个，除了正文、计数和作者，还有多档码率的视频地址、下载地址、封面和动图封面、音乐信息、话题 ID、作者头像和粉丝数等。这些对做数据分析很有用，对模型回答「哪边更新鲜」几乎没用，还会把真正有用的标题和时间淹没在一长串地址里。热搜返回本身不长，但每行带一个 URL 编码后的搜索链接，汉字被编码成 `%E9%87%91` 这样的形式，一个汉字变成九个字符，分词器也只能一段段切，所以 20 条原样就有 3,287 token。

把三轮对话完整渲染一遍，差距更直观：不裁字段时第三轮的 prompt 是 20,096 token，裁剪后是 3,177 token；三轮加起来分别是 24,565 和 4,904。Hy4 的上下文有 1M，装得下，但上下文越长，推理越慢、首个 token 越晚，按 token 计费的托管接口也越贵。裁剪规则要按任务定：做舆情摘要只要标题、时间和计数；要让模型引用原帖，就把链接留下；要分析评论情绪，就换成评论接口并留正文。我们的裁剪规则写在上面的执行器代码里，可以直接改。

## 三个时刻的实测：热搜在变，B 站和抖音跟得上吗

工具调用的价值在于「实时」，所以我们没有只跑一次就下结论。同一套流程在 2026-11-11 的三个时刻各跑一轮（新加坡时间 00:19、00:42、18:39）：先取微博热搜前 20 条，再把第 1 条原样当关键词，交给 B 站搜索和抖音搜索。判断「新不新」的规则在跑之前就写好了：结果的发布时间距请求时刻不到 24 小时，算新。第 3 轮之后，我们又用第 1 轮的关键词「金鸡奖获奖名单」重搜了一次，用来区分「话题换了」和「搜索跟不上」这两种情况。每一次请求的原始返回我们都原样存档，下面的表格和图都从这些存档里直接统计，没有手工挑选或改动任何一条结果。

| 时刻（新加坡时间） | 热搜第 1 条（热度） | 前 20 条与第 1 轮重合 | B 站综合排序 24 小时内 | B 站最新排序 24 小时内 | 抖音最近 24 小时 | 本轮扣费 |
| --- | --- | --- | --- | --- | --- | --- |
| 00:19 | 金鸡奖获奖名单（1,323,824） | 20 / 20 | 1 / 10 | 没跑 | 10 / 10 | $0.009445 |
| 00:42 | 金鸡奖获奖名单（1,035,614） | 17 / 20 | 1 / 10 | 5 / 10 | 10 / 10 | $0.010001 |
| 18:39 | 商场看中羽绒服网上便宜一千（1,105,701） | 0 / 20 | 2 / 10 | 0 / 10 | 6 / 6 | $0.010001 |
| 18:40，沿用第 1 轮关键词 | — | — | 没跑 | 8 / 10 | 10 / 10 | $0.008889 |

![横向分组条形图，四行分别是 00:19 金鸡奖获奖名单、00:42 金鸡奖获奖名单、18:39 商场看中羽绒服网上便宜一千、18:40 沿用第 1 轮关键词；每行三根条表示结果里 24 小时内发布的占比。B 站综合排序：10%、10%、20%、没跑；B 站最新排序：没跑、50%、0%、80%；抖音最近 24 小时：四行都是 100%（青绿）。标题：抖音的 24 小时过滤每轮都跟得上；B 站综合排序多是旧视频，最新排序碰上长句热搜也会落空。](https://everyinfra.com/articles/tencent-hy4-function-calling-social-data/fig-06-freshness-rounds-bar.zh.light.svg)

先看热搜本身。00:19 到 00:42 只隔 23 分钟，第 1 条没变，热度从 1,323,824 降到 1,035,614，前 20 条里有 17 条还在；到 18:39，前 20 条和第 1 轮一条都不重合，第 1 条换成了一条消费话题。这说明两件事：半小时以内重复取热搜，拿到的几乎是同一张表，执行器可以按 10 到 30 分钟缓存，省下的钱不多，但能少一轮工具调用；隔半天再看，就是另一张表，必须重新取。热搜接口每次 0.48 到 0.90 秒返回，是三个能力里最快的。

再看 B 站。综合排序三轮都以旧视频为主：00:19 那一轮，10 条里只有 1 条是 24 小时内发的，最旧的一条是 22 天前讨论提名的视频；18:39 那一轮，关键词换成羽绒服的话题，10 条里有 2 条是半小时内发的同名视频，但最旧的一条是将近 5 年前的探访视频。最新排序的表现分成两种。关键词是短的名词短语时，它有用：00:42 是 5/10，18:40 沿用「金鸡奖获奖名单」时是 8/10，最新一条 3.3 小时前发布。关键词是一整句话时，它会落空：18:39 用「商场看中羽绒服网上便宜一千」去搜，最新排序给出的 10 条里最新的也是 16 天前，内容只是同时含有「商场」和「羽绒服」的旧视频，而综合排序里那两条半小时内的同名视频，最新排序里一条都没有。我们不知道 B 站内部为什么这样排，只照实记下观察。

抖音的 `publish_time=one_day` 过滤四次都可靠：结果全部在 24 小时内，00:19 那一轮最新一条只有 0.6 小时。但 18:39 那一轮只回了 6 条，而不是 10 条，说明一个刚上榜的话题，24 小时内的视频本来就不多。这时仍按次扣 $0.008333：抖音搜索在目录里是按请求计价，不按条数；只有失败或空结果才不扣。抖音每次 5.9 到 8.3 秒返回，B 站 1.5 到 8.1 秒，执行器的超时至少要设 30 秒。

第 2 轮还有一个对模型很重要的发现：抖音 10 条结果里，「最佳男主角」的说法不一致。带认证标记的搜狐娱乐在北京时间 11-10 21:43 写的是梁家辉，和当晚微博热搜「梁家辉影史第二位三金影帝」一致；一个约 5 万粉丝、没有认证标记的个人号在 18:07 发帖，写成了另一位演员获奖，比搜狐娱乐那条早 3 个半小时。如果执行器把作者名和发布时间裁掉，模型只看正文，很可能把两种说法当成同等可信。所以我们在裁剪规则里保留了 `author_name` 和 `posted_at`；如果要做事实核对，可以再留 `author_is_verified` 和 `author_follower_count`，让模型按来源和时间判断，而不是按票数。

| 观察 | 对执行器和工具定义的要求 |
| --- | --- |
| 23 分钟内热搜前 20 条有 17 条不变，18 小时后 0 条不变 | 热搜缓存 10 到 30 分钟；跨半天的任务一定重取 |
| 热搜标题常是一整句话 | 在工具说明里让模型先把热搜缩成 2 到 4 个核心词再搜；或由执行器同时跑两种排序，按 `posted_at` 合并去重 |
| B 站综合排序多是旧视频 | 要「最新进展」时传 `sort=newest`，并在结果里保留 `posted_at` |
| 抖音 24 小时过滤可能不足 10 条，仍按次计费 | 不要为了凑条数连续重搜；条数少本身就是「话题刚起来」的信号 |
| 同一事件出现互相矛盾的帖子 | 裁剪时保留作者名和发布时间，必要时加认证状态和粉丝数 |
| 抖音 5.9–8.3 秒、B 站最长 8.1 秒 | 超时设 30 秒以上；两个搜索没有先后依赖时可以并发执行 |

三轮加上沿用关键词的重搜，一共 13 次成功调用，合计扣费 $0.038336；两次 429 和三次 422 都没有扣费。按这个节奏，一个每 30 分钟跑一轮的监控任务，一天 48 轮，取数费大约是 48 × $0.0100 ≈ $0.48；如果热搜按 30 分钟缓存、只在第 1 条变化时才去搜 B 站和抖音，费用还会更低。

## 执行器还要做的五件事

上面的执行器代码只有三十多行，生产里还要补几件事，每一件都对应我们实测里碰到的情况。第一是白名单。模型偶尔会编出一个工具清单里没有的名字，或者把参数名写错；执行器只认自己登记过的工具名，其他一律返回错误说明，不要把模型写的平台名和能力名直接拼进请求。这也是我们不建议用通用工具的另一个原因：通用工具等于把白名单交给了模型。

第二是类型补救。即使工具定义写全了类型，也难免有服务端没开严格模式、模型把整数写成带引号文本的时候。执行器按工具定义把纯数字字符串转成整数，把看起来像 JSON 的字符串转成对象，能省掉一轮 422 和一轮推理。vLLM 的 [tool_strict_level.py](https://github.com/vllm-project/vllm/blob/main/vllm/tool_parsers/tool_strict_level.py) 写明了三档约束的含义，它在服务端用 [XGrammar](https://xgrammar.mlc.ai/docs/) 的结构化标签实现；打开 `parameter` 档后，参数会被按工具定义约束，执行器的补救就成了兜底。

第三是限速和重试。我们的接口在 429 时返回 `retry_after`，执行器按它等待；不要让模型看到 429，否则它可能换个参数再调，越调越超。本文用的测试 Key 限速每分钟 10 次。第四是裁剪，前面已经讲过，规则跟着任务走。第五是记账。每次返回里都有 `charged_usd`，执行器把它累加进这一轮对话的元数据，再和模型那一侧的 token 用量放在一起，你就能知道每个回答的真实成本。解析模型交出的参数时用标准库 [json](https://docs.python.org/3/library/json.html) 即可；用 [requests](https://requests.readthedocs.io/en/latest/) 或 [OpenAI 的 Python 客户端](https://github.com/openai/openai-python)都可以，我们的接口只要求 JSON 请求体和一个 Bearer 头。

| 要做的事 | 实测里看到的情况 | 写在执行器哪里 |
| --- | --- | --- |
| 工具名白名单 | 通用工具让模型自己挑平台和能力 | `ROUTE` 字典 |
| 类型补救 | `limit` 是 "10" 时返回 422，不扣费 | 发请求前按工具定义转一遍 |
| 429 等待 | 测试 Key 连续两次 429，`retry_after` 6 秒 | 等待后原样重发 |
| 裁字段 | 抖音 10 条原样 12,902 token，裁剪后 1,110 | `KEEP` 字典 |
| 记账 | 每次 200 返回都带 `charged_usd` | `run_tool` 的返回值 |

## 上线前，在你自己的部署上回放一遍模型调用

本文没有运行 Hy4，所以「模型会不会调对」这件事，要由你在自己的部署上验证。办法不复杂：从真实业务里挑 20 到 30 个问题，覆盖三类情况，一类是需要调工具的，一类是闲聊或常识、不该调工具的，一类是要两个工具先后接力的。问题里至少放几条带错别字、口语化或中英混写的说法，因为真实用户就是这样问的，工具说明写得太窄时，这类问题最容易让模型不调工具或调错工具。每个问题在同样的采样参数下跑 3 次，把模型发出的 `tool_calls` 原样存下来，再用执行器里同一套规则逐条判。判对错的标准要在跑之前写好，不看到结果再改，否则很容易把「模型这次写成这样」当成「本来就该这样」。

| 检查项 | 怎么判对 | 不通过时先查什么 |
| --- | --- | --- |
| 工具名合法 | 名字在执行器的 `ROUTE` 里 | 几个工具的说明是否太像、太长 |
| 参数合法 | 用 [jsonschema](https://python-jsonschema.readthedocs.io/en/stable/) 按工具定义的 `parameters` 校验 `arguments` | 类型是否写全，服务端是否开了 `--tool-strict-level parameter` |
| 不该调时不调 | 闲聊类问题的 `tool_calls` 为空 | 请求里的 `tool_choice` 是否被写成了 required |
| 两步任务接得上 | 第二轮的关键词来自第一轮的返回 | 上一轮的 `tool` 消息是否完整带进了下一轮 |
| 报错后能自己改 | 把我们接口的 422 原样交回，下一轮参数通过校验 | 执行器是否把 `next_steps` 裁掉了 |

回放的成本主要在你自己的 GPU 上。数据这一侧不必每次真调：把本文这类真实返回存成固定样本，在第二轮以后原样喂回模型，就能测模型读结果、接着调用的行为，而且每次输入一致，前后版本才好比较。要测端到端，再挑几条真调，一轮三次调用按本文目录价约 $0.0094。托管的正式版也可以用同一套问题回放，和 preview 在你的工具上逐项对比；在正式版权重公开之前，这是判断要不要换模型最直接的办法。

每次回放记下四个比例：工具名合法、参数通过校验、不该调时误调、422 之后一轮内改对。preview 和正式版之间、改工具说明前后，都拿这四个数比较；只看一两段对话的观感，很难判断一处改动是不是真的有用，也很难发现某一类问题在悄悄变多。

## 算账：模型费、取数费和自托管

先算一轮往返。取数这边按目录价：`weibo/trending` $0.000556、`bilibili/search` $0.000556、`douyin/search` $0.008333，三次合计 $0.009445，就是我们真调时响应里 `charged_usd` 的累加。模型这边，我们只能算输入：三轮对话的 prompt 合计，原样塞回是 24,565 token，裁剪后 4,904 token。按 OpenRouter 在 11 月 11 日 00:16（新加坡时间）列出的 Hy4 输入价 $0.417/百万 token，分别约 $0.0102 和 $0.0020；按腾讯新闻稿写的约 $0.90/百万 token，分别约 $0.0221 和 $0.0044。模型的输出（包括默认打开的深度思考）我们没有实测，没有算进去，这部分请用你自己的日志补上。

![横向条形图，一轮往返的费用（美元）：模型输入原样塞回、按腾讯公布价 $0.0221；原样塞回、按 OpenRouter 价 $0.0102；EveryInfra 三次调用按目录价 $0.0094；模型输入裁剪后、按腾讯公布价 $0.0044；裁剪后、按 OpenRouter 价 $0.0020（青绿）。副标题：三轮对话 prompt 合计原样 24,565 token、裁剪后 4,904 token，模型输出没有实测、未计入。](https://everyinfra.com/articles/tencent-hy4-function-calling-social-data/fig-07-roundtrip-cost-bar.zh.light.svg)

这张图最值得看的是中间那根：不裁字段时，光是模型读取数据的输入费就超过了取数本身的费用；裁剪之后，模型输入费降到取数费的五分之一左右。换句话说，在这类任务里，省钱的关键不在换一个更便宜的数据源，而在执行器里那十几行裁剪代码。把这个任务放大成每小时跑一次、一个月 30 天：取数费约 $6.80；模型输入费按 OpenRouter 价裁剪后约 $1.47，不裁约 $7.38。

| 项目 | 单价（读取时间） | 一轮 | 每小时一轮、30 天 |
| --- | --- | --- | --- |
| EveryInfra 取数（3 次调用） | 目录 price_usd（11-11 00:16 新加坡时间读取，2026-11-12 复核未变） | $0.009445 | $6.80 |
| Hy4 输入，裁剪后（OpenRouter） | $0.417/百万 token（11-11 00:16 新加坡时间） | $0.0020 | $1.47 |
| Hy4 输入，原样塞回（OpenRouter） | 同上 | $0.0102 | $7.38 |
| Hy4 输入，裁剪后（腾讯公布价） | 约 $0.90/百万 token（11-04 新闻稿） | $0.0044 | $3.18 |
| 自托管 8 张 H200（按需租用） | Runpod 每卡每小时 $5.29（11-11 读取） | — | $30,470 |

表中腾讯公布价是刊例价。腾讯云在 2026 年 11 月 10 日更新的[模型价格说明](https://www.tencentcloud.com/document/product/1300/78937)写明，Hy4 推理费到 12 月 31 日按刊例价五折结算；折扣到期后托管价会翻倍，比较托管和自托管时要把这一点算进去。

自托管那一行要单独说。Hy4 preview 的 FP8 权重 813.8 GB，官方命令是 8 卡张量并行；[NVIDIA 的 H200](https://www.nvidia.com/en-us/data-center/h200/) 每卡 141 GB 显存，8 卡共 1,128 GB，放下权重后剩下的才是 KV 缓存。按 [Runpod 定价页](https://www.runpod.io/pricing)上 H200 每卡每小时 $5.29 的按需价，8 卡一小时 $42.32，30 天约 $30,470。同样的钱在 OpenRouter 上能买约 730 亿个输入 token。对「每小时查一次热搜」这种量，自托管在成本上没有任何道理；它的价值在别处：数据不出你的机房、可以微调、可以用 `--tool-strict-level` 这类服务端开关自己控制输出格式、不受托管方限流。如果你本来就有空闲的 8 卡机器，那取数费就是这件事的主要现金成本，一个月几美元。

## 错误、限速和扣费

工具调用的循环里，错误是常态，所以要知道每种错误会不会扣钱、模型能不能自己处理。下表是本文实测遇到的全部错误，时间都是 11 月 11 日新加坡时间。

| 时间 | 情况 | HTTP | 返回里写了什么 | 扣费 |
| --- | --- | --- | --- | --- |
| 00:19:54、00:19:57 | 测试 Key 超过每分钟 10 次 | 429 | rate_limited，retry_after 6 秒，Nothing was charged | 0 |
| 00:20:01 | `sort` 写成不存在的 hot | 422 | 全部允许值，did_you_mean 给出 most_liked、most_viewed | 0 |
| 00:22:45 | `limit` 是字符串 "10" | 422 | must be an integer from 1 to 50 (got '10') | 0 |
| 00:22:52 | `params` 整个是字符串 | 422 | params: Input should be a valid dictionary | 0 |

429 的处理放在执行器里，不要交给模型：按返回的 `retry_after` 等待后重发即可，模型不需要知道这件事。422 则应该交回模型，因为只有模型知道它本来想查什么。我们的错误返回里有 `fault` 字段，值是 request 表示请求本身有问题、改了再发，account 表示账户层面的限制；有 `retryable` 字段告诉你原样重试有没有意义。抖音搜索这类较慢的能力，目录写明同步请求有 85 秒的时间上限，超时可以在请求体里加 `"mode": "async"` 拿到任务号再轮询。整套接入方式和 Key 的申请见[快速上手](/docs#quickstart)，价格见[定价页](/pricing)。

## 做不了或要注意的地方

第一，模型行为没有实测。我们没有运行 Hy4，本文所有关于「模型会发出什么调用」的部分都是配置示例；模型会不会在该调的时候调、会不会编参数，只能参考腾讯公布的评测和你自己的回放。第二，token 数基于 preview 的模板和分词器。正式版权重公开后，如果模板改了，例如工具清单的写法或思考内容的保留规则变了，本文的 token 数要重算；托管接口背后用的模板我们看不到。第三，延迟没有写，因为本机没有跑模型；文中出现的秒数只是我们接口的响应时间。

第四，数据边界。热搜、视频搜索都是平台公开展示的内容，我们的接口不登录、不碰私密内容。微博、B 站、抖音各自有官方开放平台（[微博开放平台](https://open.weibo.com/wiki/API)、[B 站开放平台](https://openhome.bilibili.com/)、[抖音开放平台](https://developer.open-douyin.com/)），适合做自家账号的授权数据；跨账号看公开内容，是本文这种用法。第五，抖音搜索的单价比热搜和 B 站搜索高一个数量级，一轮的取数费里它占了 88%，如果预算紧，可以先用热搜和 B 站判断值不值得再查抖音。

## 延伸阅读

站内相关文章：[GLM 5.3 在 Claude Code 里写知乎、微博采集脚本](/blog/glm-5-3-claude-code-zhihu-weibo-scripts)；[Qwen-Agent 经远程 MCP 拿工具](/blog/qwen-agent-mcp-ecommerce-review-analyst)；[DeepSeek V4.1 Flash 清洗、打标签一万条评论的总账](/blog/deepseek-v4-1-flash-review-cleaning-tagging)；[抖音 API Python 教程](/blog/douyin-api-python)。模型前面已有支持 MCP 的客户端时，直接接[远程 MCP 服务](/mcp-server)更省事。

## 常见问题

### hy4 function calling example 在哪里能找到？

腾讯的模型卡和 GitHub 仓库只给了普通对话的示例，没有工具调用的完整例子；工具调用的格式要看 [chat_template.jinja](https://huggingface.co/tencent/Hy4-preview/blob/main/chat_template.jinja) 和 vLLM 的[工具调用文档](https://docs.vllm.ai/en/latest/features/tool_calling.html)。本文的工具定义 JSON 和执行器代码可以直接当例子用，请求格式和 [OpenAI 的函数调用](https://platform.openai.com/docs/guides/function-calling)一样。

### hy4 function calling error 一般是什么原因？

按我们读源码和真调的结果，最常见的有三类：没加 `--enable-auto-tool-choice` 和 `--tool-call-parser hy_v4`，模型的标签原样出现在回答正文里；工具定义没写参数类型，整数和对象被当成字符串交出来，下游接口报 422；vLLM 版本早于 10 月 31 日，参数名带空白时被改掉。第三类可以对照 [PR #61542](https://github.com/vllm-project/vllm/pull/61542) 判断。

### tencent hy4 api 怎么调用，和自托管有什么区别？

托管调用有腾讯云 TokenHub（OpenAI 兼容地址，见[腾讯云开发者社区的发布文章](https://developer.cloud.tencent.com/article/2776227)）和 [OpenRouter](https://openrouter.ai/docs/guides/features/tool-calling)，两者都支持 `tools`，用的是 Hy4 正式版；OpenRouter 的接入步骤见它的[快速上手文档](https://openrouter.ai/docs/quickstart)。自托管目前只能用 preview 权重，好处是模板、解析器和严格模式都在你手里，代价是 8 卡起步。

### 这么大的模型能在本地跑吗？

Hugging Face 上 Hy4-preview 的第 10 号讨论帖里，提问者说 Qwen 和 GLM 已经有 300B 以下、单机能跑的版本，Hy4 太大了。按我们算的权重大小，FP8 版 813.8 GB，至少要 8 张 141 GB 显存的卡；社区有人做了 GGUF 低比特量化（同一讨论区第 8、9 号帖，格式说明见 Hugging Face 的 [GGUF 文档](https://huggingface.co/docs/hub/gguf)），但质量和工具调用的稳定性没有官方数据。如果只是想让模型能查热搜，托管接口加我们的数据接口是更现实的起点。

## 参考资料

1. Tencent Launches Hy4, Joining the Ranks of the World's Leading Open-Source AI Models，腾讯，2026-11-04，https://www.tencent.com/tencent-launches-hy4-joining-the-ranks-of-the-worlds-leading-open-source-ai-models/
1. Introducing Hy4，腾讯混元，2026-11-04，https://hy.tencent.ai/research/hy4
1. Hy4 正式发布（中文研究页），腾讯混元，2026-11-04，https://hunyuan.tencent.com/research/hy4
1. tencent/Hy4-preview 模型卡，Hugging Face，2026-08-28 更新，https://huggingface.co/tencent/Hy4-preview
1. tencent/Hy4-preview-FP8，Hugging Face，2026-08-28 更新，https://huggingface.co/tencent/Hy4-preview-FP8
1. Tencent-Hunyuan/Hy4-preview，GitHub，https://github.com/Tencent-Hunyuan/Hy4-preview
1. Hy4-preview chat_template.jinja，Hugging Face，https://huggingface.co/tencent/Hy4-preview/blob/main/chat_template.jinja
1. Hy4-preview，ModelScope，https://modelscope.cn/models/Tencent-Hunyuan/Hy4-preview
1. tencent/Hy4-preview 使用说明，vLLM Recipes，https://recipes.vllm.ai/tencent/Hy4-preview
1. Hy4-Preview Cookbook，SGLang，https://lmsysorg.mintlify.app/cookbook/autoregressive/Tencent/Hy4-Preview
1. hy_v4_tool_parser.py，vLLM，2026-11-08 最近提交，https://github.com/vllm-project/vllm/blob/main/vllm/tool_parsers/hy_v4_tool_parser.py
1. [Bugfix][Tool Parser] Preserve whitespace in HYV4 argument names（#61542），vLLM，2026-10-31，https://github.com/vllm-project/vllm/pull/61542
1. [Frontend] Add --tool-strict-level（#56268），vLLM，2026-09-18，https://github.com/vllm-project/vllm/pull/56268
1. Tool Calling，vLLM 文档，https://docs.vllm.ai/en/latest/features/tool_calling.html
1. Structured Outputs，vLLM 文档，https://docs.vllm.ai/en/latest/features/structured_outputs.html
1. Tool Parser，SGLang 文档，https://docs.sglang.io/advanced_features/tool_parser.html
1. Function calling，OpenAI 平台文档，https://platform.openai.com/docs/guides/function-calling
1. Tool & Function Calling，OpenRouter 文档，https://openrouter.ai/docs/guides/features/tool-calling
1. Models API（tencent/hy4 价格与参数），OpenRouter，2026-11-11 00:16 读取，https://openrouter.ai/api/v1/models
1. Hy4 模型页，OpenRouter，https://openrouter.ai/tencent/hy4
1. 腾讯混元 Hy4 正式版发布，腾讯云开发者社区，2026-11-04，https://developer.cloud.tencent.com/article/2776227
1. Model pricing，腾讯云国际站，2026-11-10 更新，https://www.tencentcloud.com/document/product/1300/78937
1. Hy4 Preview FAQ：Specifications, API, Pricing，腾讯云，2026-08-28，https://intl.cloud.tencent.com/techpedia/148044
1. Chat templates，Hugging Face Transformers 文档，https://huggingface.co/docs/transformers/main/en/chat_templating
1. Evaluation results，Hugging Face Hub 文档，https://huggingface.co/docs/hub/eval-results
1. Toolathlon，HKUST NLP，GitHub，https://github.com/hkust-nlp/Toolathlon
1. DeepSeek Sparse Attention 论文，arXiv 2512.02556，https://arxiv.org/abs/2512.02556
1. IndexCache 论文，arXiv 2603.12201，https://arxiv.org/abs/2603.12201
1. Apache License 2.0，Apache 软件基金会，https://www.apache.org/licenses/LICENSE-2.0
1. AngelSlim，腾讯，GitHub，https://github.com/tencent/AngelSlim
1. NVIDIA H200 Tensor Core GPU，NVIDIA，https://www.nvidia.com/en-us/data-center/h200/
1. GPU Cloud Pricing，Runpod，2026-11-11 读取，https://www.runpod.io/pricing
1. With Qwen and GLM now in sub 300B local machine level, this is a big model（讨论 #10），Hugging Face，2026-08-29，https://huggingface.co/tencent/Hy4-preview/discussions/10
1. Tencent says its Hy4 joins 'top-tier' of open-source AI models，Nikkei Asia，2026-11-04，https://asia.nikkei.com/business/technology/artificial-intelligence/tencent-says-its-hy4-joins-top-tier-of-open-source-ai-models
1. Tools（MCP 规范），Model Context Protocol，https://modelcontextprotocol.io/specification/2025-06-18/server/tools
1. openai-python，OpenAI，GitHub，https://github.com/openai/openai-python
1. SGLang，GitHub，https://github.com/sgl-project/sglang
1. 微博开放平台 API 文档，新浪微博，https://open.weibo.com/wiki/API
1. 哔哩哔哩开放平台，哔哩哔哩，https://openhome.bilibili.com/
1. 抖音开放平台，抖音，https://developer.open-douyin.com/
1. EveryInfra 社媒数据目录，EveryInfra，2026-11-11 00:16 读取，https://api.everyinfra.com/api/v1/social/catalog
1. Tencent Hy4 Tested for Free: Is It Actually Good?，YouTube，2026-11-04（新加坡时间 11-05 凌晨发布），https://www.youtube.com/watch?v=3YFnzpwNEvM
1. Type（JSON Schema 参考），JSON Schema，https://json-schema.org/understanding-json-schema/reference/type
1. tool_strict_level.py，vLLM，https://github.com/vllm-project/vllm/blob/main/vllm/tool_parsers/tool_strict_level.py
1. XGrammar 文档，https://xgrammar.mlc.ai/docs/
1. Jinja，Pallets，GitHub，https://github.com/pallets/jinja
1. Tokenizers 文档，Hugging Face，https://huggingface.co/docs/tokenizers/index
1. Requests 文档，https://requests.readthedocs.io/en/latest/
1. Reasoning Outputs，vLLM 文档，https://docs.vllm.ai/en/latest/features/reasoning_outputs.html
1. OpenAI-Compatible Server，vLLM 文档，https://docs.vllm.ai/en/latest/serving/openai_compatible_server.html
1. Structured outputs，OpenAI 平台文档，https://platform.openai.com/docs/guides/structured-outputs
1. GGUF，Hugging Face Hub 文档，https://huggingface.co/docs/hub/gguf
1. Quickstart，OpenRouter 文档，https://openrouter.ai/docs/quickstart
1. json — JSON encoder and decoder，Python 文档，https://docs.python.org/3/library/json.html
1. jsonschema 文档，Python，https://python-jsonschema.readthedocs.io/en/stable/
