Go SDK
Deyimsel (idiomatic), bağlam-farkındalıklı (context-aware) Go istemcisi. Bağlam-öncelikli metotlar, türlü hatalar (typed errors), kaputun altında net/http. Her API sürümünden bir hafta içinde yayımlanır.
github.com/moon-born/sdk-go — resmi Go SDK'sıdır. Kanonik OpenAPI belirtiminden üretilir; Go için deyimseldir:
- Bağlam öncelikli (context-first) metotlar (
ctx context.Contextilk argüman) - Türlü hatalar (typed errors) (
*moonborn.APIError) - Kaputun altında standart
net/http(ek çalışma zamanı bağımlılığı yok) - 5xx + 429 hatalarında otomatik yeniden deneme (auto-retry) (üstel geri çekilme — exponential backoff)
Bu sayfayı bitirdiğinde
- Go SDK'sını kurabilecek ve başlatabileceksin.
- Bağlam-farkındalıklı persona oluşturma + sohbet çağırabileceksin.
- Akış (streaming) desenini (
stream.Events()) kullanabileceksin. - Hata işleme ile yeniden-deneme-farkındalıklı kod yazabileceksin.
- Eşgüçlülük (idempotency) seçeneğini doğru uygulayabileceksin.
Ön koşul: Go 1.21+, API anahtarı.
Kurulum
go get github.com/moon-born/sdk-gogo.mod'unu hedeflediğin API alt sürümüne (minor version) sabitle:
require github.com/moon-born/sdk-go v1.4.0Başlatma
package main
import (
"context"
"fmt"
"os"
"github.com/moon-born/sdk-go/moonborn"
)
func main() {
client := moonborn.NewClient(moonborn.Options{
ApiKey: os.Getenv("MOONBORN_API_KEY"),
Timeout: 60 * time.Second, // istek zaman aşımı
// BaseURL: "https://api.moonborn.co", // kendi sunucuna kurulum için
})
ctx := context.Background()
persona, err := client.Personas.CreatePersona(ctx, moonborn.CreatePersonaInput{
Intent: "İstanbul'dan 34 yaşında bir kurucu. Parlak ama huzursuz.",
WorkspaceID: "ws_...",
})
if err != nil {
panic(err)
}
fmt.Println(persona.ID, persona.Status)
}Akışlı sohbet
session, _ := client.Chat.CreateSession(ctx, moonborn.CreateSessionInput{
PersonaID: persona.ID,
})
stream, err := client.Chat.StreamMessage(ctx, moonborn.StreamMessageInput{
SessionID: session.ID,
Content: "Sessiz bir gerçek söyle.",
})
if err != nil {
panic(err)
}
defer stream.Close()
for chunk := range stream.Events() {
switch chunk.Type {
case moonborn.ChunkTypeToken:
fmt.Print(chunk.Delta)
case moonborn.ChunkTypeCompleted:
fmt.Printf("\ndrift: %.2f\n", chunk.DriftScore)
case moonborn.ChunkTypeError:
fmt.Printf("error: %v\n", chunk.Error)
}
}stream.Events() bir <-chan Event kanalıdır — kanal kapanınca döngü biter. defer stream.Close() temizleme (cleanup) için kritiktir.
Üretim hattı akışı
stream, _ := client.Personas.CreatePersonaStream(ctx, moonborn.CreatePersonaInput{
Intent: "Lagos'ta bir market satıcısı.",
})
defer stream.Close()
for event := range stream.Events() {
switch event.Type {
case moonborn.EventTypeStepStarted:
fmt.Println("Başladı:", event.Step)
case moonborn.EventTypeStepCompleted:
fmt.Printf("Bitti: %s (%dms)\n", event.Step, event.DurationMs)
case moonborn.EventTypePipelineCompleted:
fmt.Println("Persona:", event.PersonaID)
}
}Hata işleme
_, err := client.Personas.GetPersona(ctx, moonborn.GetPersonaInput{ID: "per_..."})
if err != nil {
var apiErr *moonborn.APIError
if errors.As(err, &apiErr) {
switch apiErr.Code {
case "rate_limited":
time.Sleep(time.Duration(apiErr.RetryAfter) * time.Second)
// yeniden dene
case "not_found":
return ErrPersonaMissing
case "validation_failed":
log.Printf("invalid body: %+v", apiErr.Details)
}
} else {
// ağ / bağlam iptali
return err
}
}14 hata kodunun tümü: Hatalar.
Otomatik yeniden deneme — yerleşik
İstemci 5xx + 429'da üstel geri çekilme (exponential backoff) ile otomatik yeniden deneme yapar (30 sn üst sınırlı):
client := moonborn.NewClient(moonborn.Options{
ApiKey: os.Getenv("MOONBORN_API_KEY"),
RetryConfig: &moonborn.RetryConfig{
MaxRetries: 5,
InitialWait: 500 * time.Millisecond,
MaxWait: 30 * time.Second,
},
})validation_failed, idempotency_conflict, drift_blocked hataları asla otomatik yeniden denenmez.
Eşgüçlülük (idempotency)
Yazma metotları (Create*, Fork*, Refine*) varsayılan olarak eşgüçlülük anahtarını otomatik üretir (UUID). Geçersiz kılma:
persona, err := client.Personas.CreatePersona(ctx, input,
moonborn.WithIdempotencyKey("persona-build-2026-05-17-mert"),
)24 saat içinde yeniden gönderilen istekler orijinal yanıtı döndürür.
Bağlam (context) — iptal
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
// 30 saniye sonra otomatik iptal
persona, err := client.Personas.CreatePersona(ctx, input)
if errors.Is(err, context.DeadlineExceeded) {
// zaman aşımı
}Bağlam iptali Moonborn tarafında algılanır — LLM çağrısı kesilir, kalan token'lar faturalandırılmaz.
Sık karşılaşılan hatalar
"context canceled" erken oluşuyor
context.Background() yerine context.WithTimeout(...) kullanıyorsan ve zaman aşımı akış için çok kısaysa. Akış için en az 60*time.Second kullan.
"rate_limited" sürekli geliyor
Üretimde çalışma alanı planını kontrol et. Free planı saatte 6 üretim; Pro saatte 60. Detay: Hız limitleri.
Plan gereksinimi
Her plan — kapılar sunucu tarafındadır.