Miksi LLM-sovellusten testaus on erilaista kuin perinteinen ohjelmistotestaus?
Perinteinen ohjelmisto toimii deterministisesti: sama syöte tuottaa aina saman tuloksen. Kielimallit eivät toimi niin. Ne generoivat vastauksia todennäköisyysjakaumasta, käytännössä lähes äärettömän suuresta mahdollisten vastausten avaruudesta. Ja tämä tekee kaikesta monimutkaisempaa kuin perinteisessä ohjelmistokehityksessä.
Tuotantoon viety LLM-sovellus voi toimia erinomaisesti demossa — mutta romahtaa kolmen kuukauden kuluttua reaalimaailman kuorman alla. Perinteiset testausmenetelmät eivät varoita tästä etukäteen.
Tämä on se todellisuus, jonka jokainen LLM-sovellusten parissa työskentelevä tiimi kohtaa ennemmin tai myöhemmin. Hallusinaatiot, vinoumien kertautuminen, kontekstin hukkuminen ja prompt drift ovat ongelmia, jotka eivät näy yksikkötesteissä. Ne näkyvät tuotannossa — ja yleensä pahimmalla mahdollisella hetkellä.
Jos olet lukenut aiemmat oppaamme tuotantovalmiista RAG-pipelinesta ja moniagenttiorkestroinnista, tämä artikkeli täydentää sarjan kolmantena osana. RAG-pipeline hakee oikeat dokumentit, agentit orkestroivat työnkulun — mutta miten varmistat, että koko järjestelmä oikeasti toimii luotettavasti? Vastaus on systemaattinen arviointi eli eval-järjestelmä.
Eval-ajattelu: Arviointiohjattu kehitys
Anthropic julkaisi tammikuussa 2026 insinöörioppaansa "Demystifying Evals for AI Agents", jossa he esittelevät käsitteen arviointiohjattu kehitys (eval-driven development). Periaate on yllättävän yksinkertainen: rakenna arviointikriteerit ennen kuin agentti täyttää ne, ja iteroi kunnes suorituskyky on riittävä.
Kuulostaako tutulta? Sen pitäisikin — se on käytännössä TDD:n (Test-Driven Development) luonnollinen jatke tekoälyjärjestelmille.
Käytännössä tämä tarkoittaa, että eval-järjestelmä ei ole jälkikäteen lisätty testipaketti. Se on ydininfrastruktuuria. Ilman sitä tiimit voivat tuhlata viikkoja ominaisuuksiin, jotka "toimivat" varhaisessa testauksessa mutta epäonnistuvat tuotannossa odottamattomilla tavoilla. Olen nähnyt tämän tapahtuvan useammin kuin haluaisin myöntää.
Tehtävä, yritys ja jälki
Agenttien arvioinnissa on kolme keskeistä käsitettä, jotka kannattaa erottaa toisistaan:
- Tehtävä (task) — yksittäinen testitapaus, jolla on selkeät onnistumiskriteerit
- Yritys (trial) — yksi stokastinen suoritus tehtävästä; koska kielimallit ovat epädeterministisiä, sama tehtävä voi tuottaa eri tuloksen joka kerralla
- Jälki (transcript/trace) — koko monivaiheinen vuorovaikutus, mukaan lukien työkalukutsut, välitilat ja lopputulos
Miksi tämä erottelu on tärkeä? Yksittäinen onnistunut tai epäonnistunut suoritus ei kerro tarpeeksi. Sinun on ajettava useita yrityksiä per tehtävä ja seurattava varianssia — pelkkä kyllä/ei-tulos ei yksinkertaisesti riitä.
Arviointimittarit: Mitä mitata ja miksi
LLM-sovellusten arviointimittarit jakaantuvat karkeasti kolmeen kategoriaan: RAG-spesifisiin mittareihin, yleisiin laatumittareihin ja agenttikohtaisiin mittareihin. Käydään tärkeimmät läpi.
RAG-mittarit
Jos tuotanto-RAG-pipeline on järjestelmäsi ytimessä, nämä mittarit ovat ehdottomasti välttämättömiä:
- Uskollisuus (Faithfulness) — mittaa, onko generoitu vastaus faktisesti linjassa haetun kontekstin kanssa. Pisteet lasketaan jakamalla totuudenmukaisten väitteiden määrä väitteiden kokonaismäärällä. Tämä on rehellisesti sanottuna tärkein yksittäinen mittari RAG-järjestelmälle.
- Vastauksen relevanssi (Answer Relevancy) — arvioi, onko vastaus ytimekäs ja relevantti suhteessa kysymykseen. Lasketaan relevanttien lauseiden osuutena kokonaislausemäärästä.
- Kontekstuaalinen tarkkuus (Contextual Precision) — mittaa, kuinka suuri osa haetusta kontekstista todella käytetään vastauksessa.
- Kontekstuaalinen kattavuus (Contextual Recall) — mittaa, kuinka hyvin vastaus kattaa relevantin tiedon haetusta kontekstista.
Hallusinaatiomittarit
Hallusinaatioiden mittaaminen eroaa uskollisuusmittarista, vaikka ne saattavat ensi silmäyksellä vaikuttaa samankaltaisilta. Ero on tässä: hallusinaatiomittari vertaa tulosta kontekstiin (ideaaliin tietolähteeseen), kun taas uskollisuusmittari vertaa tulosta haettuun kontekstiin (retrieval context). Käytännössä RAG-järjestelmille suositellaan uskollisuusmittaria, ja hallusinaatiomittari sopii paremmin yleisiin kielimallisovelluksiin.
Agenttimittarit
- Tehtävän suoritus (Task Completion) — suorittiko agentti sille annetun tehtävän loppuun asti?
- Työkalun oikeellisuus (Tool Correctness) — kutsuiko agentti oikeita työkaluja oikeilla parametreilla?
- Roolin noudattaminen (Role Adherence) — pysyikö keskusteluagentti roolissaan koko vuorovaikutuksen ajan?
- Tiedon säilyttäminen (Knowledge Retention) — säilyttikö chatbot aiemmin opitun tiedon keskustelun aikana?
DeepEval: Pytest LLM-sovelluksille
No niin, puhutaan työkaluista. DeepEval on avoimen lähdekoodin LLM-arviointikehys, joka toimii kuin Pytest — mutta on erikoistunut kielimallien tulosten yksikkötestaukseen. Se sisältää viimeisimmän tutkimuksen pohjalta rakennetut mittarit (kuten G-Eval, hallusinaatiotunnistuksen ja vastauksen relevanssin) ja käyttää arvioinnissa joko LLM-tuomaria tai paikallisesti ajettavia NLP-malleja.
Asennus ja ensimmäinen testi
# Asennus
pip install deepeval
# Aseta OpenAI API-avain LLM-tuomaria varten
export OPENAI_API_KEY="sk-..."
# Tai käytä paikallista mallia (Ollama)
# deepeval set-local-model --model-name ollama/llama3
Ensimmäinen eval-testi näyttää hyvin tutulta, jos olet koskaan käyttänyt Pytestiä:
import pytest
from deepeval import assert_test
from deepeval.test_case import LLMTestCase
from deepeval.metrics import (
AnswerRelevancyMetric,
FaithfulnessMetric,
HallucinationMetric
)
def test_rag_vastauksen_laatu():
"""Testaa RAG-pipelinen vastauksen laatu."""
# Simuloi RAG-pipelinen tulosta
testitapaus = LLMTestCase(
input="Mikä on yrityksen palautuspolitiikka?",
actual_output="Tuotteet voidaan palauttaa 30 päivän kuluessa "
"ostosta. Palautus edellyttää alkuperäistä kuittia "
"ja tuotteen on oltava käyttämättömässä kunnossa.",
retrieval_context=[
"Palautuspolitiikka: Asiakkaalla on oikeus palauttaa tuote "
"30 päivän kuluessa ostopäivästä. Palautettavan tuotteen "
"mukana on toimitettava alkuperäinen kuitti. Tuotteen on "
"oltava avaamattomassa ja käyttämättömässä kunnossa."
]
)
# Määritä mittarit ja kynnysarvot
relevanssi = AnswerRelevancyMetric(threshold=0.7)
uskollisuus = FaithfulnessMetric(threshold=0.8)
# Aja arviointi — epäonnistuu kuin pytest-testi
assert_test(testitapaus, [relevanssi, uskollisuus])
Jokainen mittarin pistearvo on välillä 0–1, ja threshold-parametri määrittää, läpäiseekö testi vai ei. Tämä tekee eval-testeistä yhtä selkeitä kuin perinteisistä yksikkötesteistä: vihreä tai punainen. Ei mitään tulkinnanvaraisuutta.
RAG-pipelinen kattava eval-paketti
Tuotanto-RAG-järjestelmälle kannattaa rakentaa kattava eval-paketti, joka testaa koko pipelinen kerralla. Tässä käytännön esimerkki:
from deepeval import assert_test
from deepeval.test_case import LLMTestCase
from deepeval.metrics import (
AnswerRelevancyMetric,
FaithfulnessMetric,
ContextualPrecisionMetric,
ContextualRecallMetric
)
# Testidatasetti — oikeat kysymykset tuotannosta
TESTITAPAUKSET = [
{
"input": "Miten peruutan tilaukseni?",
"expected": "Tilauksen voi peruuttaa tilaussivulta 24 tunnin kuluessa.",
"context": [
"Tilauksen peruutus: Asiakas voi peruuttaa tilauksen "
"24 tunnin sisällä tilauksen tekemisestä. Peruutus "
"tapahtuu kirjautumalla sisään ja siirtymällä tilaussivulle."
]
},
{
"input": "Tukeeko palvelu kaksivaiheista todennusta?",
"expected": "Kyllä, kaksivaiheinen todennus on tuettu.",
"context": [
"Tietoturvaominaisuudet: Palvelu tukee kaksivaiheista "
"todennusta (2FA) sekä TOTP-sovelluksella että "
"SMS-viestillä. 2FA voidaan ottaa käyttöön asetuksista."
]
}
]
# Mittarit — sama konfiguraatio kaikille
mittarit = [
AnswerRelevancyMetric(threshold=0.7),
FaithfulnessMetric(threshold=0.8),
ContextualPrecisionMetric(threshold=0.6),
ContextualRecallMetric(threshold=0.6)
]
def test_rag_pipeline():
"""Aja kattava RAG-arviointi kaikilla testitapauksilla."""
for tapaus in TESTITAPAUKSET:
testitapaus = LLMTestCase(
input=tapaus["input"],
actual_output=aja_rag_pipeline(tapaus["input"]),
expected_output=tapaus["expected"],
retrieval_context=tapaus["context"]
)
assert_test(testitapaus, mittarit)
def aja_rag_pipeline(kysymys: str) -> str:
"""Kutsu todellista RAG-pipelinea."""
# Tähän tulee oma RAG-pipelinen toteutus
from oma_rag_pipeline import hae_ja_generoi
return hae_ja_generoi(kysymys)
Agenttien arviointi DeepEvalilla
Agenttien testaus eroaa merkittävästi RAG-pipelinen testauksesta — ja tämä on kohta, jossa monet tiimit kompastuvat. Agentti ei muunna syötettä tulosteeksi yhdessä vaiheessa. Se päättää mitä tehdä, tekee sen, havainnoi tuloksen ja iteroi, mahdollisesti kymmeniä kertoja ennen lopullista vastausta.
DeepEval tukee agenttikohtaisia mittareita suoraan:
from deepeval.test_case import LLMTestCase, ToolCall
from deepeval.metrics import ToolCorrectnessMetric
def test_agentti_tyokalukutsut():
"""Testaa, kutsuuko agentti oikeita työkaluja."""
testitapaus = LLMTestCase(
input="Hae Helsingin sää ja lähetä raportti sähköpostilla.",
actual_output="Helsingin sää: 3°C, pilvistä. Raportti lähetetty.",
# Agentin todelliset työkalukutsut
tools_called=[
ToolCall(name="hae_saa", input_parameters={"kaupunki": "Helsinki"}),
ToolCall(name="laheta_sahkoposti", input_parameters={
"vastaanottaja": "[email protected]",
"aihe": "Sääraportti"
})
],
# Odotetut työkalukutsut
expected_tools=[
ToolCall(name="hae_saa", input_parameters={"kaupunki": "Helsinki"}),
ToolCall(name="laheta_sahkoposti", input_parameters={
"vastaanottaja": "[email protected]",
"aihe": "Sääraportti"
})
]
)
tyokaluarviointi = ToolCorrectnessMetric(threshold=0.8)
assert_test(testitapaus, [tyokaluarviointi])
Promptfoo: Deklaratiivinen eval-kehys ja tietoturvatestaus
Promptfoo on toinen suosittu eval-kehys, ja se eroaa DeepEvalista aika lailla. Siinä missä DeepEval on Pytest-pohjainen Python-kehys, Promptfoo on deklaratiivinen YAML-konfiguraatioon perustuva työkalu — ja mikä parasta, se on täysin kieliriippumaton.
Mielenkiintoinen yksityiskohta: Anthropic käyttää Promptfoon versiota omissa tuote-evalissaan. Se kertoo paljon kehyksen kypsyydestä.
YAML-konfiguraatio
Promptfoon ydin on promptfooconfig.yaml-tiedosto, joka määrittelee mitä testataan, millä malleilla ja millä kriteereillä:
# promptfooconfig.yaml
description: "RAG-pipelinen laadunarviointi"
providers:
- openai:gpt-4o
- anthropic:messages:claude-sonnet-4-5-20250514
prompts:
- file://prompts/rag_vastaus.txt
tests:
- vars:
kysymys: "Mikä on palautuspolitiikka?"
konteksti: "Tuotteet voidaan palauttaa 30 päivän kuluessa."
assert:
# Vastauksen on sisällettävä palautusaika
- type: contains
value: "30 päivä"
# LLM-tuomari arvioi vastauksen laadun
- type: llm-rubric
value: >
Vastauksen tulee olla faktisesti oikein, ytimekäs
ja perustua annettuun kontekstiin.
# Vastauksen on oltava riittävän samanlainen
- type: similar
value: "Tuotteet voidaan palauttaa 30 päivän kuluessa ostosta."
threshold: 0.8
- vars:
kysymys: "Miten otan 2FA käyttöön?"
konteksti: "2FA aktivoidaan asetuksista."
assert:
- type: contains
value: "asetuksi"
- type: llm-rubric
value: >
Vastauksen tulee sisältää selkeät ohjeet
kaksivaiheisen todennuksen käyttöönottoon.
# Ei saa sisältää hallusinaatioita
- type: not-contains
value: "soita asiakaspalveluun"
Suoritus ja tulosten tarkastelu
# Aja arviointi
npx promptfoo@latest eval
# Avaa interaktiivinen tulosnäkymä selaimessa
npx promptfoo@latest view
# Tai tulosta yhteenveto terminaaliin
npx promptfoo@latest eval --output results.json
Promptfoon iso vahvuus on mallien vertailu rinnakkain. Sama testitapaus ajetaan useilla malleilla, ja tulokset näytetään vierekkäin. Tämä on korvaamatonta silloin, kun arvioit mallinvaihtoa tuotannossa tai etsit kustannustehokkaampaa vaihtoehtoa.
Tietoturvatestaus ja red teaming
Promptfoo sisältää sisäänrakennetun red teaming -ominaisuuden, mikä on todella harvinaista eval-kehyksissä. Sillä voi tunnistaa prompt injection -haavoittuvuudet, ohitusyritykset ja muut tietoturvariskit automaattisesti:
# red-team-config.yaml
description: "Tietoturvatestaus"
redteam:
purpose: "Asiakaspalvelu-chatbot, joka vastaa tuotekysymyksiin"
plugins:
- prompt-injection
- jailbreak
- pii-leak
- harmful-content
strategies:
- multilingual # Testaa ohitusyrityksiä eri kielillä
- leetspeak # Testaa merkistömanipulaatioita
- rot13 # Testaa koodattuja syötteitä
# Aja tietoturvatestaus
npx promptfoo@latest redteam eval --config red-team-config.yaml
Vuoden 2026 tuotantoympäristössä tietoturvatestaus ei todellakaan ole valinnaista. OWASP Top 10 LLM-riskit — erityisesti prompt injection ja tietovuodot — vaativat systemaattista testausta ennen käyttöönottoa. Tämä ei ole pelottelua, vaan realismia.
LLM-tuomari: Miten kielimalli arvioi toista kielimallia
LLM-as-a-Judge on arviointimenetelmä, jossa kielimalli arvioi toisen kielimallisovelluksen tuottamaa tulosta. Sen sijaan, että luotettaisiin pelkästään ihmisarvioijiin tai yksinkertaisiin heuristisiin mittareihin, kyvykäs malli pisteyttää ja perustelee arvionsa määriteltyjen kriteerien pohjalta.
Menetelmä on noussut yhdeksi suosituimmista LLM-sovellusten arviointitavoista yksinkertaisesta syystä: se yhdistää inhimillisen arvioinnin vivahteet automaattisen arvioinnin skaalautuvuuteen.
G-Eval ja DAG-kehykset
DeepEval tarjoaa kaksi keskeistä LLM-tuomarikehystä:
- G-Eval — pyytää kielimallia generoimaan pisteitä pisteytysrubriikan perusteella. Voit luoda omia räätälöityjä mittareita, jotka painottavat juuri sinulle tärkeitä tekijöitä.
- DAG (Deep Acyclic Graph) — kehys determinististen, päätöspuupohjaisten LLM-tuomarimittareiden luomiseen. Tämä on tällä hetkellä muokattavin saatavilla oleva mittarityyppi, ja se kannattaa ottaa käyttöön, jos tarvitset hienosäätöisen kontrollin arviointiprosessiin.
from deepeval.metrics import GEval
from deepeval.test_case import LLMTestCaseParams
# Räätälöity G-Eval-mittari: Vastauksen ammattimaisuus
ammattimaisuus = GEval(
name="Ammattimaisuus",
criteria=(
"Arvioi vastauksen ammattimaisuutta asiakaspalvelukontekstissa. "
"Vastauksen tulee olla kohtelias, selkeä ja ratkaisukeskeinen. "
"Epäammattimaisesta kielenkäytöstä, emojien käytöstä tai "
"liian tuttavallisesta sävystä tulee rankaista."
),
evaluation_params=[
LLMTestCaseParams.INPUT,
LLMTestCaseParams.ACTUAL_OUTPUT
],
threshold=0.7
)
LLM-tuomarin rajoitukset
LLM-tuomarilla on tunnettuja rajoituksia, ja nämä on syytä tietää ennen kuin luottaa pelkästään automaattiseen arviointiin:
- Asennevinouma — kielimalli voi suosia tiettyjä vastausmalleja tai sanankäänteitä riippumatta sisällön laadusta
- Pituusvinouma — pidemmät vastaukset saavat usein korkeampia pisteitä, vaikka lyhyempi vastaus olisi parempi (tämä on yllättävän yleinen ongelma)
- Itsesuosimisvinouma — malli voi antaa korkeampia pisteitä omien malliensa tuotoksille
Siksi Anthropicin suositus on selkeä: automaattiset evalit eivät koskaan korvaa inhimillistä arviointia — ne täydentävät sitä. Tuotantojärjestelmässä tarvitaan molempia.
CI/CD-integraatio: Automaattiset evalit jokaisessa pull requestissa
Eval-järjestelmän todellinen arvo realisoituu silloin, kun se integroidaan CI/CD-putkeen. Jokainen promptin muutos, mallinvaihto tai pipelinen päivitys ajetaan automaattisesti eval-paketin läpi ennen tuotantoon pääsyä.
Tämä on ensimmäinen puolustuslinja laatuongelmia vastaan. Ja uskokaa pois, se on pelastava enkeli silloin, kun joku tekee "pienen ja harmittoman" muutoksen promptiin.
GitHub Actions + DeepEval
# .github/workflows/llm-eval.yml
name: LLM Eval Pipeline
on:
pull_request:
paths:
- "prompts/**"
- "src/rag/**"
- "src/agents/**"
jobs:
eval:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Asenna Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Asenna riippuvuudet
run: |
pip install deepeval openai langchain
- name: Aja LLM-evalit
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
run: |
deepeval test run tests/eval/ --verbose
- name: Laadun portti
run: |
# Tarkista, ettei yksikään eval epäonnistunut
deepeval test run tests/eval/ --exit-on-first-failure
GitHub Actions + Promptfoo
# .github/workflows/prompt-eval.yml
name: Prompt Eval
on:
pull_request:
paths:
- "prompts/**"
- "promptfooconfig.yaml"
jobs:
eval:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Aja Promptfoo-arviointi
uses: promptfoo/promptfoo-action@v1
with:
openai-api-key: ${{ secrets.OPENAI_API_KEY }}
github-token: ${{ secrets.GITHUB_TOKEN }}
config: promptfooconfig.yaml
cache-path: ~/.cache/promptfoo
- name: Laadun portti — hylkää PR, jos läpäisyaste < 95 %
run: |
npx promptfoo@latest eval -c promptfooconfig.yaml -o results.json
PASS_RATE=$(jq ".results.stats.successes / .results.stats.totalTests * 100" results.json)
echo "Läpäisyaste: ${PASS_RATE}%"
if (( $(echo "$PASS_RATE < 95" | bc -l) )); then
echo "HYLÄTTY: Läpäisyaste alle 95 %"
exit 1
fi
Välimuisti ja kustannusten hallinta
CI/CD-evalien suurin käytännön haaste on kustannukset — ja tämä on asia, joka yllättää monen tiimin. Jokainen eval-ajo tekee API-kutsuja kielimalliin, ja kustannukset kasvavat nopeasti suurissa testipaketeissa. Onneksi käytännön ratkaisuja on:
- Välimuisti — sekä Promptfoo että DeepEval tukevat tulosten välimuistiin tallentamista, joten sama kysely-vastaus-pari ei tuota uutta API-kutsua
- Kerrostettu testaus — aja kevyt eval-paketti jokaisessa PR:ssä ja kattava paketti yöajona tai ennen julkaisua
- Paikallinen LLM-tuomari — käytä Ollamaa tai muuta paikallista mallia kehitysympäristössä, ja pilvimallia CI/CD:ssä
- Polkupohjaiset triggerit — aja evalit vain, kun promptit tai pipelinen koodi muuttuu (ks.
paths-suodatin yllä)
Tuotannon seuranta: Evalit eivät lopu käyttöönottoon
Tässä tulee se kohta, jonka moni unohtaa: arviointi ei pääty siihen, kun sovellus on tuotannossa. Tuotannon seuranta on eval-järjestelmän toinen — ja ehkä jopa tärkeämpi — puoli. Se paljastaa ongelmia, joita offline-evalit eivät yksinkertaisesti voi ennustaa.
Langfuse: Havainnointi ja arviointi tuotannossa
Langfuse on avoimen lähdekoodin LLM-havainnointi- ja arviointialusta, joka kerää jokaisesta kielimallikutsusta jäljen (trace). Se mahdollistaa sekä reaaliaikaisen seurannan että jälkikäteisen arvioinnin:
from langfuse import Langfuse
from langfuse.decorators import observe
langfuse = Langfuse(
public_key="pk-...",
secret_key="sk-...",
host="https://cloud.langfuse.com" # Tai oma instanssi
)
@observe()
def rag_vastaus(kysymys: str) -> str:
"""RAG-pipeline, jota Langfuse havainnoi automaattisesti."""
# Hae dokumentit
dokumentit = hae_dokumentit(kysymys)
# Generoi vastaus
vastaus = generoi_vastaus(kysymys, dokumentit)
return vastaus
# Jokainen kutsu luo jäljen Langfuseen, jossa näkyvät:
# - Latenssi per komponentti
# - Token-kulutus ja kustannukset
# - Syöte, tuloste ja haettu konteksti
# - Mahdolliset virheet
Hälytykset ja kynnysarvot
Tuotannossa on asetettava hälytykset kriittisille mittareille. Kun uskollisuuspistemäärä laskee alle asetetun kynnyksen tai hallusinaatioaste nousee, tiimi saa ilmoituksen ennen kuin käyttäjät huomaavat ongelman. Tässä suuntaa-antavat kynnysarvot:
- Uskollisuuspistemäärä < 0,7 — välitön hälytys, mahdollinen tietolähteen ongelma
- Hallusinaatioaste > 15 % — tutkittava, onko malli alkanut "driffata"
- Latenssi p95 > 3 sekuntia — suorituskykyongelma, joka voi johtaa käyttäjien poistumiseen
- Token-kulutus +30 % viikon sisällä — epätavallinen kasvu, joka voi viitata silmukkavirheeseen
Käytännön eval-strategia eri agenttityypeille
Anthropicin opas korostaa yhtä asiaa erityisesti: eri agenttityypit vaativat erilaisia arviointistrategioita. Yksi koko ei todellakaan sovi kaikille.
Koodausagentit
Koodausagenttien arviointi on suhteellisen suoraviivaista — ja siinä mielessä hyvä paikka aloittaa. Yksikkötestit varmistavat oikeellisuuden ja LLM-rubriikki arvioi koodin kokonaislaadun. Lisämittareita ja arvioijia lisätään vain tarpeen mukaan.
Keskusteluagentit
Keskusteluagentit ovat haastavampia, koska vuorovaikutuksen laatu itsessään on osa arvioitavaa tulosta. Tehokkaat evalit nojaavat todennettaviin lopputilan tuloksiin ja rubriikkeihin, jotka kattavat sekä tehtävän suorituksen että vuorovaikutuksen laadun. Usein tarvitaan myös toista kielimallia simuloimaan käyttäjää — mikä lisää evaluoinnin monimutkaisuutta merkittävästi.
Tutkimusagentit
Tutkimusagenttien arviointi on ehkä kaikkein hankalinta. Asiantuntijat voivat olla eri mieltä synteesin kattavuudesta, pohjadatan totuus muuttuu jatkuvasti, ja pidemmät, avoimemmat tuotokset jättävät enemmän tilaa virheille. Tässä ei ole helppoja oikoteitä.
Promptfoo vai DeepEval? Vertailu vuonna 2026
Molemmat kehykset ovat erinomaisia — mutta eri tilanteisiin. Tässä käytännön vertailu:
- Lähestymistapa: Promptfoo käyttää deklaratiivista YAML-konfiguraatiota, DeepEval on Pytest-pohjainen Python-kehys
- Mallien vertailu: Promptfoo loistaa useiden mallien rinnakkaisvertailussa — sama testi ajetaan GPT-4o:lle, Claudelle ja Geminille samanaikaisesti. DeepEval puolestaan keskittyy yksittäisen pipelinen syvälliseen arviointiin.
- Tietoturvatestaus: Promptfoo sisältää sisäänrakennetun red teaming -ominaisuuden. DeepEvalissa vastaavaa ei ole.
- LLM-tuomari: Promptfoo käyttää
llm-rubric-assertioita, DeepEval tarjoaa G-Eval- ja DAG-kehykset, jotka mahdollistavat monipuolisemman räätälöinnin. - Kielituki: Promptfoo on kieliriippumaton (JS, Python, mikä tahansa), DeepEval on Python-ekosysteemin työkalu.
- CI/CD: Molemmat integroituvat GitHub Actionsiin, GitLabiin ja Jenkinsiin.
Käytännön suositus: käytä Promptfoo:ta, kun tarvitset mallien vertailua, tietoturvatestausta tai kieliriippumatonta ratkaisua. Käytä DeepEvalia, kun tiimisi on Python-keskeinen, tarvitset syvällisiä RAG- tai agenttimittareita ja haluat pytest-natiiviin työnkulkuun. Monet tiimit käyttävät käytännössä molempia — Promptfoo mallien valintaan ja tietoturvatestaukseen, DeepEval pipelinen yksikkötestaukseen. Se ei ole joko-tai-tilanne.
Usein kysytyt kysymykset
Mikä on LLM-eval ja miksi sitä tarvitaan?
LLM-eval (arviointi) on systemaattinen menetelmä kielimallipohjaisen sovelluksen tuotosten laadun mittaamiseen. Sitä tarvitaan, koska kielimallit ovat epädeterministisiä — sama syöte voi tuottaa eri tuloksen joka kerralla. Ilman arviointijärjestelmää ei ole mahdollista tietää, paransiko viimeisin promptin muutos tuloksia vai huononsiko se niitä. Lyhyesti: eval on tuotantovalmiin LLM-sovelluksen perusinfrastruktuuri.
Miten LLM-as-a-Judge eroaa perinteisistä testausmenetelmistä?
Perinteiset testausmenetelmät vertaavat tulosta ennalta määriteltyyn oikeaan vastaukseen (esim. assert-lauseilla). LLM-as-a-Judge sen sijaan käyttää kielimallia tuomarina, joka arvioi vastauksen laadun joustavammin — se voi arvioida ammattimaisuutta, sävyä, kattavuutta ja muita laadullisia tekijöitä, joita perinteiset yksikkötestit eivät tavoita. Parhaimmillaan se yhdistää inhimillisen arvioinnin vivahteet automaattisen arvioinnin skaalautuvuuteen.
Kuinka paljon LLM-evalien ajaminen CI/CD-putkessa maksaa?
Kustannukset riippuvat testipaketin koosta ja käytetystä LLM-tuomarista. Tyypillinen 50 testitapauksen eval-paketti GPT-4o-tuomarilla maksaa noin 0,50–2,00 dollaria per ajo. Kustannuksia voi hallita välimuistilla (sama kysely ei tuota uutta kutsua), kerrostetulla testauksella (kevyt paketti PR:ssä, kattava yöajossa) ja polkupohjaisilla triggereillä (evalit ajetaan vain promptien tai pipelinen muuttuessa).
Mikä on paras tapa aloittaa LLM-sovellusten arviointi?
Anthropicin suositus on aloittaa pienestä: kerää 20–50 yksinkertaista testitapausta todellisista tuotantovirheistä. Varhaisessa vaiheessa muutokset tuottavat suuria vaikutuksia, joten pienet otoskoot riittävät. Valitse DeepEval, jos tiimisi käyttää Pythonia, tai Promptfoo, jos haluat YAML-pohjaisen kieliriippumattoman ratkaisun. Tärkeintä on aloittaa — epätäydellinen eval-paketti on äärettömästi parempi kuin ei eval-pakettia lainkaan.
Miten testataan, ettei kielimalli vuoda arkaluontoista tietoa?
Promptfoon red teaming -ominaisuus testaa automaattisesti prompt injection -hyökkäyksiä, jailbreak-yrityksiä ja henkilökohtaisten tietojen vuotamista (PII leak). Se simuloi eri hyökkäysstrategioita — mukaan lukien monikielisiä ohitusyrityksiä ja merkistömanipulaatioita — ja raportoi haavoittuvuudet. Tuotantojärjestelmässä tietoturvatestaus on ajettava sekä ennen käyttöönottoa että säännöllisesti tuotannossa.