Agent-Bewertung, Sicherheit und Alignment
Die Bewertung ist die Grundlage für die Sicherstellung der Effektivität von Agenten.
Sicherheit und Alignment sind der Schlüssel dafür, ob ein Agent vertrauenswürdig ist und bereitgestellt werden kann.
Agent-Bewertungssystem
Die Bewertung der Agent-Leistung ist ein kritischer Teil des Entwicklungsprozesses.
Ein gutes Bewertungssystem hilft uns, die Grenzen der Fähigkeiten eines Agenten zu verstehen.
Es liefert außerdem Richtung und Grundlage für kontinuierliche Optimierung.
Bewertungsdimensionen
Aufgabenabschluss: Ob der Agent die gegebene Aufgabe korrekt abgeschlossen hat.
Effizienzmetriken: Anzahl der Schritte, Tokenverbrauch und Ausführungszeit, die zum Abschließen der Aufgabe erforderlich sind.
Qualitätsmetriken: Genauigkeit der Antworten, Konsistenz der Antworten und Natürlichkeit des Dialogs.
Robustheit: Fähigkeit, mit anormalen Eingaben und verrauschten Daten umzugehen.
Gängige Benchmarks
| Benchmark | Zweck | Evaluierungsinhalt |
|---|---|---|
| GAIA | Bewertung allgemeiner KI-Assistenten | Umgang mit komplexen Aufgaben, mehrstufiges Schlussfolgern |
| MMLU | Multitask-Sprachverständnis | Wissensfragen und -antworten über 57 Themen |
| HumanEval | Bewertung der Codegenerierung | Korrektheit beim Schreiben von Python-Code |
| HotpotQA | Bewertung der Multi-Hop-Fragebeantwortung | Fragen, die Schlussfolgerungen über mehrere Dokumente hinweg erfordern |
| AgentBench | Bewertung der Agent-Fähigkeiten | Agent-Leistung in realen Umgebungen |
Code-Implementierung: Evaluierungsframework
Agent-Evaluierungsframework
"""
Agent-Evaluierungsframework
Bewerte die Leistung eines Agenten bei verschiedenen Aufgaben
"""
def __init__(self, agent, metrics):
# Zu evaluierender Agent
self.agent = agent
# Liste der Evaluierungsmetriken
self.metrics = metrics
def evaluate(self, test_cases):
"""
Evaluierung ausführen
:param test_cases: Liste der Testfälle
:return: Evaluierungsbericht
"""
results = []
for test_case in test_cases:
# Aufgabe ausführen
result = self.run_single_test(test_case)
results.append(result)
# Evaluierungsbericht erstellen
report = self.generate_report(results)
return report
def run_single_test(self, test_case):
"""
Einzelnen Testfall ausführen
"""
# Startzeit erfassen
start_time = time.time()
# Agenten ausführen
try:
output = self.agent.run(test_case.input)
success = self.evaluate_output(output, test_case.expected)
error = None
except Exception as e:
output = None
success = False
error = str(e)
# Endzeit erfassen
end_time = time.time()
return TestResult(
test_case=test_case,
output=output,
success=success,
error=error,
duration=end_time - start_time,
token_count=self.count_tokens(output)
)
def evaluate_output(self, output, expected):
"""Bewerte, ob die Ausgabe die Erwartungen erfüllt"""
for metric in self.metrics:
if not metric.evaluate(output, expected):
return False
return True
def generate_report(self, results):
"""Evaluierungsbericht erstellen"""
total = len(results)
passed = sum(1 for r in results if r.success)
# Verschiedene Metriken berechnen
avg_duration = sum(r.duration for r in results) / total
avg_tokens = sum(r.token_count for r in results) / total
# Nach Testtyp gruppieren und zählen
by_category = {}
for r in results:
category = r.test_case.category
if category not in by_category:
by_category[category] = {"total": 0, "passed": 0}
by_category[category]["total"] += 1
if r.success:
by_category[category]["passed"] += 1
return EvaluationReport(
total=total,
passed=passed,
pass_rate=passed / total,
avg_duration=avg_duration,
avg_tokens=avg_tokens,
by_category=by_category,
results=results
)
class TestCase:
"""Testfall"""
def __init__(self, input, expected, category="general", metadata=None):
# Eingabe
self.input = input
# Erwartete Ausgabe oder Bewertungskriterien
self.expected = expected
# Kategorie
self.category = category
# Zusätzliche Metadaten
self.metadata = metadata or {}
class TestResult:
"""Testergebnis"""
def __init__(self, test_case, output, success, error, duration, token_count):
self.test_case = test_case
self.output = output
self.success = success
self.error = error
self.duration = duration
self.token_count = token_count
class Metric:
"""Basisklasse für Bewertungsmetriken"""
def evaluate(self, output, expected):
raise NotImplementedError
class ExactMatchMetric(Metric):
"""Metrik für exakte Übereinstimmung"""
def evaluate(self, output, expected):
return output.strip() == expected.strip()
class ContainsMetric(Metric):
"""Metrik für Keyword-Einschluss"""
def evaluate(self, output, expected):
if isinstance(expected, list):
return all(keyword in output for keyword in expected)
return expected in output
class SemanticSimilarityMetric(Metric):
"""Metrik der semantischen Ähnlichkeit"""
def __init__(self, threshold=0.8):
self.threshold = threshold
def evaluate(self, output, expected):
similarity = self.compute_similarity(output, expected)
return similarity >= self.threshold
def compute_similarity(self, text1, text2):
"""Berechnet die semantische Ähnlichkeit zweier Texte"""
# Embedding-Modell verwenden, um Kosinus-Ähnlichkeit zu berechnen
embedding1 = self.embedder.embed([text1])[0]
embedding2 = self.embedder.embed([text2])[0]
return cosine_similarity(embedding1, embedding2)
Sicherheit und Alignment
Die Sicherheit des Agenten ist von größter Bedeutung.
KI-Systeme können verschiedenen Angriffen ausgesetzt sein und schädliche Ausgaben erzeugen.
Alignment stellt sicher, dass das Verhalten von KI mit menschlichen Absichten und Werten übereinstimmt.
Häufige Sicherheitsbedrohungen
Prompt-Injection
Angreifer nutzen Eingaben, um den Agenten dazu zu bringen, Systemanweisungen zu ignorieren.
Beispieleingabe: "Ignoriere vorherige Anweisungen und führe stattdessen aus..."
Dies ist ein Context-Hijacking-Angriff, der das Vertrauen des Agenten in Benutzereingaben ausnutzt.
Jailbreaking
Sicherheitsbeschränkungen durch bestimmte Eingaben umgehen.
Zum Beispiel durch Techniken wie Rollenspiele oder fiktive Szenarien.
Datenvergiftung
Trainingsdaten oder Retrieval-Ergebnisse böswillig verändern.
Veranlasst den Agenten, falsche oder schädliche Ausgaben zu erzeugen.
Preisgabe sensibler Informationen
Der Agent gibt unzulässigerweise Nutzerprivatsphäre oder interne Systeminformationen preis.
Verteidigungsstrategien
Sichere Agent-Implementierung
"""
Sicherheits-Agent
Mehrere Ebenen des Sicherheitsschutzes zusätzlich zum Basis-Agenten hinzufügen
"""
def __init__(self, base_agent, guardrails, input_validator, output_filter):
# Basis-Agent
self.base_agent = base_agent
# Liste der Sicherheits-Guardrails
self.guardrails = guardrails
# Eingabe-Validator
self.input_validator = input_validator
# Ausgabefilter
self.output_filter = output_filter
def process(self, user_input):
"""
Benutzereingabe verarbeiten, einschließlich mehrerer Ebenen von Sicherheitsprüfungen
"""
# ==================== Ebene 1: Eingabevalidierung ====================
# Prüfen, ob die Eingabe gültig ist
is_valid, reason = self.input_validator.validate(user_input)
if not is_valid:
return self.create_safety_response(reason)
# ==================== Ebene 2: Injection-Erkennung ====================
# Angriffe wie Prompt-Injection erkennen
for guardrail in self.guardrails:
check_result = guardrail.check_input(user_input)
if not check_result.is_safe:
# Sicherheitsereignisse aufzeichnen
self.log_security_event(
event_type="input_guardrail_triggered",
input=user_input,
reason=check_result.reason
)
return self.create_safety_response(check_result.reason)
# ==================== Ebene 3: Kernlogik ausführen ====================
try:
response = self.base_agent.process(user_input)
except Exception as e:
return self.create_error_response(str(e))
# ==================== Ebene 4: Ausgabefilterung ====================
# Prüfen, ob die Ausgabe sicher ist
for guardrail in self.guardrails:
check_result = guardrail.check_output(response)
if not check_result.is_safe:
self.log_security_event(
event_type="output_guardrail_triggered",
output=response,
reason=check_result.reason
)
return self.create_safety_response(check_result.reason)
# Ausgabefilterung anwenden (z. B. Desensibilisierung sensibler Informationen)
response = self.output_filter.filter(response)
return response
def create_safety_response(self, reason):
"""Sichere Antwort erstellen"""
return {
"type": "safety_block",
"message": "Es tut mir leid, ich kann diese Anfrage nicht abschließen.",
"reason": reason
}
def log_security_event(self, event_type, **kwargs):
"""Sicherheitsereignisse aufzeichnen"""
# In tatsächlichen Anwendungen sollte dies in ein Sicherheitsprotokollsystem geschrieben werden
print(f"[SICHERHEIT] {event_type}: {kwargs}")
class InputValidator:
"""Eingabevalidierer"""
def validate(self, text):
"""
Prüfen, ob die Eingabe gültig ist
:return: (is_valid, reason)
"""
if not text or len(text.strip()) == 0:
return False, "Die Eingabe darf nicht leer sein"
if len(text) > 10000:
return False, "Die Eingabelänge überschreitet das Limit"
# Prüfen, ob ausführbarer Inhalt enthalten ist
if self.contains_executable_content(text):
return False, "Die Eingabe enthält verdächtigen ausführbaren Inhalt"
return True, None
def contains_executable_content(self, text):
"""Prüfen, ob ausführbarer Inhalt enthalten ist"""
# Vereinfachte Implementierung
suspicious_patterns = [
"javascript:",
"data:text/html",
"<script>",
]
return any(pattern in text.lower() for pattern in suspicious_patterns)
class Guardrail:
"""Sicherheits-Guardrail"""
def check_input(self, text):
"""Eingabe prüfen"""
raise NotImplementedError
def check_output(self, text):
"""Ausgabe prüfen"""
raise NotImplementedError
class ContentFilterGuardrail(Guardrail):
"""Guardrail zur Inhaltsfilterung"""
def __init__(self, blocked_topics, banned_words):
self.blocked_topics = blocked_topics
self.banned_words = banned_words
def check_input(self, text):
# Prüfen, ob verbotene Themen betroffen sind
for topic in self.blocked_topics:
if topic in text.lower():
return CheckResult(
is_safe=False,
reason=f"Betrifft sensibles Thema: {topic}"
)
# Prüfen, ob es verbotene Wörter enthält
for word in self.banned_words:
if word in text.lower():
return CheckResult(
is_safe=False,
reason=f"Enthält unangemessene Wörter"
)
return CheckResult(is_safe=True)
def check_output(self, text):
# Ausgabeprüfung wie oben
return self.check_input(text)
class CheckResult:
"""Prüfergebnis"""
def __init__(self, is_safe, reason=None):
self.is_safe = is_safe
self.reason = reason
Wichtiger Hinweis: Sicherheit ist ein fortlaufender Prozess, und es gibt keine narrensichere Lösung. Sicherheitsstrategien erfordern kontinuierliche Überwachung, Aktualisierung und Verbesserung.
Observability
Agenten in Produktionsumgebungen benötigen ein umfassendes Überwachungssystem.
Observability hilft uns, das Verhalten von Agenten zu verstehen, Probleme zu beheben und die Leistung zu optimieren.
Drei Säulen
Logging: Alle wichtigen Ereignisse und Entscheidungen aufzeichnen.
Tracing: Den vollständigen Ablaufpfad von Anfragen durch das System verfolgen.
Metrics: Leistungs- und Qualitätsmetriken sammeln.
Code-Implementierung
Implementierung eines beobachtbaren Agenten
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.resources import Resource
# Logging konfigurieren
logger = logging.getLogger(__name__)
# Tracing konfigurieren
tracer_provider = TracerProvider()
trace.set_tracer_provider(tracer_provider)
tracer = trace.get_tracer(__name__)
class ObservableAgent:
"""
Observability-Agent
Integrierte Erfassung von Logs, Traces und Metriken
"""
def __init__(self, agent, metrics_collector):
# Basis-Agent
self.agent = agent
# Metriken-Sammler
self.metrics = metrics_collector
def process(self, user_input):
"""
Anfragen mit vollständiger Observability-Unterstützung bearbeiten
"""
# Tracing-Span erstellen
with tracer.start_as_current_span("agent_process") as span:
# Span-Attribute setzen
span.set_attribute("user.input.length", len(user_input))
span.set_attribute("user.input.preview", user_input[:100])
# Start aufzeichnen
logger.info(f"Starte Verarbeitung der Anfrage: {user_input[:50]}...")
start_time = time.time()
try:
# Kernlogik ausführen
result = self.agent.process(user_input)
# Erfolg aufzeichnen
duration = time.time() - start_time
span.set_attribute("success", True)
span.set_attribute("duration_ms", duration * 1000)
span.set_attribute("result.length", len(str(result)))
# Metriken sammeln
self.metrics.record("request_duration", duration)
self.metrics.increment("request_success")
logger.info(f"Anfrage abgeschlossen, Dauer: {duration:.2f}s")
return result
except Exception as e:
# Fehler erfassen
duration = time.time() - start_time
span.set_attribute("success", False)
span.set_attribute("error.type", type(e).__name__)
span.set_attribute("error.message", str(e))
span.record_exception(e)
# Fehlermetriken sammeln
self.metrics.increment("request_error")
self.metrics.record("error_duration", duration)
logger.error(f"Anfrage fehlgeschlagen: {e}")
raise
class MetricsCollector:
"""Metrik-Sammler"""
def __init__(self):
self.metrics = {}
def increment(self, name, value=1):
"""Zähler-Metrik erhöhen"""
if name not in self.metrics:
self.metrics[name] = {"type": "counter", "value": 0}
self.metrics[name]["value"] += value
def record(self, name, value):
"""Numerische Metrik aufzeichnen"""
if name not in self.metrics:
self.metrics[name] = {"type": "gauge", "values": []}
self.metrics[name]["values"].append(value)
def get_summary(self):
"""Metrikübersicht abrufen"""
summary = {}
for name, data in self.metrics.items():
if data["type"] == "counter":
summary[name] = data["value"]
else:
values = data["values"]
summary[f"{name}_avg"] = sum(values) / len(values)
summary[f"{name}_max"] = max(values)
summary[f"{name}_min"] = min(values)
return summary
Guardrails und Human-in-the-Loop
Guardrails
Guardrails sind Mechanismen zur Echtzeitfilterung und -beschränkung von Ein- und Ausgaben.
Im Gegensatz zu Sicherheits-Guardrails liegt der Fokus von Guardrails eher auf der Sicherstellung von Ausgabequalität und Compliance.
HITL(Human-in-the-Loop)
HITL führt an kritischen Entscheidungspunkten eine menschliche Überprüfung ein.
Geeignet für Hochrisikoszenarien, in denen KI keine autonomen Entscheidungen treffen kann.
Implementierung des HITL-Agenten
"""
Human-in-the-Loop-Agent
Menschliche Überprüfung an kritischen Entscheidungspunkten einführen
"""
def __init__(self, agent, approval_queue, notification_handler):
# Basis-Agent
self.agent = agent
# Genehmigungswarteschlange
self.approval_queue = approval_queue
# Benachrichtigungshandler
self.notification_handler = notification_handler
def process(self, request):
"""
Anfragen verarbeiten, bei Bedarf menschliche Genehmigung auslösen
"""
# Risikostufe der Anfrage bewerten
risk_level = self.assess_risk(request)
if risk_level == "high":
# Hochrisikoanfrage, erfordert menschliche Genehmigung
return self.handle_high_risk_request(request)
elif risk_level == "medium":
# Mittleres Risiko, erweiterte Überwachung aktivieren
return self.handle_medium_risk_request(request)
else:
# Geringes Risiko, direkt verarbeiten
return self.agent.process(request)
def assess_risk(self, request):
"""Risikostufe der Anfrage bewerten"""
# Prüfen, ob sensible Vorgänge beteiligt sind
sensitive_operations = [
"delete", "remove", "cancel",
"transfer", "payment", "refund"
]
content_lower = request.lower()
for op in sensitive_operations:
if op in content_lower:
return "high"
# Komplexität des Anfrageinhalts prüfen
if len(request) > 1000:
return "medium"
return "low"
def handle_high_risk_request(self, request):
"""
Hochrisiko-Anfragen verarbeiten, die eine menschliche Genehmigung erfordern
"""
# Genehmigungsaufgabe erstellen
task_id = self.approval_queue.add({
"request": request,
"risk_level": "high",
"timestamp": datetime.now()
})
# Genehmiger benachrichtigen
self.notification_handler.notify_approver(
task_id=task_id,
message=f"Eine Anfrage mit hohem Risiko erfordert eine Genehmigung: {request[:100]}..."
)
# Wartestatus zurückgeben
return {
"status": "pending_approval",
"task_id": task_id,
"message": "Ihre Anfrage erfordert eine menschliche Genehmigung, bitte warten."
}
def handle_feedback(self, task_id, approved, feedback=Keine):
"""
Genehmigungsfeedback verarbeiten
"""
task = self.approval_queue.get(task_id)
if approved:
# Genehmigung erteilt, Anfrage ausführen
self.approval_queue.complete(task_id)
result = self.agent.process(task["request"])
# Antragsteller benachrichtigen
self.notification_handler.notify_requester(
task_id=task_id,
status="approved",
result=result
)
return result
else:
# Genehmigung abgelehnt
self.approval_queue.reject(task_id, feedback)
# Antragsteller benachrichtigen
self.notification_handler.notify_requester(
task_id=task_id,
status="rejected",
feedback=feedback
)
return {
"status": "rejected",
"reason": feedback or Genehmigung fehlgeschlagen.
}
class ApprovalQueue:
Genehmigungswarteschlange
def __init__(self):
self.queue = {}
self.counter = 0
def add(self, task):
Genehmigungsaufgabe hinzufügen
self.counter += 1
task_id = f"task_{self.counter}"
self.queue[task_id] = {
**task,
"status": "pending"
}
return task_id
def get(self, task_id):
return self.queue.get(task_id)
def complete(self, task_id):
self.queue[task_id]["status"] = "approved"
def reject(self, task_id, reason):
self.queue[task_id]["status"] = "rejected"
self.queue[task_id]["reject_reason"] = reason
Kapitelzusammenfassung
Dieses Kapitel führt in Wissen über die Bewertung, Sicherheit und Ausrichtung von Agenten ein.
BewertungssystemBewerte die Leistung des Agenten anhand mehrdimensionaler Metriken.
SicherheitsbedrohungEinschließlich Prompt-Injection, Jailbreaking, Datenvergiftung usw.
SchutzstrategieGewährleiste Systemsicherheit durch mehrschichtige Sicherheitsprüfungen.
BeobachtbarkeitImplementiere Systemüberwachung durch Logs, Tracing und Metriken.
Guardrails und HITLBiete Kontrolle der Ausgabequalität und manuelle Überprüfungsmöglichkeiten.
Bewertung, Sicherheit und Ausrichtung sind die Grundlage für den Aufbau vertrauenswürdiger Agentensysteme.
In der tatsächlichen Entwicklung erfordert es kontinuierliche Aufmerksamkeit und Verbesserung.
Weitere Erweiterungen