1. 先搞清楚 TTFT 基准测试到底在比什么
如果你正在评估 LLM 服务的实际响应速度,TTFT(Time To First Token)这个指标比单纯看“总耗时”更有参考价值。它衡量的是从发送请求到收到第一个输出 token 的时间间隔,直接反映了服务的冷启动、模型加载和初始推理效率。
这次对比测试的核心,是把 LLM Gateway 和 OpenRouter 这两个中间服务放在同等条件下跑 Claude-haiku-4.5 模型,连续执行 150 次请求。测试目的不是比谁的功能多,而是看谁在真实工作流中能更快给出“第一句回复”——这对需要实时交互的应用场景特别关键。
LLM Gateway 通常是一个自建或托管式的 API 聚合层,可以统一管理多个模型供应商的调用;OpenRouter 则是一个公开的模型路由平台,用户通过它可以用统一接口访问 Claude、GPT 等多家模型。测试选用的 Claude-haiku-4.5 是 Anthropic 推出的轻量级模型,响应速度快、成本低,适合高频或实时任务。
如果你在选型时纠结“是自建网关还是用现成路由服务”,或者担心“批量调用时首字延迟会不会不稳定”,这类基准数据就能帮上忙。不过要注意,TTFT 受网络条件、服务负载、请求参数和并发设置影响很大,不能只看平均值。
2. 测试环境怎么搭,数据怎么读
虽然原始材料没有给出完整的测试代码和服务器配置,但这类基准测试通常需要控制几个关键变量才能保证结果可对比。如果你准备自己做类似验证,下面这套准备流程更稳妥。
2.1 硬件和网络基线
TTFT 对网络延迟和服务器位置非常敏感。比较负责的做法是:
- 在同一台机器、同一个网络环境下跑两个服务的测试脚本。
- 机器最好选云服务器,位置尽量靠近服务商的主要节点(例如美国东岸或西岸)。
- 记录测试期间的网络延迟:用
ping或traceroute检查到两个服务域名的链路质量。 - 如果条件允许,用
curl -w "time_namelookup: %{time_namelookup}\ntime_connect: %{time_connect}\ntime_starttransfer: %{time_starttransfer}\n"分别测一下纯 HTTP 连接建立耗时,排除 DNS 解析和 TCP 握手的影响。
很多人一看到 TTFT 数值偏高就以为是模型慢,其实可能是网络绕路或 DNS 查询拖了后腿。
2.2 请求参数标准化
模型服务的响应时间受请求内容影响很大。为了保证 150 次请求的可比性,需要固定:
- prompt 长度和复杂度:最好用同一组提示词,或者用随机但结构相似的句子。如果一次发长文本、一次发短文本,TTFT 可能差好几倍。
- temperature 和 max_tokens:温度设为 0 避免随机性,max_tokens 统一设成 50 或 100,确保每次测试不会因为生成长度不同导致时间波动。
- stream 模式:如果测 TTFT,一定要开流式输出(
stream: true),否则拿到的是完整响应时间,不是首字时间。
在实际操作中,我会先用一个固定短 prompt(例如“请说你好”)跑 10 次,看两个服务的 TTFT 是否稳定,再开始正式的多轮测试。
2.3 测量代码怎么写
手动掐表不可靠,最好用程序化方式记录时间戳。以 Python 为例,核心测量逻辑大致长这样:
import time import requests def measure_ttft(api_url, headers, payload): start_time = time.perf_counter() response = requests.post(api_url, json=payload, headers=headers, stream=True) for chunk in response.iter_content(chunk_size=1): if chunk: # 收到第一个有效字符 first_token_time = time.perf_counter() - start_time break response.close() return first_token_time这里要注意几个细节:
- 用
time.perf_counter()而不是time.time(),前者精度更高。 stream=True必须开,然后迭代响应内容,一收到非空 chunk 就立即记时。- 每次测试后最好加 1~2 秒休眠,避免频繁请求触发服务的限流或冷启动惩罚。
150 次请求不建议一次性发完,可以分 15 批,每批 10 个请求,批间休息几秒,这样能模拟真实场景中的间歇性使用压力。
3. 结果分析不能只看平均值
原始测试没有给出具体数值,但根据类似基准的经验,TTFT 数据至少要拆成四个维度看。
3.1 平均 TTFT 和分布区间
平均值只能反映整体倾向,更重要的是分布:
- 如果 LLM Gateway 平均 TTFT 是 1.2 秒,OpenRouter 是 1.5 秒,不能直接说“Gateway 快 25%”。
- 要看 150 次请求的分布:Gateway 是否大部分请求落在 1.0~1.4 秒,而 OpenRouter 在 1.2~2.0 秒之间波动?后者稳定性可能更差。
- 记录最小值、最大值、50分位(中位数)和 95 分位值。95 分位 TTFT 更能反映“最差情况”下的体验——比如 95% 的请求在 2 秒内返回,但剩下 5% 可能慢到 5 秒,这对实时应用来说是硬伤。
我一般会画一个 TTFT 的分布直方图,一眼就能看出哪个服务的数据更“集中”。
3.2 冷启动与热缓存表现
第一轮请求和后续请求的 TTFT 可能有显著差异:
- 前 10 次请求的 TTFT 可能明显高于后面 140 次,因为服务端需要加载模型或预热计算资源。
- 如果测试中加入了随机延迟(比如每隔 10 秒发一个请求),还能看出“冷路径”和“热路径”的差异:OpenRouter 作为公共平台,可能为高频用户保持模型常驻;而自建 Gateway 如果资源分配策略保守,可能在闲置几分钟后再次冷启动。
对于需要长期在线的应用,热缓存下的 TTFT 比冷启动平均值更重要。
3.3 错误率和超时情况
TTFT 再快,如果时不时报错或超时也没用。150 次请求中:
- 统计 HTTP 200 之外的状态码数量(如 429 限流、502 网关错误、504 超时)。
- 记录 TTFT 超过某个阈值(例如 10 秒)的请求比例,这些可能实际已失败但未返回错误码。
- 对比两个服务的错误分布:是集中出现还是随机出现?是否可重试?
在实际业务中,99% 请求的 TTFT 小于 2 秒但 1% 完全失败,不如 100% 请求 TTFT 在 2.5 秒以内。
4. 选型建议:什么情况下优先考虑谁
基于 TTFT 测试结果,结合常见使用场景,可以这样决策:
4.1 适合用 LLM Gateway 的情况
- 已有基础设施集成:如果公司内部已经有身份验证、限流、审计或缓存层,Gateway 可以更容易地对接到现有 pipeline。
- 模型供应商混合使用:需要同时调用 Claude、GPT 和开源模型,且希望用统一 API 格式管理。Gateway 可以在路由层面做故障转移和负载均衡。
- 数据合规要求高:自建 Gateway 可以控制数据流出路径,甚至完全部署在私有环境。
- 请求模式可预测:如果流量比较平稳,能保持模型常驻,自建 Gateway 的冷启动问题不明显。
不过 Gateway 的 TTFT 性能高度依赖部署配置和资源分配。如果节点离用户远,或者模型缓存策略没调好,可能反而比公共平台慢。
4.2 适合用 OpenRouter 的情况
- 快速验证和原型开发:不想操心服务器部署、模型下载和依赖兼容问题,用 OpenRouter 几乎零配置就能试多个模型。
- 流量波动大:如果业务有明显的波峰波谷,公共平台能自动处理扩容缩容,避免资源闲置。
- 需要最新模型版本:像 Claude-haiku-4.5 这类更新较快的模型,OpenRouter 通常会及时上线,自建 Gateway 可能涉及手动更新。
- 成本优先:OpenRouter 按 token 计费,没有闲置成本;自建 Gateway 即使不用也要付服务器费用。
但要注意,OpenRouter 的 TTFT 可能受平台整体负载影响。晚上美国时间高峰时段,响应速度可能比凌晨慢。如果测试数据来自低负载时段,实际生产环境可能要留出余量。
4.3 性能之外的考量点
TTFT 只是选型的一个维度,还要看:
- 成本结构:Gateway 的服务器成本是固定的,OpenRouter 按用量收费。小流量时 OpenRouter 可能更划算,大流量时自建可能更经济。
- 功能支持:是否需要流式输出、并行请求、自定义参数?两个服务对高级功能的支持度可能不同。
- 限流策略:OpenRouter 可能有每分钟请求数或 token 数限制,Gateway 可以自己控制限流规则。
- 故障历史:查一下两家服务的状态页面或社区反馈,看看近期是否有频繁故障或维护窗口。
5. 真实落地时的注意事项
无论选哪个方案,上线前建议按这个顺序做一轮验证。
5.1 先用小流量试运行
不要一上线就全量切换:
- 准备 5%~10% 的生产流量,导到新服务跑几天。
- 记录 TTFT、错误率、token 消耗和成本。
- 特别关注高峰时段的稳定性:下午 2~4 点(用户活跃期)和凌晨 3~5 点(系统维护窗口)的指标可能差异很大。
如果用的是 OpenRouter,可以在控制台设置预算警报,避免测试期间意外超支。
5.2 部署客户端重试和降级逻辑
网络服务和模型 API 不可避免会有临时故障,客户端必须能应对:
- 第一次请求超时(例如 TTFT > 10 秒)后,自动重试 1~2 次,但重试前先换一个节点或服务。
- 准备降级方案:如果 Claude-haiku-4.5 不可用,能否临时切换到 GPT-3.5-turbo 或本地小模型?
- 在重试和降级过程中,继续记录 TTFT 和成功情况,这些数据对后期优化路由策略很有帮助。
5.3 建立持续监控看板
上线后不能放任不管,至少要监控:
- TTFT 日均值和 95 分位值,设警报阈值(如 95 分位 TTFT > 5 秒时触发)。
- 错误率变化趋势,特别是 5xx 错误突然增多可能意味着服务端问题。
- token 消耗和成本对比,如果实际用量远超预估,需要调整缓存或提示词优化策略。
我习惯在 Grafana 上放一个实时 TTFT 仪表盘,既能快速发现异常,也能为容量规划提供数据支持。
6. 常见问题排查思路
即使选了 TTFT 表现更好的服务,实际运行中也可能遇到延迟波动。下面是我常用的排查顺序。
6.1 突然变慢怎么办
如果平时 TTFT 在 1.5 秒左右,突然跳到 5 秒以上:
- 先检查网络:用
mtr或traceroute看是否出现绕路或丢包。 - 查服务状态页:OpenRouter 和 Anthropic 都有公开的状态页面,看是否有已知故障。
- 回顾变更:最近是否更新了提示词格式、增加了请求频率、切换了 API 密钥?这些都可能触发限流或模型重新加载。
- 对比历史:看监控图表,是突然恶化还是缓慢下降?季节性流量高峰或竞争对手的推广活动可能导致平台负载增加。
6.2 批量请求时 TTFT 不稳定
单个请求很快,但并发发 10 个请求就变慢:
- 检查客户端限流:是否在代码中正确控制了并发数?即使服务端支持高并发,客户端网络带宽或 TCP 连接数也可能成为瓶颈。
- 看服务端限流:OpenRouter 对不同套餐有不同并发限制,免费 tier 可能只允许 1-2 个并发请求。
- 验证负载均衡:如果 Gateway 背后有多个模型实例,请求是否均匀分配?有时某个实例负载过高会拖累整体 TTFT。
6.3 TTFT 正常但整体响应慢
第一个 token 来得快,但完整响应要等很久:
- 这可能是 TPS(Tokens Per Second)问题,而不是 TTFT 问题。检查流式输出中每个 chunk 的间隔时间。
- 如果用了完整响应模式(非流式),TTFT 和总耗时几乎相同,无法反映模型的实际流式输出能力。
- 尝试减少
max_tokens或简化提示词,看总耗时是否成比例下降。如果只是 TTFT 变快而总耗时不变,可能是网络传输或后端处理瓶颈。
最后提醒一点,TTFT 基准测试只是模型服务选型的一个参考维度。如果您的应用对首字延迟不敏感(比如后台批量处理),反而应该更关注吞吐量、成本和输出质量。即使需要低延迟,也要结合具体场景判断——是每个请求都独立,还是可以复用上下文?这些因素都会影响最终体验。