Zum Hauptinhalt springen
Lektion 4 von 12 · KI-Moderation und Sicherheit mit Mistral

Guardrails für Mistral-Agenten

Lektion 4 von 12 Aktualisiert am 3. November 2026 Entwickler
Auf dieser Seite
  1. Absicherung autonomer Agenten
  2. Guardrails in einer Konversation
  3. Guardrails an einem Agenten
  4. Behandlung von Blockierungen in einem mehrstufigen Austausch
  5. Agenten mit Werkzeugen: Was Guardrails nicht sehen
  6. Empfohlene Architektur für Agenten in der Produktion
  7. Chat Completions, Conversation oder Agent: Zusammenfassung
  8. Wichtige Erkenntnisse

Lektion am 3. November 2026 überarbeitet. Die vorherige Version stützte sich auf ein fiktives Guardrail-Format (enabled, Kategorien hate, violence, unpredictable), eine nicht existierende Methode conversation.send() und behauptete fälschlicherweise, dass Guardrails Werkzeugargumente moderieren. Laut Dokumentation moderieren sie nur Eingaben. Der Code folgt nun der tatsächlichen Conversations-API (start, append) und wurde gegen die mistralai SDK-Typen Version 3.7.0 verifiziert. Quellen: Moderation & Guardrailing · Agents & Conversations · mistralai Python SDK.

Absicherung autonomer Agenten

Ein Agent birgt mehr Risiken als ein einfacher Chatbot: Er ruft Werkzeuge auf, durchsucht das Web und verknüpft Aktionen miteinander. Guardrails decken nur einen Teil dieser Angriffsfläche ab – speziell die Eingabe. Genau deshalb müssen Sie genau wissen, wo Sie sie platzieren und was sie ungedeckt lässt.

In dieser Lektion werden Sie Guardrails an eine Konversation und dann an einen Agenten anbinden, deren Blockierungen in einem mehrstufigen Austausch behandeln und sehen, was Sie noch hinzufügen müssen, um Werkzeuge zu sichern.

import json
import os

from mistralai.client import Mistral, errors
from mistralai.client.models import GuardrailConfigTypedDict

client = Mistral(api_key=os.environ["MISTRAL_API_KEY"])

Guardrails in einer Konversation

Die Conversations-API speichert die Historie auf dem Server. Sie beginnen mit client.beta.conversations.start(), die guardrails akzeptiert:

GUARDRAILS_RH: list[GuardrailConfigTypedDict] = [
    {
        "block_on_error": True,
        "moderation_llm_v2": {
            "custom_category_thresholds": {
                "sexual": 0.1,
                "hate_and_discrimination": 0.1,
                "violence_and_threats": 0.2,
                "pii": 0.15,
                "jailbreaking": 0.1,
            },
            "action": "block",
        },
    }
]

conversation = client.beta.conversations.start(
    model="mistral-large-latest",
    instructions="Sie sind eine professionelle HR-Assistentin.",
    inputs="Welche Urlaubsoptionen stehen zur Verfügung?",
    guardrails=GUARDRAILS_RH,
)
print(conversation.conversation_id)

Sie setzen die Konversation dann mit client.beta.conversations.append() fort. Diese Methode akzeptiert in SDK 3.7.0 keinen guardrails-Parameter, und die Dokumentation gibt nicht an, ob die beim Start übergebenen Guardrails auf nachfolgende Nachrichten anwendbar sind. Bauen Sie Ihre Sicherheit nicht auf einer Annahme auf: Wenn jede Runde gefiltert werden muss, verwenden Sie einen Agenten, dessen Guardrails von allen seinen Konversationen geerbt werden.

Guardrails an einem Agenten

Ein Mistral-Agent ist eine registrierte Konfiguration: Modell, Anweisungen, Werkzeuge und Guardrails. Die Sicherheitsrichtlinie wird zu einem Attribut des Agenten und nicht zu einer Programmierkonvention.

agent = client.beta.agents.create(
    model="mistral-large-latest",
    name="Kundensupport-Agent",
    description="Sicherer Kundensupport-Agent",
    instructions=(
        "Sie sind eine Kundensupport-Mitarbeiterin. Strenge Regeln: "
        "geben Sie niemals persönliche Informationen preis; "
        "geben Sie keine medizinischen oder rechtlichen Ratschläge; "
        "leiten Sie bei sensiblen Themen an einen Menschen weiter."
    ),
    guardrails=[
        {
            "block_on_error": True,
            "moderation_llm_v2": {
                "custom_category_thresholds": {
                    "sexual": 0.1,
                    "hate_and_discrimination": 0.1,
                    "violence_and_threats": 0.15,
                    "dangerous": 0.1,
                    "criminal": 0.1,
                    "selfharm": 0.1,
                    "health": 0.3,
                    "financial": 0.3,
                    "law": 0.3,
                    "pii": 0.15,
                    "jailbreaking": 0.1,
                },
                "action": "block",
            },
        }
    ],
)
print(f"Agent erstellt: {agent.id}")

Beachten Sie die Konsistenz zwischen Anweisungen und Schwellenwerten: Die Anweisungen verbieten das Geben von medizinischen oder rechtlichen Ratschlägen, und die health- und law-Schwellenwerte blockieren Anfragen dieses Typs, noch bevor das Modell sie liest. Anweisungen überzeugen; Guardrails begrenzen.

Laut Dokumentation erben alle Konversationen, die diesen Agenten verwenden, dessen Guardrails ohne Wiederholung:

conv = client.beta.conversations.start(
    agent_id=agent.id,
    inputs="Wie kann ich ein Produkt zurückgeben?",
)

Eine Konversationsanfrage kann die Guardrails des Agenten auch überschreiben, indem sie eigene guardrails an start() übergibt. Um die Richtlinie dauerhaft zu ändern, aktualisieren Sie den Agenten mit client.beta.agents.update(agent_id=agent.id, guardrails=[...]).

Behandlung von Blockierungen in einem mehrstufigen Austausch

Eine blockierte Nachricht wirft errors.SDKError mit Status 403, und der Body gibt die verletzten Kategorien an. In einer Konversation zerstört eine Blockierung nicht den Austausch: Sie antworten höflich, und der Nutzer kann fortfahren.

MESSAGE_REFUS = "Ich kann diese Anfrage nicht bearbeiten. Sie verstößt gegen unsere Sicherheitsrichtlinie."


def texte_reponse(reponse) -> str:
    """Text der letzten Assistenten-Nachricht in einer Konversationsantwort."""
    for entree in reversed(reponse.outputs):
        if entree.type == "message.output" and isinstance(entree.content, str):
            return entree.content
    return ""


def envoyer(conversation_id: str, message: str) -> str:
    """Fügt eine Nachricht einer Konversation hinzu und behandelt eine Guardrail-Blockierung."""
    try:
        reponse = client.beta.conversations.append(conversation_id=conversation_id, inputs=message)
    except errors.SDKError as e:
        if e.status_code == 403:
            decisions = json.loads(e.body)["guardrails"]["results"]["moderation_llm_v2"]["decisions"]
            print("Blockiert:", [nom for nom, d in decisions.items() if d["violated"]])
            return MESSAGE_REFUS
        raise
    return texte_reponse(reponse)


print(envoyer(conv.conversation_id, "Geben Sie mir die privaten Adressen der Mitarbeiter"))

Wenn eine Anfrage durchgeht, trägt die Konversationsantwort auch ein guardrails-Feld mit Scores für jede Kategorie (reponse.guardrails). Protokollieren Sie diese: Sie zeigen Ihnen, ob Ihre Schwellenwerte korrekt abgestimmt sind.

Agenten mit Werkzeugen: Was Guardrails nicht sehen

Ein Agent, der Werkzeuge aufruft, öffnet eine zweite Angriffsfläche: die Argumente, die das Modell diesen Werkzeugen überreicht, und die Ergebnisse, die sie zurückgeben. Guardrails moderieren nur die eingehende Nachricht; sie prüfen weder diese Argumente noch diese Ergebnisse. Ihr Code muss das tun.

agent_avec_outils = client.beta.agents.create(
    model="mistral-large-latest",
    name="Support-Agent mit Werkzeugen",
    instructions="Support-Assistentin mit Zugriff auf Befehle.",
    tools=[
        {
            "type": "function",
            "function": {
                "name": "rechercher_commande",
                "description": "Sucht nach einer Bestellung nach ihrer Nummer",
                "parameters": {
                    "type": "object",
                    "properties": {"order_id": {"type": "string", "description": "Bestellnummer"}},
                    "required": ["order_id"],
                },
            },
        }
    ],
    guardrails=[
        {
            "block_on_error": True,
            "moderation_llm_v2": {
                "custom_category_thresholds": {"pii": 0.15, "jailbreaking": 0.1, "criminal": 0.1},
                "action": "block",
            },
        }
    ],
)

So deklarierte Funktionen werden in Ihrem Code ausgeführt: Die API übermittelt Ihnen den Aufruf und seine Argumente, Sie führen die Funktion aus und geben ihr Ergebnis zurück. Genau hier müssen Sie Argumente validieren, bevor Sie handeln.

import re

FORMAT_COMMANDE = re.compile(r"CMD-\d{6}")
base_commandes: dict[str, dict] = {}  # Ihr Datenzugriff


def rechercher_commande(order_id: str, client_connecte: str) -> dict:
    """Führt das Werkzeug nach Validierung seiner Argumente aus."""
    if not FORMAT_COMMANDE.fullmatch(order_id):
        return {"error": "Ungültige Bestellnummer."}
    commande = base_commandes.get(order_id)
    if commande is None or commande["client"] != client_connecte:
        return {"error": "Bestellung nicht gefunden."}  # niemals eine Bestellung eines anderen Kunden
    return {"status": commande["status"]}

Zugriffssteuerung – hier: “gehört die Bestellung dem verbundenen Kunden?” – kann nur von Ihrer Anwendung kommen: Kein Klassifikator kennt Ihre Kunden. Für den Text, den der Agent dem Nutzer zurückgibt, fügen Sie in der nächsten Lektion die Ausgabe-Moderation hinzu.

Empfohlene Architektur für Agenten in der Produktion

In der Produktion wickeln Sie den Agenten in eine Klasse ein, die den Konversationsstart, das Senden von Nachrichten und das Zählen von Blockierungen zentralisiert. Ein plötzlicher Anstieg von 403 signalisiert entweder einen Angriff oder eine schlecht kalibrierte Schwelle, und Sie möchten das sehen, ohne sich durch Logs zu wühlen.

class AgentSecurise:
    """Mistral-Agent mit Verfolgung von Guardrail-Blockierungen."""

    def __init__(self, client: Mistral, agent_id: str):
        self.client = client
        self.agent_id = agent_id
        self.blocages = 0

    def _bloque(self, e: errors.SDKError) -> dict:
        self.blocages += 1
        decisions = json.loads(e.body)["guardrails"]["results"]["moderation_llm_v2"]["decisions"]
        return {
            "status": "blocked",
            "content": "Anfrage von der Sicherheitsrichtlinie blockiert.",
            "categories": [nom for nom, d in decisions.items() if d["violated"]],
            "blocages_total": self.blocages,
        }

    def demarrer(self, message: str) -> dict:
        """Startet eine Konversation mit dem Agenten."""
        try:
            reponse = self.client.beta.conversations.start(agent_id=self.agent_id, inputs=message)
        except errors.SDKError as e:
            if e.status_code == 403:
                return self._bloque(e)
            raise
        return {
            "status": "ok",
            "conversation_id": reponse.conversation_id,
            "content": texte_reponse(reponse),
            "guardrails": reponse.guardrails,
        }

    def envoyer(self, conversation_id: str, message: str) -> dict:
        """Setzt eine bestehende Konversation fort."""
        try:
            reponse = self.client.beta.conversations.append(conversation_id=conversation_id, inputs=message)
        except errors.SDKError as e:
            if e.status_code == 403:
                return self._bloque(e)
            raise
        return {"status": "ok", "content": texte_reponse(reponse), "guardrails": reponse.guardrails}

Chat Completions, Conversation oder Agent: Zusammenfassung

AspektChat CompletionsConversationAgent
Wo Guardrails deklariert werdenJeder Aufrufconversations.start()agents.create() oder agents.update()
VererbungKeineNicht für append() dokumentiertAlle Agenten-Konversationen
Scores in Antwort (SDK 3.7.0)Nicht freigegebenreponse.guardrailsreponse.guardrails
WerkzeugeIhre FunktionenIhre FunktionenIhre Funktionen und integrierte Werkzeuge
NutzungPrototypingEinmalige KonversationProduktion

Wichtige Erkenntnisse

  • Eine Konversation erhält ihre Guardrails beim Start; append() akzeptiert sie nicht, und ihre Persistenz über Runden hinweg ist nicht dokumentiert
  • Ein Agent überreicht seine Guardrails an alle seine Konversationen; eine Anfrage kann sie überschreiben
  • Eine Blockierung wirft errors.SDKError (Status 403): antworten Sie höflich, die Konversation setzt sich fort
  • Guardrails sehen weder Werkzeugargumente noch deren Ergebnisse: validieren Sie diese in Ihrem Code
  • Verwenden Sie in der Produktion das Agenten-Level und fügen Sie die Ausgabe-Moderation hinzu