Tek satır değişiyor, gerisi aynı kalıyor
Modelion OpenAI uyumlu bir tel formatı konuşur. Mevcut SDK'nızı, mevcut istek gövdenizi ve mevcut streaming kodunuzu koruyorsunuz; değişen tek şey base_url. Bu sayfa ekleneni anlatıyor — uzantılar, yanıt başlıkları ve politika tarafındaki sözleşme.
1. Hızlı başlangıç
Konsoldan bir sanal anahtar üretin, base_url'i değiştirin, isteği gönderin. Model adı yerine bir combo anahtarı geçmek dışında hiçbir şey değişmiyor.
- 1Konsolda API Anahtarları → yeni anahtar. Anahtar
mk_live_ile başlar ve bir kez gösterilir. - 2
base_urldeğerinihttps://api.modelion.ai/v1yapın. - 3
modelalanına ya katalogdaki bir model kimliği ya dacombo/<anahtar>geçin.
1from openai import OpenAI 2 3client = OpenAI( 4 # The only line that changes. 5 base_url="https://api.modelion.ai/v1", 6 api_key="mk_live_...", 7) 8 9response = client.chat.completions.create(10 # A combo, not a model: the candidate chain lives in the console.11 model="combo/production-chat",12 messages=[{"role": "user", "content": "Summarise this invoice."}],13 stream=True,14)1516for chunk in response:17 print(chunk.choices[0].delta.content or "", end="")Yanıtla birlikte dönen karar özeti
Modelion-Decision: v1;
rule=kvkk-pii-route-resident;
effect=route;
model=gpt-4o-mini;
region=tr-west-1;
obligations=redact,no-fallback;
cache=off;
eval=181us;
requestId=req_01JQ8Z3K7M2N4P6R8T0V2X4Y6ATüm örneklerde mk_live_… sanal anahtarınız kullanılır. Anahtar bir organizasyona, bir bölgeye ve bir bütçeye bağlıdır.
2. Uç noktalar
Yüzey kasıtlı olarak küçük. Aşağıdakiler dışında bir uç nokta yok; yönetişim ve yönlendirme istek gövdesinde değil, politikada yaşıyor.
| POST | /v1/chat/completions | Sohbet tamamlama. stream: true ile SSE. |
| POST | /v1/embeddings | Vektör üretimi. Anthropic modelleri embedding vermez; OpenAI-tel veya vLLM bir modele yönlendirin. |
| GET | /v1/models | Anahtarınızın erişebildiği modeller — politika kısıtları uygulanmış hâliyle. |
| POST | /v1/prompts/{id}/completions | Registry'deki bir prompt'u kimliğiyle çağırma. |
3. Başlıklar
İstekte bir zorunlu başlık var. Yanıtta dönen iki başlık, kararı sonradan açıklayabilmeniz için.
Authorization: Bearer mk_live_…İstekZorunlu | Sanal anahtarınız. Sağlayıcı anahtarı vermezsiniz; onları Modelion yönetir. |
X-Modelion-Organizationİstek | Birden fazla organizasyona üyeyseniz hangisi adına çağrı yaptığınız. Tek organizasyonda gerekmez. |
Modelion-Route-Tagİstek | Combo'daki karar grafiğinde bir dalı seçmek için serbest etiket. Politika bunu input.request.routeTag olarak görür. |
Modelion-DecisionYanıt | Kararın 512 baytın altındaki özeti: kazanan kural, etki, model, bölge, yükümlülükler, değerlendirme süresi. |
Modelion-Request-IdYanıt | Tam karar izini çekmek için kullanılan kimlik. |
4. Combo'lar
model alanına combo/<anahtar> geçtiğinizde, hangi modelin çalışacağına aday zinciri karar verir. Zincir konsolda tanımlı; değiştirmek deploy değil. Politikanın doğurduğu kısıt bu zincirle kesişir — yani politika bir adayı listeden çıkarabilir, ama listeye ekleyemez.
1{ 2 "model": "combo/production-chat" 3} 4 5# A combo is a candidate chain, resolved at request time: 6# 7# 1. gpt-4o-mini @ tr-west-1 8# 2. llama-3.3-70b @ tr-west-1 9# x claude-sonnet-4 @ eu-east-1 ← removed by the residency constraint10#11# The chain lives in the console, not in your code. Changing it is not12# a deploy.5. Streaming
stream: true OpenAI şeklinde SSE döndürür. Bu, hangi sağlayıcıya gidildiğinden bağımsız: Anthropic'in çok olaylı çerçevelemesi bu akışa eşlenir, dolayısıyla rota değiştiğinde istemci kodunuz değişmez. İlk parça geldikten sonra failover yapılmaz — akış başladıysa taahhüt edilmiştir.
1# Server-sent events, in the OpenAI shape regardless of upstream. 2# An Anthropic model's multi-event framing is mapped onto this stream, 3# so the client code does not change when the route does. 4 5data: {"choices":[{"delta":{"content":"Müşteri"},"index":0}]} 6data: {"choices":[{"delta":{"content":" limiti"},"index":0}]} 7data: {"choices":[{"delta":{},"finish_reason":"stop","index":0}]} 8data: [DONE]6. Prompt'u kimlikle çağırmak
Prompt metnini uygulamanızla birlikte dağıtmak zorunda değilsiniz. Kimlik ve değişkenleri gönderirsiniz; şablon gateway'de giydirilir. Bu sıralama önemli: hydration politikadan önce çalışır, çünkü kişisel veri şablonda değil değişkenlerin içindedir. Guardrail hattı gerçek metni görmeli.
Bilinmeyen bir değişken 400 döner, eksik zorunlu değişken de. Sessizce boş string geçmez — bir prompt'un yarısının eksik olduğunu üretimde fark etmek pahalıdır.
7. Politika kural seti
Kurallar sırayla değerlendirilir, ilk eşleşen kazanır ve kaybedenler kayda geçer. Beş etki var: route, constrain, deny, redact, cache. Birleşme kuralı tek cümle: kısıtlar kesişir, yükümlülükler birleşir. Platform tabanında yazılmış bir kısıtı, altındaki bir organizasyon kuralı gevşetemez.
1apiVersion: modelion.ai/v1 2kind: PolicyRuleSet 3metadata: 4 name: kvkk-baseline 5 class: compliance 6 7spec: 8 - name: pii-detected-pin-resident 9 when:10 match: all11 clauses:12 - field: signals.pii.types13 operator: containsAny14 values: [tckn_tr, iban_tr]15 - field: signals.pii.available16 operator: is17 value: true18 then:19 effect: route20 route:21 candidates: [gpt-4o-mini]22 fallbackToOriginal: false23 obligations:24 redactTypes: detected25 cache: { mode: off }26 auditTags: [pii_detected]2728 - name: scan-unavailable-be-careful29 when:30 - field: signals.pii.available31 operator: is32 value: false33 then:34 effect: constrain35 constraints:36 allowedModels: [gpt-4o-mini, llama-3.3-70b]37 obligations:38 cache: { mode: off }39 auditTags: [pii_scan_unavailable]signals.pii.detected | PII bulundu mu |
signals.pii.types | Bulunan türler: tckn_tr, credit_card, iban_tr, email, phone |
signals.pii.available | Tarama yapılabildi mi — yokluğunu temizlik sanmayın |
signals.injection.detected | Prompt injection denemesi |
signals.secrets.detected | Prompt içinde anahtar veya token |
principal.subscription.tier | Çağıranın katmanı |
request.promptTokens | Girdi token sayısı — aralığa göre rota için |
request.headers.* | Kendi başlıklarınız, örneğin bir veri sınıfı |
runtime.health.* | Sağlayıcı sağlığı, bucket'lanmış |
8. Hata kodları
Aşağıdakiler politika ya da bütçe kaynaklı olanlar. Sağlayıcı hataları normal OpenAI semantiğiyle döner.
| Durum | Kod | Anlamı |
|---|---|---|
| 400 | unknown_prompt_variable | Şablonda tanımlı olmayan bir değişken gönderildi. |
| 400 | missing_prompt_variable | Şablonun zorunlu tuttuğu bir değişken eksik. |
| 403 | policy_denied | Bir kural isteği reddetti. Gövdede kuralın yazdığı kullanıcı mesajı döner. |
| 429 | rate_limited | Anahtarın veya organizasyonun hız limiti. |
| 429 | budget_exceeded | Bütçe üst sınırı aşıldı. Bütçe hiyerarşisi anahtar ve organizasyon seviyesinde ayrı ayrı çalışır. |
| 503 | no_eligible_candidate | Aday kalmadı. Yerleşim kuralı yürürlükteyse bu kasıtlıdır — istek başka bir bölgeye taşınmaz. Bunu azaltmanın yolu bölge içinde birden fazla aday tanımlamak. |
9. Kararı sonradan açıklamak
Her yanıt bir Modelion-Decision özeti taşır. Tam izi requestId ile çekersiniz. İzde eşleşip kaybeden kurallar da listelenir — denetimde "bu kural devreye girdi mi" sorusunun cevabı "eşleşti ama daha spesifik bir kural kazandı" olabilir, ve bu "eşleşmedi"den farklı bir cevaptır.
1curl "https://api.modelion.ai/v1/traces/req_01JQ8Z3K7M2N4P6R8T0V2X4Y6A" \ 2 -H "Authorization: Bearer $MODELION_API_KEY" 3 4{ 5 "requestId": "req_01JQ8Z3K7M2N4P6R8T0V2X4Y6A", 6 "decision": { 7 "winner": "pii-detected-pin-resident", 8 "effect": "route", 9 "matchedButLost": ["default-allow-with-cache"],10 "obligations": ["redact", "no-fallback", "audit"],11 "evalMicros": 18112 },13 "route": { "model": "gpt-4o-mini", "region": "tr-west-1", "attempts": 1 },14 "usage": { "promptTokens": 1204, "completionTokens": 286, "costUsd": 0.00042 }15}Bu sayfa tel formatının özeti. Alan bazında tam referans ve OpenAPI şeması konsolda, oturum açtıktan sonra.
Kendi trafiğinizle denemek için
Sandbox anahtarı ve shadow modda ölçülmüş bir sapma raporu ilk oturumun çıktısı oluyor.