LLM-sovellusten arviointi tuotannossa: DeepEval, Promptfoo ja CI/CD käytännössä

LLM-sovellusten arviointi on tuotantovalmiin tekoälyjärjestelmän ydininfrastruktuuria. Opas kattaa DeepEval- ja Promptfoo-kehykset, LLM-as-a-Judge-menetelmän, CI/CD-integraation GitHub Actionsilla ja tuotannon seurannan Langfusella — käytännön koodiesimerkein.

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.

Tietoa Kirjoittajasta Editorial Team

Our team of expert writers and editors.