Best Practices und Zusammenfassung
Auf dieser Seite
Kurszusammenfassung
Sie haben den gesamten Spektrum der von der Mistral-API angebotenen Mechanismen für strukturierte Ausgaben erkundet. Diese abschließende Lektion fasst zusammen, was im täglichen Arbeitsalltag den Unterschied macht: Wie Sie zwischen den beiden Ansätzen wählen, welche Einstellungen unverhandelbar sind, die häufigsten Fallstricke und was Sie im Produktivbetrieb überwachen müssen.
Ihre Ansatzwahl
Vier Fragen reichen aus, um in dieser Reihenfolge zu entscheiden. Besitzen Sie ein definiertes Ausgabe-Schema? Wenn die Antwort nein lautet, bleiben Sie bei JSON Mode: Sie befinden sich im Forschungs- oder Prototypenmodus, und die Festlegung eines Datenmodells wäre hier vorzeitig. Wenn ja, gehen Sie zur nächsten Frage.
Arbeiten Sie in Python oder TypeScript? Falls ja, sind Custom Structured Outputs für Sie mit Pydantic oder Zod bereit. Falls nein, bleibt Ihnen der Weg über JSON Mode mit manueller Validierung.
Befinden Sie sich im Produktivbetrieb? Wenn ja, sind Custom Structured Outputs zwingend erforderlich, immer. Ansonsten ist JSON Mode für das Prototyping mehr als ausreichend.
Ändert sich das Schema häufig? Ein noch sich entwickelndes Schema macht JSON Mode zunächst praktischer, bis sich die Anforderungen stabilisieren; ein feststehendes Schema spricht für Custom Structured Outputs und die Zuverlässigkeit, die sie bieten.
Die zehn goldenen Regeln
Die ersten fünf betreffen, wie Sie Ihre Aufrufe formulieren. Setzen Sie in der Produktion immer temperature=0: Temperaturschwankungen sind der Feind der Zuverlässigkeit, und die Extraktion benötigt keine Kreativität.
# Produktion: deterministisch
response = client.chat.parse(
model="mistral-large-latest",
messages=messages,
response_format=MonSchema,
temperature=0 # Reproduzierbarkeit
)
Prüfen Sie immer finish_reason. Dies ist der einzige Indikator, der Sie vor einer abgebrochenen Antwort warnt, bevor Sie diese verwenden.
if response.choices[0].finish_reason != "stop":
# Antwort ist abgeschnitten — erhöhen Sie max_tokens
raise ValueError(f"Unvollständige Antwort: {response.choices[0].finish_reason}")
Weisen Sie im JSON Mode das Modell im Prompt an. Der Parameter garantiert die Syntax, nicht die Struktur: Es liegt an Ihnen, die Schlüssel und ihre Typen zu benennen.
# JSON Mode — der Prompt MUSS die Struktur beschreiben
messages = [
{
"role": "system",
"content": "Geben Sie JSON mit den Schlüsseln zurück: name (string), age (number), city (string)."
},
{"role": "user", "content": text}
]
Dokumentieren Sie Ihre Felder im Custom Mode. Eine präzise Beschreibung ist wertvoller als ein langer Prompt und reist mit dem Schema in beiden Sprachen mit.
class Product(BaseModel):
name: str = Field(description="Kommerzieller Produktname")
price: float = Field(description="Preis in EUR ohne MwSt., auf 2 Dezimalstellen gerundet")
const ProductSchema = z.object({
name: z.string().describe("Kommerzieller Produktname"),
price: z.number().describe("Preis in EUR ohne MwSt., auf 2 Dezimalstellen gerundet"),
});
Trennen Sie Kontext von Inhalt. Anweisungen leben im System-Message, die zu verarbeitenden Daten im User-Message – niemals umgekehrt, sonst verwechselt das Modell die Anweisung mit dem Quelltext.
messages = [
{"role": "system", "content": "Sie sind ein Datenextraktor. [Formatanweisungen]"},
{"role": "user", "content": "[Text zur Verarbeitung — KEINE Formatanweisungen hier]"}
]
Die nächsten zwei Regeln betreffen Ihr Sicherheitsnetz. Implementieren Sie einen Retry-Mechanismus: niemals einen einzelnen Aufruf ohne Reserve machen; Retry mit Feedback ist das minimale Muster in der Produktion. Und validieren Sie über das Schema hinaus, da das Schema die Struktur garantiert, während die semantische Validierung – Grenzen, Konsistenz, Geschäftslogik – Ihre Verantwortung bleibt.
Die letzten drei betreffen die Orchestrierung. Wählen Sie das richtige Modell für den richtigen Anwendungsfall: mistral-large-latest für komplexe Aufgaben und mehrfeldige Extraktionen, mistral-small-latest für einfache Klassifizierungen und grundlegende Extraktionen, ministral-8b-latest für hohe Frequenz und minimale Latenz. Loggen Sie jeden Aufruf in der Produktion, indem Sie das verwendete Modell, die Dauer, finish_reason und das Ergebnis erfassen: Ohne Logs sind Sie blind. Schließlich optimieren Sie den Prompt nicht zu früh übermäßig – beginnen Sie einfach, messen Sie, iterieren Sie; eine vorzeitige Prompt-Optimierung ist ein häufiger Fallstrick, wohingegen das Schema und die Validierung die wirklichen Hebel sind.
Drei kostspielige Fallstricke
Der erste ist ein max_tokens-Wert, der zu niedrig ist. JSON wird bei langen Antworten abgeschnitten, und der Fehler zeigt sich oft erst bei großen Dokumenten, häufig nach dem Go-Live.
# Gefährlich — JSON wird bei langen Antworten abgeschnitten
response = client.chat.parse(
model="mistral-large-latest",
messages=messages,
response_format=MonSchema,
max_tokens=128 # Zu niedrig für ein komplexes Schema
)
Setzen Sie max_tokens basierend auf der erwarteten Größe Ihrer Ausgabe: Eine Rechnung mit 20 Zeilen benötigt mehr Tokens als eine einfache Klassifizierung.
Der zweite ist eine nicht-null Temperatur, die Ihre Ergebnisse für keinen Gewinn bei einer Extraktionsaufgabe nicht reproduzierbar macht.
# In der Produktion gefährlich — nicht reproduzierbare Ergebnisse
response = client.chat.parse(
...,
temperature=0.7 # Unnötige Variation für Extraktion
)
Der dritte ist die Reflex, ein einzelnes Modell zu verwenden. Nutzen Sie mistral-large nicht für alles: Eine binäre Klassifizierung erfordert nicht das leistungsstärkste Modell, und ministral-8b erledigt die Aufgabe 5-mal schneller und kostengünstiger.
Was Sie überwachen müssen
Vier Kennzahlen geben Auskunft über die Gesundheit Ihres Pipelines. Die Erfolgsrate misst den Prozentsatz der Aufrufe, die beim ersten Versuch ein gültiges Objekt zurückgeben; die Retry-Rate, den Prozentsatz der Aufrufe, die eine zweite Chance benötigten. P50/P95-Latenz gibt die Median-Antwortzeit und den 95. Perzentil an, was aussagekräftiger ist als der Durchschnitt. Die Kosten pro Extraktion, ausgedrückt in verbrauchten Tokens pro Aufruf, halten die Rechnung im Schach.
Bei diesen Kennzahlen halten einige Warnschwellen gut stand: Eine Erfolgsrate unter 95 % rechtfertigt eine gelbe Warnung, unter 85 % eine rote Warnung; eine P95-Latenz größer als 10 s erfordert eine Untersuchung; und ein offener Circuit Breaker ruft eine sofortige Warnung hervor.
Weiterführendes
Vier Richtungen erweitern diesen Kurs natürlich. Function Calling verwendet strukturierte Ausgaben, um Funktionsaufrufe in einem Agenten zu versorgen. Streaming ermöglicht es Ihnen, die strukturierte Ausgabe schrittweise zu empfangen, was bei langen Antworten wichtig ist. Fine-Tuning passt ein Mistral-Modell an, um die Extraktionsqualität auf Ihren spezifischen Daten zu verbessern. Evaluation besteht schließlich darin, ein automatisches Framework basierend auf einem Golden Dataset und Kennzahlen einzurichten – das zeigt Ihnen, ob eine Prompt-Änderung tatsächlich etwas verbessert.
Ein vollständiges Pipeline
Der folgende Code bringt die Kurspraktiken in einem einzigen Fluss zusammen: ein Schema, das Feld für Feld beschrieben wird, ein Validator, der ausserhalb der Grenzen liegende Scores ablehnt, ein Modell, das auf die Aufgabe zugeschnitten ist, temperature=0, ein explizites max_tokens, eine Überprüfung von finish_reason und Protokollierung für beide möglichen Ergebnisse.
from mistralai.client import Mistral
from pydantic import BaseModel, Field, field_validator
import logging
import time
logger = logging.getLogger("pipeline")
class CustomerFeedback(BaseModel):
sentiment: str = Field(description="positive, negative, or neutral")
score: float = Field(description="Score between -1.0 and 1.0")
category: str = Field(description="product, service, delivery, price, or other")
action_required: bool = Field(description="True if action is required")
summary: str = Field(description="One-sentence summary")
@field_validator("score")
@classmethod
def score_in_range(cls, v):
if not -1.0 <= v <= 1.0:
raise ValueError(f"Score out of bounds: {v}")
return v
def analyze_feedback(client: Mistral, text: str) -> CustomerFeedback:
start = time.time()
try:
response = client.chat.parse(
model="mistral-small-latest",
messages=[
{"role": "system", "content": "Analyze customer feedback."},
{"role": "user", "content": text}
],
response_format=CustomerFeedback,
temperature=0,
max_tokens=256
)
assert response.choices[0].finish_reason == "stop"
result = response.choices[0].message.parsed
logger.info(f"OK in {time.time()-start:.2f}s — {result.sentiment} ({result.score:+.1f})")
return result
except Exception as e:
logger.error(f"ERROR in {time.time()-start:.2f}s — {e}")
raise
Etwa dreißig Zeilen, und Sie haben eine Komponente, die sicher in die Mitte eines Systems eingefügt werden kann: genau das ermöglichen strukturierte Ausgaben.
Wichtige Erkenntnisse
- Verwenden Sie Custom Structured Outputs in der Produktion, JSON Mode für das Prototyping
temperature=0, die Prüfung vonfinish_reasonund Retry sind unverhandelbar- Wählen Sie das Modell basierend auf der Komplexität der Aufgabe und dem Budget
- Überwachen Sie Erfolgsrate, Latenz und Kosten
- Beginnen Sie einfach, messen Sie, optimieren Sie dann
Wissenstest
JSON Mode, Schemata, Retry: strukturierte Ausgabe unter Kontrolle?
1. JSON Mode vs Custom Structured Outputs: Was ist der Unterschied?
Antwort: JSON Mode garantiert syntaktisch gültiges JSON; Custom Structured Outputs erzwingen zusätzlich Ihr exaktes Schema – Felder, Typen, Struktur: den vollständigen Vertrag.
2. Was bietet client.chat.parse() mit Pydantic?
Antwort: Den kompletten Kreislauf: Das Pydantic-Schema deklariert die Struktur, die API begrenzt die Generierung, und die Antwort kommt bereits validiert und getypisiert als Python-Objekt an – keine manuelle Parsing-Notwendigkeit.
3. Und auf der TypeScript-Seite?
Antwort: Der gleiche Komfort mit Zod: Das Zod-Schema definiert und validiert die Struktur – eine einzige Quelle der Wahrheit für Generierung und Typisierung.
4. Was tun, wenn die Ausgabe das Schema nicht respektiert?
Antwort: Systematisch validieren und eine Retry-Strategie planen: Neu-Anfrage mit dem Fehler im Kontext oder abwärtskompatible Degradierung – niemals blindes Vertrauen in die Ausgabe.
5. Wann ist strukturierte Ausgabe unverzichtbar?
Antwort: Sobald ein Programm die Antwort ohne menschliche Prüfung konsumiert: Extraktion, Integrationen, Pipelines – das Format hört auf, eine Höflichkeit zu sein, und wird zur Schnittstelle.
Dezidiertes Schema, begrenzte Generierung, Ausgabe-Validierung: Die Triade, die KI in echte Software integrierbar macht.