first commit
This commit is contained in:
@@ -0,0 +1,191 @@
|
||||
# optoant — LLM Gateway
|
||||
|
||||
Go + Fiber v3 tabanlı OpenAI-uyumlu ve Anthropic-uyumlu LLM proxy/gateway. DeepSeek gibi tek upstream backend üzerinden hem OpenAI (`/v1/*`) hem Anthropic (`/anthropic/*`) API sunar. Anthropic↔OpenAI dönüşümü built-in. PostgreSQL request loglama, Swagger UI ve Docker desteği ile birlikte gelir.
|
||||
|
||||
## Özellikler
|
||||
|
||||
- **OpenAI-uyumlu proxy**: `/v1/*` → `OPENAI_BACKEND` (direct passthrough)
|
||||
- **Anthropic-uyumlu proxy**: `/anthropic/*` → Anthropic↔OpenAI dönüşümü → `OPENAI_BACKEND`
|
||||
- **Built-in dönüşüm**: Anthropic Messages ↔ OpenAI Chat Completions format çevrimi
|
||||
- **PostgreSQL loglama**: Her isteği GORM ile otomatik loglar
|
||||
- **Swagger UI**: `/swagger/*` adresinde erişilebilir
|
||||
- **Docker**: Multi-stage build + docker-compose
|
||||
- **Konfigürasyon**: Sadece 4 env değişkeni
|
||||
|
||||
---
|
||||
|
||||
## Hızlı Başlangıç
|
||||
|
||||
### 1. Bağımlılıkları Kur
|
||||
|
||||
```bash
|
||||
go mod download
|
||||
```
|
||||
|
||||
### 2. Ortam Değişkenlerini Ayarla
|
||||
|
||||
```bash
|
||||
cp .env.example .env
|
||||
# .env dosyasını düzenle
|
||||
```
|
||||
|
||||
Minimum `.env`:
|
||||
```env
|
||||
PORT=8000
|
||||
OPENAI_BACKEND=https://api.deepseek.com
|
||||
DATABASE_DSN=postgres://user:pass@localhost:5432/optoant?sslmode=disable
|
||||
REQUEST_TIMEOUT_SECONDS=30
|
||||
```
|
||||
|
||||
### 3. Çalıştır
|
||||
|
||||
```bash
|
||||
go run main.go
|
||||
```
|
||||
|
||||
veya derleyip çalıştır:
|
||||
|
||||
```bash
|
||||
go build -o gateway ./main.go
|
||||
./gateway
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Docker ile Çalıştırma
|
||||
|
||||
```bash
|
||||
# Sadece uygulamayı derle
|
||||
docker build -t optoant-gateway:latest -f docker/Dockerfile .
|
||||
|
||||
# Postgres dahil tüm stack'i ayağa kaldır
|
||||
cd docker
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Konfigürasyon Tablosu
|
||||
|
||||
| Değişken | Varsayılan | Açıklama |
|
||||
|----------|-----------|----------|
|
||||
| `PORT` | `8000` | Dinleme portu |
|
||||
| `OPENAI_BACKEND` | `https://api.deepseek.com` | Upstream backend (OpenAI ve Anthropic için ortak) |
|
||||
| `DATABASE_DSN` veya `POSTGRES_DSN` | — | PostgreSQL bağlantı string'i |
|
||||
| `REQUEST_TIMEOUT_SECONDS` | `30` | Upstream timeout (saniye) |
|
||||
|
||||
---
|
||||
|
||||
## Endpoint'ler
|
||||
|
||||
| Endpoint | Method | Açıklama |
|
||||
|----------|--------|----------|
|
||||
| `/v1/*` | ANY | OpenAI-uyumlu proxy |
|
||||
| `/anthropic/*` | ANY | Anthropic-uyumlu proxy (Anthropic↔OpenAI dönüşümlü) |
|
||||
| `/health` | GET | Sağlık kontrolü |
|
||||
| `/swagger/*` | GET | Swagger UI |
|
||||
|
||||
---
|
||||
|
||||
## Örnek curl Çağrıları
|
||||
|
||||
### OpenAI-uyumlu (DeepSeek / Bifrost OpenAI)
|
||||
|
||||
```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 (Anthropic↔OpenAI dönüşümlü)
|
||||
|
||||
```bash
|
||||
curl -X POST "http://localhost:8000/anthropic/v1/messages" \
|
||||
-H "Authorization: Bearer $ANTHROPIC_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"model": "claude-3-5-sonnet-20241022",
|
||||
"max_tokens": 1024,
|
||||
"messages": [{"role": "user", "content": "Hello!"}]
|
||||
}'
|
||||
```
|
||||
|
||||
### Sağlık kontrolü
|
||||
|
||||
```bash
|
||||
curl http://localhost:8000/health
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Testler
|
||||
|
||||
```bash
|
||||
go test ./tests/...
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Proje Yapısı
|
||||
|
||||
```
|
||||
opantoantro/
|
||||
├── main.go # Fiber app, DB, route kayıt
|
||||
├── config/config.go # Env yükleme
|
||||
├── handlers/
|
||||
│ ├── openai.go # /v1/* handler
|
||||
│ ├── anthropic.go # /anthropic/* handler
|
||||
│ └── health.go # /health handler
|
||||
├── internal/
|
||||
│ ├── proxy/proxy.go # Generic HTTP forwarder
|
||||
│ └── transform/anthropic_bifrost.go # Format dönüşümleri
|
||||
├── models/request_log.go # GORM modeli
|
||||
├── docs/
|
||||
│ ├── swagger.json # Swagger spec
|
||||
│ └── wiki/ # Obsidian knowledge graph
|
||||
│ ├── Index.md
|
||||
│ ├── Config.md
|
||||
│ ├── Proxy.md
|
||||
│ ├── Handlers.md
|
||||
│ └── Models_Transform.md
|
||||
├── tests/openai_test.go # Unit testler
|
||||
├── docker/
|
||||
│ ├── Dockerfile # Multi-stage build
|
||||
│ └── docker-compose.yml # Servis tanımı
|
||||
├── .env # Aktif env (git'e ekleme!)
|
||||
└── .env.example # Örnek env
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Anthropic ↔ OpenAI Dönüşümü
|
||||
|
||||
Anthropic `/anthropic/*` istekleri otomatik olarak OpenAI formatına çevrilip `OPENAI_BACKEND`'e gönderilir, yanıt tekrar Anthropic formatına dönüştürülür:
|
||||
|
||||
**Request dönüşümü (Anthropic → OpenAI):**
|
||||
```json
|
||||
// Anthropic giriş
|
||||
{ "model": "claude-3", "max_tokens": 100, "system": "You are helpful.", "messages": [{"role": "user", "content": "Hi"}] }
|
||||
|
||||
// Bifrost çıkış
|
||||
{ "model": "claude-3", "max_tokens": 100, "messages": [{"role": "system", "content": "You are helpful."}, {"role": "user", "content": "Hi"}] }
|
||||
```
|
||||
|
||||
**Response dönüşümü (OpenAI → Anthropic):**
|
||||
```json
|
||||
// Bifrost giriş
|
||||
{ "choices": [{"message": {"role": "assistant", "content": "Hello!"}, "finish_reason": "stop"}] }
|
||||
|
||||
// Anthropic çıkış
|
||||
{ "type": "message", "role": "assistant", "content": [{"type": "text", "text": "Hello!"}], "stop_reason": "stop" }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Lisans
|
||||
|
||||
MIT
|
||||
Reference in New Issue
Block a user