LangSmith Agent Server 的默认配置旨在处理各种工作负载下的大量读写请求。通过遵循下述最佳实践,您可以根据自身特定工作负载调整 Agent Server,使其达到最佳性能。本页面描述了自托管部署中 Agent Server 的扩展考量,并提供了配置示例。
如果您还不熟悉 API 服务器和队列工作器在容器层面的运作方式,请先阅读运行时架构概述。
对于云服务,平台会自动扩展,因此下述 Helm 配置不适用。

请求并发与运行并发

两种相互独立的并发类型决定了 Agent Server 的扩展方式,并且它们是分别控制的:
  • 请求并发是指部署同时处理的 API 请求数量(创建运行、读取线程状态、流式传输结果)。API 服务器异步处理请求,请求并发随 API 服务器副本数量的增加而水平扩展。
  • 运行并发是指同时执行的运行数量。单个队列工作器最多可并发执行 N_JOBS_PER_WORKER 个运行(默认值为 10)。运行并发上限为队列工作器数量乘以 N_JOBS_PER_WORKER。
创建运行是一个快速的写入请求:API 服务器持久化一个待处理的运行后立即返回,无需等待运行执行完成。如果所有运行槽位都已占满,额外的运行将在队列中等待,直到有槽位释放。提高 N_JOBS_PER_WORKER 或增加队列工作器数量可以提高运行吞吐量;但这不会改变部署能够并发处理的请求数量。

写入负载

写入负载主要由以下因素驱动:
  • 创建新的运行
  • 运行执行期间创建新的检查点
  • 写入长期记忆
  • 创建新的线程
  • 创建新的助手
  • 删除运行、检查点、线程、助手和定时任务
以下组件主要负责处理写入负载:
  • API 服务器:处理初始请求并将数据持久化到数据库。
  • 队列工作器:处理运行的执行。
  • Redis:存储关于进行中运行的临时数据。
  • Postgres:存储所有数据,包括运行、线程、助手、定时任务、检查点和长期记忆。

根据助手特性调整 N_JOBS_PER_WORKER

N_JOBS_PER_WORKER 的默认值为 10。您可以根据助手的特性更改此值,以调整单个队列工作器同时执行的最大运行数量。 调整 N_JOBS_PER_WORKER 的一些通用指南:
  • 如果您的助手是 CPU 密集型,默认值 10 可能已经足够。如果您注意到队列工作器 CPU 使用率过高或运行执行延迟,可以降低 N_JOBS_PER_WORKER。
  • 如果您的助手是内存密集型,或队列工作器接近内存限制,请降低 N_JOBS_PER_WORKER 以减少每个工作器的并发运行数量。
  • 如果您的助手是 IO 密集型,请提高 N_JOBS_PER_WORKER 以处理每个工作器更多的并发运行。
N_JOBS_PER_WORKER 没有上限。但是,队列工作器在获取新运行时是贪婪的,这意味着它们会尽可能多地拾取可用的运行并立即开始执行。在流量突发的环境中,将 N_JOBS_PER_WORKER 设置过高可能导致工作器利用率不均、运行执行时间增加以及队列工作器内存使用率过高。

避免同步阻塞操作

在代码中避免使用同步阻塞操作,优先使用异步操作。长时间的同步操作会阻塞主事件循环,导致请求和运行执行时间变长,并可能引发超时。 例如,考虑一个需要休眠 1 秒的应用程序。不要使用这样的同步代码:
请优先使用这样的异步代码:
如果助手需要同步阻塞操作,请在 asyncio.to_thread() 或等效方法中运行这些操作。

最小化冗余检查点

通过将 durability 设置为确保数据持久性所需的最小值,来最小化冗余检查点。 默认持久性模式为 "async",即每个步骤后异步写入检查点。如果助手只需要持久化运行的最终状态,可以将 durability 设置为 "exit",仅存储运行的最终状态。这可以在创建运行时设置:

启用队列工作器

默认情况下,API 服务器管理队列,不使用队列工作器。通过将 queue.enabled 设置为 true 来启用队列工作器:
这将队列管理从 API 服务器卸载到专用的队列工作器,减少 API 服务器的负载,使其能够专注于处理请求。

根据预期吞吐量调整作业规模

本节对运行执行容量(队列工作器)进行规模调整,这与请求服务容量(API 服务器副本)是分开的。更多信息,请参阅请求并发与运行并发。 并行执行的运行越多,处理负载所需的作业就越多。扩展可用作业有两个主要参数:
  • number_of_queue_workers:配置的队列工作器数量。
  • N_JOBS_PER_WORKER:单个队列工作器同时执行的运行数量。默认值为 10。
您可以使用以下公式计算可用作业数:
吞吐量则是可用作业每秒可以执行的运行数量:
因此,为支持预期的稳态吞吐量,您应配置的最小队列工作器数量为:

为突发写入工作负载配置自动扩展

自动扩展默认是禁用的,但应为突发工作负载进行配置。使用与上一节相同的计算,您可以根据最大预期吞吐量确定允许自动扩展器扩展到的最大队列工作器数量。

读取负载

读取负载主要由以下因素驱动: 以下组件主要负责处理读取负载:
  • API 服务器:处理请求并直接从数据库检索数据。
  • Postgres:存储所有数据,包括运行、线程、助手、定时任务、检查点和长期记忆。
  • Redis:存储关于进行中运行的临时数据,包括将消息从队列工作器流式传输到 API 服务器。

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

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

设置 TTL 以自动删除旧数据

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

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

避免轮询运行状态,请使用 /join API 端点。此方法在运行完成后返回运行的最终状态。 如果您需要实时监控运行的输出,请使用 /stream API 端点。此方法流式传输运行输出,包括运行的最终状态。

为突发读取工作负载配置自动扩展

自动扩展默认是禁用的,但应为突发工作负载进行配置。根据最大预期吞吐量确定允许自动扩展器扩展到的最大 API 服务器数量。

配置示例

确切的最佳配置取决于您的应用程序复杂性、请求模式和数据需求。请结合前几节的信息以及您的具体使用情况,使用以下示例按需更新您的部署配置。如有任何疑问,请通过 support.langchain.com 联系支持。
下表概述了不同负载模式(每秒读取请求数 / 每秒写入请求数)和标准助手特性(平均运行执行时间 1 秒,中等 CPU 和内存使用率)下不同 Agent Server 配置的对比。请求速率决定了所需的稳态运行吞吐量,该吞吐量通过队列工作器和 N_JOBS_PER_WORKER 进行规模调整,而 API 服务器副本则根据请求量本身进行规模调整: 示例中的负载级别定义如下:
  • 低 表示大约每秒 5 个请求
  • 中 表示大约每秒 50 个请求
  • 高 表示大约每秒 500 个请求

低读取,低写入

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

低读取,高写入

您的部署正在处理大量写入请求(每秒 500 个),但读取请求相对较少(每秒 5 个)。 为此,我们推荐如下配置:

高读取,低写入

您的部署正在处理大量读取请求(每秒 500 个),但写入请求相对较少(每秒 5 个)。 为此,我们推荐如下配置:

中读取,中写入

这是一个均衡的配置,应能处理中等读写负载(每秒 50 个读取/50 个写入请求)。 为此,我们推荐如下配置:

高读取,高写入

您的部署正在处理大量读取和写入请求(每秒 500 个读取/500 个写入请求)。 为此,我们推荐如下配置:

自动扩展

如果您的部署遇到突发流量,您可以启用自动扩展来调整 API 服务器和队列工作器的数量以处理负载。 以下是一个针对高读取和高写入场景的自动扩展配置示例:
确保您的部署环境有足够的资源扩展到推荐的大小。监控您的应用程序和基础设施以确保最佳性能。考虑实施监控和告警以跟踪资源使用情况和应用程序性能。