Zum Hauptinhalt springen
Middleware ist das Muster, jede KI-Antwort abzufangen und einen RAIL-Score anzuhängen, bevor sie den Rest Ihrer Anwendung erreicht. Sie ersetzen Ihren Modell-Client durch einen RAIL-Wrapper. Der Wrapper ruft das Modell auf, bewertet die Antwort und gibt sowohl den Inhalt als auch die Scores in einem einzigen Objekt zurück.

Das Problem, das es löst

Ohne Middleware bedeutet das Hinzufügen von Prüfungen für verantwortungsvolle KI zu jedem Modellaufruf, dass Sie Bewertungscode an jeder Stelle schreiben, an der Sie das Modell aufrufen, Logik duplizieren, Abdeckungslücken riskieren und Ihren Anwendungscode überfrachten:
# Eval code scattered everywhere
async def get_response(user_message):
    response = await openai_client.chat.completions.create(
        model="gpt-4o", messages=[{"role": "user", "content": user_message}]
    )
    content = response.choices[0].message.content

    # Must remember to eval in every function
    score = rail_client.eval(content=content, mode="basic")
    if score.rail_score.score < 7.0:
        raise ValueError("Response below quality threshold")

    return content

Funktionsweise

Wenn Sie eine Methode auf dem RAIL-Wrapper aufrufen, geschehen drei Dinge transparent:
  1. Ihre Nachrichten werden als normaler API-Aufruf an die zugrunde liegende Modell-API weitergeleitet.
  2. Die Antwort des Modells wird im konfigurierten Modus an den RAIL-Bewertungs-Endpunkt übermittelt.
  3. Ein umhülltes Antwortobjekt wird zurückgegeben, das den ursprünglichen Inhalt, den RAIL-Score, die Scores pro Dimension und einen threshold_met-Boolean enthält, alles in einem einzigen Rückgabewert.

Unterstützte Anbieter

WrapperUmhülltPythonJavaScript
RAILOpenAIOpenAI Chat CompletionsJaJa
RAILGeminiGoogle GeminiJaJa
RAILAnthropicAnthropic ClaudeJaJa
RAILLangChainJedes LangChain-ModellJa
Custom wrapperJedes HTTP-basierte ModellJaJa

Beobachtungsmodus vs. Durchsetzungsmodus

Bewerten Sie jede Antwort, blockieren Sie nie. Verwenden Sie dies, um Qualität zu messen, ohne den Antwortfluss zu unterbrechen.
client = RAILOpenAI(
    openai_api_key="...",
    rail_api_key="...",
    eval_mode="basic",
    # No threshold — always returns response
)

response = await client.chat(messages=[...])
print(response.content)        # The model's response
print(response.rail_score)     # RAIL score (always present)
print(response.threshold_met)  # None — no threshold configured

Eigene Middleware schreiben

Wenn Sie einen Modellanbieter ohne integrierten Wrapper verwenden, bauen Sie Ihre eigene Middleware mit dem zentralen eval()-Aufruf:
from rail_score_sdk import RailScoreClient

rail = RailScoreClient(api_key="...")

async def rail_middleware(llm_call, messages, threshold=7.0):
    """Generic RAIL middleware for any async LLM call."""
    content = await llm_call(messages)

    result = rail.eval(content=content, mode="basic")

    if result.rail_score.score < threshold:
        raise ValueError(
            f"Response scored {result.rail_score.score:.1f} — below threshold {threshold}. "
            f"Failed: {[d for d, s in result.dimension_scores.items() if s.score < threshold]}"
        )

    return content, result

# Use with any LLM:
content, score = await rail_middleware(my_llm_call, messages, threshold=7.5)

Wie geht es weiter

Konzepte: Richtlinien-Engine

Deklarative Regeln, um über eine Session hinweg auf Scores zu reagieren.

Python: Integrationen

Vollständige Dokumentation und Optionen der Anbieter-Wrapper.

JavaScript: Anbieter

TypeScript-Wrapper für OpenAI, Gemini, Anthropic.

Python: Middleware SDK

RAILMiddleware - jede Modellfunktion umhüllen.