Varför agenttestning skiljer sig
Icke-determinism, LLM-kostnader och varför vanliga enhetstester inte räcker.
Varför agenttestning skiljer sig är en gratis lektion i AI-agenter på CoddyKit. Detta är lektion 1 av 4. Ni kan läsa hela lektionen gratis nedan och sedan öva praktiskt i webbläsaren med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt. Den ingår i lärvägen för AI-agenter, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i AI-agenter innehåller totalt 4 lektioner.
Testa programvara kontra testa agenter
Traditionell programvara är deterministisk: samma indata ger samma utdata. Enhetstester bygger på denna egenskap för att kontrollera exakta förväntade värden.
AI-agenter bryter mot detta antagande. Samma prompt kan ge olika utdata vid varje körning, vilket gör att vanliga testmetoder inte räcker på egen hand.
Icke-determinism: samma indata, olika utdata
LLM:er är av naturen probabilistiska. Parametern temperature styr slumpmässigheten – även vid temperature=0 kan utdata variera mellan modellversioner eller förändringar i infrastrukturen.
Det innebär att ett agenttest som klarar sig i dag kan misslyckas i morgon utan någon kodändring.
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: SaturnKostnadsproblemet: riktiga LLM-anrop är dyra
Att köra en testsamling som gör riktiga API-anrop till OpenAI eller Anthropic kan kosta flera dollar per körning. En CI-pipeline som kör 100 tester × 10 iterationer kan kosta hundratals dollar i månaden.
Det gör det opraktiskt att köra agenttester på samma sätt som enhetstester – ni behöver strategier för att kontrollera kostnaderna.
# 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')Fördröjningsproblemet
Riktiga LLM-API-anrop tar vanligtvis 2–20 sekunder. En testsamling med 50 tester skulle ta 100–1 000 sekunder att köra. Det försämrar utvecklarnas produktivitet – snabb återkoppling är ett centralt värde i bra tester.
Genom att simulera LLM-anrop körs tester på millisekunder.
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 testsExterna beroenden i agenttester
Agenter anropar ofta externa verktyg: sök-API:er, databaser, filsystem och webbskrapare. I tester kan dessa beroenden:
- vara otillgängliga (nätverksavbrott eller API-avbrott)
- returnera olika data vid varje körning
- ha hastighetsbegränsningar som blockerar CI-pipelines
Dessa beroenden måste kontrolleras eller simuleras i enhetstester.
# 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')Vad vanliga enhetstester förutsätter
Vanliga ramverk för enhetstester, som pytest, förutsätter att:
- tester är snabba (millisekunder)
- tester är deterministiska
- tester inte har några externa sidoeffekter
- tester kan köras i valfri ordning
Agenttester bryter mot alla fyra antaganden om ni inte uttryckligen utformar dem med hänsyn till detta.
# 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')Testpyramiden för agenter
En praktisk teststrategi för agenter följer en pyramid:
- Enhetstester (många, snabba): Testa enskilda verktyg och funktioner med simulerade LLM-anrop
- Integrationstester (färre, långsammare): Testa agentens pipeline från början till slut med isolerade tjänster
- Utvärderingstester (sällsynta, dyra): Testa utdatakvalitet med riktiga LLM-anrop och bedömning på mänskligt sätt
Strukturella kontra semantiska påståenden
I stället för exakt strängmatchning bör agenttester använda strukturella påståenden (anropade agenten rätt verktyg?) eller semantiska kontroller (innehåller utdatan det relevanta konceptet?).
# 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)) # TrueUtvärderingsramverk och LLM-as-Judge
För kvalitetsutvärdering använder branschen LLM-as-judge: be en andra LLM att bedöma agentens utdata. Ramverk som DeepEval och RAGAS automatiserar detta mönster.
Detta är avsett för dyra utvärderingskörningar, inte för rutinmässig 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}Regressionstestning för agenter
När ni uppdaterar en prompt eller ändrar agentens logik verifierar regressionstester att ni inte har förstört befintligt beteende. Spara gyllene exempel (indata → förväntad struktur) och kör dem automatiskt vid varje commit.
# 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')
Konfigurera en enkel testfil för en agent
Här är en minimal struktur för en pytest-testfil för en agent. Den skiljer snabba enhetstester (med simulerade anrop) från långsamma integrationstester (med riktiga anrop), så att ni kan köra bara de tester ni behöver.
# 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']) > 50Kunskapskontroll: Varför agenttestning skiljer sig
Testa er förståelse av de unika utmaningarna med att testa AI-agenter.
Sammanfattning: Varför testning av agenter skiljer sig åt
Testning av AI-agenter kräver ett annat tankesätt än vanlig enhetstestning:
- Icke-determinism: Samma indata kan ge olika giltiga utdata
- Kostnad: Riktiga LLM-anrop är dyra — mocka dem i enhetstester
- Fördröjning: Riktiga API-anrop tar sekunder — mock-anrop körs på millisekunder
- Externa beroenden: Verktyg och API:er måste kontrolleras i tester
- Verifieringar: Använd strukturella och semantiska kontroller i stället för exakt strängmatchning
Använd en testpyramid: många billiga enhetstester med mockar och färre dyra integrationstester med riktiga anrop.
Lär dig AI-agenter med en AI-lärare – gratis
Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.
- Kurser
- 60
- Lektioner
- 239
Vanliga frågor
Är lektionen ”Varför agenttestning skiljer sig” gratis?
Ja – hela texten till ”Varför agenttestning skiljer sig” kan läsas gratis här på webben. Om Ni vill öva interaktivt med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt och låsa upp resten av kursen i AI-agenter, kan Ni uppgradera till CoddyKit PRO. Kursen i AI-agenter innehåller totalt 4 lektioner.
Vad lär jag mig i ”Varför agenttestning skiljer sig”?
Icke-determinism, LLM-kostnader och varför vanliga enhetstester inte räcker. Ni övar på AI-agenter med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.
Behöver jag någon erfarenhet för att börja lära mig AI-agenter?
Du behöver inga förkunskaper. Utbildningen i AI-agenter på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 1 av 4.
Hur lång tid tar lektionen ”Varför agenttestning skiljer sig”?
De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.
Kan jag skriva och köra kod i den här AI-agenter-lektionen?
Ja. Varje AI-agenter-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.
Alla lektioner i den här kursen
- Varför agenttestning skiljer sig
- Mocka LLM-anrop i tester
- Assertions-baserad agenttestning
- Integrationstester för agentpipelines