Penyedia Cadangan dan Pemutus Sirkuit
Bangun rangkaian penyedia yang secara otomatis berpindah dari OpenAI ke Anthropic lalu ke model lokal ketika penyedia utama lambat atau tidak tersedia, menggunakan pola pemutus sirkuit.
Penyedia Cadangan dan Pemutus Sirkuit adalah pelajaran AI Engineering Academy gratis di CoddyKit. Ini adalah pelajaran 3 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar AI Engineering Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus AI Engineering Academy mencakup 4 pelajaran total.
Risiko Satu Penyedia
Mengandalkan satu penyedia LLM menciptakan satu titik kegagalan. OpenAI pernah mengalami gangguan yang memerlukan waktu beberapa menit hingga beberapa jam untuk diselesaikan. Jika seluruh aplikasi Anda bergantung pada ketersediaan GPT-4o, setiap insiden penyedia akan segera menyebabkan waktu henti yang dirasakan pengguna. Strategi penyedia cadangan mempertahankan kesinambungan layanan dengan merutekan permintaan ke penyedia alternatif saat penyedia utama gagal.
Mendefinisikan Rangkaian Penyedia
Rangkaian penyedia adalah daftar penyedia dan model yang dicoba secara berurutan. Saat penyedia utama gagal atau mengalami batas waktu, sistem otomatis mencoba penyedia berikutnya. Rangkaian yang umum mungkin berupa: OpenAI GPT-4o → Anthropic Claude 3.5 Sonnet → model Llama yang diterapkan secara lokal. Setiap tingkat merupakan cadangan, dengan model lokal sebagai pilihan terakhir yang tidak boleh berhenti beroperasi.
from dataclasses import dataclass
from typing import Optional
@dataclass
class Provider:
name: str
base_url: Optional[str]
api_key_env: str
model: str
priority: int # lower = higher priority
CASCADE = [
Provider('openai', None, 'OPENAI_API_KEY', 'gpt-4o', 1),
Provider('anthropic', 'https://api.anthropic.com/v1', 'ANTHROPIC_API_KEY', 'claude-3-5-sonnet', 2),
Provider('local', 'http://localhost:8000/v1', 'LOCAL_KEY', 'llama-3.1-8b-inst', 3),
]Menerapkan Perulangan Cadangan
Terapkan perulangan cadangan sebagai try/except sederhana yang mengiterasi rangkaian. Tangkap kesalahan sementara (batas waktu, 500, 503) dan lanjutkan ke penyedia berikutnya. Jangan tangkap kesalahan autentikasi (401) atau kesalahan permintaan tidak valid (400)—ini adalah kesalahan pemrograman yang harus segera ditampilkan, bukan dialihkan ke penyedia lain.
import openai
import os
TRANSIENT_ERRORS = (openai.APITimeoutError, openai.InternalServerError, openai.APIConnectionError)
async def call_with_fallback(messages: list, **kwargs) -> str:
for provider in CASCADE:
try:
client = openai.AsyncOpenAI(
api_key=os.environ[provider.api_key_env],
base_url=provider.base_url
)
resp = await client.chat.completions.create(
model=provider.model,
messages=messages,
timeout=10.0,
**kwargs
)
return resp.choices[0].message.content
except TRANSIENT_ERRORS as e:
print(f'Provider {provider.name} failed: {e}, trying next...')
raise RuntimeError('All providers failed')Apa Itu Pemutus Sirkuit?
Pemutus sirkuit mencegah layanan yang gagal dibebani permintaan selama gangguan. Namanya diambil dari pemutus sirkuit listrik dan memiliki tiga status: Closed (permintaan diteruskan secara normal), Open (permintaan langsung ditolak), dan Half-Open (satu permintaan pengujian diizinkan untuk memeriksa apakah layanan telah pulih). Ini melindungi layanan hilir dan aplikasi Anda sendiri selama insiden.
# Circuit breaker state machine:
#
# CLOSED --> (failure_count >= threshold) --> OPEN
# ^ |
# | (test_request succeeds) | (timeout expires)
# +------------ HALF_OPEN <-----------------+
#
# In OPEN state: immediately return fallback/error
# In HALF_OPEN: allow one request through to test recovery
# In CLOSED: normal operation, count failuresMenerapkan Pemutus Sirkuit
Berikut adalah penerapan pemutus sirkuit minimal. Lacak jumlah kegagalan dan waktu saat sirkuit dibuka. Saat jumlah kegagalan melebihi ambang batas, buka sirkuit. Setelah batas waktu pengaturan ulang yang dapat dikonfigurasi, izinkan satu permintaan pemeriksaan. Jika pemeriksaan berhasil, tutup sirkuit. Jika gagal, biarkan sirkuit terbuka dan atur ulang batas waktunya.
import time
from enum import Enum
class State(Enum):
CLOSED = 'closed'
OPEN = 'open'
HALF_OPEN = 'half_open'
class CircuitBreaker:
def __init__(self, failure_threshold=5, reset_timeout=60):
self.state = State.CLOSED
self.failure_count = 0
self.failure_threshold = failure_threshold
self.reset_timeout = reset_timeout
self.opened_at = None
def record_success(self):
self.failure_count = 0
self.state = State.CLOSED
def record_failure(self):
self.failure_count += 1
if self.failure_count >= self.failure_threshold:
self.state = State.OPEN
self.opened_at = time.time()
def can_attempt(self) -> bool:
if self.state == State.CLOSED:
return True
if self.state == State.OPEN:
if time.time() - self.opened_at > self.reset_timeout:
self.state = State.HALF_OPEN
return True # allow one probe
return False
return True # HALF_OPEN: allow probeMengintegrasikan Pemutus Sirkuit dengan Penyedia
Pertahankan satu pemutus sirkuit untuk setiap penyedia. Sebelum memanggil penyedia, periksa apakah pemutus sirkuitnya mengizinkan percobaan. Setelah setiap panggilan, catat keberhasilan atau kegagalan. Saat sirkuit penyedia terbuka, perulangan cadangan secara alami melewatinya dan mencoba penyedia berikutnya dalam rangkaian, tanpa menunggu batas waktu pada setiap panggilan.
breakers = {p.name: CircuitBreaker(failure_threshold=5, reset_timeout=60) for p in CASCADE}
async def call_with_circuit_breaker(messages: list) -> str:
for provider in CASCADE:
breaker = breakers[provider.name]
if not breaker.can_attempt():
continue # skip this provider, circuit is open
try:
result = await call_provider(provider, messages)
breaker.record_success()
return result
except TRANSIENT_ERRORS as e:
breaker.record_failure()
print(f'{provider.name} failed ({breaker.failure_count}/{breaker.failure_threshold})')
raise RuntimeError('All providers exhausted')Mendeteksi Panggilan Lambat sebagai Kegagalan
Penyedia yang merespons dalam 30 detik hampir sama buruknya dengan penyedia yang benar-benar tidak aktif, jika dilihat dari pengalaman pengguna. Konfigurasikan batas waktu yang agresif untuk setiap panggilan penyedia dan perlakukan pengecualian batas waktu sebagai kegagalan dalam pemutus sirkuit. Batas waktu 10 detik berarti cadangan aktif cukup cepat sehingga pengguna hanya melihat sedikit jeda, bukan layar yang macet.
async def call_provider(provider: Provider, messages: list) -> str:
client = openai.AsyncOpenAI(
api_key=os.environ[provider.api_key_env],
base_url=provider.base_url
)
try:
resp = await asyncio.wait_for(
client.chat.completions.create(model=provider.model, messages=messages),
timeout=10.0 # fail fast, let circuit breaker count it
)
return resp.choices[0].message.content
except asyncio.TimeoutError:
raise openai.APITimeoutError('Provider timed out')Dasbor Kesehatan Penyedia
Sediakan endpoint /health/providers yang menampilkan status pemutus sirkuit saat ini untuk setiap penyedia, termasuk jumlah kegagalan, status (closed/open/half-open), dan waktu hingga pengaturan ulang. Dengan demikian, Anda dapat segera melihat penyedia mana yang sehat selama insiden dan menentukan apakah perlu memaksa pengaturan ulang secara manual atau menunggu pemulihan otomatis.
from fastapi import FastAPI
app = FastAPI()
@app.get('/health/providers')
def provider_health():
return {
name: {
'state': cb.state.value,
'failure_count': cb.failure_count,
'seconds_until_reset': (
max(0, cb.reset_timeout - (time.time() - cb.opened_at))
if cb.state == State.OPEN else None
)
}
for name, cb in breakers.items()
}Menyelaraskan Keluaran Penyedia
Penyedia yang berbeda memiliki format respons, filter keamanan, dan kemampuan yang berbeda. Saat beralih dari GPT-4o ke Claude, model tersebut mungkin menolak permintaan tertentu yang akan dijawab oleh GPT-4o. Pertahankan pembungkus perintah khusus penyedia yang menyesuaikan perintah Anda dengan konvensi setiap penyedia. Uji setiap penyedia cadangan secara terpisah untuk memastikan keluarannya dapat diterima untuk kasus penggunaan Anda.
def adapt_messages_for_provider(provider: Provider, messages: list) -> list:
if provider.name == 'anthropic':
# Claude prefers explicit task descriptions
system = next((m['content'] for m in messages if m['role'] == 'system'), '')
if 'JSON' not in system:
messages = [{'role': 'system', 'content': system + ' Respond in JSON.'}] + [
m for m in messages if m['role'] != 'system'
]
return messagesMenguji Perilaku Cadangan
Tulis pengujian yang memaksa penyedia utama gagal (dengan memberikan kunci API yang salah atau mock yang memunculkan kesalahan) dan memverifikasi bahwa cadangan aktif serta mengembalikan respons yang valid. Uji juga bahwa pemutus sirkuit terbuka dengan benar setelah jumlah kegagalan yang dikonfigurasi dan pulih setelah batas waktu pengaturan ulang. Logika cadangan yang tidak pernah diuji tidak dapat diandalkan saat terjadi gangguan nyata.
import pytest
from unittest.mock import AsyncMock, patch
@pytest.mark.asyncio
async def test_fallback_on_primary_timeout():
# Primary provider times out
with patch('your_module.call_provider', side_effect=[
openai.APITimeoutError('Timeout'), # primary fails
'Claude response' # fallback succeeds
]):
result = await call_with_circuit_breaker([{'role': 'user', 'content': 'Hello'}])
assert result == 'Claude response'Pertimbangan Biaya Rangkaian Penyedia
Penyedia cadangan sering kali memiliki harga yang berbeda dari penyedia utama Anda. Anthropic Claude dapat berbiaya lebih mahal atau lebih murah daripada OpenAI GPT-4o, bergantung pada tingkat modelnya. Catat penyedia mana yang menangani setiap permintaan dan hitung atribusi biaya secara terpisah. Jika penyedia cadangan secara konsisten lebih mahal, selidiki apakah penyedia utama kekurangan kapasitas dan apakah peningkatan ke tingkat batas laju yang lebih tinggi akan lebih hemat biaya daripada sering menggunakan penyedia cadangan.
# Approximate costs per 1M tokens (2026):
PROVIDER_COSTS = {
'openai/gpt-4o': {'input': 2.50, 'output': 10.00},
'anthropic/claude-3.5-sonnet': {'input': 3.00, 'output': 15.00},
'openai/gpt-4o-mini': {'input': 0.15, 'output': 0.60},
'local/llama-3.1-8b': {'input': 0.00, 'output': 0.00}, # infra cost only
}
# If fallback adds $0.50/day and a Tier 2 upgrade costs $100/month:
# Tier 2 pays off if you use fallback > 200 requests/dayPemeriksaan Singkat
Uji pemahaman Anda tentang pemutus sirkuit dan penyedia cadangan.
Rangkuman Pelajaran
Dalam pelajaran ini, Anda mempelajari bahwa rangkaian penyedia menentukan urutan cadangan dari penyedia LLM utama hingga penyedia cadangan, pemutus sirkuit mencegah permintaan berlebihan kepada penyedia yang gagal dengan segera memutus aliran setelah jumlah kegagalan tertentu tercapai, dan batas waktu per penyedia memastikan panggilan yang lambat segera memicu penggunaan cadangan, bukan membuat pengguna menunggu. Selanjutnya, kita akan menetapkan anggaran batas waktu dan menerapkan penurunan kualitas secara anggun.
Belajar Python dengan tutor AI — gratis
Tulis dan jalankan kode asli di browser kamu, dapatkan bantuan instan dari tutor AI 24/7, dan lanjutkan di mana kamu tinggalkan di web atau aplikasi.
- Kursus
- 30
- Pelajaran
- 120
Pertanyaan yang Sering Diajukan
Apakah pelajaran “Penyedia Cadangan dan Pemutus Sirkuit” gratis?
Ya — teks lengkap “Penyedia Cadangan dan Pemutus Sirkuit” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus AI Engineering Academy, upgrade ke CoddyKit PRO. Kursus AI Engineering Academy mencakup 4 pelajaran total.
Apa yang akan aku pelajari di “Penyedia Cadangan dan Pemutus Sirkuit”?
Bangun rangkaian penyedia yang secara otomatis berpindah dari OpenAI ke Anthropic lalu ke model lokal ketika penyedia utama lambat atau tidak tersedia, menggunakan pola pemutus sirkuit. Kamu berlatih AI Engineering Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.
Apakah aku perlu pengalaman untuk memulai AI Engineering Academy?
Tidak diperlukan pengalaman sebelumnya. AI Engineering Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 3 dari 4.
Berapa lama pelajaran “Penyedia Cadangan dan Pemutus Sirkuit” memakan waktu?
Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.
Bisakah aku menulis dan menjalankan kode dalam pelajaran AI Engineering Academy ini?
Ya. Setiap pelajaran AI Engineering Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.
Semua pelajaran dalam kursus ini
- Mengukur Latensi LLM: TTFT dan TPOT
- Penyeimbangan Beban dan Strategi Banyak Kunci
- Penyedia Cadangan dan Pemutus Sirkuit
- Anggaran Batas Waktu dan Penurunan Layanan yang Terkendali