Přeskočit na obsah
LLM & Agenti

LLM Hallucination Detection

8 min čtení
HalucinaceLLMKvalita

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.

CORE SYSTEMS tým

Enterprise architekti a AI inženýři.