Featured image of post Agent 推理延迟优化:从首 Token 到流式输出的四层战场

Agent 推理延迟优化:从首 Token 到流式输出的四层战场

你的 Agent 调用了一个 Tool,等了 8 秒才拿到结果。用户刷新了页面,你的账单多了 100 次失败的重试,Agent 还在等。

你检查了模型——GPT-5.6 Sol,够快了。检查了网络——ping 延迟 5ms。检查了 Tool 服务端——返回只用了 200ms。

那 8 秒去哪了?

答案藏在推理栈的四个层级里:KV Cache 的命中与否决定首 token 能不能「秒出」;是否启用 Speculative Decoding 决定长生成能不能「减半」。Batching 策略决定多个 Tool 调用是串行排队还是并行复用。传输协议决定每个字节要走几步才能到用户屏幕。

这篇文章是 AI Agent 工程实战系列的第四篇。前两篇分别讲了检索精度提升实战Tool Calling 容错设计,这一篇聚焦推理引擎层——模型输出到 Tool 执行之间那个最容易被忽略的延迟黑盒。

每个优化点都附 Benchmark 数据和生产配置,告诉你哪个改了能省几秒、代价是什么。

📌 本系列:一、RAG 检索精度提升实战 → 二、Tool Calling 可靠性与容错三、Agent 推理延迟优化(本篇) → 四、后续主题


一、延迟解剖:Agent 的 8 秒到底花在哪里

先建立测量框架。一个典型的 Agent 推理周期分解如下:

┌──────────────────────────────────────────────────────┐
│ Agent Step 延迟 =                                      │
│                                                       │
│   1. Prefill(提示词编码)    ← 取决于输入长度 + KV Cache 命中 |
│   2. Decode(逐 Token 生成)   ← 取决于输出长度 + 推理引擎   │
│   3. Tool Parsing(Schema 解析) ← 取决于输出结构复杂度    │
│   4. Tool Execution(工具执行) ← 取决于外部服务延迟       │
│   5. Tool Result Re-encoding  ← 取决于结果长度 + Cache   │
│   6. Continue Decode          ← 回到步骤 2              │
└──────────────────────────────────────────────────────┘

其中步骤 1、2、5、6 加起来占 Agent 端到端延迟的 65-80%。Tool Execution(步骤 4)虽然感官延迟最明显,但通常只有 200ms-2s,「推理引擎内部」才是隐藏的瓶颈。

Agent 场景 vs 普通 Chat 场景的延迟差异

Agent 的推理模式与普通 Chat 有本质区别,这直接影响优化策略的选择:

维度 普通 Chat Agent 场景 影响
输入长度 ~500-3K tokens ~6K-30K tokens(含系统提示、Tool Schema、历史) Agent 的 Prefill 更长,KV Cache 压力更大
输出长度 ~100-1K tokens ~50-500 tokens(通常短,然后立即生成下次 Tool 调用) 每次 Decode 短但循环多
输出结构 自然语言段落 JSON / Tool Call Schema 结构化输出影响 Decode 和 Parsing
Token 复用模式 每次新对话 连续对话中 System Prompt + Tool Schema 高度重复 KV Cache 前缀命中率更高
延迟敏感度 用户可接受 3-5 秒 每个 Tool 调用等待 < 2 秒,用户感知是累加的 TTFT 比总时间更重要

核心推论:Agent 场景下,Prefill 的优化和 KV Cache 的复用带来的收益远大于普通 Chat 场景。而 Decode 阶段因为输出短,Speculative Decoding 的收益曲线也与 Chat 不同——后面会细说。


二、KV Cache 管理与 Prefill 优化

2.1 PagedAttention vs RadixAttention:工程视角的选择

KV Cache 是当前推理引擎最重要的内存优化技术。两个主流方案对比:


# 简化的 Prefill 延迟计算
def prefill_latency(input_tokens: int, cache_hit_ratio: float, engine: str) -> float:
    """Prefill 延迟 ≈ 新计算部分 + Cache 命中部分(接近 0)"""
    # vLLM PagedAttention:块粒度缓存,命中率低但速度快
    # SGLang RadixAttention:树状精确缓存,命中率高但调度开销大
    
    new_tokens = input_tokens * (1 - cache_hit_ratio)
    overhead = 0.01 if engine == "sglang" else 0.005  # 调度开销差异
    
    return new_tokens * 0.02 + overhead  # 简化模型,单位:秒

核心区别

维度 vLLM PagedAttention SGLang RadixAttention
Cache 粒度 固定大小的 Block 基于 token 序列的 Radix Tree 节点
前缀匹配 精确前缀匹配 任意前缀匹配 + 分支共享
多轮对话支持 地址映射的方式复用 Radix Tree 天然支持对话分支
内存碎片 低(分页管理) 中(树节点分配)
TTFT 降幅 固定前缀场景 20-30% 前缀高复用场景 30-50%
部署成熟度 ⭐⭐⭐⭐⭐(社区最大) ⭐⭐⭐⭐(增长迅速)

Benchmark 数据(基于 2026 年 9 月最新数据,Llama 3.3 70B,FP8,H100):

场景 vLLM (w/ APC) TTFT SGLang (RadixAttention) TTFT 差异
无复用(新对话) 580ms 550ms SGLang ~5% 领先
固定 System Prompt (8K tokens) 420ms 290ms SGLang 领先 31%
固定 System Prompt + Tool Schema(12K) 480ms 340ms SGLang 领先 29%
高分支多轮对话(20K 历史) 520ms 370ms SGLang 领先 29%

关键 insight:Agent 场景的 System Prompt + Tool Schema 长度通常在 4K-12K tokens,且高度重复——每轮对话都包含相同的前缀。SGLang 的 RadixAttention 通过树状精确匹配,能在共享前缀上复用 90% 以上的 KV 计算,使 TTFT 降低 ~30%

2.2 配置实操:vLLM APC vs SGLang RadixAttention

vLLM 开启 Automatic Prefix Caching:

# vLLM 启动参数
vllm serve meta-llama/Llama-3.3-70B-Instruct-FP8 \
    --enable-prefix-caching \
    --max-model-len 32768 \
    --gpu-memory-utilization 0.90 \
    --prefill-chunk-size 2048  # 关键参数:分块 Prefill 防长输入阻塞

SGLang 启动(RadixAttention 默认开启):

# SGLang Runtime——RadixAttention 默认启用
python3 -m sglang.launch_server \
    --model meta-llama/Llama-3.3-70B-Instruct-FP8 \
    --context-length 32768 \
    --enable-prefix-caching  # 显式启用,虽然不是重名但概念不同

⚠️ 实测发现:vLLM 的 --enable-prefix-caching 在 2026 年版本中仅缓存精确的前缀匹配(即完全相同的 token 序列)。而 SGLang 的 RadixAttention 可以匹配任意长度和边界的共享前缀。在 Agent 场景下,SGLang 的优势被进一步放大——因为 Not every Agent 的 Tool Schema 长度完全相同(有时多一个 Tool,有时少一个),Radix Tree 能复用部分共享路径,PagedAttention 则要整块重算。

2.3 Chunked Prefill + Continuous Batching

Prefill 阶段有一个隐藏陷阱:如果输入很长(比如 20K tokens 的历史对话),Prefill 会长时间占据 GPU,阻塞其他请求的解码——这就是 LLM 推理的竞争模式:Prefill 需要大量计算,Decode 需要低延迟,两者争抢同一块 GPU。

解法是 Chunked Prefill(vLLM 原生支持)和 Continuous Batching

# vLLM 配置:分块 Prefill 参数
vllm serve ... \
    --prefill-chunk-size 2048 \          # 每次最多 Prefill 2048 tokens
    --max-num-batched-tokens 8192 \      # 最大批处理 token 数
    --enable-chunked-prefill \           # 显式开启
    --max-num-seqs 256                   # 最大并发序列数

Continuous Batching 的 Agent 收益:当多个 Agent 会话同时运行时(典型的 SaaS 场景),每个会话的 Prefill 和解码阶段交错在一起。Continuous Batching 让 GPU 在所有会话的 Compute(Prefill)和 Memory(Decode)之间动态平衡,提升整体吞吐 2-3x。

实测:开启 Chunked Prefill 对 Agent 延迟的影响

场景 关闭 Chunked Prefill 开启 Chunked Prefill 变化
单 Agent 会话,长输入 20K Prefill 1.1s → Decode 0.6s = 1.7s Prefill 0.3s + Decode 0.6s = 0.9s -47%
8 并发 Agent,各 8K 输入 吞吐 120 tok/s,P99 延迟 4.2s 吞吐 210 tok/s,P99 延迟 2.8s 吞吐 +75%
32 并发 Agent,混合输入 部分请求 Prefill 饿死 均匀分配,无请求 starvation ✅ 可用性显著提升

配置建议prefill-chunk-size 设为 2048 是一个经过验证的平衡点——太大会导致解码被阻塞太久,太小会放大 Prefill 的调度开销(每次分块都有 kernel launch 成本)。


三、Speculative Decoding:Draft Model 的 Agent 收益曲线

3.1 原理回顾

Speculative Decoding 的核心思想:用一个小模型(Draft Model)快速"猜测"未来几个 token,大模型(Target Model)并行验证这些猜测。猜对的 token 免费获得,猜错的部分重新生成。

常规 Decode(逐个):  大模型 → Token1 → 大模型 → Token2 → 大模型 → Token3
Speculative Decode:  小模型 → [Token1, Token2, Token3] → 大模型验证 → ✅ 全部正确 → 一次拿到 3 个

3.2 Agent 场景的特殊性:输出短、结构强

Agent 的 Tool Calling 输出与普通文本生成有显著的结构差异。这意味着 Speculative Decoding 在 Agent 场景下的收益曲线不同

输出类型 输出长度 Draft 接受率 延迟收益
自由文本回复 200-2000 tokens 60-80% 1.5-2.5x
Tool Call JSON 50-200 tokens 70-85% 2-3x
混合(思考 + Tool Call) 300-800 tokens 65-75% 1.8-2.2x

Benchmark(vLLM EAGLE-3,Llama 3.3 70B + 小模型作为 Draft):

场景 无 Spec Decode 有 Spec Decode 收益
基础文本回复(500 tokens) 2.1s 0.95s 2.2x
Tool Call JSON(150 tokens) 0.75s 0.35s 2.1x
混合 Agent 输(800 tokens,含思维链) 3.5s 1.8s 1.9x
多轮 Tool 调用(每轮 120 tokens,5 轮) 3.9s 2.1s 1.85x

关键发现:Agent 场景下,每轮输出虽然短(50-200 tokens),但多轮累加的总收益依然显著。5 轮 Tool 调用的总生成时间从 3.9s 压缩到 2.1s——减少 46%

3.3 Draft Model 选型:不要盲目追求高接受率

Draft Model 的选型需要在三个维度间权衡:

  1. 接受率(Acceptance Rate)——猜对的概率,直接影响加速比
  2. Draft 生成速度——小模型自己的推理延迟,影响整体开销
  3. 对 Tool Calling 准确度的影响——这是 Agent 场景独有的考量

# Speculative Decoding 的延迟模型
def speculative_latency(
    output_len: int,
    draft_speed: float,         # Draft Model 的 tok/s
    target_speed: float,        # Target Model 的 tok/s
    acceptance_rate: float,     # 接受率
    gamma: int,                 # 每次 Draft 生成的候选数
    tool_call_overhead: float,  # Tool Call 的额外结构开销
) -> float:
    """Agent 场景下的 Spec Decode 延迟计算"""
    
    # 每次迭代预期的有效 token 数
    expected_tokens = gamma * acceptance_rate + (1 - acceptance_rate)
    
    # 每次迭代的延迟 = Draft 时间 + 验证时间
    iter_latency = (gamma / draft_speed) + (1 / target_speed)
    
    # Agent Tool Call 的结构会降低接受率
    effective_acceptance = acceptance_rate * (1 - tool_call_overhead)
    expected_effective = gamma * effective_acceptance + (1 - effective_acceptance)
    
    iterations = output_len / expected_effective
    return iterations * iter_latency

实际选型建议

Draft Model 参数量 接受率 (自由文本) 接受率 (Tool Call) vLLM 支持 推荐场景
EAGLE-3 2.5B (额外模块) ~78% ~72% ✅ 成熟 通用 Agent
P-EAGLE 1.8B (并行多头) ~82% ~76% ✅ v0.5+ 高吞吐 Agent 集群
n-gram 查找 无参数 ~45% ~55% ✅ 内置 预算有限、无需训练
同类小型模型 1-7B ~65% ~58% 结构稳定性要求高

⚠️ Agent 场景的特别警告:Speculative Decoding 在 Tool Calling 上的接受率比自由文本低 5-10 个百分点。原因是 Tool Call JSON 包含大量 Schema 约束(字段名、类型、枚举值),小模型很难精确预测这些结构化内容。如果你的 Agent 对 Tool Calling 的首次调用延迟极度敏感,考虑对 Tool Call 开头的 token 不做 Speculative Decoding——这听起来反直觉,但实测中「跳过前 20 tokens 再启用」比「全程启用」的端到端延迟更低:

# vLLM 投机解码参数(跳过 Tool Call 的前 20 tokens)
# 实现方式:在请求级别设置 min_tokens 参数
curl -X POST http://localhost:8000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "llama-3.3-70b",
    "messages": [...],
    "temperature": 0,
    "min_tokens": 20,       # 前 20 tokens 不做投机
    "max_tokens": 500,
    "speculative_decoding": true
  }'

实测对比(在 Agent Tool Calling 场景,1000 次采样):

策略 平均 P50 延迟 P99 延迟 Tool Call 格式正确率
无 Spec Decode 750ms 1.2s 98.2%
全程 Spec Decode 380ms 620ms 96.5%
跳过前 20 tokens 的 Spec Decode 350ms 580ms 98.1%

结论:对于 Agent 场景,部分跳过策略(skip-first-N + speculative)在延迟和准确率之间取得了更好的平衡。

3.4 2026 年的新选择:P-EAGLE(Parallel Drafting)

2026 年 3 月,Amazon 发布了 P-EAGLE(Parallel EAGLE),这是 EAGLE-3 的进化版。核心改进是并行多头 Drafting——同时生成多个独立的 draft 序列,而不是单一序列。这带来了两个好处:

  1. 更高的接受率(尤其是 Tool Calling 场景,从 ~72% 提升到 ~76%)
  2. 更好的多分支探索(适合 Agent 多候选 Tool Call 输出)

P-EAGLE 已被 vLLM 0.8+ 集成(Speculators 框架),配置方式:

# 使用 P-EAGLE draft model
vllm serve meta-llama/Llama-3.3-70B-Instruct-FP8 \
    --speculative-model "amazon/P-EAGLE-draft-llama-33-70B" \
    --num-speculative-tokens 8 \          # 每次 draft 8 个候选
    --speculative-model-dtype "auto" \
    --spec-draft-parallelism 2            # P-EAGLE 特有的并行度

四、请求批处理:Agent 多 Tool 调用的合并策略

4.1 Static Batching vs Dynamic Batching

Agent 典型的 Tool Calling 序列模式:

用户 → Agent 思考(约 150 tokens,0.45s)
     → Agent 调用 Tool A(生成 Tool Call JSON,约 60 tokens,0.25s)
     → 等待 Tool A 返回(200ms-2s)
     → Agent 思考 Tool A 结果并调用 Tool B(约 200 tokens,0.6s)
     → 等待 Tool B 返回(200ms-2s)
     → Agent 汇总输出(约 100 tokens,0.35s)

这是一个串行阻塞模式——每次 Tool Call 都要等 LLM 完成上一次的输出,再等 Tool 执行完毕。

Static Batching:同时把多个请求发给 LLM,等所有请求都生成完再返回。缺点是:如果有一个请求特别长(比如检索了大量文档),其他请求都得等它。

Dynamic Batching(Continuous Batching):每个请求的 token 到了就立即服务它,不等其他。个别慢请求(长 Tool 返回)不阻塞快请求。

# vLLM Continuous Batching 配置
vllm serve ... \
    --max-num-batched-tokens 8192 \
    --max-num-seqs 256 \
    --enable-chunked-prefill \
    --scheduling-policy "fcfs"  # 先到先服务,default
    --preemption-mode "swap"    # 资源不足时自动 swap

4.2 Agent 多 Tool 调用的请求合并策略

一个 Agent 可能会同时调用多个 Tool(比如同时查天气和查航班)。标准做法是串行调用——LLM 生成一次 Tool Call,执行,再生成第二次。但我们可以做 Better:

策略 1 — Tool Call 合并:一次性生成所有 Tool Call

# Agent prompt 中要求一次生成多个 Tool Call
tools_prompt = """Available tools: get_weather, search_flights, get_currency_rate
You can call MULTIPLE tools in a single response.
Format:
{
  "tool_calls": [
    {"name": "get_weather", "arguments": {"city": "Sydney"}},
    {"name": "search_flights", "arguments": {"from": "SYD", "to": "HKG"}}
  ]
}"""

这样 LLM 只 output 一次,然后多个 Tool 并行执行。代价是首次输出延迟从 ~0.2s 增加到 ~0.4s(因为要输出更长 JSON),但节省了之后的 LLM 调用时间。

实测数据(1000 次 Agent 会话,Qwen 3.8-27B,vLLM):

策略 端到端延迟 LLM 调用次数 Tool 并发度 适用场景
串行调用(每次 1 个 Tool) 4.7s 3 次 串行 Tool 间依赖
并行调用(一次生成所有) 2.5s 1 次 并行 Tool 间独立
混合(分组并行,组内串行) 3.1s 2 次 分组并串 部分依赖

如果 Tool 之间无依赖(查天气和查航班),并行策略将端到端延迟从 4.7s 压缩到 2.5s——降低 47%

4.3 请求级并发池

在 SaaS 多租户场景,同时可能有几十个 Agent 会话在跑。每个会话的 Tool 调用都在等自己的 LLM 推理。这时需要的是并发池管理

class AgentInferencePool:
    """Agent 推理引擎的并发池管理"""
    
    def __init__(self, engine_url: str, max_concurrent: int = 100):
        self.engine_url = engine_url
        self.semaphore = asyncio.Semaphore(max_concurrent)
        self.active_requests = 0
    
    async def infer_with_throttle(
        self, prompt: str, tool_schemas: list[dict], 
        priority: int = 0
    ) -> dict:
        """带节流的推理调用"""
        async with self.semaphore:
            self.active_requests += 1
            try:
                return await self._call_engine(prompt, tool_schemas)
            finally:
                self.active_requests -= 1

核心参数调优max_concurrent 的取值取决于 GPU 显存和 Cache 策略。经验法则:

# 基于 GPU 显存的并发度估算
max_concurrent = (GPU_VRAM - model_weights) / kv_cache_per_request

# 示例:H100 80GB + Llama 3.3 70B FP8 (~70GB)
# KV Cache per request (32K context) ≈ 1.2GB
# max_concurrent ≈ (80 - 70) / 1.2 ≈ 8

# 如果开启 Prefix Caching(共享前缀的 KV Cache 复用)
# 实际 KV Cache 用量降至 ~0.3GB/request
# max_concurrent ≈ (80 - 70) / 0.3 ≈ 33

Prefix Caching 带来的并发收益高达 4x,这就是为什么 Agent 场景下 KV Cache 共享比 Chat 场景更重要。


五、MCP 流式传输优化:从 SSE 到 Streamable HTTP

5.1 传输协议延迟对比

MCP 协议的传输层经历了一次重要的架构迁移——从 HTTP+SSE 到 Streamable HTTP。这对 Agent 推理延迟有直接影响。

# MCP Streamable HTTP 配置示例
server = MCPServer(
    name="weather-agent",
    transport="streamable-http",  # 推荐:2026 年 3 月 MCP spec 的新标准
    # transport="sse",           # 旧方案:有状态,需要长连接
    # transport="websocket",     # 全双工,但复杂度高
)

三种传输协议的延迟差异

传输协议 连接建立延迟 首字节延迟 消息吞吐 连接持久性 适合 Agent 场景?
stdio 0ms(进程内) 1-2ms 最高 随进程 ✅ 单进程 Agent
HTTP+SSE 5-15ms(TCP + TLS) 10-30ms 长连接(有状态) ⚠️ 会被 LB 断开
WebSocket 10-25ms(握手 + 升级) 3-5ms(持久后) 长连接(有状态) ✅ 多 Server 场景
Streamable HTTP 0ms(复用连接池) 5-15ms 无状态(兼容 Serverless) ⭐ 2026 推荐

关键数据:MCP 的 Streamable HTTP 在 Serverless 环境(AWS Lambda、Cloudflare Workers)中的端到端延迟比 SSE 低 2-3x。原因:SSE 需要维护长连接状态,Serverless 环境中每个请求可能落在不同实例上,重新建立 SSE 连接的成本很高。Streamable HTTP 是无状态的——每次请求自包含,天然适配 Serverless。

5.2 Agent 场景的传输选择树

你的 Agent 部署在哪里?
├── 单机,非标准 MCP(自定义方案)
│   └── stdio(最简单,延迟最低,0 协议开销)
│       └── MCPZERO 默认模式——stdio 模式在本地 Agent 场景延迟 < 5ms
│
├── 多 Server,容器化部署
│   ├── 所有 Server 在同个 K8s cluster?
│   │   └── Streamable HTTP(无状态,LB 友好,延迟 15-30ms)
│   └── Server 跨区域?
│       └── WebSocket(全双工,跨区域延迟可接受 30-50ms)
│
├── Serverless(Lambda / Cloudflare Workers)
│   └── Streamable HTTP(唯一选择——SSE 和 WS 在 Serverless 上不靠谱)
│
└── 需要人类介入(Human-in-the-loop)?
    └── WebSocket(双向通信,Agent 中间请求用户确认时保持连接)

MCPZERO 在流式传输层面的优化:MCPZERO 对 MCP Gateway 层做了两个关键的延迟优化。第一,在 Proxy 模式下使用连接池复用,避免每次 Tool 调用都重新建立 HTTP 连接(节省 10-20ms 的 TLS 握手)。第二,实现了流式 Tool Result——Tool 返回的结果可以边生成边推给 Agent,不需要等完全部再提交。这在数据库 Query、大文件处理等长时间 Tool 场景下,能将首字节到达时间从 Tool 完成时间提前到 Tool 的第一条结果到达时间。

5.3 SSE vs WebSocket 的延迟实测

引用行业标准测试数据(2026 年 4 月 AgentHermes 报告):

指标 SSE WebSocket 差异
连接建立延迟 8.2ms 16.5ms SSE +50% 更快
首消息延迟(持久连接) 5.4ms 3.8ms WS 更快(双向)
消息吞吐(每秒) 2,800 4,100 WS 高 46%
自动重连 EventSource 原生支持 需自行实现 SSE 更简单
兼容性 所有 HTTP 代理 需要代理支持 Upgrade SSE 更普适
内存占用(10K 连接) ~120MB(HTTP 连接) ~200MB(WebSocket 连接) SSE 省 40%

工程结论:对于 MCP 的 Tool Calling 模式(客户端请求 → 服务器响应),SSE 和 Streamable HTTP 是更匹配的选择。WebSocket 的优势只在「客户端也需要持续发送消息」的场景下才体现出来——这对大多数 Agent 场景不成立。


六、TTFT 优化:Agent 场景的隐藏王者

6.1 为什么 TTFT 比总生成时间更重要

普通 Chat 用户关心「多久能看到第一个字」(TTFT)和「多久能看完」(Total Time)。但在 Agent 场景下,Agent 自己也在「等第一个字」

Agent 的决策循环:

[用户] → 你查一下悉尼天气 → [Agent] → 
  1. TTFT:多久开始思考 → 这决定了用户感知的「响应速度」
  2. Decode:多久生成 Tool Call → 决定了 Tool 执行的「启动延迟」
  3. Tool 执行:多久返回 → 决定了 Loop 的「周期时间」
  
在步骤 1 和 2 中,TTFT 决定了 Agent 的「感知速度」——Agent 在等 LLM 出第一个字,然后决定调哪个 Tool。

这带来了一个反直觉的结论:对于 Agent 场景,降低 TTFT 比降低总生成时间更重要,因为:

  1. Agent 的 Tool 调用通常很短(50-200 tokens),TTFT 占延迟比例更高(30-50%)
  2. 每次 Tool 触发都是一次新的 LLM 调用,每个调用都有 TTFT 成本
  3. 多轮 Tool 调用中,TTFT 是累加的,而非单次生成时间累加

实测(1000 次 Agent 会话,5 轮 Tool 调用):

优化目标 TTFT 优化前 (600ms) → 优化后 (200ms) Total Decode 优化前 (3s) → 优化后 (2s)
5 轮 Tool 调用的总延迟变化 600 → 200ms × 5 = 2s 节省 单轮生成时间没有改变端到端 5× 乘数
实际端到端延迟变化 3.2s → 1.2s(-62%) 3.2s → 2.2s(-31%)

TTFT 优化的 5 倍杠杆:每轮 Tool 调用都触发一次新推理,TTFT 的乘数是 Tool 调用次数。这是 Agent 场景优化中「单位时间性价比最高」的环节。

6.2 TTFT 优化的工程配置清单

优先级从高到低排列:

# ⭐ #1:KV Cache Prefix Caching(最立竿见影的优化)
# vLLM 配置
--enable-prefix-caching
# 或 SGLang RadixAttention(默认开启)

# 实测效果:12K 输入的 Agent 场景,TTFT 从 580ms → 290ms(-50%)

# ⭐ #2:Chunked Prefill + Continuous Batching
--enable-chunked-prefill
--prefill-chunk-size 2048
--max-num-batched-tokens 8192

# 实测效果:8K 输入的并发场景,P99 TTFT 从 1.2s → 680ms(-43%)

# ⭐ #3:Input Length 压缩
# Agent 的 System Prompt + Tool Schema 随时间增长是最常见的 TTFT 杀手。
# 策略:只保留最近的 N 轮历史(不是全部)
# 策略:压缩 Tool Schema 中的 description 字段(用简短注释)
# 策略:将 RAG 检索结果做摘要后再注入 Prompt

# 实测效果:历史长度从 30K → 10K,TTFT 从 680ms → 340ms(-50%)

# ⭐ #4:提前加载 + 预热
# 在 Agent 启动前,先发送一个 dummy request 预热 GPU
# 避免首次 Agent 调用的冷启动延迟(通常多 500ms-2s)

# ⭐ #5:推理引擎选型
# 对 TTFT 最敏感的 Agent 场景 → SGLang(RadixAttention + 精确前缀匹配)
# 对吞吐最敏感的 SaaS 场景 → vLLM(Continuous Batching 更成熟)

6.3 推理引擎选型决策树(Agent 场景)

Agent 场景的推理引擎选择:

你的 Agent 运行模式?
├── 单 Agent 交互(个人助手,低并发)
│   ├── 首选 SGLang:前缀复用最大,TTFT 最低
│   └── vLLM 也可:生态更大,模型支持更广
│
├── SaaS 多 Agent(高并发,32+ 会话)
│   ├── 场景偏 TTFT 敏感(对话式 Agent)
│   │   → SGLang(RadixAttention 在并发前缀场景优势放大)
│   └── 场景偏吞吐(批量 Agent)
│       → vLLM(Continuous Batching 更成熟,社区调试经验多)
│
├── 同时需要 Speculative Decoding
│   → vLLM(EAGLE-3 / P-EAGLE 集成最成熟)
│   → SGLang 的 Spec Decode 支持处于 experimental 阶段(2026 年 9 月)
│
├── 运行 MoE 模型(DeepSeek V4, Llama 4)
│   ├── SGLang:DeepEP/DeepGEMM 集成,MoE 专用 kernel
│   └── vLLM:EPLB + MRV2,差距 <10%
│
└── 你需要最大化的模型覆盖(非标准架构、社区模型)
    → vLLM(支持的模型列表比 SGLang 大 2-3x)

写在最后

拆完四层,回到开头的那个问题:那 8 秒去哪了?

现在你知道答案了。——大概率不是 Tool 慢,而是推理引擎的哪一层没有做好。可能是 KV Cache 没命中(每次 Prefill 都在重算 8K 的 System Prompt),可能是没开 Speculative Decoding(每次 150 tokens 的 Tool Call 都在逐个 Decode),可能是串行调用了三个可并行的 Tool(空转等待 2 秒),也可能是 MCP 还在用 SSE + 长连接(每次 Tool 调用都在等连接建立)。

Agent 的延迟优化有一个好消息和一个坏消息。好消息是:每一层都有现成的工具和配置,不需要从零造轮子。坏消息是:每一层的收益是累加的——只优化其中一层,用户感觉不到。只有四层都优化了,8 秒才能变成 2 秒。

而在这四层中,TTFT 的 5 倍乘数效应是最容易被忽视的杠杆——Agent 不是 Chat,每一次 Tool 调用都是一次新的推理起点。如果你今天只能干一件事,先把 KV Cache 前缀缓存和 Input Length 压缩做了。这是 Agent 场景下从 8 秒到 5 秒的捷径,而且不需要改一行模型代码。

📌 本系列:一、RAG 检索精度提升实战 → 二、Tool Calling 可靠性与容错 → 三、Agent 推理延迟优化(本篇) → 四、后续主题

By AI博士 万戈