Upstash Ratelimit 回呼
在本指南中,我們將介紹如何使用 UpstashRatelimitHandler
,根據請求數量或權杖數量新增速率限制。此處理常式使用 Upstash 的 ratelimit 程式庫,該程式庫利用 Upstash Redis。
Upstash Ratelimit 的運作方式是,每次呼叫 limit
方法時,都會向 Upstash Redis 發送 HTTP 請求。系統會檢查並更新使用者的剩餘權杖/請求。根據剩餘權杖,我們可以停止執行耗費資源的操作,例如叫用 LLM 或查詢向量儲存庫。
response = ratelimit.limit()
if response.allowed:
execute_costly_operation()
UpstashRatelimitHandler
可讓您在幾分鐘內將速率限制邏輯整合到您的鏈中。
首先,您需要前往 Upstash 主控台 並建立 Redis 資料庫 (請參閱我們的文件)。建立資料庫後,您需要設定環境變數
UPSTASH_REDIS_REST_URL="****"
UPSTASH_REDIS_REST_TOKEN="****"
接下來,您需要使用以下命令安裝 Upstash Ratelimit 和 Redis 程式庫
pip install upstash-ratelimit upstash-redis
您現在已準備好將速率限制新增至您的鏈!
依請求次數進行速率限制
假設我們想要允許使用者每分鐘叫用我們的鏈 10 次。達成此目的非常簡單,只需
# set env variables
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
# create ratelimit
ratelimit = Ratelimit(
redis=Redis.from_env(),
# 10 requests per window, where window size is 60 seconds:
limiter=FixedWindow(max_requests=10, window=60),
)
# create handler
user_id = "user_id" # should be a method which gets the user id
handler = UpstashRatelimitHandler(identifier=user_id, request_ratelimit=ratelimit)
# create mock chain
chain = RunnableLambda(str)
# invoke chain with handler:
try:
result = chain.invoke("Hello world!", config={"callbacks": [handler]})
except UpstashRatelimitError:
print("Handling ratelimit.", UpstashRatelimitError)
Error in UpstashRatelimitHandler.on_chain_start callback: UpstashRatelimitError('Request limit reached!')
``````output
Handling ratelimit. <class 'langchain_community.callbacks.upstash_ratelimit_callback.UpstashRatelimitError'>
請注意,我們將處理常式傳遞至 invoke
方法,而不是在定義鏈時傳遞處理常式。
如需 FixedWindow
以外的速率限制演算法,請參閱 upstash-ratelimit 文件。
在執行管線中的任何步驟之前,速率限制將檢查使用者是否已超過請求限制。如果超過,則會引發 UpstashRatelimitError
。
依權杖數量進行速率限制
另一個選項是根據以下項目限制鏈叫用速率
- 提示中的權杖數量
- 提示和 LLM 完成中的權杖數量
這僅在您的鏈中有 LLM 時才有效。另一個要求是您使用的 LLM 應在其 LLMOutput
中傳回權杖使用量。
運作方式
處理常式將在呼叫 LLM 之前取得剩餘權杖。如果剩餘權杖大於 0,則會呼叫 LLM。否則,將引發 UpstashRatelimitError
。
在呼叫 LLM 後,權杖使用量資訊將用於從使用者的剩餘權杖中扣除。在此鏈階段不會引發錯誤。
組態
對於第一個組態,只需像這樣初始化處理常式即可
ratelimit = Ratelimit(
redis=Redis.from_env(),
# 1000 tokens per window, where window size is 60 seconds:
limiter=FixedWindow(max_requests=1000, window=60),
)
handler = UpstashRatelimitHandler(identifier=user_id, token_ratelimit=ratelimit)
對於第二個組態,以下是如何初始化處理常式
ratelimit = Ratelimit(
redis=Redis.from_env(),
# 1000 tokens per window, where window size is 60 seconds:
limiter=FixedWindow(max_requests=1000, window=60),
)
handler = UpstashRatelimitHandler(
identifier=user_id,
token_ratelimit=ratelimit,
include_output_tokens=True, # set to True
)
您也可以同時使用依請求次數和權杖數量的速率限制,只需同時傳遞 request_ratelimit
和 token_ratelimit
參數即可。
以下是使用 LLM 的鏈的範例
# set env variables
import os
os.environ["UPSTASH_REDIS_REST_URL"] = "****"
os.environ["UPSTASH_REDIS_REST_TOKEN"] = "****"
os.environ["OPENAI_API_KEY"] = "****"
from langchain_community.callbacks import UpstashRatelimitError, UpstashRatelimitHandler
from langchain_core.runnables import RunnableLambda
from langchain_openai import ChatOpenAI
from upstash_ratelimit import FixedWindow, Ratelimit
from upstash_redis import Redis
# create ratelimit
ratelimit = Ratelimit(
redis=Redis.from_env(),
# 500 tokens per window, where window size is 60 seconds:
limiter=FixedWindow(max_requests=500, window=60),
)
# create handler
user_id = "user_id" # should be a method which gets the user id
handler = UpstashRatelimitHandler(identifier=user_id, token_ratelimit=ratelimit)
# create mock chain
as_str = RunnableLambda(str)
model = ChatOpenAI()
chain = as_str | model
# invoke chain with handler:
try:
result = chain.invoke("Hello world!", config={"callbacks": [handler]})
except UpstashRatelimitError:
print("Handling ratelimit.", UpstashRatelimitError)
Error in UpstashRatelimitHandler.on_llm_start callback: UpstashRatelimitError('Token limit reached!')
``````output
Handling ratelimit. <class 'langchain_community.callbacks.upstash_ratelimit_callback.UpstashRatelimitError'>