实测新模型服务后,为何仍保留旧默认
作者为桌面 AI 助手接入 Modal 上的 DeepSeek 服务,并将服务商配置从分散的条件分支整理为统一元数据。针对语音回复的基准测试未支持替换原默认服务,因此新接入仅作为可选项发布。
AI 深度解读
DeepSeek V4.1 Flash 在独立测试里首 token 快了 38%,接进桌面助手的真实语音链路后,整体却慢了 32%。Ankita AI 作者最终交付了 Modal 接入,但保留 Baseten 作为默认服务。
这次改造值得看的,是作者怎样识破一个看似漂亮的跑分:模型回复快,不等于用户更早听到声音。工具定义、提示词长度和缓存状态,都可能改变结论。
接一个新服务,先把供应商配置收拢
Ankita 原先在几处代码里写死了 Baseten。作者先把供应商差异整理进 src/core/provider.mjs:base URL、model、key 和请求默认参数统一存成元数据,语音规划器与文字聊天都从这里读取。以后增加供应商,主要是添加配置记录。
Modal 使用 deepseek-ai/DeepSeek-V4.1-Flash-1017。部署的 /v1/models 宣称上下文窗口为 1,048,576 tokens;默认输出上限为 4,096 tokens,最低设为 400 tokens,给推理过程留空间,reasoning_effort 设为 low。
鉴权也集中处理:MODAL_PROXY_TOKEN_ID 与 MODAL_PROXY_TOKEN_SECRET 合成端点要求的 bearer token;若配置了 MODAL_PROXY_TOKEN,则优先使用它。Settings 暴露 URL 和 token,遇到 401 会提示预期的 token 格式。语音默认仍走 Baseten,设置 VOICE_PROVIDER=modal 才切换。
这类整理的价值很实际:接入差异集中在一处,业务流程不用到处判断供应商。
为什么独立跑分快,真实语音却慢了
第一轮只测规划器。作者准备了 6 条口语式提示,每条跑 3 轮,每个规划器 18 次请求,两边合计 36 次全部成功。
Modal 的首 token 耗时中位数是 408 ms,Baseten 是 657 ms,快 38%;完整回复分别为 725 ms 和 1,477 ms,快 51%。但 Modal 只输出 68 tokens,Baseten 输出 236 tokens。回复短了,完整响应自然可能更早结束,不能全算成生成能力的优势。
随后,作者用 scripts/verify-voice-latency.mjs 驱动真实 CLI 语音循环,带上实际规划器、agent 提示词、全部 30 个工具 schema,以及 Sarvam TTS。每个规划器测试 6 轮,结果反转:
- 从转写文本到音频播放器,Baseten 中位数为 2,593 ms,Modal 为 3,414 ms,慢了 32%。
- 单看规划器环节,Modal 慢了 67%。
- Baseten 的单轮范围为 2,340–2,724 ms;Modal 为 2,019–3,933 ms,波动明显更大。
对语音助手而言,用户等多久才能听见声音,比规划器单独跑多快更有意义。
追踪记录进一步缩小了问题范围。真实请求包含 11,793 个提示词字符,以及 39,701 个工具 schema 字符。响应头返回前的耗时,包含输入预填充(prefill)与排队;此时还没有生成 token。
Baseten 三轮分别为 1,136 / 1,126 / 1,118 ms,比较稳定。Modal 则为 2,229 / 669 / 1,953 ms。作者将这种波动归因于前缀缓存:相同输入前缀被复用时快,未命中时慢。
作者还缩过工具集合。在另一组从 22 个工具、16.3k 字符缩到 8 个工具、8.1k 字符的测试中,Modal 到响应头仍需 1,662–1,717 ms,Baseten 为 890–902 ms。这组实验和前面的 30 工具完整链路口径不同,不能混为一谈,但支持了作者的判断:瓶颈主要在部署的输入处理与排队阶段。
推理参数也没带来捷径。reasoning_effort: "minimal" 被 HTTP 400 拒绝;传入 reasoning_effort: 1 反而生成了 78 个推理 tokens,高于 low 的 39 个,所以继续使用 low。
保留可选接入,也要写清切换默认的门槛
Modal 最终随 Ankita v2.7.5 发布,作为可选供应商,Baseten 保持语音默认。
作者给后续切换写了验收条件:启用前缀缓存,或补足 prefill 容量,让完整 30 工具请求稳定地在 1.1 秒以内返回响应头;然后重跑两套基准脚本,只有「转写到播放器」的耗时改善才接受。原文只给出了一套脚本的具体路径。
同一个 PR 还为 Plugins 页面增加了 MCP 标签页,支持搜索官方 MCP registry,按固定命令安装,以及列出、启用、启动、停止和移除服务器。
这里的边界处理也值得借鉴。DesktopMcp 包装已有的 McpStore 和 McpManager,沿用现有审批机制。安装只记录命令,启动时才要求确认那条具体命令。应用自带的 browser 和 computer-use 服务不进入用户管理列表;仅支持远程连接的条目会展示原因。
这和供应商改造有共同点:扩展能力时,尽量复用已有配置与执行机制。
我的判断
保留旧默认的决定有依据。真实链路已经出现退步,团队没有必要为了独立跑分更漂亮而切换。
但这还不足以判定 Modal 或 DeepSeek 普遍更慢。每个规划器只有 6 轮真实测试,样本偏薄;原文也没有提供受控的缓存命中与未命中对照、并发测试或部署容量数据。前缀缓存是作者提出的解释,不能仅凭响应头耗时就彻底排除其他因素。
这些数据足以支持当前产品的保守选择,尚不足以给供应商下普遍结论。
更便宜的 token、百万级上下文、没有共享队列的专属部署,是作者最初尝试的理由。但原文没有给出实际成本对照,也没有证明这些条件能换来稳定的语音低延迟。它们适合作为候选筛选项,不能替代验收。
能拿来做什么
- 为 AI 编程助手或语音助手更换模型服务时,保留真实系统提示词和工具定义,测量用户任务完成时间,再用首 token 等指标定位原因。
- 在 Node 服务中增加供应商时,可以把 URL、模型、鉴权和请求默认值集中管理,避免业务代码不断增加条件分支。
- 比较响应速度时,同时记录输出 tokens、输入规模和缓存条件;回复长度差异很大时,不要只凭完整响应耗时排名。
- 新服务可以先作为可选配置交付,并提前写清默认切换门槛;像 MCP 服务器这样的命令执行能力,则应继续走已有审批流程。