Đang gặp giới hạn tần suất API Claude? Đây là những gì bạn cần làm

中村 拓也

中村 拓也

18 tháng 3 2025

Đang gặp giới hạn tần suất API Claude? Đây là những gì bạn cần làm

Trong thế giới của các ứng dụng powered by AI, API Claude của Anthropic đã trở thành giải pháp phổ biến cho nhiều nhà phát triển đang tìm kiếm khả năng xử lý ngôn ngữ tiên tiến. Tuy nhiên, giống như bất kỳ dịch vụ phổ biến nào, bạn có khả năng gặp phải giới hạn tốc độ có thể tạm thời làm gián đoạn chức năng của ứng dụng của bạn. Hiểu rõ những giới hạn này và thực hiện các chiến lược để làm việc trong chúng là rất quan trọng để duy trì trải nghiệm người dùng mượt mà.

Đối với việc lập trình AI, Claude đã trỗi dậy như một trợ lý mạnh mẽ cho cả người dùng thông thường và nhà phát triển. Tuy nhiên, nhiều người dùng gặp phải một sự phiền toái phổ biến: giới hạn tốc độ.

Người dùng đang phàn nàn về Giới hạn Sử dụng của Claude

Dù bạn đang sử dụng giao diện web của Claude hay tích hợp với API của nó thông qua các công cụ như Cursor hoặc Cline, việc chạm đến những giới hạn này có thể làm gián đoạn quy trình làm việc và năng suất của bạn. Trong khi các công cụ như Claude cung cấp khả năng AI mạnh mẽ, việc quản lý hiệu quả các tương tác API yêu cầu các công cụ thử nghiệm và gỡ lỗi thích hợp. Apidog giúp các nhà phát triển điều hướng những phức tạp này khi làm việc với AI và các API khác.

button

Hướng dẫn toàn diện này sẽ khám phá lý do tại sao giới hạn tốc độ của API Claude tồn tại, cách xác định khi nào bạn đã chạm vào chúng và cung cấp ba giải pháp chi tiết để giúp bạn vượt qua những thách thức này một cách hiệu quả.

Giới hạn tốc độ của API Claude là gì và tại sao chúng tồn tại?

Giới hạn tốc độ là những hạn chế do nhà cung cấp API áp đặt để kiểm soát khối lượng yêu cầu mà người dùng có thể thực hiện trong một khung thời gian cụ thể. Anthropic thực hiện những giới hạn này vì một số lý do quan trọng:

Giới hạn tốc độ cụ thể của API Claude

Giới hạn tốc độ của Claude thay đổi dựa trên loại tài khoản của bạn:

Thêm vào đó, trong thời gian sử dụng cao điểm, những giới hạn này có thể được thực thi nghiêm ngặt hơn, và bạn có thể trải qua việc giảm tốc độ tạm thời ngay cả trước khi đạt đến hạn ngạch tối đa của mình.

Xác định sự cố giới hạn tốc độ

Bạn có khả năng đã chạm vào giới hạn tốc độ khi ứng dụng của bạn nhận được mã trạng thái HTTP 429 Too Many Requests. Phản hồi thường bao gồm các headers thông tin về:

Giải pháp 1: Triển khai giới hạn tốc độ đúng cách trong mã của bạn

Cách tiếp cận cơ bản nhất để xử lý các giới hạn tốc độ API là triển khai giới hạn tốc độ phía khách hàng. Điều này sẽ chủ động ngăn chặn ứng dụng của bạn vượt quá khối lượng yêu cầu cho phép.

Sử dụng Thuật toán Token Bucket

Thuật toán token bucket là một thuật toán phổ biến cho giới hạn tốc độ hoạt động bằng cách:

  1. Giữ một "xô" được làm đầy với các token với tốc độ không đổi
  2. Tiêu thụ một token cho mỗi yêu cầu API
  3. Chặn các yêu cầu khi không có token có sẵn

Dưới đây là một triển khai Python:

import time
import threading

class TokenBucket:
    def __init__(self, tokens_per_second, max_tokens):
        self.tokens_per_second = tokens_per_second
        self.max_tokens = max_tokens
        self.tokens = max_tokens
        self.last_refill = time.time()
        self.lock = threading.Lock()
    
    def _refill_tokens(self):
        now = time.time()
        elapsed = now - self.last_refill
        new_tokens = elapsed * self.tokens_per_second
        self.tokens = min(self.max_tokens, self.tokens + new_tokens)
        self.last_refill = now
    
    def get_token(self):
        with self.lock:
            self._refill_tokens()
            if self.tokens >= 1:
                self.tokens -= 1
                return True
            return False
    
    def wait_for_token(self, timeout=None):
        start_time = time.time()
        while True:
            if self.get_token():
                return True
            
            if timeout is not None and time.time() - start_time > timeout:
                return False
                
            time.sleep(0.1)  # Ngủ để tránh chờ bận

# Ví dụ sử dụng với API Claude
import anthropic

# Tạo một bộ giới hạn tốc độ (5 yêu cầu mỗi giây, tối đa bùng nổ 10)
rate_limiter = TokenBucket(tokens_per_second=5, max_tokens=10)
client = anthropic.Anthropic(api_key="your_api_key")

def generate_with_claude(prompt):
    # Chờ một token trở nên có sẵn
    if not rate_limiter.wait_for_token(timeout=30):
        raise Exception("Hết thời gian chờ token giới hạn tốc độ")
    
    try:
        response = client.messages.create(
            model="claude-3-opus-20240229",
            max_tokens=1000,
            messages=[{"role": "user", "content": prompt}]
        )
        return response.content
    except Exception as e:
        if "429" in str(e):
            print("Giới hạn tốc độ đã bị chạm mặc dù chúng tôi đã giới hạn tốc độ! Đang chờ...")
            time.sleep(10)  # Thời gian chờ thêm
            return generate_with_claude(prompt)  # Thử lại
        raise

Việc triển khai này:

Xử lý phản hồi 429 với Giảm tốc độ mũ

Ngay cả với việc giới hạn tốc độ chủ động, bạn cũng có thể thỉnh thoảng chạm vào giới hạn. Triển khai giảm tốc độ mũ giúp ứng dụng của bạn khôi phục một cách duyên dáng:

import time
import random

def call_claude_api_with_backoff(prompt, max_retries=5, base_delay=1):
    retries = 0
    
    while retries <= max_retries:
        try:
            # Chờ token bộ giới hạn tốc độ
            rate_limiter.wait_for_token()
            
            # Thực hiện cuộc gọi API
            response = client.messages.create(
                model="claude-3-opus-20240229",
                max_tokens=1000,
                messages=[{"role": "user", "content": prompt}]
            )
            return response.content
            
        except Exception as e:
            if "429" in str(e) and retries < max_retries:
                # Tính toán độ trễ với giảm tốc độ mũ và jitter
                delay = base_delay * (2 ** retries) + random.uniform(0, 0.5)
                print(f"Giới hạn tốc độ. Thử lại trong {delay:.2f} giây...")
                time.sleep(delay)
                retries += 1
            else:
                raise
    
    raise Exception("Đã vượt quá số lần thử tối đa")

Chức năng này:

Giải pháp 2: Triển khai hàng đợi yêu cầu và ưu tiên

Đối với các ứng dụng có mức độ quan trọng của yêu cầu khác nhau, việc triển khai một hàng đợi yêu cầu với quản lý ưu tiên có thể tối ưu hóa việc sử dụng API của bạn.

Xây dựng hệ thống hàng đợi ưu tiên

import heapq
import threading
import time
from dataclasses import dataclass, field
from typing import Any, Callable, Optional

@dataclass(order=True)
class PrioritizedRequest:
    priority: int
    execute_time: float = field(compare=False)
    callback: Callable = field(compare=False)
    args: tuple = field(default_factory=tuple, compare=False)
    kwargs: dict = field(default_factory=dict, compare=False)
    
class ClaudeRequestQueue:
    def __init__(self, requests_per_minute=60):
        self.queue = []
        self.lock = threading.Lock()
        self.processing = False
        self.requests_per_minute = requests_per_minute
        self.interval = 60 / requests_per_minute
        
    def add_request(self, callback, priority=0, delay=0, *args, **kwargs):
        """Thêm một yêu cầu vào hàng đợi với ưu tiên đã cho."""
        with self.lock:
            execute_time = time.time() + delay
            request = PrioritizedRequest(
                priority=-priority,  # Đảo ngược để các giá trị cao hơn có ưu tiên cao hơn
                execute_time=execute_time,
                callback=callback,
                args=args,
                kwargs=kwargs
            )
            heapq.heappush(self.queue, request)
            
            if not self.processing:
                self.processing = True
                threading.Thread(target=self._process_queue, daemon=True).start()
                
    def _process_queue(self):
        """Xử lý các yêu cầu từ hàng đợi, tôn trọng giới hạn tốc độ."""
        while True:
            with self.lock:
                if not self.queue:
                    self.processing = False
                    return
                
                # Lấy yêu cầu có ưu tiên cao nhất đã sẵn sàng thực hiện
                request = self.queue[0]
                now = time.time()
                
                if request.execute_time > now:
                    # Chờ cho đến khi yêu cầu sẵn sàng
                    wait_time = request.execute_time - now
                    time.sleep(wait_time)
                    continue
                
                # Loại bỏ yêu cầu khỏi hàng đợi
                heapq.heappop(self.queue)
            
            # Thực hiện yêu cầu bên ngoài khóa
            try:
                request.callback(*request.args, **request.kwargs)
            except Exception as e:
                print(f"Có lỗi khi thực hiện yêu cầu: {e}")
                
            # Chờ khoảng thời gian giới hạn tốc độ
            time.sleep(self.interval)

# Ví dụ sử dụng
queue = ClaudeRequestQueue(requests_per_minute=60)

def process_result(result, callback):
    print(f"Nhận được kết quả: {result[:50]}...")
    if callback:
        callback(result)

def make_claude_request(prompt, callback=None, priority=0):
    def execute():
        try:
            response = client.messages.create(
                model="claude-3-opus-20240229",
                max_tokens=1000,
                messages=[{"role": "user", "content": prompt}]
            )
            process_result(response.content, callback)
        except Exception as e:
            if "429" in str(e):
                # Đưa vào hàng đợi lại với độ trễ nếu bị giới hạn tốc độ
                print("Bị giới hạn tốc độ, đang đưa vào hàng đợi lại...")
                queue.add_request(
                    make_claude_request, 
                    priority=priority-1,  # Giảm ưu tiên cho các lần thử lại
                    delay=10,  # Chờ 10 giây trước khi thử lại
                    prompt=prompt, 
                    callback=callback,
                    priority=priority
                )
            else:
                print(f"Lỗi: {e}")
    
    queue.add_request(execute, priority=priority)

# Thực hiện một số yêu cầu với các ưu tiên khác nhau
make_claude_request("Câu hỏi ưu tiên cao", priority=10)
make_claude_request("Câu hỏi ưu tiên trung bình", priority=5)
make_claude_request("Câu hỏi ưu tiên thấp", priority=1)

Việc triển khai này:

Giải pháp 3: Phân phối các yêu cầu qua nhiều phiên bản khác nhau

Đối với các ứng dụng có khối lượng lớn, việc phân phối các yêu cầu API Claude qua nhiều phiên bản có thể giúp bạn mở rộng vượt qua các giới hạn của tài khoản đơn lẻ.

Phân phối tải qua nhiều khóa API

import random
import threading
from datetime import datetime, timedelta

class APIKeyManager:
    def __init__(self, api_keys, requests_per_day_per_key):
        self.api_keys = {}
        self.lock = threading.Lock()
        
        # Khởi tạo theo dõi mức sử dụng cho từng khóa API
        for key in api_keys:
            self.api_keys[key] = {
                'key': key,
                'daily_limit': requests_per_day_per_key,
                'used_today': 0,
                'last_reset': datetime.now().date(),
                'available': True
            }
    
    def _reset_daily_counters(self):
        """Đặt lại các bộ đếm hàng ngày nếu đó là một ngày mới."""
        today = datetime.now().date()
        for key_info in self.api_keys.values():
            if key_info['last_reset'] < today:
                key_info['used_today'] = 0
                key_info['last_reset'] = today
                key_info['available'] = True
    
    def get_available_key(self):
        """Lấy một khóa API có sẵn mà chưa vượt quá giới hạn hàng ngày của nó."""
        with self.lock:
            self._reset_daily_counters()
            
            available_keys = [
                key_info for key_info in self.api_keys.values()
                if key_info['available'] and key_info['used_today'] < key_info['daily_limit']
            ]
            
            if not available_keys:
                return None
            
            # Chọn một khóa với số yêu cầu đã sử dụng hôm nay ít nhất
            selected_key = min(available_keys, key=lambda k: k['used_today'])
            selected_key['used_today'] += 1
            
            # Nếu khóa đã đạt giới hạn của nó, đánh dấu là không có sẵn
            if selected_key['used_today'] >= selected_key['daily_limit']:
                selected_key['available'] = False
                
            return selected_key['key']
    
    def mark_key_used(self, api_key):
        """Đánh dấu rằng một yêu cầu đã được thực hiện với khóa này."""
        with self.lock:
            if api_key in self.api_keys:
                self.api_keys[api_key]['used_today'] += 1
                
                if self.api_keys[api_key]['used_today'] >= self.api_keys[api_key]['daily_limit']:
                    self.api_keys[api_key]['available'] = False
    
    def mark_key_rate_limited(self, api_key, retry_after=60):
        """Đánh dấu một khóa là tạm thời không có sẵn do bị giới hạn tốc độ."""
        with self.lock:
            if api_key in self.api_keys:
                self.api_keys[api_key]['available'] = False
                
                # Bắt đầu bộ đếm thời gian để đánh dấu khóa trở lại có sẵn sau khoảng thời gian thử lại
                def make_available_again():
                    with self.lock:
                        if api_key in self.api_keys:
                            self.api_keys[api_key]['available'] = True
                
                timer = threading.Timer(retry_after, make_available_again)
                timer.daemon = True
                timer.start()

# Ví dụ sử dụng
api_keys = [
    "key1_abc123",
    "key2_def456",
    "key3_ghi789"
]

key_manager = APIKeyManager(api_keys, requests_per_day_per_key=100)

def call_claude_api_distributed(prompt):
    api_key = key_manager.get_available_key()
    
    if not api_key:
        raise Exception("Không có khóa API nào có sẵn - tất cả đã đạt giới hạn hàng ngày của chúng")
    
    client = anthropic.Anthropic(api_key=api_key)
    
    try:
        response = client.messages.create(
            model="claude-3-opus-20240229",
            max_tokens=1000,
            messages=[{"role": "user", "content": prompt}]
        )
        return response.content
    except Exception as e:
        if "429" in str(e):
            # Phân tích header retry-after nếu có sẵn, nếu không thì dùng mặc định
            retry_after = 60  # Mặc định
            key_manager.mark_key_rate_limited(api_key, retry_after)
            
            # Thử lại một cách đệ quy với một khóa khác
            return call_claude_api_distributed(prompt)
        else:
            raise

Cách tiếp cận này:

Các thực tiễn tốt nhất để quản lý giới hạn tốc độ API Claude

Ngoài ba giải pháp ở trên, đây là một số thực tiễn tốt nhất bổ sung:

Theo dõi mức sử dụng của bạn một cách chủ động

Thực hiện việc suy giảm duyên dáng

Tối ưu hóa các truy vấn của bạn

Giao tiếp với Anthropic

Kết luận

Giới hạn tốc độ là một phần không thể tránh khỏi khi làm việc với bất kỳ API mạnh mẽ nào như Claude. Bằng cách thực hiện các giải pháp được nêu trong bài viết này—mã giới hạn tốc độ đúng cách, hàng đợi yêu cầu, và xử lý yêu cầu phân phối—bạn có thể xây dựng các ứng dụng mạnh mẽ có thể xử lý những hạn chế này một cách duyên dáng.

Hãy nhớ rằng giới hạn tốc độ tồn tại để đảm bảo quyền truy cập công bằng và sự ổn định của hệ thống cho tất cả người dùng. Làm việc trong những ràng buộc này không chỉ cải thiện độ tin cậy của ứng dụng của bạn mà còn góp phần vào sức khỏe tổng thể của hệ sinh thái.

Với việc lập kế hoạch cẩn thận và triển khai các chiến lược này, bạn có thể tối đa hóa việc sử dụng các khả năng AI mạnh mẽ của Claude đồng thời duy trì trải nghiệm mượt mà cho người dùng của bạn, ngay cả khi ứng dụng của bạn mở rộng.

Thực hành thiết kế API trong Apidog

Khám phá cách dễ dàng hơn để xây dựng và sử dụng API