LangSmith Agent Server 的默认配置旨在处理各种不同工作负载的大量读写负载。通过遵循以下最佳实践,您可以调整 Agent Server 以在特定工作负载下达到最佳性能。本页面介绍了自托管部署中 Agent Server 的扩展注意事项,并提供了示例配置。
对于 云,平台会自动扩展,以下 Helm 配置不适用。
写入负载
写入负载主要由以下因素驱动:
以下组件主要负责处理写入负载:
- - API 服务器:处理初始请求并将数据持久化到数据库。
- - 队列工作进程:处理运行的执行。
- - Redis:处理正在运行的临时数据存储。
- - Postgres:处理所有数据的存储,包括运行、线程、助手、定时任务、检查点和长期记忆。
根据助手特性调整 N_JOBS_PER_WORKER 基于助手特性进行调整
的默认值为 10。您可以根据助手特性更改此值,以扩展单个队列工作进程可同时执行的最大运行数。 N_JOBS_PER_WORKER 默认值是 10。您可以根据助手的特性更改此值,以扩展单个队列工作进程可同时执行的最大运行数。
更改的一些通用指南 N_JOBS_PER_WORKER:
- - 如果您的助手受 CPU 限制,默认值 10 可能就足够了。如果您注意到队列工作进程的 CPU 使用率过高或运行执行延迟,您可能需要降低
N_JOBS_PER_WORKER的值。 - - 如果您的助手受 IO 限制,请增加
N_JOBS_PER_WORKER的值以处理每个工作进程更多并发运行。
没有上限 N_JOBS_PER_WORKER。但是,队列工作进程在获取新运行时会贪婪,这意味着它们会尝试获取所有可用的运行并立即开始执行。在流量突发环境中设置 N_JOBS_PER_WORKER 过高会导致工作进程利用率不均匀和运行执行时间增加。
避免同步阻塞操作
在代码中避免同步阻塞操作,优先使用异步操作。长时间同步操作可能会阻塞主事件循环,导致请求和运行执行时间延长以及可能的超时。
例如,考虑一个需要休眠1秒的应用程序。与其使用如下同步代码:
def my_function():
time.sleep(1)
推荐使用如下异步代码:
async def my_function():
await asyncio.sleep(1)
如果助手需要同步阻塞操作,请在 asyncio.to_thread() 或同等工具中运行。
最小化冗余检查点
通过设置 durability 为确保数据持久性所需的最小值来最小化冗余检查点。
默认的持久性模式是 "async",这意味着检查点会在每个步骤后异步写入。如果助手只需要持久化运行的最终状态, durability 可以设置为 "exit",仅存储运行的最终状态。可以在创建运行时设置:
from langgraph_sdk import get_client
client = get_client(url=)
thread = await client.threads.create()
run = await client.runs.create(
thread_id=thread["thread_id"],
assistant_id="agent",
durability="exit"
)
启用队列工作进程
默认情况下,API服务器管理队列,不使用队列工作进程。通过设置来启用队列工作进程 queue.enabled to true:
queue:
enabled: true
这将队列管理从API服务器转移到专用队列工作进程,减轻API服务器的负载,让它能够专注于处理请求。
根据预期吞吐量调整作业大小
并行执行的运行越多,需要处理负载的作业就越多。有两个主要参数可以扩展可用作业:
- -
number_of_queue_workers:配置的工作进程数量。 - -
N_JOBS_PER_WORKER:单个工作进程可以同时执行的运行数。默认为10。
可以使用以下公式计算可用作业数:
available_jobs = number_of_queue_workers * N_JOBS_PER_WORKER
然后,吞吐量是可用作业每秒可以执行的运行数:
throughput_per_second = available_jobs / average_run_execution_time_seconds
因此,为支持预期的稳态吞吐量,您应该配置的最少工作进程数是:
number_of_queue_workers = throughput_per_second * average_run_execution_time_seconds / N_JOBS_PER_WORKER
为突发写入工作负载配置自动扩展
默认情况下,自动扩展是禁用的,但应该为突发工作负载配置。使用与上一节相同的计算方法,可以根据最大预期吞吐量确定应该允许自动扩展的最大工作进程数。
读取负载
读取负载主要由以下因素驱动:
以下组件主要负责处理读取负载:
- - API服务器:处理请求并直接从数据库检索数据。
- - Postgres:处理所有数据的存储,包括运行、线程、助手、定时任务、检查点和长期记忆。
- - Redis:处理关于正在运行的临时数据的存储,包括从队列工作进程到API服务器的流式消息。
使用过滤来减少每个请求的结果
代理服务器 为每种资源类型提供搜索 API。这些 API 默认实现分页,并提供多种过滤选项。使用过滤可以减少每次请求返回的资源数量并提高性能。
设置 TTL 以自动删除旧数据
设置一个 线程上的 TTL 以自动清理旧数据。关联线程被删除时,运行和检查点会自动删除。
避免轮询;使用 /join 来监控运行
使用 /join API 端点来避免轮询运行状态。该方法会在运行完成后返回运行的最终状态。
如果需要实时监控运行输出,请使用 /stream API 端点。该方法会流式传输运行输出,包括运行的最终状态。
为突发读取工作负载配置自动扩展
默认情况下自动扩展处于禁用状态,但应该为突发工作负载配置自动扩展。根据最大预期吞吐量确定应该允许自动扩展器扩展到的最大 API 服务器数量。
示例配置
The following table provides an overview comparing different Agent Server configurations for various load patterns (read requests per second / write requests per second) and standard assistant characteristics (average run execution time of 1 second, moderate CPU and memory usage):
| **Low / low** | **Low / high** | **High / low** | Medium / medium | High / high | |
|---|---|---|---|---|---|
| 每秒写入请求数 | 5 | 5 | 500 | 50 | 500 |
| 每秒读取请求数 | 5 | 500 | 5 | 50 | 500 |
| **API 服务器**<br />(1 CPU, 2Gi 每服务器) | 1 (默认) | 6 | 10 | 3 | 15 |
| **队列工作器**<br />(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<br />8 Gi (默认) | 4 CPU<br />16 Gi 内存 | 4 CPU<br />16 Gi | 4 CPU<br />16 Gi 内存 | 8 CPU<br />32 Gi 内存 |
示例中的负载级别定义如下:
- - 低表示大约每秒 5 个请求
- - 中表示大约每秒 50 个请求
- - 高表示大约每秒 500 个请求
低读取,低写入
默认 LangSmith 部署 配置将处理此负载。此处无需自定义资源配置。
低读取,高写入
您的部署正在处理大量写入请求(每秒 500 个),但读取请求相对较少(每秒 5 个)。
对于这种情况,我们建议如下配置:
# 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 个)。
对此,我们推荐这样的配置:
# 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
中等读取,中等写入
This is a balanced configuration that should handle moderate read and write loads (50 read/50 write requests per second).
对此,我们推荐这样的配置:
# 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"
高读取,高写入
You have high volumes of both read and write requests (500 read/500 write requests per second).
对此,我们推荐这样的配置:
# 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 服务器和队列工作进程的数量以处理负载。
以下是高读取和高写入的自动扩缩容示例配置:
api:
autoscaling:
enabled: true
minReplicas: 15
maxReplicas: 25
queue:
autoscaling:
enabled: true
minReplicas: 10
maxReplicas: 20