Platform yalnızca sohbet modelleri sunmuyor. Bazı modeller metni vektöre çevirir, bazıları
belgeleri bir soruya göre puanlar, bazıları türü belli sorulara olasılıklarla yanıt verir,
bazıları da görüntüdeki ya da sesteki metni çıkarır. Bu makale model türlerini, hangi
uygulamanın hangisini gösterdiğini ve her türü kendi kodunuzdan nasıl çağıracağınızı
anlatıyor. Bütün türleri kapsadıkları için örneklerin hepsinde Evren modelleri (EV/…)
kullanılıyor. Her örnek 10 Ekim 2026’da canlı bir kurulumda çalıştırıldı; aktarılan
yanıtlar o gün alınanlardır.
Model türleri
GET /v1/models yanıtındaki her kaydın bir type alanı vardır. Bu alan, modele hangi
uç noktanın yanıt verdiğini söyler. Bir model yalnızca kendi uç noktasında çalışır: sohbet
uç noktasına gönderilen bir rerank modeli, doğru uç noktayı adıyla söyleyen bir 400 alır.
| Tür | Ne yapar | Tipik kullanım | Uç nokta | Evren modelleri |
|---|---|---|---|---|
llm |
Metin yazar, talimat izler, araç çağırır | Asistanlar, ajanlar, özetler, kod | POST /v1/chat/completions |
EV/deepseek-v4-flash, EV/glm-5.3, EV/gemma-4-31b, EV/qwen3-vl-30b (görüntü okur), EV/auto ve diğerleri |
guard |
Bir mesajı güvenli ya da güvensiz diye sınıflandırır, kategorileriyle | Bir LLM çağrısından önce ya da sonra denetim | POST /v1/chat/completions |
EV/qwen3-guard-4b |
embedding |
Metni 4096 sayılık bir vektöre çevirir | Anlamsal arama, bilgi getirme, kümeleme, tekrarları bulma | POST /v1/embeddings |
EV/qwen3-embedding-8b |
rerank |
Her belgenin bir soruyla ne kadar ilgili olduğunu puanlar | Arama sonuçlarını LLM’e gitmeden önce sıralamak | POST /v1/rerank |
EV/qwen3-reranker-8b |
decision |
Bir metin hakkındaki türü belli sorulara düz metin yerine olasılıklarla yanıt verir | Talep yönlendirme, önceliklendirme, evet/hayır kontrolleri | POST /api/alpha/decisions |
EV/clef (metin ve görüntü), EV/laya |
ocr |
Görüntüdeki metni olduğu gibi döndürür | Fişler, taranmış formlar, ekran görüntüleri | POST /v1/ocr |
EV/dots-ocr, EV/deepseek-ocr-2 |
transcription |
Konuşmayı metne çevirir | Toplantı notları, sesli giriş | POST /v1/audio/transcriptions |
EV/qwen3-asr-1.7b |
Diğer sağlayıcılar da aynı türleri kullanır; vlm, şirket içi havuzda görüntü de okuyabilen
bir sohbet modelidir. Sohbet modelleri, sağlayıcı bildiriyorsa capabilities alanını da
taşır: vision, tools ve reasoning. Diğer türlerde bu alan yoktur.
Model nasıl seçilir
| Nerede | Ne sunar |
|---|---|
| aimo, sohbet penceresi | Yalnızca sohbet modelleri. Diğer türler orada gizlenir, çünkü onlarla sohbet başarısız olur. |
| VS Code için aimo 1.1.4 ve sonrası | Select Model listesinde ve varsayılan seçimde yalnızca sohbet modelleri. |
| Ajan çalışma alanı | Ajan düzenleyicide yalnızca sohbet modelleri. Model yönlendiricisi, her istek için model seçerken karar modellerini kullanabilir. |
| Kendi kodunuz | Anahtarınızla GET /v1/models okuyun ve type alanına göre seçin. Model profiliniz listeyi daraltabilir; yalnızca çağırabileceğiniz modelleri görürsünüz. |
Model kimlikleri bir sağlayıcı önekiyle gelir. EV/ Evren demektir: Türkiye’de barındırılır,
kendi Evren anahtarınızla çalışır ve ücreti kendi Evren krediniz ödenir. Öneksiz kimlik de
çalışır.
curl -s $GW/v1/models -H "Authorization: Bearer $BOSPHORUS_KEY" \
| jq -r '.data[] | select(.id | startswith("EV/")) | "\(.type)\t\(.id)"' | sort
Bu yazının hazırlandığı gün 16 Evren modeli listelendi: iki decision, bir embedding, bir
guard, sekiz llm, iki ocr, bir rerank ve bir transcription.
Bölüm A: anahtarlarınız, bir kez
Evren modelleri herkesin kendi Evren anahtarıyla çalışır. Bu anahtarı bir istekte asla
göndermezsiniz: My variables sayfasında saklarsınız ve ağ geçidi, isteğin kimliğini
bildirdiği kişi için onu okur. Bu yüzden kodunuzun sizi tanıtan bir kişisel platform
anahtarına, gpk_…, ihtiyacı vardır. Örneklerde bu anahtarın adı $BOSPHORUS_KEY. Bir
ekip ya da servis anahtarı bir kişiyi tanıtmaz; Evren modelleri onu 503 ile geri çevirir.
A1. Evren anahtarınızı kaydedin
- Evren portalında bir Evren LLM anahtarı oluşturun.
evren_llm_ile başlar.evren_mdl_ile başlayan anahtar yanlış türdür ve kabul edilmez. - Konsolda My variables sayfasını açın, Evren keys bölümünü bulun, LLM anahtarını
yapıştırıp Save düğmesine basın. Kaydetmek, Evren’in kullanım koşullarını sizin
adınıza kabul eder. Platform anahtarı (
evren_plt_…) isteğe bağlıdır ve yalnızca kredi bakiyenizi gösterir.
A2. Kişisel API anahtarınızı alın
Aynı My variables sayfasında, en üstteki My API key kartında Create my API key
düğmesine basın. Anahtar bir Copy düğmesiyle birlikte görünür; kabuğunuza
BOSPHORUS_KEY olarak yükleyin. Bir kopyası kendi kasanızda saklanır: Show key aynı
anahtarı daha sonra yeniden gösterir, Replace de gerektiğinde yenisini verir.
Bunun yerine terminalden
Hesabınız konsolu açamıyorsa anahtarı şirket hesabınızla oturum açarak üretin. curl ve
jq gerekir; Windows’ta WSL ya da Git Bash kullanın. Microsoft Entra ID ile oturum açan bir
kurulumda:
GW=https://ai.corp.example
CFG=$(curl -s $GW/api/identity/config)
TENANT=$(echo "$CFG" | jq -r .entra.tenantId)
CLIENT=$(echo "$CFG" | jq -r .entra.clientId)
SCOPE=$(echo "$CFG" | jq -r .entra.scope)
DA=https://login.microsoftonline.com/$TENANT/oauth2/v2.0/devicecode
TE=https://login.microsoftonline.com/$TENANT/oauth2/v2.0/token
DC=$(curl -s $DA -d client_id=$CLIENT --data-urlencode "scope=$SCOPE")
echo "$DC" | jq -r .message
Yazdırdığı adresi açın, kodu girin ve oturum açın. Sonra aynı terminalde:
TOKEN=$(curl -s $TE -d grant_type=urn:ietf:params:oauth:grant-type:device_code \
-d client_id=$CLIENT -d device_code=$(echo "$DC" | jq -r .device_code) | jq -r .access_token)
curl -s -X POST "$GW/api/identity/token?client=api" -H "Authorization: Bearer $TOKEN" | jq -r .key.key
Son komut anahtarınızı bir kez yazdırır ve kopyasını saklamaz. Bir parola yöneticisinde
saklayın ve kabuğunuza BOSPHORUS_KEY olarak yükleyin. Kendi OpenID Connect sağlayıcısıyla oturum açan
bir kurulumda adımlar aynıdır, yalnızca adresler değişir;
API’yi kendi anahtarlarınızla çağırmak
makalesi ikisini de gösteriyor.
Anahtarı hangi yoldan almış olursanız olun, sizi tanıttığını ve Evren anahtarınızın kayıtlı olduğunu kontrol edin:
export GW=https://ai.corp.example
export BOSPHORUS_KEY=gpk_...
curl -s $GW/api/identity/me -H "Authorization: Bearer $BOSPHORUS_KEY" | jq -r .user.email
curl -s $GW/api/identity/evren-key -H "Authorization: Bearer $BOSPHORUS_KEY" | jq -r .llm.status
İlk satır e-posta adresinizi, ikincisi active yazar. İlk satırda null görürseniz bir
ekip anahtarı kullanıyorsunuz demektir.
A3. Anahtarı kaybettiniz ya da yardım mı gerekiyor?
| Durumunuz | Ne yapmalı |
|---|---|
| Hiç anahtarınız olmadı | My variables sayfasında Create my API key düğmesine basın. Birkaç saniye sürer. |
| Vardı, kaybettiniz | My variables sayfasında oluşturduysanız orada Show key düğmesine basın. Terminalden alınan anahtar yalnızca üretildiği anda gösterilir: terminal adımlarını yeniden çalıştırıp son komuta &rotate=true ekleyin; eski anahtar geçersiz olur, yenisi yazdırılır. VS Code için aimo’nun tuttuğu anahtar gibi diğer anahtarlarınız etkilenmez. |
| Sızmış olabilir | Hemen yenileyin: My variables sayfasında Replace, terminal anahtarı için &rotate=true. Anahtarı ele geçiren herkes sizin adınıza, sizin Evren kredinizle model çağırabilir. |
| Yalnızca tek bir çağrı denemek istiyorsunuz | Oturum açma belirteci, $TOKEN, en az bir kez kişisel anahtar ürettiyseniz yaklaşık bir saat boyunca Bearer olarak çalışır. |
Oturum açma reddediliyor ya da kontrol null yazıyor |
Platform yöneticinize başvurun. Hesabınızın oturum açabildiğini ve ekip anahtarı kullanmadığınızı kontrol edebilir. Sizin yerinize kişisel anahtar üretemez: anahtar yalnızca sizin oturum açmanızdan üretilir ve sizi tanıtmasını sağlayan da budur. |
| Kişiye değil, ortak bir servise anahtar gerekiyor | Yöneticiden Teams & Keys üzerinde bir ekip ya da servis anahtarı isteyin. Böyle bir anahtar EV/ modellerini kullanamaz, çünkü arkasında Evren anahtarı okunabilecek bir kişi yoktur. |
Bölüm B: örnekler
Python örnekleri, karşılığı olan çağrılarda OpenAI SDK’sını, tanımadığı üç uç nokta için de
requests kütüphanesini kullanır: rerank, karar ve OCR. Önce GW ve BOSPHORUS_KEY
değişkenlerini A2’deki gibi ayarlayın.
B1. Sohbet
Herhangi bir OpenAI SDK’sı, yalnızca adres ve anahtar değiştirilerek çalışır. Bazı Evren
sohbet modelleri yanıt vermeden önce düşünür ve max_tokens değerini düşünme ile yanıt
arasında paylaşır; küçük bir max_tokens boş bir yanıt döndürebilir. Bu değeri hiç
vermeyin ya da geniş tutun.
curl -s $GW/v1/chat/completions -H "Authorization: Bearer $BOSPHORUS_KEY" \
-H 'Content-Type: application/json' \
-d '{"model":"EV/deepseek-v4-flash","messages":[{"role":"user","content":"Merhaba"}]}' \
| jq -r '.choices[0].message.content'
Bir denemede Merhaba! Size nasıl yardımcı olabilirim? yanıtını verdi. Aynı çağrı Python’dan, ardından akış hâlinde bir çağrı:
import os
from openai import OpenAI
client = OpenAI(base_url=os.environ["GW"] + "/v1", api_key=os.environ["BOSPHORUS_KEY"])
reply = client.chat.completions.create(
model="EV/deepseek-v4-flash",
messages=[{"role": "user", "content": "Merhaba"}],
)
print(reply.choices[0].message.content)
for chunk in client.chat.completions.create(
model="EV/glm-5.3", stream=True,
messages=[{"role": "user", "content": "Count to five."}],
):
if chunk.choices and chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="", flush=True)
B2. Guard
EV/qwen3-guard-4b sohbet etmez. Kontrol edilecek mesajı gönderirsiniz, bir karar ve
kategorilerle yanıt verir. Bir ajan kullanıcı girdisine göre davranmadan önce ya da bir
yanıtı göstermeden önce kullanın.
curl -s $GW/v1/chat/completions -H "Authorization: Bearer $BOSPHORUS_KEY" \
-H 'Content-Type: application/json' \
-d '{"model":"EV/qwen3-guard-4b","messages":[{"role":"user","content":"What is the weather in Izmir?"}]}' \
| jq -r '.choices[0].message.content'
İki satırda Safety: Safe ve Categories: None yanıtını verdi. Silah yapımıyla ilgili bir
soru ise Safety: Unsafe ve Categories: Violent döndürdü. Küçük bir ayrıştırıcı:
def guard(client, text):
out = client.chat.completions.create(
model="EV/qwen3-guard-4b",
messages=[{"role": "user", "content": text}],
).choices[0].message.content
fields = dict(line.split(": ", 1) for line in out.splitlines() if ": " in line)
safe = fields.get("Safety") == "Safe"
cats = [] if fields.get("Categories") in (None, "None") else fields["Categories"].split(", ")
return safe, cats
B3. Embedding
Embedding bir metni anlamına göre konumlandırır: aynı konudaki metinler birbirine yakın
düşer. Belgelerinizi bir kez vektöre çevirip saklayın, sonra her soruyu da çevirip
karşılaştırın. Birden çok metni tek çağrıda çevirmek için input alanına bir liste verin.
curl -s $GW/v1/embeddings -H "Authorization: Bearer $BOSPHORUS_KEY" \
-H 'Content-Type: application/json' \
-d '{"model":"EV/qwen3-embedding-8b","input":"Merhaba dünya"}' \
| jq '.data[0].embedding | length'
4096 yazdırdı. Üç metni karşılaştırmak:
import math
def embed(client, texts):
r = client.embeddings.create(model="EV/qwen3-embedding-8b", input=texts)
return [d.embedding for d in r.data]
def cosine(a, b):
dot = sum(x * y for x, y in zip(a, b))
return dot / (math.sqrt(sum(x * x for x in a)) * math.sqrt(sum(y * y for y in b)))
q, related, unrelated = embed(client, [
"How do I reset my VPN password?",
"Steps to change the password of your VPN account",
"The canteen serves lentil soup on Fridays",
])
print(round(cosine(q, related), 3), round(cosine(q, unrelated), 3))
0.856 0.262 yazdırdı: ilgili çift çok daha yüksek puan alıyor. Her dizinde tek bir
embedding modeli kullanın, çünkü farklı modellerin vektörleri karşılaştırılamaz.
B4. Rerank
Rerank modeli soruyu ve her belgeyi birlikte okuyup ilgiyi puanlar. Embedding
karşılaştırmasından daha isabetli ama daha yavaştır, bu yüzden kısa bir listede kullanın:
embedding ile 20-50 aday bulun, onları yeniden sıralayın ve en iyi birkaçını LLM’e verin.
Sonuçlar puana göre sıralı gelir; index, gönderdiğiniz listedeki sırayı gösterir.
curl -s $GW/v1/rerank -H "Authorization: Bearer $BOSPHORUS_KEY" \
-H 'Content-Type: application/json' -d '{
"model": "EV/qwen3-reranker-8b",
"query": "What is the capital of France?",
"documents": ["Bananas are yellow.", "Paris is the capital of France.", "Berlin is in Germany."]
}' | jq -c '.results[] | {index, relevance_score}'
1 numaralı belgeyi 0.551 ile ilk sıraya koydu, ardından 2 numarayı 0.002 ve 0 numarayı 0.0004
ile. Yanıt her belgeyi de geri verir ve usage.prompt_tokens değerini bildirir. Model, soru
ve belge için toplam 4K token okur; uzun belgeleri parçalara bölün. Python’dan:
import os, requests
GW, KEY = os.environ["GW"], os.environ["BOSPHORUS_KEY"]
def rerank(query, documents, top=3):
r = requests.post(f"{GW}/v1/rerank", timeout=60,
headers={"Authorization": f"Bearer {KEY}"},
json={"model": "EV/qwen3-reranker-8b", "query": query, "documents": documents})
r.raise_for_status()
return [(documents[x["index"]], x["relevance_score"]) for x in r.json()["results"][:top]]
B5. Karar
Karar modeli bir e-posta, talep ya da JSON kaydı gibi bir state okur ve adı konmuş, türü
belli questions sorularına düz metin yerine olasılıklarla yanıt verir. Yanıt hızlıdır ve
biçimi sabittir; bu da yönlendirme ve önceliklendirme için uygundur. choice sorusu
criteria alır: etiketlerden oluşan bir liste ya da etiket ve açıklamadan oluşan bir
nesne. Diğer türler score ve noul (evet/hayır olasılığı); bu makalede choice denendi.
EV/clef ayrıca images alanında data URL olarak en fazla dört görüntü kabul eder.
curl -s $GW/api/alpha/decisions -H "Authorization: Bearer $BOSPHORUS_KEY" \
-H 'Content-Type: application/json' -d '{
"model": "EV/clef",
"state": "Hi, I want my money back for the broken kettle.",
"questions": {
"intent": {
"type": "choice",
"instructions": "What does the customer want?",
"criteria": {"refund": "money back", "shipping": "where is my package", "other": "anything else"}
}
}
}' | jq .answers
"choice": "refund" yanıtını 0.99 güvenle ve her etiket için bir olasılıkla verdi.
criteria yerine options göndermek a choice question takes ‘criteria’ as a dict of
label -> description, or a list of labels hatasıyla reddedilir. Python’dan:
import os, requests
GW, KEY = os.environ["GW"], os.environ["BOSPHORUS_KEY"]
def route_ticket(text):
r = requests.post(f"{GW}/api/alpha/decisions", timeout=60,
headers={"Authorization": f"Bearer {KEY}"},
json={
"model": "EV/clef",
"state": text,
"questions": {"intent": {
"type": "choice",
"instructions": "What does the customer want?",
"criteria": {"refund": "money back",
"shipping": "where is my package",
"other": "anything else"},
}},
})
r.raise_for_status()
a = r.json()["answers"]["intent"]
return a["choice"], a["confidence"]
B6. OCR
Görüntüyü image alanında data URL olarak gönderin. Yanıt, görüntüdeki metni olduğu gibi
text alanında verir. Ağ geçidi yalnızca JSON kabul eder, bu yüzden dosyayı kendiniz
kodlayın. Denetim kaydı görüntünün türünü ve boyutunu tutar, görüntünün kendisini asla.
IMG=$(base64 < invoice.png | tr -d '\n')
jq -n --arg img "data:image/png;base64,$IMG" '{model: "EV/dots-ocr", image: $img}' \
| curl -s $GW/v1/ocr -H "Authorization: Bearer $BOSPHORUS_KEY" \
-H 'Content-Type: application/json' -d @- | jq -r .text
Bir fatura satırının 640 x 160 piksellik görüntüsü için Invoice 4711 ve
Total: 128.50 EUR döndürdü. Python’dan:
import base64, mimetypes, os, requests
GW, KEY = os.environ["GW"], os.environ["BOSPHORUS_KEY"]
def ocr(path, model="EV/dots-ocr"):
mime = mimetypes.guess_type(path)[0] or "image/png"
data = base64.b64encode(open(path, "rb").read()).decode()
r = requests.post(f"{GW}/v1/ocr", timeout=120,
headers={"Authorization": f"Bearer {KEY}"},
json={"model": model, "image": f"data:{mime};base64,{data}"})
r.raise_for_status()
return r.json()["text"]
Küçük görüntülerde çıktıyı kontrol edin. Aynı metin 420 x 90 piksele ve iki renge
küçültüldüğünde alakasız bir metin döndü; görüntüleri özgün çözünürlükleriyle gönderin.
Denememizde EV/dots-ocr örneği okudu, EV/deepseek-ocr-2 ise aynı görüntü için boş metin
döndürdü; işe EV/dots-ocr ile başlayın.
B7. Konuşmadan metne
Bu, OpenAI ses API’sidir: file ve model alanlarıyla çok parçalı bir yükleme. Yanıt
varsayılan olarak JSON’dur; response_format için text, srt ve vtt de çalışır. Evren
zaman damgası döndürmediği için srt ve vtt tüm kaydı tek bir satırda taşır,
verbose_json ise reddedilir.
curl -s $GW/v1/audio/transcriptions -H "Authorization: Bearer $BOSPHORUS_KEY" \
-F model=EV/qwen3-asr-1.7b -F file=@note.wav | jq -r .text
Seslendirilmiş bir deneme cümlesi The meeting starts at 9:30 tomorrow morning. olarak geri
geldi. Mac’te say -o note.aiff "…" ve ardından
afconvert -f WAVE -d LEI16@16000 -c 1 note.aiff note.wav böyle bir kayıt üretir.
Bölüm C: her türü tek seferde deneyin
Bu betik kurulumunuzu kontrol eder ve her türü bir kez çağırır. Her kontrol için bir satır
yazar ve bir şey başarısız olursa sıfırdan farklı bir kodla çıkar; böylece bir hatta duman
testi olarak da çalışır. OCR’ı da denemek için OCR_IMAGE değişkenine üzerinde metin olan
bir görüntü, konuşmadan metni denemek için de AUDIO_FILE değişkenine bir WAV dosyası
verin.
#!/usr/bin/env python3
import math, os, sys, base64, mimetypes, requests
GW = os.environ.get("GW", "https://ai.corp.example").rstrip("/")
KEY = os.environ.get("BOSPHORUS_KEY") or sys.exit("set BOSPHORUS_KEY to your personal key")
H = {"Authorization": f"Bearer {KEY}"}
failed = 0
def post(path, body):
r = requests.post(GW + path, headers=H, json=body, timeout=120)
if r.status_code != 200:
raise RuntimeError(f"HTTP {r.status_code}: {r.text[:300]}")
return r.json()
def check(name, fn):
global failed
try:
print(f" ok {name}: {fn()}")
except Exception as e:
failed += 1
print(f" FAIL {name}: {e}")
def whoami():
me = requests.get(GW + "/api/identity/me", headers=H, timeout=30).json()
email = (me.get("user") or {}).get("email")
assert email, "this key names no person: mint a personal key with ?client=api"
return email
def evren_key():
st = requests.get(GW + "/api/identity/evren-key", headers=H, timeout=30).json()
status = (st.get("llm") or {}).get("status")
assert status == "active", f"Evren LLM key status is {status!r}: save it on My variables"
return status
def listing():
data = requests.get(GW + "/v1/models", headers=H, timeout=30).json()["data"]
ev = {m["id"]: m.get("type") for m in data if m["id"].startswith("EV/")}
want = {"EV/qwen3-embedding-8b": "embedding", "EV/qwen3-reranker-8b": "rerank",
"EV/clef": "decision", "EV/dots-ocr": "ocr", "EV/qwen3-guard-4b": "guard"}
for mid, t in want.items():
assert ev.get(mid) == t, f"{mid} is listed as {ev.get(mid)!r}, expected {t!r}"
return f"{len(ev)} EV/ models, types as expected"
def chat():
j = post("/v1/chat/completions", {"model": "EV/deepseek-v4-flash",
"messages": [{"role": "user", "content": "Reply with the single word: pong"}]})
text = j["choices"][0]["message"]["content"] or ""
assert "pong" in text.lower(), repr(text)
return text.strip()
def guard():
j = post("/v1/chat/completions", {"model": "EV/qwen3-guard-4b",
"messages": [{"role": "user", "content": "What is the weather in Izmir?"}]})
text = j["choices"][0]["message"]["content"]
assert text.startswith("Safety: Safe"), repr(text)
return text.replace("\n", " / ")
def embeddings():
j = post("/v1/embeddings", {"model": "EV/qwen3-embedding-8b", "input": [
"How do I reset my VPN password?",
"Steps to change the password of your VPN account",
"The canteen serves lentil soup on Fridays"]})
v = [d["embedding"] for d in j["data"]]
cos = lambda a, b: sum(x * y for x, y in zip(a, b)) / (
math.sqrt(sum(x * x for x in a)) * math.sqrt(sum(y * y for y in b)))
related, unrelated = cos(v[0], v[1]), cos(v[0], v[2])
assert len(v[0]) == 4096 and related > unrelated, (len(v[0]), related, unrelated)
return f"{len(v[0])} dims, related {related:.3f} vs unrelated {unrelated:.3f}"
def rerank():
docs = ["Bananas are yellow.", "Paris is the capital of France.", "Berlin is in Germany."]
j = post("/v1/rerank", {"model": "EV/qwen3-reranker-8b",
"query": "What is the capital of France?", "documents": docs})
top = j["results"][0]
assert top["index"] == 1, j["results"]
return f"top: {docs[top['index']]!r} ({top['relevance_score']:.3f})"
def decision():
j = post("/api/alpha/decisions", {"model": "EV/clef",
"state": "Hi, I want my money back for the broken kettle.",
"questions": {"intent": {"type": "choice", "instructions": "What does the customer want?",
"criteria": {"refund": "money back",
"shipping": "where is my package",
"other": "anything else"}}}})
a = j["answers"]["intent"]
assert a["choice"] == "refund", a
return f"choice {a['choice']} ({a['confidence']:.2f})"
def ocr():
path = os.environ["OCR_IMAGE"]
mime = mimetypes.guess_type(path)[0] or "image/png"
data = base64.b64encode(open(path, "rb").read()).decode()
text = post("/v1/ocr", {"model": "EV/dots-ocr", "image": f"data:{mime};base64,{data}"})["text"]
assert text.strip(), "no text came back"
return text.replace("\n", " / ")[:120]
def speech():
with open(os.environ["AUDIO_FILE"], "rb") as f:
r = requests.post(GW + "/v1/audio/transcriptions", headers=H, timeout=120,
data={"model": "EV/qwen3-asr-1.7b"}, files={"file": f})
assert r.status_code == 200, f"HTTP {r.status_code}: {r.text[:300]}"
return r.json()["text"]
def wrong_endpoint():
r = requests.post(GW + "/v1/chat/completions", headers=H, timeout=60,
json={"model": "EV/qwen3-reranker-8b",
"messages": [{"role": "user", "content": "hi"}]})
assert r.status_code == 400 and "/v1/rerank" in r.text, f"HTTP {r.status_code}: {r.text[:200]}"
return "400, names /v1/rerank"
print(f"gateway {GW}")
for name, fn in [("personal key", whoami), ("Evren key", evren_key), ("model listing", listing),
("chat", chat), ("guard", guard), ("embeddings", embeddings),
("rerank", rerank), ("decision", decision),
("wrong endpoint is refused", wrong_endpoint)]:
check(name, fn)
if os.environ.get("OCR_IMAGE"):
check("ocr", ocr)
if os.environ.get("AUDIO_FILE"):
check("speech to text", speech)
print("all passed" if not failed else f"{failed} failed")
sys.exit(1 if failed else 0)
evren_smoke.py adıyla kaydedin, requests kütüphanesini kurun ve
python3 evren_smoke.py ile çalıştırın. Başarılı bir çalışma all passed ile biter.
Bir şey ters gittiğinde
| Gördüğünüz | Ne yapmalı |
|---|---|
| 503 “EV/…” is served with YOUR OWN Evren key and you have not registered one | Evren LLM anahtarınızı My variables sayfasına kaydedin (A1). |
| 503 … this request carries no user identity to look one up for | Bir ekip ya da servis anahtarı gönderdiniz. Kişisel anahtarınızı kullanın (A2). |
| 400 “qwen3-reranker-8b” is a rerank model — use POST /v1/rerank, not /v1/chat/completions | Mesajın adını verdiği uç noktayı çağırın. |
| 404 … does not serve /v1/rerank — it is served by Evren rerank models only | O türde bir EV/ modeli kullanın. |
| 400 field “image” is required … | OCR için "image": "data:image/png;base64,…" gönderin. |
| 400 a choice question takes ‘criteria’ … | Liste ya da nesne olarak criteria kullanın. |
| 400 Currently do not support verbose_json … | Konuşmadan metne için json, text, srt ya da vtt kullanın. |
finish_reason: "length" ile boş bir sohbet yanıtı |
Düşünen bir model max_tokens değerini düşünmeye harcadı. Değeri artırın ya da hiç vermeyin. |
| 401 invalid api key | Anahtar iptal edilmiş ya da yanlış yazılmış, ya da Evren anahtarınızın kendisini gönderdiniz. gpk_… anahtarınızı gönderin ya da &rotate=true ile yenisini üretin (A3). |
| 429 | Bir hız limiti. retry-after başlığındaki süre kadar bekleyin. |
Her çağrı, uç noktasıyla birlikte etkinlik sayfasında sizin adınızla görünür.