跳到主要内容
在本指南中,我们将介绍如何使用 UpstashRatelimitHandler 添加基于请求数量或 token 数量的限速。此处理程序使用 Upstash 的限速库,该库利用 Upstash Redis Upstash Ratelimit 的工作原理是:每次调用 limit 方法时,它都会向 Upstash Redis 发送一个 HTTP 请求。用户的剩余 token/请求会得到检查和更新。根据剩余 token,我们可以停止执行耗时操作,例如调用 LLM 或查询向量存储:
const response = await ratelimit.limit();
if (response.success) {
  execute_costly_operation();
}
UpstashRatelimitHandler 允许您在几分钟内将此限速逻辑整合到您的链中。

设置

首先,您需要访问 Upstash 控制台 并创建一个 Redis 数据库(请参阅我们的文档)。创建数据库后,您需要设置环境变量。
UPSTASH_REDIS_REST_URL="****"
UPSTASH_REDIS_REST_TOKEN="****"
接下来,您需要安装 Upstash Ratelimit 和 @langchain/community
有关安装 LangChain 软件包的一般说明,请参阅此部分
npm
npm install @upstash/ratelimit @langchain/community @langchain/core
现在您已准备好为您的链添加限速!

每请求限速

假设我们希望允许用户每分钟调用我们的链 10 次。实现这一点非常简单:
const UPSTASH_REDIS_REST_URL = "****";
const UPSTASH_REDIS_REST_TOKEN = "****";

import {
  UpstashRatelimitHandler,
  UpstashRatelimitError,
} from "@langchain/community/callbacks/handlers/upstash_ratelimit";
import { RunnableLambda } from "@langchain/core/runnables";
import { Ratelimit } from "@upstash/ratelimit";
import { Redis } from "@upstash/redis";

// create ratelimit
const ratelimit = new Ratelimit({
  redis: new Redis({
    url: UPSTASH_REDIS_REST_URL,
    token: UPSTASH_REDIS_REST_TOKEN,
  }),
  // 10 requests per window, where window size is 60 seconds:
  limiter: Ratelimit.fixedWindow(10, "60 s"),
});

// create handler
const user_id = "user_id"; // should be a method which gets the user id
const handler = new UpstashRatelimitHandler(user_id, {
  requestRatelimit: ratelimit,
});

// create mock chain
const chain = new RunnableLambda({ func: (str: string): string => str });

try {
  const response = await chain.invoke("hello world", {
    callbacks: [handler],
  });
  console.log(response);
} catch (err) {
  if (err instanceof UpstashRatelimitError) {
    console.log("Handling ratelimit.");
  }
}
请注意,我们将处理程序传递给 invoke 方法,而不是在定义链时传递处理程序。 对于 FixedWindow 以外的限速算法,请参阅 upstash-ratelimit 文档 在执行管道中的任何步骤之前,ratelimit 将检查用户是否已超出请求限制。如果超出,则会抛出 UpstashRatelimitError

每 token 限速

另一个选项是根据以下内容对链调用进行限速:
  1. 提示中的 token 数量
  2. 提示和 LLM 完成中的 token 数量
这仅在您的链中包含 LLM 时才有效。另一个要求是您正在使用的 LLM 应该在其 LLMOutput 中返回 token 用量。返回的 token 用量字典的格式取决于 LLM。要了解如何根据您的 LLM 配置处理程序,请参阅下面“配置”部分的末尾。

工作原理

处理程序将在调用 LLM 之前获取剩余 token。如果剩余 token 大于 0,将调用 LLM。否则将抛出 UpstashRatelimitError 调用 LLM 后,token 用量信息将用于从用户的剩余 token 中减去。在此链阶段不会引发错误。

配置

对于第一种配置,只需这样初始化处理程序:
const user_id = "user_id"; // should be a method which gets the user id
const handler = new UpstashRatelimitHandler(user_id, {
  requestRatelimit: ratelimit,
});
对于第二种配置,初始化处理程序的方法如下:
const user_id = "user_id"; // should be a method which gets the user id
const handler = new UpstashRatelimitHandler(user_id, {
  tokenRatelimit: ratelimit,
});
您还可以通过同时传递 request_ratelimittoken_ratelimit 参数来同时采用基于请求和 token 的限速。 为了使 token 用量正常工作,LangChain.js 中的 LLM 步骤应以以下格式返回 token 用量字段:
{
  "tokenUsage": {
    "totalTokens": 123,
    "promptTokens": 456,
    "otherFields: "..."
  },
  "otherFields: "..."
}
然而,LangChain.js 中的所有 LLM 并非都符合此格式。如果您的 LLM 返回具有不同键的相同值,您可以通过将 llmOutputTokenUsageFieldllmOutputTotalTokenFieldllmOutputPromptTokenField 参数传递给处理程序来使用它们。
const handler = new UpstashRatelimitHandler(
  user_id,
  {
    requestRatelimit: ratelimit
    llmOutputTokenUsageField: "usage",
    llmOutputTotalTokenField: "total",
    llmOutputPromptTokenField: "prompt"
  }
)
这是一个使用 LLM 的链示例:
const UPSTASH_REDIS_REST_URL = "****";
const UPSTASH_REDIS_REST_TOKEN = "****";
const OPENAI_API_KEY = "****";

import {
  UpstashRatelimitHandler,
  UpstashRatelimitError,
} from "@langchain/community/callbacks/handlers/upstash_ratelimit";
import { RunnableLambda, RunnableSequence } from "@langchain/core/runnables";
import { OpenAI } from "@langchain/openai";
import { Ratelimit } from "@upstash/ratelimit";
import { Redis } from "@upstash/redis";

// create ratelimit
const ratelimit = new Ratelimit({
  redis: new Redis({
    url: UPSTASH_REDIS_REST_URL,
    token: UPSTASH_REDIS_REST_TOKEN,
  }),
  // 500 tokens per window, where window size is 60 seconds:
  limiter: Ratelimit.fixedWindow(500, "60 s"),
});

// create handler
const user_id = "user_id"; // should be a method which gets the user id
const handler = new UpstashRatelimitHandler(user_id, {
  tokenRatelimit: ratelimit,
});

// create mock chain
const asStr = new RunnableLambda({ func: (str: string): string => str });
const model = new OpenAI({
  apiKey: OPENAI_API_KEY,
});
const chain = RunnableSequence.from([asStr, model]);

// invoke chain with handler:
try {
  const response = await chain.invoke("hello world", {
    callbacks: [handler],
  });
  console.log(response);
} catch (err) {
  if (err instanceof UpstashRatelimitError) {
    console.log("Handling ratelimit.");
  }
}

以编程方式连接这些文档到 Claude、VSCode 等,通过 MCP 获取实时答案。
© . This site is unofficial and not affiliated with LangChain, Inc.