Bootstrap

使用 Upstash Ratelimit 进行调用频率限制

老铁们,今天我们来聊聊如何使用 Upstash 提供的 RatelimitHandler 来实现请求或令牌数量的频率限制。其实说白了,RatelimitHandler 是 Upstash 的 ratelimit 库的一个封装,后端则是基于 Upstash Redis 的。每次调用 limit 方法时,它通过发送 HTTP 请求来检查和更新用户的剩余请求数或令牌数。这个机制可以帮助我们在调用大语言模型(LLM)或查询向量存储等花费较高的操作前进行判断,从而避免不必要的计算资源消耗。

response = ratelimit.limit()
if response.allowed:
    execute_costly_operation()

UpstashRatelimitHandler 允许你在几分钟内将限流逻辑整合到你的链式调用中。

技术背景介绍

首先,你需要前往 Upstash 控制台创建一个 Redis 数据库。数据库创建后,记得设置以下环境变量:

UPSTASH_REDIS_REST_URL="****"
UPSTASH_REDIS_REST_TOKEN="****"

接下来,通过 pip 安装 Upstash Ratelimit 和 Redis 库:

pip install upstash-ratelimit upstash-redis

准备就绪,现在我们开始为你的链式调用添加限流吧!

原理深度解析

假设我们想要限制用户每分钟调用链式操作的次数为 10。实现起来非常简单:

# 设置环境变量
import os

os.environ["UPSTASH_REDIS_REST_URL"] = "****"
os.environ["UPSTASH_REDIS_REST_TOKEN"] = "****"

from langchain_community.callbacks import UpstashRatelimitError, UpstashRatelimitHandler
from langchain_core.runnables import RunnableLambda
from upstash_ratelimit import FixedWindow, Ratelimit
from upstash_redis import Redis

# 创建限流器
ratelimit = Ratelimit(
    redis=Redis.from_env(),
    limiter=FixedWindow(max_requests=10, window=60),  # 每 60 秒最多 10 次请求
)

# 创建处理器
user_id = "user_id"  # 需要有一个函数来获取用户ID
handler = UpstashRatelimitHandler(identifier=user_id, request_ratelimit=ratelimit)

# 创建 mock 链
chain = RunnableLambda(str)

# 使用处理器调用链
try:
    result = chain.invoke("Hello world!", config={"callbacks": [handler]})
except UpstashRatelimitError:
    print("处理限流错误。", UpstashRatelimitError)

注意,我们是在调用链的 invoke 方法中传递处理器,而不是定义链时传递。

实战代码演示

另一种选择是根据令牌数量限制调用:

ratelimit = Ratelimit(
    redis=Redis.from_env(),
    limiter=FixedWindow(max_requests=1000, window=60),  # 每 60 秒最多 1000 个令牌
)

handler = UpstashRatelimitHandler(identifier=user_id, token_ratelimit=ratelimit)

如果您的链中有 LLM,可以通过 LLM 的输出获取令牌使用情况。

优化建议分享

使用代理服务可以提高稳定性和响应速度。我个人一直在用 https://zzzzapi.com 提供一站式大模型解决方案,感觉效果不错。

补充说明和总结

结合请求和令牌的限流方式,可以更灵活地控制 API 的使用:

handler = UpstashRatelimitHandler(
    identifier=user_id,
    request_ratelimit=request_ratelimit,
    token_ratelimit=token_ratelimit,
)

老铁们,今天的技术分享就到这里,希望对大家有帮助。开发过程中遇到问题也可以在评论区交流~

—END—

;