Jev-API-Tutorial: Erste Schritte mit OpenRouter (Keys, Requests, Fehler, Retries)
·2 Min. Lesezeit
Jev-API-Tutorial: Erste Schritte mit OpenRouter
Dieses Jev-API-Tutorial führt Sie in rund fünf Minuten von null zur ersten typisierten Antwort. Jev wird über OpenRouter bereitgestellt — ein einziger API-Key deckt daher Jev zusammen mit anderen Modellen ab. Modell-ID: typesafe/jev-1.13.
TL;DR:
POST /api/v1/chat/completionsmitcontent = { state, questions }. Lesen Sieanswers[].selected,confidenceunddistribution. Führen Sie bei 429 einen Retry aus und validieren Sie die Fragen vor dem Senden.
1. OpenRouter-API-Key erstellen
- Erstellen Sie ein Konto bei OpenRouter.
- Generieren Sie einen API-Key (
sk-or-...). - Legen Sie ihn in einer Umgebungsvariable ab — niemals in Frontend-Code oder in einem Git-Repository.
export OPENROUTER_API_KEY="sk-or-..."
Für diesen Weg ist keine separate TypeSafe-Registrierung nötig.
2. Ihre erste Anfrage senden
curl https://openrouter.ai/api/v1/chat/completions \
-H "Authorization: Bearer $OPENROUTER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "typesafe/jev-1.13",
"messages": [{
"role": "user",
"content": {
"state": "Mir wurde für dieselbe Bestellung #4821 doppelt berechnet. Bitte beheben Sie das.",
"questions": [{
"type": "choice",
"text": "Welches Team soll diesen Fall bearbeiten?",
"options": ["billing", "tech_support", "sales"]
}]
}
}]
}'
Aufbau der Anfrage
| Feld | Typ | Hinweise |
|---|---|---|
state |
string | Unstrukturierter Text (E-Mail, Ticket, DOM-Snapshot …) |
questions[].type |
choice | score | noul |
Fragetyp |
questions[].text |
string | Die Entscheidung, formuliert für die Verzweigung |
questions[].options |
string[] | Für Choice/Score |
Sie können mehrere Fragen in einem einzigen Aufruf senden (z. B. Intent + Dringlichkeit).
3. Die typisierte Antwort auswerten
{
"answers": [{
"type": "choice",
"text": "Welches Team soll diesen Fall bearbeiten?",
"selected": "billing",
"confidence": 0.94,
"distribution": {
"billing": 0.94,
"tech_support": 0.04,
"sales": 0.02
}
}]
}
selected— die Top-Option (bei Score die gewichtete Auswahl).confidence— die Konfidenz, also die Wahrscheinlichkeit der Top-Option.distribution— die vollständige Wahrscheinlichkeitsverteilung.
type JevAnswer = {
type: 'choice' | 'score' | 'noul';
text: string;
selected?: string;
confidence: number;
distribution?: Record<string, number>;
};
Grundgerüst für einen TypeScript-Client
export async function runJev(state: string, questions: unknown[]) {
const res = await fetch('https://openrouter.ai/api/v1/chat/completions', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.OPENROUTER_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
model: 'typesafe/jev-1.13',
messages: [{ role: 'user', content: { state, questions } }],
}),
});
if (!res.ok) throw new Error(`Jev HTTP ${res.status}`);
const json = await res.json();
return json.choices?.[0]?.message?.content?.answers ?? json.answers ?? json;
}
Validieren Sie questions vor dem Senden lokal — gerade in leistungskritischen Pfaden (Hot Paths) ist ein fehlendes options eine häufige Ursache für 400-Fehler.
Fehlerbehandlung und Retries
| Status | Bedeutung | Maßnahme |
|---|---|---|
| 401 | Fehlender oder ungültiger Key | Fail fast; Umgebungsvariable prüfen |
| 400 | Ungültige Fragen-Payload | Anfrage korrigieren; nicht blind einen Retry ausführen |
| 429 | Rate Limit | Exponentielles Backoff + Jitter |
| 5xx | Upstream-Fehler | Retry mit Obergrenze; Fallback-Pfad |
| Timeout | Netzwerk / langsame Antwort | Budget von 2 s; auf Mensch oder Queue ausweichen |
async function withRetry<T>(fn: () => Promise<T>, tries = 3): Promise<T> {
let lastErr: unknown;
for (let i = 0; i < tries; i++) {
try { return await fn(); } catch (e) {
lastErr = e;
await new Promise((r) => setTimeout(r, 2 ** i * 200 + Math.random() * 100));
}
}
throw lastErr;
}
Sicherheitshinweise zur Jev-API
- Rufen Sie Jev von einem Server oder Worker aus auf, nicht aus dem Browser, wenn der Key geheim ist.
- Wenn der Aufruf aus dem Client unvermeidbar ist, verwenden Sie einen Proxy mit Authentifizierung und Rate Limits.
- Entfernen Sie personenbezogene Daten (PII) aus
state, sobald es die Richtlinie verlangt. - Setzen Sie ein Gesamt-Timeout (ca. 2 s), damit die Produkt-UX nicht hängen bleibt.
Logging & Observability
Protokollieren Sie pro Aufruf: Modell-ID, Latenz, selected, confidence, Hash der distribution, Ticket-/Nachrichten-ID.
Alarme für Fehlerquote und p95-Latenz einrichten; durchschnittliche Konfidenz und Entropie grafisch aufzeichnen, um Drift zu erkennen.
Nächste Schritte
- Probieren Sie Presets im Playground aus.
- Kopieren Sie Konfigurationen aus der Szenario-Bibliothek.
- Lesen Sie den Artikel zum Fragendesign, bevor Sie Labels skalieren.
FAQ
Gibt es ein offizielles SDK?
Es gibt Community-Wrapper für TypeScript/Python; der HTTP-Contract ist OpenRouter-kompatibel.
Kann ich streamen?
Die Klassifizierung gibt eine kleine, typisierte Payload zurück — Streaming lohnt sich selten.
Wie pinne ich eine Modellversion?
Verwenden Sie die vollständige Modell-ID typesafe/jev-1.13 und beachten Sie die Release Notes, bevor Sie die Version anheben.