Warum das Testen von Agenten anders ist
Nichtdeterminismus, LLM-Kosten und die Gründe, warum Standard-Unit-Tests nicht ausreichen.
Warum das Testen von Agenten anders ist ist eine kostenlose AI Agents-Lektion auf CoddyKit. Dies ist Lektion 1 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des AI Agents-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der AI Agents-Kurs umfasst insgesamt 4 Lektionen.
Software testen vs. Agenten testen
Traditionelle Software ist deterministisch: Bei derselben Eingabe erhalten Sie dieselbe Ausgabe. Unit-Tests stützen sich auf diese Eigenschaft, um exakt erwartete Werte zu überprüfen.
KI-Agenten brechen diese Annahme. Derselbe Prompt kann bei jedem Durchlauf unterschiedliche Ausgaben erzeugen, sodass herkömmliche Testansätze allein nicht ausreichen.
Nichtdeterminismus: Gleiche Eingabe, unterschiedliche Ausgabe
LLMs sind von Natur aus probabilistisch. Der Parameter temperature steuert die Zufälligkeit – selbst bei temperature=0 können die Ausgaben zwischen Modellversionen oder aufgrund von Änderungen an der Infrastruktur variieren.
Das bedeutet, dass ein Agententest, der heute erfolgreich ist, morgen ohne Änderung am Code fehlschlagen kann.
import openai
client = openai.OpenAI(api_key='YOUR_API_KEY')
# Same prompt, potentially different outputs each run
for i in range(3):
response = client.chat.completions.create(
model='gpt-4o-mini',
messages=[{'role': 'user', 'content': 'Name a planet.'}],
temperature=0.9 # High randomness
)
print(f'Run {i+1}: {response.choices[0].message.content}')
# Run 1: Mars
# Run 2: Jupiter
# Run 3: SaturnDas Kostenproblem: Echte LLM-Aufrufe sind teuer
Eine Testsuite, die echte API-Aufrufe an OpenAI oder Anthropic ausführt, kann pro Durchlauf mehrere Dollar kosten. Eine CI-Pipeline mit 100 Tests × 10 Durchläufen könnte mehrere hundert Dollar pro Monat kosten.
Dadurch ist es unpraktisch, Agententests genauso auszuführen wie Unit-Tests – Sie benötigen Strategien zur Kostenkontrolle.
# A test that calls the real API costs tokens every run
# 100 tests x 500 tokens each x 10 CI runs/day = 500,000 tokens/day
# At $0.15/1M tokens (gpt-4o-mini): ~$0.075/day = ~$27/year for a tiny suite
# For gpt-4o: 15x more expensive = ~$400/year
# This is why mocking and recording API responses is essential
print('Real API calls in tests = expensive and slow')
print('Solution: Mock or record LLM responses in unit tests')
print('Reserve real calls for scheduled integration tests')Das Latenzproblem
Echte LLM-API-Aufrufe dauern typischerweise 2–20 Sekunden. Eine Testsuite mit 50 Tests würde 100–1.000 Sekunden für die Ausführung benötigen. Das beeinträchtigt die Produktivität von Entwicklern erheblich – schnelles Feedback ist ein zentraler Wert guter Tests.
Durch das Mocken von LLM-Aufrufen laufen Tests in Millisekunden.
import time
# Simulating what a test suite looks like with real vs mocked calls
num_tests = 50
# Real API calls
real_time = num_tests * 5 # avg 5 seconds per call
print(f'With real API calls: {real_time}s = {real_time/60:.1f} minutes')
# Mocked calls
mock_time = num_tests * 0.001 # <1ms per mock
print(f'With mocked calls: {mock_time:.3f}s = nearly instant')
# Conclusion: mock in unit tests, use real calls in integration testsExterne Abhängigkeiten in Agententests
Agenten rufen häufig externe Tools auf: Such-APIs, Datenbanken, Dateisysteme und Web-Scraper. In Tests können diese Abhängigkeiten:
- nicht verfügbar sein (Netzwerkausfall, API-Ausfall)
- bei jedem Durchlauf andere Daten zurückgeben
- Ratenbegrenzungen haben, die CI-Pipelines blockieren
Diese Abhängigkeiten müssen in Unit-Tests kontrolliert oder gemockt werden.
# An agent might call multiple external services
# Each is a potential test failure point
def agent_pipeline(query: str) -> str:
search_results = search_web(query) # External: Tavily/Serper API
documents = fetch_documents(search_results) # External: HTTP calls
answer = llm_summarize(documents) # External: OpenAI API
saved = database_store(answer) # External: PostgreSQL
return answer
# In unit tests: mock ALL of these
# In integration tests: use sandboxed versions of real services
print('Each external call is a test reliability risk')Was Standard-Unit-Tests voraussetzen
Standard-Frameworks für Unit-Tests wie pytest setzen voraus:
- Tests sind schnell (Millisekunden)
- Tests sind deterministisch
- Tests haben keine externen Seiteneffekte
- Tests können in beliebiger Reihenfolge ausgeführt werden
Agententests verletzen alle vier Annahmen, sofern Sie sie nicht ausdrücklich entsprechend gestalten.
# Standard unit test — works perfectly for deterministic code
def add(a, b):
return a + b
def test_add():
assert add(2, 3) == 5 # Always passes — deterministic
# Agent 'unit test' that calls a real LLM — problematic
# def test_agent_answers_question():
# response = agent.run('What is 2+2?')
# assert response == '4' # Might return 'The answer is 4' or 'Four'
print('Exact string matching fails for LLM outputs')
print('Need structural or semantic assertions instead')Die Testpyramide für Agenten
Eine praxistaugliche Teststrategie für Agenten folgt einer Pyramide:
- Unit-Tests (viele, schnell): Testen Sie einzelne Tools und Funktionen mit gemockten LLM-Aufrufen
- Integrationstests (weniger, langsamer): Testen Sie die Agenten-Pipeline Ende zu Ende mit isolierten Diensten
- Evaluationstests (selten, teuer): Testen Sie die Ausgabequalität mit echten LLM-Aufrufen und einer Bewertung nach menschlichen Maßstäben
Strukturelle vs. semantische Assertions
Statt Zeichenketten exakt abzugleichen, sollten Agententests strukturelle Assertions verwenden (hat der Agent das richtige Tool aufgerufen?) oder semantische Prüfungen durchführen (enthält die Ausgabe das relevante Konzept?).
# Fragile: exact string match
# assert response.content == 'The capital of France is Paris.'
# Better: structural assertion
# assert response.tool_calls[0]['function']['name'] == 'search_web'
# Better: semantic check
def test_capital_in_response(response_text: str) -> bool:
key_words = ['paris', 'france', 'capital']
lower = response_text.lower()
return all(word in lower for word in key_words)
response = 'Paris is the capital city of France.'
print(test_capital_in_response(response)) # TrueEvaluierungs-Harnesses und LLM-as-Judge
Für die Qualitätsbewertung verwendet die Branche LLM-as-Judge: Sie bitten ein zweites LLM, die Ausgabe des Agenten zu bewerten. Frameworks wie DeepEval und RAGAS automatisieren dieses Muster.
Dies ist für teure Evaluierungsläufe vorgesehen, nicht für die routinemäßige CI.
import openai
client = openai.OpenAI(api_key='YOUR_API_KEY')
def llm_judge(question: str, answer: str) -> dict:
prompt = f'Question: {question}\nAnswer: {answer}\nRate the answer 1-5 for accuracy. Reply with only a number.'
response = client.chat.completions.create(
model='gpt-4o-mini',
messages=[{'role': 'user', 'content': prompt}]
)
score = int(response.choices[0].message.content.strip())
return {'score': score, 'pass': score >= 4}
# result = llm_judge('What is the capital of France?', 'Paris')
# print(result) # {'score': 5, 'pass': True}Regressionstests für Agenten
Wenn Sie einen Prompt aktualisieren oder die Logik eines Agenten ändern, überprüfen Regressionstests, dass Sie kein bestehendes Verhalten beeinträchtigt haben. Erfassen Sie beispielhafte Referenzfälle (Eingabe → erwartete Struktur) und führen Sie sie bei jedem Commit automatisch aus.
# golden_examples.py
GOLDEN_EXAMPLES = [
{
'input': 'Search for the weather in Paris',
'expected_tool': 'get_weather',
'expected_args': {'city': 'Paris'}
},
{
'input': 'Calculate 15% tip on $45',
'expected_tool': 'calculate',
'expected_args': {'expression': '45 * 0.15'}
}
]
def run_regressions(agent, examples: list) -> int:
failures = 0
for ex in examples:
result = agent.plan(ex['input']) # mocked LLM
if result['tool'] != ex['expected_tool']:
print(f'FAIL: expected {ex["expected_tool"]}, got {result["tool"]}')
failures += 1
return failures
# --- demo: a stub agent whose .plan() mimics an LLM's tool choice ---
class _StubAgent:
def plan(self, text):
if 'weather' in text.lower():
return {'tool': 'get_weather'}
if 'tip' in text.lower() or 'calculate' in text.lower():
return {'tool': 'wrong_tool'} # simulate a regression
return {'tool': 'unknown'}
failures = run_regressions(_StubAgent(), GOLDEN_EXAMPLES)
print(f'{failures} of {len(GOLDEN_EXAMPLES)} golden examples failed')
Eine einfache Agententestdatei einrichten
Hier sehen Sie die minimale Struktur einer pytest-Testdatei für einen Agenten. Sie trennt schnelle Unit-Tests mit Mocks von langsamen Integrationstests mit echten Aufrufen, sodass Sie nur die benötigten Tests ausführen können.
# tests/test_agent.py
import pytest
# Fast unit tests — run on every commit
class TestAgentTools:
def test_tool_returns_dict(self, mock_llm):
result = my_tool(query='test')
assert isinstance(result, dict)
assert 'data' in result
def test_agent_selects_correct_tool(self, mock_llm):
response = agent.run('Search for Python tutorials')
assert response['tool_used'] == 'web_search'
# Slow integration tests — run nightly or on release
@pytest.mark.integration
class TestAgentIntegration:
def test_full_pipeline_with_real_api(self):
# Uses real OpenAI + sandboxed services
result = agent.run('Summarize the Python docs')
assert len(result['answer']) > 50Wissenscheck: Warum sich Agententests unterscheiden
Testen Sie Ihr Verständnis der besonderen Herausforderungen beim Testen von KI-Agenten.
Zusammenfassung: Warum sich das Testen von Agenten unterscheidet
Das Testen von KI-Agenten erfordert eine andere Herangehensweise als standardmäßige Unit-Tests:
- Nichtdeterminismus: Dieselbe Eingabe kann unterschiedliche gültige Ausgaben erzeugen
- Kosten: Echte LLM-Aufrufe sind teuer – mocken Sie sie in Unit-Tests
- Latenz: Echte API-Aufrufe dauern Sekunden – Mocks laufen in Millisekunden
- Externe Abhängigkeiten: Tools und APIs müssen in Tests kontrolliert werden
- Assertions: Verwenden Sie strukturelle und semantische Prüfungen statt eines exakten String-Vergleichs
Verwenden Sie eine Testpyramide: viele kostengünstige Unit-Tests mit Mocks und weniger aufwendige Integrationstests mit echten Aufrufen.
Häufig gestellte Fragen
Ist die Lektion „Warum das Testen von Agenten anders ist“ kostenlos?
Ja — der vollständige Text von „Warum das Testen von Agenten anders ist“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des AI Agents-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der AI Agents-Kurs umfasst insgesamt 4 Lektionen.
Was lerne ich in „Warum das Testen von Agenten anders ist“?
Nichtdeterminismus, LLM-Kosten und die Gründe, warum Standard-Unit-Tests nicht ausreichen. Du übst AI Agents mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.
Brauche ich Erfahrung, um AI Agents zu starten?
Keine Vorkenntnisse erforderlich. AI Agents auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 1 von 4.
Wie lange dauert die Lektion „Warum das Testen von Agenten anders ist“?
Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.
Kann ich in dieser AI Agents-Lektion Code schreiben und ausführen?
Ja. Jede AI Agents-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.
Alle Lektionen in diesem Kurs
- Warum das Testen von Agenten anders ist
- LLM-Aufrufe in Tests mocken
- Assertion-basiertes Agenten-Testing
- Integrationstests für Agenten-Pipelines