# LLM Gateway / Proxy Projesi - Geliştirici İş Emri (Türkçe) Bu doküman, bir geliştiriciye veya yapay zeka asistanına verilip projeyi tamamen uygulattıracak detaylı iş emridir. Hedef: Go + Fiber v3 tabanlı bir servis geliştirmek; OpenAI-compat ve Anthropic-compat proxy/gateway, Bifrost mapping, PostgreSQL (GORM) entegrasyonu, Swagger dokümanları ve Docker destekli dağıtım. --- ## Özet Hedefler - OpenAI-uyumlu istekleri alın, hedef backend: `https://api.deepseek.com`. - Anthropic-uyumlu istekleri alın, hedef backend: `https://api.deepseek.com/anthropic` veya (konfigürasyona bağlı olarak) Bifrost (`http://10.80.80.70:8080/v1`). - Lokalde Anthropic endpoint'i: `http://localhost:8000/anthropic` (Bifrost mapping). - Kullanılacak kütüphaneler: - `github.com/gofiber/fiber/v3` - `gorm.io/gorm` - `gorm.io/driver/postgres` --- ## Çalışma Ortamı / Gereksinimler - Go modül yapısı (go1.20+ önerilir). - PostgreSQL veritabanı (docker-compose ile sağlanabilir). - Docker & docker-compose (opsiyonel ama önerilir). - İstenen `go get` komutları (README'de gösterilecek): - `go mod download` (tüm bağımlılıklar go.mod'da tanımlı) - `go get -u gorm.io/gorm` - `go get -u gorm.io/driver/postgres` --- ## Konfigürasyon (Environment Variables) - `PORT` (default: `8000`) - `OPENAI_BACKEND` (default: `https://api.deepseek.com`) ##Örnek - `ANTHROPIC_BACKEND` (default: `https://api.deepseek.com/anthropic`)##Örnek - `USE_BIFROST_FOR_ANTHROPIC` (`true`/`false`) — `true` ise Anthropic çağrıları `BIFROST_URL`'e yönlendirilir - `BIFROST_URL` (örnek: `http://10.80.80.70:8080/v1`)##Örnek - `POSTGRES_DSN` (örnek: `host=localhost user=app password=pass dbname=app port=5432 sslmode=disable TimeZone=UTC`)##Örnek - `REQUEST_TIMEOUT_SECONDS` (ör: `30`)##Örnek Örnek `.env.example`: ```env PORT=8000 OPENAI_BACKEND=https://api.deepseek.com ANTHROPIC_BACKEND=https://api.deepseek.com/anthropic BIFROST_URL=http://10.80.80.70:8080/v1 USE_BIFROST_FOR_ANTHROPIC=true POSTGRES_DSN=host=postgres user=app password=pass dbname=app port=5432 sslmode=disable TimeZone=UTC REQUEST_TIMEOUT_SECONDS=30 ``` --- ## API Endpoint Gereksinimleri ### OpenAI-uyumlu - `POST /v1/chat/completions` -> forward to `${OPENAI_BACKEND}/v1/chat/completions` - `POST /v1/completions` -> forward to `${OPENAI_BACKEND}/v1/completions` - Tüm `/v1/*` OpenAI endpoint'leri generic olarak hedef backend'e yönlendirilmeli (method korunacak). Kurallar: - Authorization header (Bearer ...) ve diğer önemli header'lar hedefe iletilecek. - Body genelde olduğu gibi POST edilecek. - Hedeften gelen status code ve body olduğu gibi client'a iletilecek. - Hedefe ulaşılamazsa 502 döndürülecek. ### Anthropic-uyumlu - `POST /anthropic/*` (ör. `/anthropic/complete`) -> eğer `USE_BIFROST_FOR_ANTHROPIC=false` ise `${ANTHROPIC_BACKEND}`'e, `true` ise `${BIFROST_URL}`'e yönlendir. - Eğer Bifrost formatı ile Anthropic formatı farklıysa, minimal bir dönüşüm fonksiyonu yazılmalı (request/response mapping). Hata durumları: - Hedefe ulaşılamaz veya hata alınırsa uygun HTTP kodu döndürülecek (502/504/500 gibi). ### Sağlık ve Dokümantasyon - `GET /health` -> servis, DB ve opsiyonel hedef backendlere temel sağlık bilgisi dönecek. - Swagger UI: `/swagger/*` (Fiber v3 native HTML + CDN Swagger UI ile sunulacak). --- ## İstek / Yanıt İşleme - Timeout yönetimi (env'den): `REQUEST_TIMEOUT_SECONDS`. - Retries (opsiyonel): tercih halinde `github.com/hashicorp/go-retryablehttp` veya benzeri kullanılabilir. - İsteklerin DB'ye loglanması (Postgres + GORM) — minimal kayıt: - timestamp, endpoint, method, client IP, model (varsa), tokens estimate (opsiyonel), response status, latency - Büyük request body'leri truncation ile kaydedilecek (ör. 2000 karakter). - Sensitive veriler (Authorization vb.) maskelenmeli, düz kaydedilmemeli. --- ## Veri Modeli (Minimal) - `RequestLog`: - ID (UUID / auto increment) - CreatedAt - Endpoint (string) - Method (string) - ClientIP (string) - RequestBody (text, truncate) - ResponseStatus (int) - LatencyMs (int) - GORM AutoMigrate ile migration sağlanacak. --- ## Proje Yapısı (Öneri) - `main.go` (Fiber app, config yükleme, route register) - `handlers/openai.go` - `handlers/anthropic.go` - `internal/proxy/proxy.go` (generic forwarder) - `internal/transform/anthropic_bifrost.go` (dönüşüm fonksiyonları) - `models/request_log.go` - `config/config.go` (env yükleme) - `docker/Dockerfile` - `docker/docker-compose.yml` - `README.md` - `tests/*` (unit test örnekleri) - `go.mod`, `go.sum` --- ## Swagger - Fiber v3 native HTML handler + CDN Swagger UI ile `/swagger/*` altında UI sunulacak. - En az OpenAI-compatible `chat/completions` ve Anthropic endpoint'leri için örnek request/response gösterilecek. --- ## Docker & docker-compose - Multi-stage `Dockerfile` (build + runtime). - `docker-compose.yml`: - `app` servisi (build) - `postgres` servisi (resmi image, örnek env) - `docker-compose` ile test sağlanabilecek (izole ortam). --- ## Testler - Unit test: OpenAI proxy handler için en az iki test: - başarılı forward (mock backend ile) - hedef hata verdiğinde uygun hata dönüşü - Integration test (opsiyonel): docker-compose altında mocked backend'e karşı örnek. --- ## Komutlar / Kurulum (README'de belirtilecek) - `go mod init github.com//` - `go mod download` (fiber v3 ve diğer bağımlılıklar go.mod'da) - `go get -u gorm.io/gorm` - `go get -u gorm.io/driver/postgres` - `go build ./...` - `docker build -t llm-gateway:latest .` - `docker-compose up -d` --- ## Örnek curl Çağrıları OpenAI compatible: ```bash curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Authorization: Bearer $OPENAI_KEY" \ -H "Content-Type: application/json" \ -d '{"model":"gpt-4","messages":[{"role":"user","content":"Hello"}]}' ``` Anthropic (lokal mapped to Bifrost veya deepseek): ```bash curl -X POST "http://localhost:8000/anthropic/complete" \ -H "Authorization: Bearer $ANTHROPIC_KEY" \ -H "Content-Type: application/json" \ -d '{"prompt":"Say hello", "max_tokens": 64}' ``` --- ## Teslim Edilecekler (Repository içinde) - `main.go` - `handlers/openai.go` - `handlers/anthropic.go` - `internal/proxy/proxy.go` - `internal/transform/anthropic_bifrost.go` - `models/request_log.go` - `config/config.go` - `docker/Dockerfile` - `docker/docker-compose.yml` - `README.md` (kurulum, env örnekleri, docker-compose, curl örnekleri) - `tests/*` (unit testler) - `go.mod`, `go.sum` --- ## Kabul Kriterleri (Acceptance Criteria) - `/v1/*` istekleri `OPENAI_BACKEND`'e başarılı yönleniyor. - `/anthropic/*` istekleri `USE_BIFROST_FOR_ANTHROPIC` konfigürasyonuna göre `BIFROST_URL` veya `ANTHROPIC_BACKEND`'e gidiyor. - İstekler DB'ye loglanıyor (Postgres çalışırken). - Swagger UI erişilebilir (`/swagger/*`). - README yönergelerine göre proje çalıştırılabiliyor. - En az 1 birim testi geçiyor (`go test ./...`). --- ## Teknik Notlar / İpuçları - HTTP client: `net/http` + `context` (timeout) veya tercih edilirse fiber'ın client'ı. - Retries: isteğe bağlı; `go-retryablehttp` önerilir. - Büyük body'leri DB'ye kaydederken truncate et (ör. 2000 char). - Sensitive alanlar maskelenmeli. - Anthropic <-> Bifrost dönüşümleri karmaşıksa, minimal mapping uygula ve README'de açıkla. - Environment swap ile Deepseek <-> Bifrost kolayca değiştirilebilmeli. --- ## Geliştirme Adımları (Öneri Sırayla) 1. Repo skeleton oluştur (go mod init, klasör yapısı). 2. `config/config.go`: env yükleme ve default ayarlar. 3. `main.go`: Fiber app init, DB bağlantısı (GORM), AutoMigrate, route register. 4. `internal/proxy/proxy.go`: generic forwarder implementasyonu (timeout, header forwarding). 5. `handlers/openai.go` & `handlers/anthropic.go`: handler'ları yaz, DB logging çağrılarını ekle. 6. Basit Swagger dokümantasyonu ekle. 7. Dockerfile & docker-compose ekle. 8. Unit testleri yaz ve çalıştır. 9. README güncelle, örnek env ve curl'leri ekle. --- ## İletişim / Teslim - Repo URL veya zip ile teslim. - README ile çalıştırma adımları. - Örnek curl komutları ve `.env.example`. - (Opsiyonel) Dönüşümlere dair kısa açıklama ve input/output örnekleri. --- Eğer bu prompt'u doğrudan bir geliştiriciye/assistant'e vereceksen bu dosyayı kullan. İstersen ben bu prompt'u kullanarak ilk adımda repository skeleton'ını ve `main.go` + temel proxy handler'ı oluşturmaya başlayabilirim — başlamak istersen sadece "başla" de.