AI proxy ve LLM gateway: fark nedir?

16 dk

Ağ iletmeyi, bir API gateway'i ve model yönlendirmesini ayırın ki işe uyan katmanı seçin.

İnsanlar «AI proxy»yi üç farklı kutu için söyler: bir ağ ileticisi, bir ters API gateway ve bir model yönlendirici. Bu rehber, işlerini karıştırmadan bir katman seçmesi gereken geliştiriciler içindir. IP satmaz, anahtar dağıtmaz ve bir proxy'nin hesap veya coğrafya uygunluğunu değiştirdiğini iddia etmez.

01İnsanlar «AI proxy» deyince genelde ne kasteder

İfade bir standart değildir. RFC 9110 (HTTP Semantics, Haziran 2022, STD 97) aracıları zaten proxy, gateway ve tünel diye ayırır ve bir sürecin istek başına rol değiştirebileceğini uyarır. Ürün metninde aynı söz bir kez daha başka bir şey için kullanılır: OpenAI tarzı bir JSON gövdesi kabul edip model seçen bir süreç.

Bu üç iş diyagramda benzer durur çünkü her biri istemciniz ile yukarıdaki bir şey arasında oturur. Farklı yerlerde başarısız olurlar. Bir ileri proxy TCP tüneli açıp sizi yine sağlayıcı 401'iyle bırakabilir. Bir LLM gateway, ağ yolu sağlamken bilinmeyen model hakkında JSON hatalı HTTP 200 döndürebilir. Yanlış katmanı ayıklarsanız yanlış sırrı döndürürsünüz.

2026-10-15'teki sınırlı yerel bir çalıştırma o ayrımı somutlaştırdı. Bir loopback HTTP CONNECT proxy TLS'i bir düzenek origin'ine iletti. Ayrı bir loopback süreci yerel bir Bearer kontrolünden sonra fixture-alpha ile fixture-bravo'yu yönlendirdi. Hiçbir şey 127.0.0.1'i terk etmedi. Hiçbir şey ücretli bir model API'sini aramadı. Düzenek JSON'u kasten CONTROLLED_FIXTURE_NOT_A_PROVIDER diye etiketlenir.

Bir satıcı ürüne «AI proxy» diyorsa gerçekte o işlerden hangisini uyguladığını okuyun. Ana sayfada gateway sözcüğü geçti diye yeniden deneme, akış veya yedek olduğunu varsaymayın.

02CONNECT dahil HTTP ve SOCKS ileri proxyler

İleri proxy'yi istemci seçer. RFC 9110 §3.7 onu, bazı mutlak URI'ler için istek alan ve onları HTTP üzerinden karşılamaya çalışan bir ileti-iletme aracısı diye adlandırır. Sıradan http URL'lerde istemci tam URL'yi proxy'ye gönderir. https için olağan kalıp farklıdır.

RFC 9110 §9.3.6 CONNECT'i tanımlar: istemci proxy'den host:port'a bir tünel kurmasını ister ve herhangi bir 2xx'ten sonra tünel kapanana kadar kendini kör iletmeyle sınırlamasını bekler. Tüneller bundan sonra sık TLS'e sarılır. Başarılı bir CONNECT uygulama başarısı değildir. Yalnızca tünelin var olduğu anlamına gelir. Başka herhangi bir yanıt tünelin kurulmadığı demektir.

SOCKS5 daha eskidir ve daha aşağıda oturur. RFC 1928 (Mart 1996) onu uygulama ile taşıma arasında bir ara katman diye anlatır; geleneksel olarak TCP 1080. Yöntem müzakeresinden sonra istemci bir komut gönderir; CONNECT X'01''dir. SOCKS HTTP yöntemlerini ayrıştırmaz. İstemcinin adlandırdığı bir hedefe TCP (ve isteğe bağlı UDP) iletir.

HTTP kütüphaneniz HTTPS'i proxy üzerinden konuşuyorsa genelde CONNECT yapar, sonra origin'e TLS. Proxy tüneli kimlik doğrular, sık Proxy-Authorization ile. O başlık, model API'sinin beklediği Authorization: Bearer başlığı değildir. Karıştırmak, «curl'de proxy çalışıyor ama SDK hâlâ 401»nin olağan kaynağıdır.

İş yalnızca «bu süreç başka bir IP üzerinden çıksın» ise İngilizce HTTP proxy, HTTPS proxy ve SOCKS5 proxy listelerinden başlayın. O sayfalar çıkışları karşılaştırır. Model yönlendirici değildir.

03Ters proxyler ve sıradan API gateway'ler

RFC 9110'un §3.7'de gateway diye de adlandırdığı ters proxy, istemciye origin gibi görünür ve gelenleri başka bir sunucuya iletir. İstemci onu bir proxy URL'si diye seçmedi. İstemci yalnızca https://api.example.com açtı.

NGINX ters-proxy rehberi (erişim 2026-10-15) mekanik döngüyü anlatır: isteği bir proxy_pass upstream'ine gönder, yanıtı çek, geri gönder. Varsayılan olarak NGINX Host ve Connection'ı yeniden yazar. Host'tan sanal ana bilgisayar anahtarlayan API'ler için bu ayrıntı önemlidir. Bir ters proxy genel kenarda TLS'i sonlandırıp içeride yeni bir bağlantı açabilir. İstemcinin TLS oturumu o zaman model satıcısında değil, ters proxy'de biter.

Bu katman yol yönlendirme (/v1/'e karşı /admin/), yük dengeleme, başlık temizleme ve birkaç iç hizmetin önünde tek ana bilgisayar adı gösterme için doğru araçtır. Bir model adının ne olduğunu bilmeyebilir. Yalnızca /v1/chat/completions'ı tek bir upstream'e iletiyorsa HTTP anlamında hâlâ bir API gateway'dir, LLM gateway değildir.

«Önüne NGINX koyduk»u yeniden deneme, jeton bütçesi veya model yedeği kanıtı saymayın. Bunlar kimi ürünlerin eklediği ekstra özelliklerdir. Okuduğumuz NGINX sayfası onları iddia etmez.

04LLM gateway'ler: anahtarlar, limitler, yönlendirme ve günlükler

Bir LLM gateway uygulama hizmetidir. İstemciler sohbet veya embeddings gövdesini tek bir URL'ye gönderir. Gateway sanal bir anahtarı kontrol eder, bütçe uygulayabilir, bir sağlayıcı ve model seçebilir, jetonları günlüğe yazabilir ve ancak o zaman bir satıcıyla — veya birkaç satıcıyla — konuşur.

LiteLLM'in AI Gateway sayfası (2026-10-15'te HTTP 200) tek bir OpenAI-uyumlu uç sunan kendi barındırılan bir sunucu anlatır. Belgelenen işler arasında anahtar başına modeller ve hız limitleriyle sanal anahtarlar, harcama takibi, yük dengeleme, yedekler, yeniden denemeler, guardrail'ler ve günlükleme vardır. Aynı sayfa der: bir istemci OpenAI API'sini kullanabiliyorsa istemci kodunu değiştirmeden gateway'i kullanabilir. Bu, chat completions istek şekli hakkında bir ürün iddiasıdır. Her OpenAI ucunun, başlığının ve hatasının 1:1 eşlendiğinin kanıtı değildir. LiteLLM kurmadık, çalıştırmadık.

Cloudflare AI Gateway (sayfa dateModified 2026-04-20, alındı 2026-10-15) analitik, günlükleme, önbellek, hız sınırlama, istek yeniden denemeleri ve model yedeğini özellik diye listeler. dynamic-routing sayfası (güncelleme 2026-10-02) uyumluluk konusunda daha kesindir: dinamik yollar yalnızca OpenAI chat completions istek şeklini kabul eder; Anthropic Messages HTTP 400 döndürür. «OpenAI-uyumlu»nun dar kalmasının nedeni o cümledir. Cloudflare'i aramadık, yeniden deneme veya yedek çalıştırmadık. Bir gateway belgesi o özellikleri listeliyorsa, onları o ürüne karşı çalıştırana kadar yalnızca kaynak sayın.

Yerelde o ürünler olmayan küçük bir yönlendirici kurduk. Authorization: Bearer local-demo-key-not-a-provider-secret kabul etti, fixture-alpha ve fixture-bravo'yu iki düzenek yüküne eşledi, geçerli yerel jeton olmadan 401, bilinmeyen model için 400 döndürdü. Kontrol düzleminin CONNECT'te değil HTTP JSON'da oturduğunu göstermek yeter.

05Bir isteği izleyin: TLS, Host ve gövdeyi kim okur

Tek bir POST /v1/chat/completions'ı iki tasarımda yürütün.

Loopback çalıştırmadaki ileri yol: istemci 127.0.0.1:54318'e TCP açtı, CONNECT 127.0.0.1:54316 HTTP/1.1 gönderdi, 200 Connection Established aldı, sonra origin sertifikasına TLS'i bitirdi. Ancak TLS'ten sonra JSON gövdesini ve origin için Bearer başlığını gönderdi. CONNECT süreci hedef 127.0.0.1:54316'yı kaydetti. Düzenek JSON'unu veya Bearer jetonunu görmedi: tünelde gözlenen HTTP gövde parçalarının jeton listesi boştu. TLS düzenek origin'inde bitti. Origin kontrollü düzenekle HTTP 200 yanıtladı.

Gateway yolu: istemci CONNECT olmadan 127.0.0.1:54317'ye TCP açtı. O hop'ta demoda TLS yoktu (loopback'te düz HTTP). Gateway JSON model alanını ve yerel Bearer jetonunu, o istek için herhangi bir origin var olmadan önce okudu. Eksik veya yanlış yerel kimlik, başarılı bir yol olarak bir model düzeneğine hiç ulaşmadı; ikisi de invalid_local_gateway_auth ile HTTP 401 üretti. Bilinmeyen bir model, kimlik başarılı olduktan sonra unsupported_model_or_route ile HTTP 400 üretti. Taşıma ayaktaydı. Uygulama işi reddetti.

Üretim HTTPS'te bir LLM gateway neredeyse her zaman TLS'i sonlandırır. JSON ayrıştıracak, bütçe uygulayacak veya model seçecekse zorundadır. TLS orta kutusu olmayan bir CONNECT ileri proxy o origin TLS'ini sonlandırmaz. Birisi kurumsal proxy'de HTTPS incelemeyi açarsa bu başka bir dağıtımdır: proxy origin'e TLS istemcisi, size TLS sunucusu olur. CONNECT başarılı diye inceleme varsaymayın.

OpenAI'nin API genel bakışı (alındı 2026-10-15; istenen platform.openai.com/docs/api-reference buraya yönlendirdi) origin istekte Bearer kimlik bilgilerini belgeler. x-request-id'yi, x-ratelimit-limit-requests gibi hız-limit başlıklarından ayrı bir istek korelasyon tanımlayıcısı sayar. O alanlar sağlayıcı konuşmasına aittir. Bir gateway kendi istek kimliklerini ekleyebilir. Bir ileri proxy genelde eklemez.

06Uyumluluk bir istemci şeklidir, tüm API değil

SDK'ler sık base_url koyup chat.completions.create kullanmaya devam etmenize izin verir. Satıcılar buna OpenAI-uyumlu der. Cloudflare'in dynamic-routing notu uyarıdır: tek bir satıcının içinde bile bir uyumluluk yolu yalnızca bir istek şeklini kabul edip diğerine 400 verebilir.

Uyumlu bir uç kimlik doğrulamada (sanal anahtar ve sağlayıcı anahtarı), model adlarında (gpt-4.1 ve azure/gpt-4.1 ve bir gateway takma adı), akış olay düzenlerinde, tool-call alanlarında, dosya yüklemelerinde, realtime soketlerde ve yönetim API'lerinde yine farklı olabilir. OpenAI'nin kendi genel bakışı Responses, Realtime ve Administration'ı ayrı yüzeyler sayar. /v1/chat/completions'ı kopyalamak o ağacın tamamını kopyalamaz.

Loopback gateway, sohbet tamamlanması gibi duran JSON döndürdü (choices[0].message). O bir düzenekti. Demoyu herhangi bir ürün anlamında «OpenAI uyumlu» yapmaz.

07«Çalıştı»nın üç ayrı türü

Günlük okurken bu üç sonucu ayrı tutun.

KatmanÖrnek başarıÖrnek başarısızlıkKanıtlamadığı şey
Taşıma / tünelCONNECT 200 Connection Established; SOCKS CONNECT yanıtıProxy 403, zaman aşımı, TLS el sıkışması hatasıModelin istemi veya anahtarı kabul ettiği
Sonraki hop'a HTTPJSON gövdeli 200 hatta 401/400Boş yanıt, RST, ters proxy'den HTTP 502JSON'un bir model sonucu olduğu
Uygulama / model yoluGateway fixture-alpha'yı alpha düzeneğine eşler; sağlayıcı bir tamamlanma döndürürGateway 400 desteklenmeyen model; sağlayıcı 401 geçersiz API anahtarı; HTTP 200 içinde model güvenlik reddiDiğer katmanların sağlıklı olduğu veya ikinci bir satıcının aynı davranacağı

2026-10-15'te yerel betik Python 3.9.6 ve LibreSSL 3.3.6 ile altı durum ve on altı iddia kaydetti, hepsi geçti:

Loopback düzeneğinden İngilizce sonuç tablosu: CONNECT iletme ve gateway model yönlendirmesi.

İletme origin HTTP 200 üretti. Gateway yönlendirmesi iki farklı düzenek yolu üretti. Kimlik başarısızlıkları 401 ile gateway'de kaldı. Desteklenmeyen model 400 ile gateway'de kaldı. Yeniden denemeler, akış ve yedekler çalıştırılmadı ve iddia edilmez.

IP adresim sayfası tarayıcınızdan o sayfaya ulaşan adresi bildirir. Proxy kontrolü sizin verdiğiniz bir ucun sunucu tarafı sondasıdır. İkisi de bir Python SDK sürecinin alacağı yolu göstermez ve LLM API uygunluğu kurmaz. Kontrol bir model satıcısının bir IP'yi kabul edeceğini, bir anahtarın geçerli olduğunu veya belirli bir hesabı kullanmanıza izin verildiğini kanıtlamaz.

08İşe uyan katmanı seçin

Sorun TCP oturumunun nereden çıktığıysa — kurumsal bir çıkış, satıcıya ulaşamayan bir geliştirme dizüstü veya yayımlanmış bir datacenter ya da mobil çıkış — ileri HTTP CONNECT veya SOCKS5 proxy kullanın. SDK'nin proxy ayarlarını (veya HTTPS_PROXY) yapılandırın ve sağlayıcı API anahtarını origin'in göreceği istekte tutun. Proxy'nin model seçeceğini beklemeyin.

Sorun tek ana bilgisayar adı, birçok iç hizmet, kenarda TLS veya başlık politikasıysa ters proxy veya genel API gateway kullanın. DNS'i o gateway'e bakın. Jeton harcamasını siz eklemediyseniz bilmesini beklemeyin.

Sorun çok istemci, çok model, tek politika ise LLM gateway kullanın. Sanal anahtar verin, bütçe koyun, politikanız izin veriyorsa istemleri günlüğe yazın ve takma adları sağlayıcı modellerine eşleyin. Sağlayıcı anahtarlarını her dizüstünde değil, gateway ana bilgisayarında tutun. Satıcının güncel uyumluluk notlarını okuyun; yeniden deneme veya yedek varsaymayın. Yalnızca bir Python süreciniz ve paylaşılan politikanız yoksa gateway fazla hareketli parça olabilir — LiteLLM'in kendi belgeleri «gateway ve SDK»yı o eksende ayırır.

Satın almadan veya kurmadan önce kontrol listesi:

  1. Gerçekten gördüğünüz başarısızlığı yazın: TCP, TLS, HTTP durumu veya JSON hatası.
  2. TLS'i kimin sonlandırdığını adlandırın.
  3. Hangi sırrın tünel, hangisinin gateway, hangisinin sağlayıcı için olduğunu adlandırın.
  4. İstemcinin gönderdiği model dizgesini ve sağlayıcının beklediğini adlandırın.
  5. Akış, yeniden deneme ve yedeğin o üründe belgelenip belgelenmediğini ve test edilip edilmediğini doğrulayın. Çalıştırmadıysanız iddia etmeyin.
  6. İstemci istek şeklini doğrulayın (chat completions'a karşı başka bir şema).
  7. Yalnızca farklı bir çıkış IP'si gerektiyseniz ileri proxy'de durun ve model yönlendiriciyi atlayın.

Yukarıdaki numaralı tablo ve WebP şekil, aynı gün ayrı bir CONNECT+TLS loopback laboratuvarından gelir. O laboratuvar gerçek istemci-seçimli iletmedir: HTTP CONNECT, sonra origin'e TLS. Aşağıdaki kopyala-yapıştır tarifi değildir.

Bu kamuya açık tarif yalnızca 127.0.0.1'de düz HTTP'dir. CONNECT tüneli açmaz, TLS kullanmaz, model satıcısı aramaz. Forward hop'u her zaman sabit bir origin_port'a POST atar ve istemci origin-form yol kullanır (/v1/chat/completions). RFC 9110 anlamında bu ters-tarz, sabit-upstream geçiştir, istemci-seçimli HTTP ileri proxy değildir. O hop'u aynı betikteki uygulama model yönlendiricisiyle karşılaştırın. Beklenen çıktıdaki forward_http'yi istemcinin seçtiği ileri proxy kanıtı diye okumayın.

Kurulum: Python 3.9 veya daha yenisi. Yalnızca standart kütüphane. Paket yok. API anahtarı yok.

  1. Aşağıdaki betiği sahip olduğunuz herhangi bir dizine forwarding_vs_routing.py olarak kaydedin.
  2. Çalıştırın: python3 forwarding_vs_routing.py
  3. stdout'unuz betikten sonraki beklenen çıktıyla uyuşmalıdır.
#!/usr/bin/env python3
"""Plain-HTTP loopback demo: forwarding vs model routing. Stdlib only."""
from __future__ import annotations

import json
import threading
from http.client import HTTPConnection
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer

BIND = "127.0.0.1"
KEY = "***"
LABEL = "CONTROLLED_FIXTURE_NOT_A_PROVIDER"
TIMEOUT = 5


class Origin(BaseHTTPRequestHandler):
    protocol_version = "HTTP/1.1"

    def log_message(self, *_args):
        return

    def do_POST(self):
        n = int(self.headers.get("Content-Length") or 0)
        self.rfile.read(n)
        body = json.dumps(
            {
                "label": LABEL,
                "origin": "loopback-http-origin",
                "choices": [
                    {
                        "index": 0,
                        "message": {
                            "role": "assistant",
                            "content": "FIXTURE: forwarded origin",
                        },
                    }
                ],
            }
        ).encode()
        self.send_response(200)
        self.send_header("Content-Type", "application/json")
        self.send_header("Content-Length", str(len(body)))
        self.send_header("Connection", "close")
        self.end_headers()
        self.wfile.write(body)


class Gateway(BaseHTTPRequestHandler):
    protocol_version = "HTTP/1.1"
    ROUTES = {
        "fixture-alpha": {"label": LABEL, "route": "alpha"},
        "fixture-bravo": {"label": LABEL, "route": "bravo"},
    }

    def log_message(self, *_args):
        return

    def _send(self, code, obj):
        raw = json.dumps(obj).encode()
        self.send_response(code)
        self.send_header("Content-Type", "application/json")
        self.send_header("Content-Length", str(len(raw)))
        self.send_header("Connection", "close")
        self.end_headers()
        self.wfile.write(raw)

    def do_POST(self):
        n = int(self.headers.get("Content-Length") or 0)
        raw = self.rfile.read(n)
        auth = self.headers.get("Authorization") or ""
        try:
            model = json.loads(raw.decode() or "{}").get("model")
        except json.JSONDecodeError:
            model = None
        if auth != "Bearer " + KEY:
            self._send(401, {"error": "invalid_local_gateway_auth", "label": LABEL})
            return
        route = self.ROUTES.get(model)
        if route is None:
            self._send(
                400,
                {
                    "error": "unsupported_model_or_route",
                    "requested": model,
                    "label": LABEL,
                },
            )
            return
        self._send(200, route)


class Forward(BaseHTTPRequestHandler):
    protocol_version = "HTTP/1.1"
    origin_port = 0

    def log_message(self, *_args):
        return

    def do_POST(self):
        n = int(self.headers.get("Content-Length") or 0)
        body = self.rfile.read(n)
        upstream = HTTPConnection(BIND, self.origin_port, timeout=TIMEOUT)
        try:
            skip = {"host", "proxy-connection"}
            headers = {k: v for k, v in self.headers.items() if k.lower() not in skip}
            upstream.request("POST", self.path, body=body, headers=headers)
            resp = upstream.getresponse()
            data = resp.read()
            status = resp.status
            ctype = resp.getheader("Content-Type") or "application/json"
        finally:
            upstream.close()
        self.send_response(status)
        self.send_header("Content-Type", ctype)
        self.send_header("Content-Length", str(len(data)))
        self.send_header("Connection", "close")
        self.end_headers()
        self.wfile.write(data)


def start(handler):
    httpd = ThreadingHTTPServer((BIND, 0), handler)
    httpd.daemon_threads = False
    httpd.timeout = 0.3
    thread = threading.Thread(
        target=httpd.serve_forever,
        name="srv-%s" % httpd.server_address[1],
        daemon=False,
    )
    thread.start()
    return httpd, thread


def post(port, path, payload, headers):
    conn = HTTPConnection(BIND, port, timeout=TIMEOUT)
    try:
        raw = json.dumps(payload).encode()
        hdrs = {"Content-Type": "application/json"}
        hdrs.update(headers)
        conn.request("POST", path, body=raw, headers=hdrs)
        resp = conn.getresponse()
        return resp.status, json.loads(resp.read().decode())
    finally:
        conn.close()


def main():
    origin_httpd = gw_httpd = fwd_httpd = None
    threads = []
    try:
        origin_httpd, origin_thread = start(Origin)
        threads.append(origin_thread)
        Forward.origin_port = origin_httpd.server_address[1]
        fwd_httpd, fwd_thread = start(Forward)
        threads.append(fwd_thread)
        gw_httpd, gw_thread = start(Gateway)
        threads.append(gw_thread)

        ping = {
            "model": "ignored-by-forward",
            "messages": [{"role": "user", "content": "ping"}],
        }
        rows = []
        status, body = post(
            fwd_httpd.server_address[1],
            "/v1/chat/completions",
            ping,
            {"Authorization": "***"},
        )
        rows.append(("forward_http", status, body.get("origin") or body.get("error")))
        assert status == 200
        assert body.get("label") == LABEL
        assert body.get("origin") == "loopback-http-origin"

        gw = gw_httpd.server_address[1]
        status, body = post(
            gw,
            "/v1/chat/completions",
            {"model": "fixture-alpha", "messages": []},
            {"Authorization": "Bearer " + KEY},
        )
        rows.append(("gateway_route_alpha", status, body.get("route") or body.get("error")))
        assert status == 200 and body.get("route") == "alpha"

        status, body = post(
            gw,
            "/v1/chat/completions",
            {"model": "fixture-bravo", "messages": []},
            {"Authorization": "Bearer " + KEY},
        )
        rows.append(("gateway_route_bravo", status, body.get("route") or body.get("error")))
        assert status == 200 and body.get("route") == "bravo"

        status, body = post(
            gw,
            "/v1/chat/completions",
            {"model": "fixture-alpha", "messages": []},
            {},
        )
        rows.append(("gateway_auth_missing", status, body.get("error")))
        assert status == 401

        status, body = post(
            gw,
            "/v1/chat/completions",
            {"model": "fixture-alpha", "messages": []},
            {"Authorization": "***"},
        )
        rows.append(("gateway_auth_invalid", status, body.get("error")))
        assert status == 401

        status, body = post(
            gw,
            "/v1/chat/completions",
            {"model": "no-such-model", "messages": []},
            {"Authorization": "Bearer " + KEY},
        )
        rows.append(("gateway_unsupported_model", status, body.get("error")))
        assert status == 400

        print("CONTROLLED_FIXTURE public recipe — not a provider call, not TLS")
        for name, status, extra in rows:
            print("%s HTTP %s %s" % (name, status, extra))
        print("assertions=6 ok")
        return 0
    finally:
        for httpd in (origin_httpd, gw_httpd, fwd_httpd):
            if httpd is not None:
                httpd.shutdown()
                httpd.server_close()
        for thread in threads:
            thread.join(timeout=TIMEOUT)


if __name__ == "__main__":
    raise SystemExit(main())

Beklenen çıktı:

CONTROLLED_FIXTURE public recipe — not a provider call, not TLS
forward_http HTTP 200 loopback-http-origin
gateway_route_alpha HTTP 200 alpha
gateway_route_bravo HTTP 200 bravo
gateway_auth_missing HTTP 401 invalid_local_gateway_auth
gateway_auth_invalid HTTP 401 invalid_local_gateway_auth
gateway_unsupported_model HTTP 400 unsupported_model_or_route
assertions=6 ok

forward_http satırı o sabit-upstream geçiştir. Tablo ve WebP'teki CONNECT+TLS laboratuvarı iletme kanıtı olarak kalır.

Bir ağ proxy'si göndermem gereken model API anahtarını değiştirir mi?

Hayır. CONNECT veya SOCKS5 tünel için Proxy-Authorization veya SOCKS kullanıcı adı/parola alabilir. Model satıcısı origin istekte yine kendi Bearer (veya başka) kimliğini bekler; araya sanal anahtarı saklı bir sağlayıcı anahtarıyla değiştiren bir LLM gateway koymadıysanız.

HTTP CONNECT TLS JSON gövdesini okur mu?

[RFC 9110](https://www.rfc-editor.org/rfc/rfc9110.html#CONNECT) 2xx CONNECT yanıtından sonra proxy'nin kör iletmesi gerektiğini söyler. 2026-10-15 loopback çalıştırmasında CONNECT süreci hedef host:port'u gördü, tünellenen baytlarda düzenek JSON'unu veya Bearer jetonlarını görmedi. Ayrı bir HTTPS-inceleme ürünü o yalnızca-CONNECT davranışı değildir.

Gateway kimliği sağlayıcı kimliğinden neden farklıdır?

Bir gateway sanal anahtarı gateway'de projenizi, bütçenizi ve izinli modellerinizi adlandırır. Bir sağlayıcı anahtarı OpenAI veya başka bir satıcıdaki hesabınızı adlandırır. [OpenAI'nin genel bakışı](https://developers.openai.com/api/reference/overview) (alındı 2026-10-15) API'nin kendisi için Bearer kimlik bilgilerini belgeler. Bir sırrı kaybetmek, diğerini kaybetmekle aynı olay değildir.

«OpenAI-uyumlu» gerçekte ne demektir?

Genelde bir istemcinin chat-completions şekilli bir JSON gövdesini başka bir base URL'ye POST edebilmesi. Her OpenAI yüzeyinin çalıştığı anlamına gelmez. [Cloudflare'in dynamic-routing belgeleri](https://developers.cloudflare.com/ai-gateway/features/dynamic-routing/) (güncelleme 2026-10-02) o özellikte chat-completions dışı biçimlerin 400 verebileceğini bile söyler. Uyumluluğu tam API denkliği değil, belgelenmiş bir alt küme sayın.

SOCKS5, HTTPS model API'leri için HTTP CONNECT'in yerini alabilir mi?

Birçok TLS istemcisi için evet, çünkü SOCKS5 CONNECT ([RFC 1928](https://www.rfc-editor.org/rfc/rfc1928.txt)) bir TCP ileticisidir ve HTTPS TLS-üzerinden-TCP'dir. Kütüphaneniz SOCKS konuşmalıdır. Kimi ortamlar yalnızca HTTP CONNECT gösterir. Protokol desteği bir istemci yeteneğidir, modelin özelliği değil.

Proxy kontrolü bir LLM API'sinin o IP'yi kabul edeceğini kanıtlar mı?

Hayır. İngilizce kontrol, verdiğiniz bir HTTP, HTTPS veya SOCKS5 ucunun sunucu tarafı sondasıdır. Bir Python SDK sürecinin alacağı yolu göstermez, model satıcısına giriş yapmaz, API anahtarlarını doğrulamaz ve hesap uygunluğunu değiştirmez.

Tüm LLM gateway'ler aynı şekilde yeniden dener, yedekler ve akar mı?

Hayır. [LiteLLM](https://docs.litellm.ai/docs/simple_proxy) ve [Cloudflare AI Gateway](https://developers.cloudflare.com/ai-gateway/) 2026-10-15'te alınan sayfalarda o özelliklerden bazılarını, farklı kapsam notlarıyla belgeler. Bu yazının yerel yönlendiricisi yeniden deneme, yedek veya akış uygulamadı, bu yüzden o davranışlar burada iddia edilmez.