Guardrails für Mistral-Agenten
Auf dieser Seite
- Absicherung autonomer Agenten
- Guardrails in einer Konversation
- Guardrails an einem Agenten
- Behandlung von Blockierungen in einem mehrstufigen Austausch
- Agenten mit Werkzeugen: Was Guardrails nicht sehen
- Empfohlene Architektur für Agenten in der Produktion
- Chat Completions, Conversation oder Agent: Zusammenfassung
- Wichtige Erkenntnisse
Lektion am 3. November 2026 überarbeitet. Die vorherige Version stützte sich auf ein fiktives Guardrail-Format (
enabled, Kategorienhate,violence,unpredictable), eine nicht existierende Methodeconversation.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 diemistralaiSDK-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
| Aspekt | Chat Completions | Conversation | Agent |
|---|---|---|---|
| Wo Guardrails deklariert werden | Jeder Aufruf | conversations.start() | agents.create() oder agents.update() |
| Vererbung | Keine | Nicht für append() dokumentiert | Alle Agenten-Konversationen |
| Scores in Antwort (SDK 3.7.0) | Nicht freigegeben | reponse.guardrails | reponse.guardrails |
| Werkzeuge | Ihre Funktionen | Ihre Funktionen | Ihre Funktionen und integrierte Werkzeuge |
| Nutzung | Prototyping | Einmalige Konversation | Produktion |
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(Status403): 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