Skip to content
LangSmith 文档版本 跟随上游 源快照 31eabd8a 更新于 2026-10-18

为规模化配置 Agent Server

为自托管部署调优 Agent Server——包括写入负载、读取负载,以及针对不同负载模式的 Helm 配置示例。

LangSmith Agent Server 的默认配置旨在应对各种不同工作负载下的大量读写负载。通过遵循下面概述的最佳实践,你可以调优你的 Agent Server,使其针对你的特定工作负载达到最佳性能。本页描述了自托管部署中 Agent Server 的扩展性注意事项,并提供了示例配置。

TIP

如果你还不熟悉 API 服务器和队列 worker 在容器层面的运作方式,请先阅读运行时架构概述。

对于 Cloud,平台会自动进行自动扩缩容,下面的 Helm 配置不适用。

请求并发与运行并发

有两种相互独立的并发类型共同决定 Agent Server 如何扩缩容,而且它们分别受控:

  • 请求并发 指的是部署一次能处理多少个 API 请求(创建运行、读取线程状态、流式输出结果)。API 服务器以异步方式处理请求,请求并发会随 API 服务器副本数横向扩缩。
  • 运行并发 指的是同时执行多少个运行。单个队列 worker 最多并发执行 N_JOBS_PER_WORKER 个运行(默认 10)。运行并发的上限是队列 worker 数量乘以 N_JOBS_PER_WORKER。

创建运行是一个快速的写请求:API 服务器将待处理的运行持久化后立即返回,不会等待运行执行。如果所有运行槽位都繁忙,额外的运行会在队列中等待,直到有槽位释放。调高 N_JOBS_PER_WORKER 或增加队列 worker 可以提高运行吞吐量;但这不会改变部署能并发处理多少请求。

写负载

写负载主要由以下因素驱动:

  • 创建新的运行
  • 在运行执行期间创建新的检查点
  • 写入长期记忆
  • 创建新的线程
  • 创建新的助手
  • 删除运行、检查点、线程、助手和定时任务

以下组件主要负责处理写负载:

  • API server:处理初始请求并将数据持久化到数据库。
  • 队列 worker:处理运行的执行。
  • Redis:处理关于正在进行中的运行的临时数据的存储。
  • Postgres:处理所有数据的存储,包括运行、线程、助手、定时任务、检查点以及长期记忆。

根据助手特征调整 N_JOBS_PER_WORKER

N_JOBS_PER_WORKER 的默认值为 10。你可以根据助手特征修改该值,以调整单个队列 worker 一次能执行的最大运行数。

关于修改 N_JOBS_PER_WORKER 的一些通用准则:

  • 如果你的助手受 CPU 限制,默认值 10 通常就足够了。如果你发现队列 worker 的 CPU 使用率过高或运行执行出现延迟,可以调低 N_JOBS_PER_WORKER。
  • 如果你的助手受内存限制,或者队列 worker 接近内存上限,请调低 N_JOBS_PER_WORKER,以减少每个 worker 的并发运行数。
  • 如果你的助手受 IO 限制,请调高 N_JOBS_PER_WORKER,以便每个 worker 处理更多并发运行。

N_JOBS_PER_WORKER 没有上限。不过,队列 worker 在获取新运行时会尽可能贪婪地拉取,也就是说它们会尝试拉取与可用作业数一样多的运行并立即开始执行。在流量突发性较强的环境中把 N_JOBS_PER_WORKER 设得过高,可能导致 worker 利用率不均衡、运行执行时间变长,以及队列 worker 内存占用过高。

避免同步阻塞操作

在代码中避免同步阻塞操作,优先使用异步操作。长时间的同步操作会阻塞主事件循环,导致请求和运行的执行时间变长,并可能引发超时。

例如,假设某个应用需要休眠 1 秒。不要使用下面这样的同步代码:

python
import time

def my_function():
    time.sleep(1)

而应优先使用下面这样的异步代码:

python
import asyncio

async def my_function():
    await asyncio.sleep(1)

如果某个助手需要同步阻塞操作,请在 asyncio.to_thread() 或等效方法中运行这些操作。

尽量减少冗余检查点操作

将 durability 设为确保数据持久所需的最小值,以尽量减少冗余检查点操作。

默认的 durability 模式为 "async",表示在每个步骤之后异步写入检查点。如果某个助手只需要持久化运行的最终状态,可以将 durability 设为 "exit",仅存储运行的最终状态。这可以在创建运行时设置:

python
from langgraph_sdk import get_client

client = get_client(url=<DEPLOYMENT_URL>)
thread = await client.threads.create()
run = await client.runs.create(
    thread_id=thread["thread_id"],
    assistant_id="agent",
    durability="exit"
)

启用队列 worker

默认情况下,API 服务器管理队列,不使用队列 worker。将 queue.enabled 设为 true 即可启用队列 worker:

yaml
queue:
  enabled: true

这会将队列管理从 API 服务器卸载到专用的队列 worker,减轻 API 服务器的负载,使其能够专注于处理请求。

根据预期吞吐量为作业设定规模

本节讨论的是运行执行容量(队列 worker)的规模设定,它与请求处理容量(API 服务器副本)相互独立。更多信息,请参阅请求并发与运行并发。

并行执行的运行越多,处理该负载所需的作业就越多。用于扩缩可用作业的主要有两个参数:

  • number_of_queue_workers:配置的队列 worker 数量。
  • N_JOBS_PER_WORKER:单个队列 worker 一次可以执行的运行数。默认为 10。

你可以用以下公式计算可用作业数:

available_jobs = number_of_queue_workers * N_JOBS_PER_WORKER

那么吞吐量就是可用作业每秒可以执行的运行数:

throughput_per_second = available_jobs / average_run_execution_time_seconds

因此,为支持预期的稳态吞吐量,你应配置的队列 worker 最小数量为:

number_of_queue_workers = throughput_per_second * average_run_execution_time_seconds / N_JOBS_PER_WORKER

为突发性写工作负载配置自动扩缩容

自动扩缩容默认处于禁用状态,但对于突发性工作负载应予以配置。使用与上一节相同的计算方法,你可以根据预期的最大吞吐量确定允许自动扩缩器扩展到的队列 worker 最大数量。

读负载

读负载主要由以下因素驱动:

以下组件主要负责处理读负载:

  • API server:处理请求并直接从数据库检索数据。
  • Postgres:处理所有数据的存储,包括运行、线程、助手、定时任务、检查点以及长期记忆。
  • Redis:处理关于正在进行中的运行的临时数据的存储,包括从队列 worker 到 API 服务器的流式消息。

使用过滤器减少每次请求返回的结果数

Agent Server 为每种资源类型都提供了搜索 API。这些 API 默认实现分页,并提供许多过滤选项。使用过滤可以减少每次请求返回的资源数量并提升性能。

设置 TTL 以自动删除旧数据

为线程设置 TTL 以自动清理旧数据。当关联的线程被删除时,运行和检查点会被自动删除。

避免轮询;使用 /join 监控运行

避免轮询运行状态,改用 /join API 端点。该方法会在运行完成后返回运行的最终状态。

如果你需要实时监控运行的输出,请使用 /stream API 端点。该方法会流式输出运行结果,包括运行的最终状态。

为突发性读工作负载配置自动扩缩容

自动扩缩容默认处于禁用状态,但对于突发性工作负载应予以配置。根据预期的最大吞吐量确定允许自动扩缩器扩展到的 API 服务器最大数量。

示例配置

NOTE

确切的最优配置取决于你的应用复杂度、请求模式和数据需求。请将以下示例与前面各节的信息以及你的具体使用情况结合起来,按需更新你的部署配置。如有任何疑问,请通过 support.langchain.com 联系支持团队。

下表概述了针对不同负载模式(每秒读请求数 / 每秒写请求数)和标准助手特征(平均运行执行时间 1 秒、中等 CPU 和内存使用)的不同 Agent Server 配置对比。请求速率决定了所需的稳态运行吞吐量,该吞吐量通过队列 worker 和 N_JOBS_PER_WORKER 来设定规模;而 API 服务器副本则按服务请求量本身来设定规模:

低 / 低低 / 高高 / 低中 / 中高 / 高

每秒写请求数

| 5 | 5 | 500 | 50 | 500 | |

每秒读请求数

| 5 | 500 | 5 | 50 | 500 | | API 服务器
(每个服务器 1 CPU、2Gi) | 1(默认) | 6 | 10 | 3 | 15 | | 队列 worker
(每个 worker 1 CPU、2Gi) | 1(默认) | 10 | 1(默认) | 5 | 10 | | N_JOBS_PER_WORKER | 10(默认) | 50 | 10 | 10 | 50 | | Redis 资源 | 2 Gi(默认) | 2 Gi(默认) | 2 Gi(默认) | 2 Gi(默认) | 2 Gi(默认) | | Postgres 资源 | 2 CPU
8 Gi(默认) | 4 CPU
16 Gi 内存 | 4 CPU
16 Gi | 4 CPU
16 Gi 内存 | 8 CPU
32 Gi 内存 |

示例中的负载级别定义如下:

  • 低表示大约每秒 5 个请求
  • 中表示大约每秒 50 个请求
  • 高表示大约每秒 500 个请求

低读、低写

默认的 LangSmith Deployment 配置即可处理此负载。这里无需自定义资源配置。

低读、高写

你的部署要处理大量写请求(每秒 500 个),但读请求相对较少(每秒 5 个)。

为此,我们推荐如下配置:

yaml
# Example configuration for low reads, high writes (5 read/500 write requests per second)
api:
  replicas: 6
  resources:
    requests:
      cpu: "1"
      memory: "2Gi"
    limits:
      cpu: "2"
      memory: "4Gi"

queue:
  replicas: 10
  resources:
    requests:
      cpu: "1"
      memory: "2Gi"
    limits:
      cpu: "2"
      memory: "4Gi"

config:
  numberOfJobsPerWorker: 50

redis:
  resources:
    requests:
      memory: "2Gi"
    limits:
      memory: "2Gi"

postgres:
  resources:
    requests:
      cpu: "4"
      memory: "16Gi"
    limits:
      cpu: "8"
      memory: "32Gi"

高读、低写

你的读请求量很大(每秒 500 个),但写请求相对较少(每秒 5 个)。

为此,我们推荐如下配置:

yaml
# Example configuration for high reads, low writes (500 read/5 write requests per second)
api:
  replicas: 10
  resources:
    requests:
      cpu: "1"
      memory: "2Gi"
    limits:
      cpu: "2"
      memory: "4Gi"

queue:
  replicas: 1  # Default, minimal write load
  resources:
    requests:
      cpu: "1"
      memory: "2Gi"
    limits:
      cpu: "2"
      memory: "4Gi"

redis:
  resources:
    requests:
      memory: "2Gi"
    limits:
      memory: "2Gi"

postgres:
  resources:
    requests:
      cpu: "4"
      memory: "16Gi"
    limits:
      cpu: "8"
      memory: "32Gi"
  # Consider read replicas for high read scenarios
  readReplicas: 2

中读、中写

这是一种均衡配置,应能处理中等规模的读写负载(每秒 50 读/50 写请求)。

为此,我们推荐如下配置:

yaml
# Example configuration for medium reads, medium writes (50 read/50 write requests per second)
api:
  replicas: 3
  resources:
    requests:
      cpu: "1"
      memory: "2Gi"
    limits:
      cpu: "2"
      memory: "4Gi"

queue:
  replicas: 5
  resources:
    requests:
      cpu: "1"
      memory: "2Gi"
    limits:
      cpu: "2"
      memory: "4Gi"

redis:
  resources:
    requests:
      memory: "2Gi"
    limits:
      memory: "2Gi"

postgres:
  resources:
    requests:
      cpu: "4"
      memory: "16Gi"
    limits:
      cpu: "8"
      memory: "32Gi"

高读、高写

你的读请求和写请求量都很大(每秒 500 读/500 写请求)。

为此,我们推荐如下配置:

yaml
# Example configuration for high reads, high writes (500 read/500 write requests per second)
api:
  replicas: 15
  resources:
    requests:
      cpu: "1"
      memory: "2Gi"
    limits:
      cpu: "2"
      memory: "4Gi"

queue:
  replicas: 10
  resources:
    requests:
      cpu: "1"
      memory: "2Gi"
    limits:
      cpu: "2"
      memory: "4Gi"

config:
  numberOfJobsPerWorker: 50

redis:
  resources:
    requests:
      memory: "2Gi"
    limits:
      memory: "2Gi"

postgres:
  resources:
    requests:
      cpu: "8"
      memory: "32Gi"
    limits:
      cpu: "16"
      memory: "64Gi"

自动扩缩容

如果你的部署遇到突发性流量,可以启用自动扩缩容来调整 API 服务器和队列 worker 的数量以应对负载。

以下是一个针对高读、高写的自动扩缩容示例配置:

yaml
api:
  autoscaling:
    enabled: true
    minReplicas: 15
    maxReplicas: 25

queue:
  autoscaling:
    enabled: true
    minReplicas: 10
    maxReplicas: 20

NOTE

确保你的部署环境有足够的资源扩展到推荐规模。监控你的应用和基础设施以确保最佳性能。考虑实施监控和告警,以跟踪资源用量和应用性能。


BytesRouter 是社区翻译站点,所有译文仅供参考,一切以官方英文原文为准。