Přeskočit na obsah
_CORE
AI & Agentic Systems Core Informační Systémy Cloud & Platform Engineering Data Platforma & Integrace Security & Compliance QA, Testing & Observability IoT, Automatizace & Robotika Mobile & Digital Banky & Finance Pojišťovnictví Veřejná správa Obrana & Bezpečnost Zdravotnictví Energetika & Utility Telco & Média Průmysl & Výroba Logistika & E-commerce Retail & Loyalty
Reference Technologie Blog Knowledge Base O nás Spolupráce Kariéra
Pojďme to probrat

LLM Hallucination Detection

01. 01. 2024 5 min čtení intermediate

Halucinace LLM představují jeden z největších problémů současných AI systémů - modely často generují informace, které vypadají věrohodně, ale jsou fakticky nesprávné. Tento článek prozkoumává efektivní metody detekce a prevence halucinací u velkých jazykových modelů a AI agentů.

Co jsou halucinace v LLM a proč je důležité je detekovat

Halucinace v kontextu Large Language Models (LLM) označují situace, kdy model generuje informace, které jsou fakticky nesprávné, zavádějící nebo zcela vymyšlené, přestože je prezentuje s vysokou mírou důvěry. Tento fenomén představuje jeden z největších výzev při nasazování LLM v produkčních systémech, zejména v aplikacích vyžadujících vysokou spolehlivost dat.

Halucinace se mohou projevovat různými způsoby - od inventování neexistujících faktů, přes nesprávné citace zdrojů, až po vytváření fiktivních API endpointů nebo konfigurací. Pro enterprise aplikace je proto klíčové implementovat robustní mechanismy pro jejich detekci.

Typy halucínací a jejich charakteristiky

Rozlišujeme několik kategorií halucínací podle jejich povahy:

  • Faktické halucinace - nesprávné historické údaje, statistiky nebo vědecké informace
  • Strukturální halucinace - neexistující API endpoints, chybné konfigurační parametry
  • Kontextuální halucinace - informace, které jsou samy o sobě správné, ale neodpovídají danému kontextu
  • Referenční halucinace - citace neexistujících zdrojů, dokumentů nebo studií

Technické přístupy k detekci halucínací

Statistické metody na základě confidence scoring

Jeden z nejpřímočařejších přístupů využívá analýzu pravděpodobnostních rozdělení tokenů generovaných modelem. Implementace může vypadat následovně:

import numpy as np
from transformers import AutoTokenizer, AutoModelForCausalLM
import torch

class ConfidenceDetector:
    def __init__(self, model_name):
        self.tokenizer = AutoTokenizer.from_pretrained(model_name)
        self.model = AutoModelForCausalLM.from_pretrained(model_name)

    def calculate_uncertainty(self, text, context=""):
        inputs = self.tokenizer(context + text, return_tensors="pt")

        with torch.no_grad():
            outputs = self.model(**inputs)
            logits = outputs.logits[0, -len(self.tokenizer(text)["input_ids"]):]

        # Výpočet entropie pro každý token
        probs = torch.softmax(logits, dim=-1)
        entropy = -torch.sum(probs * torch.log(probs + 1e-9), dim=-1)

        # Průměrná nejistota
        avg_uncertainty = torch.mean(entropy).item()

        return {
            "average_uncertainty": avg_uncertainty,
            "max_uncertainty": torch.max(entropy).item(),
            "high_uncertainty_ratio": (entropy > np.percentile(entropy.numpy(), 75)).float().mean().item()
        }

Semantic consistency checking

Pokročilejší přístup ověřuje sémantickou konzistenci generované odpovědi vůči známým faktům nebo poskytnutému kontextu:

from sentence_transformers import SentenceTransformer
from sklearn.metrics.pairwise import cosine_similarity
import requests

class SemanticConsistencyChecker:
    def __init__(self):
        self.encoder = SentenceTransformer('all-MiniLM-L6-v2')

    def check_factual_consistency(self, claim, knowledge_base):
        """
        Ověří konzistenci tvrzení vůči knowledge base
        """
        claim_embedding = self.encoder.encode([claim])

        similarities = []
        for fact in knowledge_base:
            fact_embedding = self.encoder.encode([fact])
            similarity = cosine_similarity(claim_embedding, fact_embedding)[0][0]
            similarities.append(similarity)

        max_similarity = max(similarities) if similarities else 0

        return {
            "max_similarity": max_similarity,
            "is_supported": max_similarity > 0.7,
            "confidence": max_similarity
        }

    def detect_contradictions(self, generated_text, context):
        """
        Detekuje kontradikce mezi generovaným textem a kontextem
        """
        sentences = generated_text.split('.')
        context_embedding = self.encoder.encode([context])

        contradictions = []
        for sentence in sentences:
            if len(sentence.strip()) < 10:
                continue

            sentence_embedding = self.encoder.encode([sentence])
            similarity = cosine_similarity(sentence_embedding, context_embedding)[0][0]

            if similarity < 0.3:  # Nízká podobnost může indikovat kontradikci
                contradictions.append({
                    "sentence": sentence,
                    "similarity": similarity
                })

        return contradictions

External validation přístup

Pro kritické aplikace je často nutné ověřovat generované informace proti externím zdrojům:

import asyncio
import aiohttp
from typing import List, Dict

class ExternalValidator:
    def __init__(self, api_keys: Dict[str, str]):
        self.api_keys = api_keys

    async def validate_factual_claims(self, claims: List[str]) -> List[Dict]:
        """
        Asynchronní ověření faktických tvrzení proti externím API
        """
        results = []

        async with aiohttp.ClientSession() as session:
            tasks = [self._validate_single_claim(session, claim) for claim in claims]
            results = await asyncio.gather(*tasks, return_exceptions=True)

        return results

    async def _validate_single_claim(self, session, claim: str):
        # Příklad integrace s Wikipedia API
        search_url = "https://en.wikipedia.org/api/rest_v1/page/summary/"

        try:
            # Extrakce klíčových entit z tvrzení (zjednodušeno)
            entities = self._extract_entities(claim)

            validation_results = []
            for entity in entities:
                async with session.get(f"{search_url}{entity}") as response:
                    if response.status == 200:
                        data = await response.json()
                        validation_results.append({
                            "entity": entity,
                            "found": True,
                            "summary": data.get("extract", "")
                        })
                    else:
                        validation_results.append({
                            "entity": entity,
                            "found": False,
                            "summary": None
                        })

            return {
                "claim": claim,
                "validations": validation_results,
                "confidence": sum(1 for v in validation_results if v["found"]) / len(validation_results)
            }

        except Exception as e:
            return {"claim": claim, "error": str(e), "confidence": 0.0}

    def _extract_entities(self, text: str) -> List[str]:
        # Zjednodušená extrakce entit - v praxi použijte NER model
        import re
        # Hledá slova začínající velkým písmenem (možné vlastní jména)
        entities = re.findall(r'\b[A-Z][a-z]+(?:\s+[A-Z][a-z]+)*\b', text)
        return list(set(entities))

Implementace pipeline pro detekci halucínací

V produkčním prostředí je efektivní kombinovat více přístupů do jednotného pipeline:

class HallucinationDetectionPipeline:
    def __init__(self, config):
        self.confidence_detector = ConfidenceDetector(config["model_name"])
        self.semantic_checker = SemanticConsistencyChecker()
        self.external_validator = ExternalValidator(config["api_keys"])
        self.thresholds = config["thresholds"]

    async def analyze_response(self, generated_text: str, context: str = "", knowledge_base: List[str] = None):
        """
        Komplexní analýza generované odpovědi
        """
        results = {
            "text": generated_text,
            "hallucination_probability": 0.0,
            "details": {}
        }

        # 1. Confidence scoring
        confidence_results = self.confidence_detector.calculate_uncertainty(generated_text, context)
        results["details"]["confidence"] = confidence_results

        # 2. Semantic consistency
        if knowledge_base:
            consistency_results = self.semantic_checker.check_factual_consistency(
                generated_text, knowledge_base
            )
            results["details"]["semantic_consistency"] = consistency_results

        # 3. Contradiction detection
        contradictions = self.semantic_checker.detect_contradictions(generated_text, context)
        results["details"]["contradictions"] = contradictions

        # 4. External validation (pro kritické případy)
        claims = self._extract_factual_claims(generated_text)
        if claims:
            validation_results = await self.external_validator.validate_factual_claims(claims)
            results["details"]["external_validation"] = validation_results

        # Výpočet celkové pravděpodobnosti halucinace
        results["hallucination_probability"] = self._calculate_overall_probability(results["details"])

        return results

    def _calculate_overall_probability(self, details: Dict) -> float:
        """
        Kombinuje výsledky z různých detektorů do celkového skóre
        """
        probability = 0.0

        # Confidence-based scoring
        if "confidence" in details:
            uncertainty = details["confidence"]["average_uncertainty"]
            probability += min(uncertainty / 5.0, 0.4)  # Max 40% příspěvek

        # Semantic consistency
        if "semantic_consistency" in details and not details["semantic_consistency"]["is_supported"]:
            probability += 0.3

        # Contradictions
        if "contradictions" in details and len(details["contradictions"]) > 0:
            probability += min(len(details["contradictions"]) * 0.2, 0.5)

        # External validation
        if "external_validation" in details:
            avg_confidence = sum(v.get("confidence", 0) for v in details["external_validation"]) / len(details["external_validation"])
            probability += (1 - avg_confidence) * 0.4

        return min(probability, 1.0)

    def _extract_factual_claims(self, text: str) -> List[str]:
        # Zjednodušená extrakce faktických tvrzení
        sentences = [s.strip() for s in text.split('.') if len(s.strip()) > 20]
        return sentences[:3]  # Omezte na první 3 pro rychlost

Optimalizace performance a škálování

Pro produkční nasazení je důležité zvážit výkonnostní aspekty detekce halucínací. Implementace caching mechanismů a asynchronního zpracování může výrazně zlepšit responseivnost:

import redis
import hashlib
import json
from typing import Optional

class CachedHallucinationDetector:
    def __init__(self, pipeline, redis_client: redis.Redis):
        self.pipeline = pipeline
        self.redis = redis_client
        self.cache_ttl = 3600  # 1 hodina

    def _generate_cache_key(self, text: str, context: str) -> str:
        content = f"{text}:{context}"
        return f"hallucination:{hashlib.md5(content.encode()).hexdigest()}"

    async def analyze_with_cache(self, text: str, context: str = ""):
        cache_key = self._generate_cache_key(text, context)

        # Pokus o získání z cache
        cached_result = self.redis.get(cache_key)
        if cached_result:
            return json.loads(cached_result)

        # Analýza a uložení do cache
        result = await self.pipeline.analyze_response(text, context)
        self.redis.setex(cache_key, self.cache_ttl, json.dumps(result, default=str))

        return result

Shrnutí

Detekce halucínací v LLM je komplexní problém vyžadující kombinaci statistických, sémantických a validačních přístupů. Klíčem k úspěchu je implementace vícevrstvého pipeline, který kombinuje rychlé heuristické metody s důkladnějšími validačními technikami. Pro produkční nasazení je nezbytné zvážit trade-off mezi přesností detekce a výkonností systému, implementovat vhodné caching mechanismy a průběžně monitorovat efektivitu detekčních algoritmů na reálných datech.

halucinacellmkvalita