Prompt Rate Limits & Batching : 귀하의 LLM API에는 속도 제한이 있습니다 (귀하의 제품이 그렇지 않더라도) 당신은 기능을 전송, 당신의 트래픽 스픽, 그리고 갑자기 당신의 LLM 레이어가 돌아오기 시작합니다. 마치 주차 티켓을 배달하는 것처럼. 429s 나쁜 소식 : 금리 제한은 불가피합니다. 좋은 소식 : 일반적으로 과도한 인스턴스, 폭발적인 트래픽 및 규모에서 분석할 수없는 출력 형식에 의해 발생합니다. most LLM “rate limit incidents” are self-inflicted 이 문서는 다음을위한 실용적인 플레이북입니다: 빠른 속도에 대한 이해, 일반적인 실패 모드를 피하고, 당신의 응답을 수프로 바꾸지 않고 요청을 배치합니다. 1) 당신이 실제로 만난 세 가지 경계 (그리고 그들이 의미하는 것) 다른 공급자가 물건을 다르게 지칭하지만 메커니즘은 일관되었습니다 : 1.1 컨텍스트 창 (수요당 최대 토큰) 만약 당신의 모델 컨텍스트 창을 초과하면 요청이 즉시 실패합니다. input + output 증상 : “최대 컨텍스트 길이 초과” “당신의 메시지는 X 토큰으로 이어졌습니다...” 고정 : 데이터를 짧게, 요약하거나 조각합니다. RPM (Requests Per Minute - 분당 요청) 당신은 토큰 한계 아래에있을 수 있으며 여전히 너무 많은 호출을 터뜨리면 흔들릴 수 있습니다.Gemini는 RPM를 핵심 차원으로 명시적으로 문서화합니다. 증상 : “분당 요청에 대한 가격 제한이 달성되었습니다” HTTP 429 고정 : 클라이언트 사이드 패싱, 꼬리, 그리고 백코프 1.3 TPM / 토큰 통과 제한 Anthropic Measures Rate Limits에 관한 정보 (ITPM/OTPM) 쌍둥이는 마찬가지로 토큰당 분을 키 차원으로 묘사합니다. RPM + input tokens/minute + output tokens/minute 증상 : “분당 토큰 사용에 대한 가격 제한이 달성되었습니다” 429 + Retry-After header (Anthropic은 이것을 호출합니다) 고정 : 토큰을 줄이고, 배치를 효율적으로 만들거나, 더 높은 금액을 요구합니다. 2) 가장 일반적인 “프롬프트 리미트” 실패 패턴 2.1 “One prompt to rule them all” 안티 패턴 당신은 요청 : 추출 분류 다시 쓰기 유효성 형식화 비즈니스 논리 ...한 번의 요청으로, 그리고 왜 토큰 사용이 높아지는지 궁금합니다. 다중 단계 논리를 사용하려면 (Structured intermediate outputs를 가진 소규모 프롬프트) Split the workflow Prompt Chaining 버스티 트래픽(The Silent RPM Killer) Cron jobs, retries, user clicks, webhook bursts—모든 것이 최악의 순간에 일치합니다. 귀하의 클라이언트가 기관총과 같은 요청을 보낸다면, 귀하의 공급자는 반역자처럼 응답할 것입니다. 2.3 구조화되지 않은 출력 = 비싼 파싱 당신의 출력은 "Kinda JSON-ish"라면, 당신의 분석가는 풀 타임 치료사가됩니다. 모델 output 만들기 또는 고정 테이블. 계약 형식으로 취급하십시오. strict JSON 3) Rate Limit Survival Kit (공정, 실용적, 지루한) 3.1 Prompt-side: 신호를 잃지 않고 토큰을 줄이기 마케팅 흐름을 삭제하십시오 (모델은 회사의 기원 이야기를 필요로하지 않습니다). 반복되는 염소판을 짧은 "정책 블록"으로 변환하고 재사용하십시오. 프로즈보다 필드를 선호합니다 (“재료=316 스테인레스 스틸” 단락을 때린다). 일반적으로 30-50%를 절약하는 작은 인스턴트 다시 쓰기 Before (chatty): “우리는 2010 년에 설립 된 스마트 홈 브랜드입니다 ... 3 마케팅 라인을 작성하십시오...” “우리는 2010 년에 설립 된 스마트 홈 브랜드입니다 ... 3 마케팅 라인을 작성하십시오...” After (dense + precise): “Write 3 UK ecommerce lines. Product: smart bulb. Material=PC flame-retardant. Feature=3 colour temperatures. Audience=living room.” “Write 3 UK ecommerce lines. Product: smart bulb. Material=PC flame-retardant. Feature=3 colour temperatures. Audience=living room.” 3.2 요청 측면 : 어른처럼 백코프 공급자가 돌아오면 Anthropic은 명시적으로 Retry-After를 429s에서 반환합니다. Retry-After Exponential Backoff + Jitter를 사용하십시오. 시도 1 : 1s 시도 2: 2–3s 시도 3: 4–6s 그리하여 훌륭한 실패를 3.3 시스템 측면: 꼬리 + 경쟁 캡 귀하의 계정이 10 개의 동시 요청을 지원하는 경우 200 개의 코루틴과 "희망"을 실행하지 마십시오. 사용하기 : 직업 꼬리 경쟁을 위한 시메올 그리고 RPM/TPM에 대한 속도 제한자 4) 배치 : 전화, 비용 및 429을 줄이는 가장 빠른 방법 배팅은 의미 : . one API request handles multiple independent tasks 그것은 작업이있을 때 가장 잘 작동합니다 : 동일한 유형 (예를 들어, 20 제품 blurbs) 독립적(아무 단계도 다른 단계에 달려 있지 않음) 동일한 출력 계획 왜 도움이 되는지 네트워크 round-trips 더 낮은 RPM 압력 더 예측할 수 있는 통로 또한: OpenAI의 가격 페이지에는 여러 모델에 대한 "배치 API 가격" 열이 명시적으로 포함됩니다. (그것은 "배치가 무료"라는 것을 의미하지는 않지만 생태계가이 패턴을 기대한다는 강력한 힌트입니다.) 5) 분리되지 않는 배치 프롬프트 템플릿 여기에 압력으로 읽을 수있는 형식이 있습니다. 5.1 작업 블록 + 엄격한 JSON 응답 계획 사용 SYSTEM: You output valid JSON only. No Markdown. No commentary. USER: You will process multiple tasks. Return a JSON array. Each item must be: { "task_id": <int>, "title": <string>, "bullets": [<string>, <string>, <string>] } Rules: - UK English spelling - Title ≤ 12 words - 3 bullets, each ≤ 18 words - If input is missing: set title="INSUFFICIENT_DATA" and bullets=[] TASKS: ### TASK 1 product_name: Insulated smart mug material: 316 stainless steel features: temperature alert, 7-day battery audience: commuters ### TASK 2 product_name: Wireless earbuds material: ABS shock-resistant features: ANC, 24-hour battery audience: students 그 “INSUFFICIENT_DATA” 조항은 당신의 생명 구원자입니다. 하나의 깨진 작업은 전체 배치를 중독해서는 안됩니다. 6) Python Implementation: Batch → Call → Parse (With Guardrails) 아래는 당신이 적응할 수있는 현대적인 패턴입니다 (공급자 SDK는 다릅니다, 그래서 그것을 보증서가 아닌 보증서가 있습니다.) structure import json import random import time from typing import Any, Dict, List, Tuple MAX_RETRIES = 4 def backoff_sleep(attempt: int, retry_after: float | None = None) -> None: if retry_after is not None: time.sleep(retry_after) return base = 2 ** attempt jitter = random.random() time.sleep(min(10, base + jitter)) def build_batch_prompt(tasks: List[Dict[str, str]]) -> str: header = ( "You output valid JSON only. No Markdown. No commentary.\n\n" "Return a JSON array. Each item must be:\n" "{\n \"task_id\": <int>,\n \"title\": <string>,\n \"bullets\": [<string>, <string>, <string>]\n}\n\n" "Rules:\n" "- UK English spelling\n" "- Title ≤ 12 words\n" "- 3 bullets, each ≤ 18 words\n" "- If input is missing: set title=\"INSUFFICIENT_DATA\" and bullets=[]\n\n" "TASKS:\n" ) blocks = [] for t in tasks: blocks.append( f"### TASK {t['task_id']}\n" f"product_name: {t.get('product_name','')}\n" f"material: {t.get('material','')}\n" f"features: {t.get('features','')}\n" f"audience: {t.get('audience','')}\n" ) return header + "\n".join(blocks) def parse_json_strict(text: str) -> List[Dict[str, Any]]: # Hard fail if it's not JSON. This is intentional. return json.loads(text) def call_llm(prompt: str) -> Tuple[str, float | None]: """Return (text, retry_after_seconds). Replace with your provider call.""" raise NotImplementedError def run_batch(tasks: List[Dict[str, str]]) -> List[Dict[str, Any]]: prompt = build_batch_prompt(tasks) for attempt in range(MAX_RETRIES): try: raw_text, retry_after = call_llm(prompt) return parse_json_strict(raw_text) except json.JSONDecodeError: # Ask the model to repair formatting in a second pass (or log + retry) prompt = ( "Fix the output into valid JSON only. Preserve meaning.\n\n" f"BAD_OUTPUT:\n{raw_text}" ) backoff_sleep(attempt) except Exception as e: # If your SDK exposes HTTP status + retry-after, use it here backoff_sleep(attempt) last_error = e raise RuntimeError(f"Batch failed after retries: {last_error}") 무엇이 “클래식” snippets에 비해 변했습니까? 우리는 JSON을 단단한 계약으로 취급합니다. 우리는 포맷 수리를 명시적으로 처리합니다 (그리고 저렴하게 유지). 우리는 백코프 논리를 중앙화하여 모든 호출이 동일한 방식으로 행동합니다. 7) 배치 크기를 선택하는 방법 (모두가 어려운 방법을 배우는 규칙) 배치 크기는 : Batch size is restricted by: 컨텍스트 윈도우 (max tokens per request) TPM 통과 Response Parsing 안정성 "one batch failed"에 대한 귀하의 비즈니스 관용 실용적인 heuristic : 배치 당 10-20 항목으로 시작 토큰 사용법 increase until you see: output format drift, or timeouts / latency spikes, or context overflow risk 그리고 항상 A . max batch token budget 8) Fantasy Numbers 없이 ‘Cost Math’ 가격이 바뀌고 모델이 바뀌고 그래서 원래 1K 토큰 값을 단단히 인코딩하는 대신, 제공자의 현재 가격 페이지를 사용하여 비용을 계산하십시오. OpenAI는 API 가격 페이지에 토큰당 가격을 게시합니다.Anthropic은 또한 가격 및 문서 가격 제한 수준을 게시합니다. 유용한 비용 계산기 : cost ≈ (input_tokens * input_price + output_tokens * output_price) / 1,000,000 다음은 당신이 제어하는 변수를 최적화합니다: Shrink Input 토큰 제한된 출력 토큰 통화 수를 줄이기 (batch) 9) 배치의 위험 (그리고 태워지지 않는 방법) 위험 1: 하나의 나쁜 항목이 배치를 망친다. “INSUFFICIENT_DATA” fallback per task. Fix: 위험 2: 출력 형식 드라이브 파싱 엄격한 JSON, 수리 단계 및 로깅. Fix: 위험 3: 배치 너무 큰 → 컨텍스트 오버플로우 토큰 예산 + 자동 분할. Fix: 위험 4: 금액을 우회하려는 ‘창의적인’ 시도 더 많은 용량이 필요하면 더 높은 제한을 요청하고 공급자의 조건을 따르십시오. Fix: 최종 Take 가격 제한은 적이 아닙니다.그들은 당신의 초기 경고 시스템입니다 : 빠른 시간은 너무 길고, 교통이 너무 부드럽고, 또는 귀하의 아키텍처는 "무한한 통과량"을 가정합니다. payloads (프로즈가 아닙니다)와 같은 인스턴트를 처리하면, pacing을 추가하고, 어른처럼 배치를 추가하면, 당신은 얻을 것입니다 : 429 미만 낮은 비용 그리고 드라마 없이 규모를 차지하는 시스템 그것이 전체 게임이다.