单次 LLM 调用只需要 1 秒,为什么一个 AI Agent 任务仍然可能需要几秒,甚至几十秒才能完成?
原因在于,Agent 的执行过程通常不止一次模型请求。它可能先让模型拆解任务,再调用数据库或外部 API,随后将工具结果交给模型分析;如果中途出现超时,还可能触发重试。多个步骤串联起来之后,单次请求的耗时就不再能代表整个任务的响应速度。
要定位这类问题,除了查看模型接口的响应时间,还需要还原完整执行链路,识别关键路径,并通过可重复的测试验证优化效果。
本文从一个可计算的耗时模型出发,介绍如何利用 Trace 拆解 Agent 延迟、区分串行与并行开销,以及建立一套可复用的性能排查流程。
一、先拆解 Agent 的端到端耗时
一个 Agent 任务的整体耗时,可以拆成以下几部分:
Agent 总耗时 = 模型调用耗时 + 工具调用耗时 + 调度与数据处理耗时 + 队列等待耗时 + 重试带来的额外耗时
这里的各项是便于分析的耗时分类,不代表任何场景下都能直接相加。对于并行执行的任务,需要根据步骤之间的依赖关系计算关键路径。
假设某个 Agent 依次执行以下操作:
| 执行步骤 | 耗时 |
|---|---|
| 第一次 LLM 调用 | 1.2 秒 |
| 第一次工具调用 | 0.4 秒 |
| 第二次 LLM 调用 | 1.5 秒 |
| 第二次工具调用 | 3 秒 |
| 本地处理与调度 | 0.5 秒 |
| 总耗时 | 6.6 秒 |
在这个纯串行示例中,模型调用一共耗时 2.7 秒,工具调用一共耗时 3.4 秒,其余处理耗时 0.5 秒。
如果只优化模型调用,将其总耗时降低 30%,那么节省的时间约为:
2.7 × 30% = 0.81 秒
端到端耗时将从 6.6 秒降至约 5.79 秒,整体改善约 12.3%。
这个例子说明,模型请求本身更快,并不意味着 Agent 整体任务会获得相同比例的性能提升。如果外部工具、调度或排队占用了大量时间,就需要进一步分析这些环节。
以上数字仅用于说明计算方法,不代表实际生产测试结果。
二、常见的四类性能瓶颈
1. 多轮模型调用形成串行等待
一些 Agent 采用规划、执行、观察、再规划的循环结构。后一步必须等待前一步的输出,因此即使每次模型调用都很快,多轮等待仍会累积。
排查时可以关注:
- 单个任务触发了多少次模型请求;
- 每次请求的输入和输出 Token 数量;
- 是否存在重复规划或重复总结;
- 哪些调用必须串行执行,哪些可以独立运行。
优化方向包括减少不必要的模型调用、控制上下文长度,以及在依赖关系允许时并行处理独立任务。
并行并不总是更快。它可能增加资源竞争、请求排队和结果汇总成本,需要结合实际执行路径验证。
2. 外部工具调用占据关键路径
Agent 调用的数据库、搜索服务、企业内部 API 或第三方平台,都可能成为延迟来源。
以 HTTP API 为例,一次调用可能涉及 DNS 解析、TCP 连接、TLS 握手、请求传输、服务端处理和响应读取。不同阶段出现问题,最终表现都可能是"工具调用很慢",但处理方法并不相同。
建议为关键工具调用记录以下指标:
- 总耗时及状态码;
- DNS、连接建立和 TLS 握手耗时;
- 请求发出到首字节返回的时间;
- 服务端处理时间(如果服务端能提供);
- 超时、错误与重试次数。
其中,客户端测得的首字节时间包含网络传输与服务端处理等环节,不能直接等同于纯网络延迟。
如果服务部署在不同区域,还需要结合实际请求链路评估跨区域访问的影响。单独执行 Ping 测试只能提供部分网络信息,不能替代真实 HTTPS 请求的耗时测量。
3. 重试机制放大了原有延迟
重试可以提高瞬时故障下的成功率,但如果超时阈值、重试次数和退避策略配置不当,也会放大整体耗时。
例如,一个工具请求超时后再次执行,Agent 不仅需要等待第一次请求超时,还要承担后续请求的执行时间。如果多个任务同时失败并集中重试,还可能进一步增加服务端负载。
建议区分记录:
- 首次请求耗时;
- 每次重试的耗时与原因;
- 重试后的最终状态;
- 重试是否增加了服务端负载;
- 重试是否可能造成重复写入等副作用。
对于具有写入副作用的工具,还需要考虑幂等性,不能只为了降低失败率而无限重试。
4. 并发、队列和连接池限制
当多个 Agent 任务同时执行时,性能问题可能来自模型服务的请求队列、工具服务限流、数据库连接池或本地工作线程不足。
此时,单个请求的处理时间未必明显增加,但任务开始执行前的等待时间可能持续上升。
建议将排队时间与实际处理时间分开记录,并结合并发数、连接池利用率、超时率和资源占用情况分析。否则,容易把排队造成的延迟误判成模型推理变慢。
三、用 Trace 还原完整执行链路
只查看每次模型调用的日志,通常难以回答三个关键问题:
- 一次任务到底执行了哪些步骤?
- 哪个步骤拖慢了最终完成时间?
- 这些步骤之间是否存在可以消除的等待?
分布式追踪可以将一个 Agent 任务关联起来,并通过 Span 记录模型请求、工具调用、调度和结果处理等操作。
可以参考 OpenTelemetry 的 GenAI 语义约定设计观测字段。不过,相关约定及其实现支持可能随版本变化,接入前应核对当前规范与 SDK 支持范围。
一个示例 Trace
假设某个研究型 Agent 的执行链路如下:
| Span | 耗时 |
|---|---|
| 任务规划 LLM | 0.8 秒 |
| 数据库查询 | 0.2 秒 |
| 外部 API 调用 | 3.6 秒 |
| 结果整理 LLM | 0.9 秒 |
| 本地处理 | 0.3 秒 |
| 端到端耗时 | 5.8 秒 |
这组数字是用于讲解分析方法的示例,不是真实生产数据。
在这个示例中,外部 API 的耗时占据了较大比例。但下一步不应直接认定"网络有问题",而应继续检查该调用内部的连接建立、服务端响应、传输过程和重试记录。
如果 Trace 显示连接建立耗时很短,而首字节返回前等待很久,就需要进一步区分服务端处理和网络往返等因素;如果连接池等待明显,则应优先检查并发与连接池配置。
Trace 应当记录哪些字段?
建议从以下几个维度设计:
| 维度 | 建议记录的内容 |
|---|---|
| 任务级 | 总耗时、任务状态、步骤数、成功或失败原因 |
| 模型调用 | 模型名称、请求耗时、TTFT、输入与输出 Token 数 |
| 工具调用 | 工具名称、调用耗时、状态码、重试次数 |
| 网络请求 | DNS、连接建立、TLS、首字节时间 |
| 资源等待 | 队列等待、连接池等待、并发数 |
| 结果质量 | 任务是否完成、结果是否正确、是否超时 |
TTFT(Time to First Token)表示请求开始后等待首个 Token 的时间。它可以反映部分交互体验,但对于需要多轮模型调用的 Agent,仍应与端到端任务耗时一起分析。
还需要注意,Span 的耗时总和不一定等于任务总耗时。并行 Span 可能在时间上重叠,父 Span 也可能包含子 Span 的执行时间。直接累加所有 Span,容易重复计算。
四、从 Trace 到延迟预算:怎样确定优化优先级
Trace 能告诉我们每个操作用了多长时间,但优化之前还需要回答:这个操作是否真正影响了任务的完成时间?
可以通过以下方法建立一份可复用的延迟预算表。
第一步:还原依赖关系
为每个 Span 记录父子关系、开始时间、结束时间、状态,以及必要的分支或依赖标识。
假设三个步骤中,步骤 A 耗时 0.8 秒;步骤 B 耗时 2.4 秒;步骤 C 耗时 0.6 秒。
如果三者依次执行,总耗时为:
0.8 + 2.4 + 0.6 = 3.8 秒
如果 B 和 C 都依赖 A,但 B 与 C 之间没有依赖关系,那么 B 和 C 可以并行执行。在没有额外排队与调度开销的理想情况下,总耗时约为:
0.8 + max(2.4, 0.6) = 3.2 秒
这里的关键不是 Span 数量减少了多少,而是并行执行缩短了任务的关键路径。
第二步:区分关键路径和非关键路径
关键路径是决定任务最早完成时间的依赖链。位于关键路径上的耗时增加,通常会直接推迟任务完成;非关键路径上的操作即使耗时较长,也可能被其他并行操作覆盖。
因此,优化前应同时检查:
- 每个操作的实际耗时;
- 操作之间的依赖关系;
- 并行分支的汇合位置;
- 是否存在队列等待和重试;
- 优化后是否会产生新的资源竞争。
这能避免仅凭"某个 Span 最长"就认定它一定是首要优化对象。
第三步:把瓶颈映射到具体动作
| 观察结果 | 优先检查的方向 |
|---|---|
| 模型请求占据关键路径 | 上下文长度、输出长度、模型配置、请求排队 |
| 外部工具占据关键路径 | 连接阶段、服务端处理、响应传输、超时与重试 |
| 独立步骤被串行执行 | 依赖关系、并发执行条件、结果汇总成本 |
| 队列等待持续增加 | 并发限制、工作线程、连接池、服务端容量 |
| 重试占用大量时间 | 超时策略、错误分类、退避机制、幂等设计 |
如果瓶颈不在关键路径上,单独优化它对端到端耗时的改善可能很有限。反过来,减少关键路径上的一次长等待,即使没有提升模型吞吐量,也可能显著改善用户体验。
五、参考真实工作负载进行性能测试
只使用固定输入长度、固定输出长度的模型基准测试,难以完整覆盖 Agent 的执行结构。实际任务可能存在多轮模型请求、不同工具等待时间、共享上下文和并行分支。
NVIDIA TensorRT-LLM 团队公开的 Agent Trace Replay 评测提供了一种更贴近实际工作负载的思路:先采集 Agent 执行轨迹,再使用 Trace Replay 重放代表性的模型请求与工具等待结构,从而比较不同推理服务配置的表现。
该公开评测涵盖了多种 Agent 工作负载,包括连续工具调用、并行研究、上下文重建和树状推理分支。它所展示的方法说明,缓存、批处理和调度策略的收益会受到工作负载结构影响,不能仅凭固定请求形状下的吞吐量推断完整 Agent 任务的表现。
复现这类测试时,需要固定模型版本、推理服务配置、硬件、Trace 数据集和并发参数,并记录完整运行配置。回放测试适合比较推理服务和执行结构的性能,但不能替代真实任务的正确性与完成率评估。
公开资料:NVIDIA TensorRT-LLM,Evaluating Agentic Serving with Trace Replay and Job-Level Metrics。
六、建立可重复的性能优化闭环
性能优化应当从可观察、可比较的基线开始,而不是一次性调整多个参数后凭感觉判断效果。
推荐按以下顺序开展:
- 建立基线:固定代表性任务集,记录端到端耗时、任务成功率、模型与工具调用次数。
- 定位关键路径:结合 Trace、日志和指标,判断主要时间消耗来自模型、工具、队列还是重试。
- 提出单一假设:例如某个外部 API 的连接池等待过长,或某类任务存在可并行的独立步骤。
- 进行受控测试:尽量一次只改变一个关键变量,保留优化前后的配置和运行记录。
- 联合评估结果:比较平均耗时、P95/P99、任务成功率、超时率、调用次数及单次成功任务成本。
- 持续监控:在实际负载下观察结果,确认改善不会因并发、任务结构或服务端负载变化而消失。
平均耗时可以反映总体趋势,但对于交互式 Agent,P95 和 P99 往往更能揭示少数任务被长时间拖慢的问题。性能提升也不能以任务正确性下降为代价。
总结
排查 AI Agent 的性能问题,需要从单次模型调用扩展到整个任务执行过程。
先通过 Trace 还原调用链路,再根据依赖关系识别关键路径,接着将瓶颈映射到模型、工具、队列、重试或并发等具体环节,最后使用固定任务集和受控测试验证结果。
markdown
**真正值得优化的,不一定是耗时最长的单个操作,而是决定任务何时完成的关键路径。**