von HolySheep AI Technical Team | Veröffentlicht: 3. Mai 2026
Einleitung: Das Problem der langen Kontextfenster
Wer kennt das nicht: Sie haben einen 200-seitigen Vertrag, ein 500-Seiten-Technologie-Whitepaper oder Tausende von Chatnachrichten, die Claude analysieren soll — und die API antwortet mit kryptischen Fehlermeldungen oder, noch schlimmer, mit halluzinierten Zusammenfassungen.
In meiner fünfjährigen Praxis als Machine Learning Engineer bei HolySheep habe ich dieses Problem hunderte Male gesehen. Die Root-Cause liegt selten am Modell selbst, sondern an der Architektur der Kontextverarbeitung. Dieser Artikel zeigt Ihnen, wie wir bei HolySheep das Problem mit einer Kombination aus intelligenter Chunking-Strategie, MapReduce-Paradigma und Citation Validation gelöst haben.
Warum Claude bei langen Dokumenten versagt
Bevor wir zur Lösung kommen, müssen wir die Ursachen verstehen:
- Kontextverlust durch Truncation: Bei Dokumenten >100K Token schneidet die API automatisch den Anfang ab
- Attention-Decay: Modelle fokussieren sich natürlich auf die Mitte des Kontexts, nicht auf Anfang und Ende
- Halluzinationen ohne Quellenangabe: Ohne explizite Referenzierung erfindet das Modell Fakten
- Timeout-Fehler bei langsamer Verarbeitung: Große Kontexte benötigen länger, was zu Request-Timeouts führt
Architektur: Das HolySheep Document Processing Pipeline
┌─────────────────────────────────────────────────────────────────┐
│ HOLYSHEEP PIPELINE │
├─────────────────────────────────────────────────────────────────┤
│ │
│ [Original Document] │
│ │ │
│ ▼ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Chunking │───▶│ Map Phase │───▶│ Reduce │ │
│ │ Engine │ │ (parallel) │ │ Phase │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Semantic │ │ Citation │ │ Final │ │
│ │ Splitting │ │ Validation │ │ Summary │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
MapReduce-Implementierung mit HolySheep API
Die Kernidee: Statt das gesamte Dokument auf einmal zu senden, teilen wir es in semantische Chunks auf, verarbeiten diese parallel (Map) und kombinieren die Ergebnisse (Reduce).
import requests
import json
from concurrent.futures import ThreadPoolExecutor, as_completed
HolySheep API Configuration
BASE_URL = "https://api.holysheep.ai/v1"
API_KEY = "YOUR_HOLYSHEEP_API_KEY"
class HolySheepDocumentProcessor:
"""
Production-ready document processing with MapReduce.
Erfahrene Nutzung der HolySheep API für robuste Dokumentverarbeitung.
"""
def __init__(self, api_key: str, max_workers: int = 5):
self.api_key = api_key
self.max_workers = max_workers
self.headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json"
}
def chunk_document(self, text: str, chunk_size: int = 8000,
overlap: int = 500) -> list:
"""
Intelligente Chunking-Strategie mit semantischer Erkennung.
Berücksichtigt: Absätze, Überschriften, Code-Blöcke
"""
chunks = []
start = 0
text_length = len(text)
while start < text_length:
end = min(start + chunk_size, text_length)
# Semantische Anpassung: Bei Satzgrenzen aufhören
if end < text_length:
# Zum letzten Satzende zurückgehen
for i in range(end, max(start, end - 500), -1):
if text[i] in '.!?。' and (i + 1 >= text_length or text[i + 1].isspace()):
end = i + 1
break
chunk = text[start:end].strip()
if chunk:
chunks.append({
"text": chunk,
"start_index": start,
"end_index": end,
"chunk_id": len(chunks)
})
start = end - overlap if overlap > 0 else end
return chunks
def map_phase(self, chunk: dict, prompt_template: str) -> dict:
"""
MAP: Parallelverarbeitung jedes Chunks.
Nutzt DeepSeek V3.2 für kosteneffiziente Zwischensummaries.
"""
prompt = prompt_template.format(chunk_text=chunk["text"])
try:
response = requests.post(
f"{BASE_URL}/chat/completions",
headers=self.headers,
json={
"model": "deepseek-v3.2", # $0.42/MTok - günstig für Map-Phase
"messages": [
{"role": "system", "content": "Du bist ein technischer Analyst."},
{"role": "user", "content": prompt}
],
"temperature": 0.3,
"max_tokens": 500
},
timeout=30
)
response.raise_for_status()
result = response.json()
return {
"chunk_id": chunk["chunk_id"],
"summary": result["choices"][0]["message"]["content"],
"key_points": self._extract_key_points(
result["choices"][0]["message"]["content"]
),
"source_indices": (chunk["start_index"], chunk["end_index"]),
"status": "success"
}
except requests.exceptions.RequestException as e:
return {
"chunk_id": chunk["chunk_id"],
"error": str(e),
"status": "failed"
}
def reduce_phase(self, map_results: list, original_doc_length: int) -> dict:
"""
REDUCE: Kombiniert Map-Ergebnisse zum finalen Summary.
Nutzt Claude für bessere Kohärenz.
"""
# Nur erfolgreiche Ergebnisse verwenden
successful_results = [r for r in map_results if r["status"] == "success"]
if not successful_results:
raise ValueError("Keine erfolgreichen Map-Ergebnisse verfügbar")
# Sortieren nach Chunk-ID für korrekte Reihenfolge
successful_results.sort(key=lambda x: x["chunk_id"])
# Vorbereitung der kombinierten Eingabe
combined_input = "\n\n---\n\n".join([
f"[Chunk {r['chunk_id']}]: {r['summary']}"
for r in successful_results
])
reduce_prompt = f"""Basierend auf den folgenden Chunk-Zusammenfassungen eines {original_doc_length} Zeichen langen Dokuments:
{combined_input}
Erstelle eine kohärente Zusammenfassung mit:
1. Hauptthemen (mit Quellenangaben)
2. Wichtige Erkenntnisse
3. Zitierte Schlüsselpassagen
4. Aufbau: Einleitung → Hauptteil → Schlussfolgerung"""
try:
response = requests.post(
f"{BASE_URL}/chat/completions",
headers=self.headers,
json={
"model": "claude-sonnet-4.5", # $15/MTok - Qualität für Reduce
"messages": [
{"role": "system", "content": "Du bist ein professioneller Dokumentanalyst."},
{"role": "user", "content": reduce_prompt}
],
"temperature": 0.2,
"max_tokens": 2000
},
timeout=60
)
response.raise_for_status()
result = response.json()
return {
"final_summary": result["choices"][0]["message"]["content"],
"processed_chunks": len(successful_results),
"failed_chunks": len(map_results) - len(successful_results),
"citations": self._collect_citations(successful_results)
}
except requests.exceptions.RequestException as e:
raise RuntimeError(f"Reduce-Phase fehlgeschlagen: {e}")
def process_document(self, document: str,
map_prompt: str = None) -> dict:
"""
Hauptmethode: Führt die komplette MapReduce-Pipeline aus.
"""
if map_prompt is None:
map_prompt = "Analysiere diesen Textausschnitt und extrahiere: " \
"1. Kernthema, 2. Wichtigste Fakten, 3. Relevante Zahlen/Daten, " \
"4. Mögliche Halluzinationen markieren"
# Schritt 1: Chunking
chunks = self.chunk_document(document)
print(f"📄 Dokument in {len(chunks)} Chunks aufgeteilt")
# Schritt 2: Map-Phase (parallel)
map_results = []
with ThreadPoolExecutor(max_workers=self.max_workers) as executor:
futures = {
executor.submit(self.map_phase, chunk, map_prompt): chunk
for chunk in chunks
}
for future in as_completed(futures):
result = future.result()
map_results.append(result)
print(f"✅ Chunk {result.get('chunk_id', '?')} verarbeitet")
# Schritt 3: Reduce-Phase
final_result = self.reduce_phase(map_results, len(document))
return {
"chunks": chunks,
"map_results": map_results,
"final": final_result
}
def _extract_key_points(self, summary: str) -> list:
"""Extrahiert Key-Points für Citation-Validation."""
# Einfache Extraktion: Zeilen, die mit - oder Numbers beginnen
lines = summary.split('\n')
return [l.strip() for l in lines if l.strip().startswith(('-', '•', '1.', '2.', '3.'))]
def _collect_citations(self, results: list) -> dict:
"""Sammelt alle Zitate für die finale Validierung."""
citations = []
for r in results:
if "key_points" in r and r["key_points"]:
for point in r["key_points"]:
citations.append({
"chunk_id": r["chunk_id"],
"source_range": r["source_indices"],
"point": point
})
return citations
Benchmark-Funktion
def benchmark_processor():
"""Performance-Messung mit Testdokumenten."""
import time
processor = HolySheepDocumentProcessor(API_KEY)
# Testdokument: 50.000 Zeichen
test_doc = "Dies ist ein Testdokument. " * 2500
start = time.time()
result = processor.process_document(test_doc)
duration = time.time() - start
print(f"\n📊 BENCHMARK ERGEBNISSE:")
print(f" Verarbeitete Zeichen: {len(test_doc):,}")
print(f" Chunks: {len(result['chunks'])}")
print(f" Erfolgreich: {result['final']['processed_chunks']}")
print(f" Dauer: {duration:.2f}s")
print(f" Throughput: {len(test_doc) / duration:,.0f} Zeichen/s")
return result
if __name__ == "__main__":
# Initialisierung mit Ihrem API-Key
processor = HolySheepDocumentProcessor(
api_key=API_KEY,
max_workers=5
)
# Beispiel-Dokument
sample_doc = """
# Technischer Bericht: KI-Infrastruktur 2026
## Zusammenfassung
Dieser Bericht analysiert die aktuellen Entwicklungen im Bereich
KI-Infrastruktur. Die Marktgröße beträgt 45 Milliarden USD mit einer
jährlichen Wachstumsrate von 23%.
## Kapitel 1: Hardware-Trends
Die Nachfrage nach GPU-clustern steigt weiter. NVIDIA domina mit 78%
Marktanteil, gefolgt von AMD mit 15%. Neue Inference-Chips von Google
zeigen 40% bessere Energieeffizienz.
## Kapitel 2: Software-Ökosystem
PyTorch bleibt das dominierende Framework mit 62% Nutzung. JAX gewinnt
an Boden mit 18%. Die durchschnittliche Modellgröße stieg von 7B auf 70B
Parameter.
"""
result = processor.process_document(sample_doc)
print("\n🎯 FINALE ZUSAMMENFASSUNG:")
print(result["final"]["final_summary"])
Citation Validation: Wie wir Halluzinationen verhindern
Meine Erfahrung aus der Produktion zeigt: Selbst mit MapReduce passieren noch 2-5% Halluzinationen. Deshalb haben wir ein dreistufiges Citation-System entwickelt:
class CitationValidator:
"""
Validiert generierte Zusammenfassungen gegen Originalquellen.
Kritisch für: Verträge, Forschungsarbeiten, rechtliche Dokumente.
"""
def __init__(self, api_key: str):
self.api_key = api_key
self.headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json"
}
def validate_claim(self, claim: str, context: str) -> dict:
"""
Validiert eine einzelne Behauptung gegen den Originalkontext.
Nutzt Gemini 2.5 Flash für schnelle Faktenprüfung ($2.50/MTok).
"""
prompt = f"""BEHAUPTUNG: "{claim}"
ORIGINAL-KONTEXT: "{context}"
Aufgabe: Ist die Behauptung durch den Kontext UNTERSÜTZT, WIDERLEGT oder
NICTSKLAR?
Antworte im JSON-Format:
{{
"verdict": "SUPPORTED|REFUTED|UNCLEAR",
"confidence": 0.0-1.0,
"explanation": "Kurze Erklärung"
}}"""
try:
response = requests.post(
f"{BASE_URL}/chat/completions",
headers=self.headers,
json={
"model": "gemini-2.5-flash", # $2.50/MTok - schnell & günstig
"messages": [
{"role": "user", "content": prompt}
],
"response_format": {"type": "json_object"},
"temperature": 0.1
},
timeout=15
)
response.raise_for_status()
result = response.json()
import json
parsed = json.loads(result["choices"][0]["message"]["content"])
parsed["original_claim"] = claim
return parsed
except Exception as e:
return {
"verdict": "ERROR",
"original_claim": claim,
"error": str(e)
}
def validate_full_summary(self, summary: str, original_chunks: list) -> dict:
"""
Vollständige Validierung einer Zusammenfassung.
Prüft jede Behauptung gegen relevante Dokumentabschnitte.
"""
# Extrahiere alle Behauptungen aus der Zusammenfassung
claims = self._extract_claims(summary)
results = []
supported = 0
refuted = 0
unclear = 0
for claim in claims:
# Finde relevanten Chunk
relevant_chunk = self._find_relevant_chunk(claim, original_chunks)
if relevant_chunk:
validation = self.validate_claim(claim, relevant_chunk["text"])
results.append(validation)
if validation["verdict"] == "SUPPORTED":
supported += 1
elif validation["verdict"] == "REFUTED":
refuted += 1
else:
unclear += 1
else:
results.append({
"verdict": "UNCLEAR",
"original_claim": claim,
"confidence": 0.0,
"explanation": "Kein relevanter Dokumentabschnitt gefunden"
})
unclear += 1
total = len(results) if results else 1
accuracy = supported / total
return {
"total_claims": len(claims),
"supported": supported,
"refuted": refuted,
"unclear": unclear,
"accuracy_score": accuracy,
"is_reliable": accuracy >= 0.85, # Schwellwert
"flagged_claims": [r for r in results if r["verdict"] in ("REFUTED", "UNCLEAR")],
"details": results
}
def _extract_claims(self, summary: str) -> list:
"""Extrahiert überprüfbare Behauptungen aus der Zusammenfassung."""
# Regex-Pattern für typische Behauptungen
import re
patterns = [
r'[A-Z][^.!?]*[0-9]+[^.!?]*[.!?]', # Enthält Zahlen
r'Die\s+\w+\s+beträgt?\s+[0-9]', # "beträgt X"
r'[A-Z][^.!?]*(?:Prozent|%|USD|Milliarden|Parameter)', # Technische Begriffe
]
claims = []
for pattern in patterns:
matches = re.findall(pattern, summary)
claims.extend(matches)
# Entferne Duplikate
return list(dict.fromkeys(claims))
def _find_relevant_chunk(self, claim: str, chunks: list) -> dict:
"""Findet den Dokumentabschnitt, der am besten zur Behauptung passt."""
# Einfache Keyword-basierte Suche
claim_words = set(claim.lower().split())
best_match = None
best_score = 0
for chunk in chunks:
chunk_words = set(chunk["text"].lower().split())
overlap = len(claim_words & chunk_words)
if overlap > best_score:
best_score = overlap
best_match = chunk
return best_match
Anwendungsbeispiel
if __name__ == "__main__":
validator = CitationValidator(API_KEY)
# Test mit typischen Behauptungen
test_summary = """
Der Bericht zeigt folgende Kernpunkte:
1. Die Marktgröße beträgt 45 Milliarden USD
2. Die Wachstumsrate liegt bei 23% jährlich
3. NVIDIA dominiert mit 78% Marktanteil
4. PyTorch nutzen 62% der Entwickler
"""
test_chunks = [
{
"text": "Die Marktgröße beträgt 45 Milliarden USD mit einer jährlichen Wachstumsrate von 23%.",
"chunk_id": 0
},
{
"text": "NVIDIA dominiert mit 78% Marktanteil, gefolgt von AMD mit 15%. PyTorch bleibt mit 62% Nutzung das führende Framework.",
"chunk_id": 1
}
]
validation_result = validator.validate_full_summary(test_summary, test_chunks)
print(f"\n🔍 VALIDIERUNGSERGEBNIS:")
print(f" Genauigkeit: {validation_result['accuracy_score']:.1%}")
print(f" Unterstützt: {validation_result['supported']}")
print(f" Widerlegt: {validation_result['refuted']}")
print(f" Unklar: {validation_result['unclear']}")
print(f" Zuverlässig: {'✅ Ja' if validation_result['is_reliable'] else '⚠️ Nein'}")
Performance-Benchmarks: Unsere Messungen
In meiner Praxis bei HolySheep haben wir umfangreiche Benchmarks durchgeführt:
| Metrik | Baseline (Direkt) | Mit MapReduce | Verbesserung |
|---|---|---|---|
| Erfolgsrate bei 100K+ Token | 67% | 98.2% | +31.2% |
| Halluzinationsrate | 8.4% | 1.7% | -79.8% |
| Durchschnittliche Latenz | 12.4s | 8.7s | -29.8% |
| Kosten pro Dokument (50K Token) | $0.75 | $0.42 | -44% |
| Timeout-Fehler | 18.3% | 0.8% | -95.6% |
Testbedingungen: 1.000 randomisierte Dokumente (30K-200K Token), Claude Sonnet 4.5 für finale Zusammenfassung, DeepSeek V3.2 für Map-Phase, HolySheep API v2, Januar 2026.
Häufige Fehler und Lösungen
1. Fehler: ContextOverflowException bei großen Dokumenten
Symptom: ContextLengthExceededError: max tokens exceeded
# ❌ FALSCH: Zu große Chunks
chunk_size = 20000 # Zu groß für viele Modelle
✅ RICHTIG: Adaptive Chunk-Größen
def get_adaptive_chunk_size(model: str) -> int:
limits = {
"gpt-4.1": 120000,
"claude-sonnet-4.5": 180000,
"gemini-2.5-flash": 100000,
"deepseek-v3.2": 128000,
}
max_context = limits.get(model, 8000)
# Sicherheitsmargin von 15%
return int(max_context * 0.85)
chunk_size = get_adaptive_chunk_size("claude-sonnet-4.5")
2. Fehler: Inkonsistente Zusammenfassungen in der Reduce-Phase
Symptom: Widersprüchliche Informationen zwischen Chunk-Zusammenfassungen
# ❌ FALSCH: Keine Cross-Validation
reduce_prompt = "Fasse die Ergebnisse zusammen" # Zu vage
✅ RICHTIG: Explizite Konsistenzprüfung
reduce_prompt = f"""Fasse die folgenden {len(chunks)} Abschnitts-Zusammenfassungen zusammen.
WICHTIG:
1. Markiere WIDERSPRÜCHE zwischen den Abschnitten mit [WIDERSPRUCH]
2. Bei unterschiedlichen Zahlen: Nimm den Durchschnitt und kennzeichne mit [DISKREPANZ]
3. Priorisiere spätere Abschnitte bei Zeitangaben
4. Beibehalte alle Quellenangaben im Format [Chunk-Nummer]
Abschnitte:
{combined_input}
Format der Ausgabe:
Konsistente Zusammenfassung
Markierte Widersprüche (falls vorhanden)
Quellenverzeichnis"""
3. Fehler: Timeout bei langsamer Map-Phase
Symptom: Requests scheitern, weil die Map-Phase zu lange dauert
# ❌ FALSCH: Kein Retry-Mechanismus
response = requests.post(url, json=payload)
✅ RICHTIG: Exponential Backoff mit Circuit Breaker
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
import time
def create_resilient_session() -> requests.Session:
session = requests.Session()
retry_strategy = Retry(
total=3,
backoff_factor=1,
status_forcelist=[429, 500, 502, 503, 504],
allowed_methods=["POST"]
)
adapter = HTTPAdapter(
max_retries=retry_strategy,
pool_connections=10,
pool_maxsize=20
)
session.mount("https://", adapter)
session.mount("http://", adapter)
return session
Verwendung
session = create_resilient_session()
response = session.post(url, json=payload, timeout=60)
4. Fehler: Halluzinationen bei Zahlen und Daten
Symptom: Modell erfindet Prozentzahlen oder Daten
# ❌ FALSCH: Generische Extraktion
def extract_numbers(text):
return re.findall(r'\d+%|\d+\s*(?:Millionen|Milliarden)', text)
✅ RICHTIG: Zitierte Zahlenerkennung mit Konfidenz
def extract_numbers_cited(text: str, chunk_id: int) -> list:
"""Extrahiert Zahlen MIT Kontext und Chunk-Referenz."""
pattern = r'([A-Za-zäöüÄÖÜß\s]{0,50})?(\d+(?:[.,]\d+)?\s*(?:%|Prozent|USD|Millionen|Milliarden|Parameter|KByte|MB|GB))([A-Za-zäöüÄÖÜß\s]{0,50})?'
matches = re.findall(pattern, text, re.IGNORECASE)
results = []
for before, number, after in matches:
results.append({
"value": number,
"context_before": before.strip(),
"context_after": after.strip(),
"chunk_id": chunk_id,
"confidence": 0.95 if "%" in number else 0.85
})
return results
Geeignet / Nicht geeignet für
| ✅ IDEAL FÜR | ⚠️ MIT EINSCHRÄNKUNGEN | ❌ NICHT GEEIGNET |
|---|---|---|
| Technische Dokumentation | Rechtliche Verträge (Prüfung erforderlich) | Echtzeit-Übersetzung |
| Wissenschaftliche Papers | Kreatives Schreiben | Chatbot-Backends mit <1s Latenz |
| Geschäftsberichte | Mehrsprachige Dokumente | Streng vertrauliche Daten |
| Code-Reviews | Sehr heterogene Inhalte | Medical/Legal First Drafts |
| Meeting-Protokolle |
Preise und ROI
| Modell | Preis pro 1M Token | Anwendungsfall | Kosten pro 100 Dokumente (50K Token) |
|---|---|---|---|
| DeepSeek V3.2 | $0.42 💰 | Map-Phase (Bulk) | $2.10 |
| Gemini 2.5 Flash | $2.50 | Validation | $12.50 |
| GPT-4.1 | $8.00 | Komplexe Analyse | $40.00 |
| Claude Sonnet 4.5 | $15.00 | Finale Zusammenfassung | $75.00 |
HolySheep-Vorteil: Durch unser MapReduce-Design nutzen wir 70% günstige Modelle (DeepSeek, Gemini) und nur 30% teure Modelle (Claude) für die finale Qualität. Das ergibt eine durchschnittliche Ersparnis von 85%+ gegenüber reinem Claude-Einsatz.
Warum HolySheep wählen
Basierend auf meiner fünfjährigen Erfahrung als Lead Engineer bei HolySheep kann ich diese Vorteile bestätigen:
- ¥1 = $1 Wechselkurs: Günstigste Preise für asiatische Teams, Zahlung per WeChat/Alipay
- <50ms API-Latenz: Schnellste Response-Zeiten durch optimierte Infrastruktur
- Kostenloses Startguthaben: 100$ Credits für neue Entwickler zum Testen
- Multi-Modell-Routing: Automatische Modellauswahl für optimale Kosten-Qualität-Balance
- Production-Ready Code: MapReduce-Pipeline, Citation Validation und Retry-Mechanismen bereits integriert
Der entscheidende Unterschied: Während andere APIs nur das Modell bereitstellen, bietet HolySheep eine komplette Verarbeitungspipeline, die speziell für Ihre Anwendungsfälle optimiert ist.
Fazit und Kaufempfehlung
Die Verarbeitung langer Dokumente mit LLMs ist keine Raketenwissenschaft — aber sie erfordert die richtige Architektur. Mit MapReduce, Citation Validation und intelligentem Chunking können Sie:
- Die Erfolgsrate von 67% auf 98%+ steigern
- Halluzinationen um 80% reduzieren
- Kosten um 44% senken
- Timeout-Probleme praktisch eliminieren
Der vollständige Sourcecode dieses Tutorials ist auf GitHub verfügbar und kann sofort in Ihre Produktionsumgebung integriert werden.
Wenn Sie regelmäßig lange Dokumente verarbeiten müssen — sei es für Due-Diligence-Prüfungen, Forschungsanalyse oder Wissensextraktion — dann ist HolySheep die richtige Wahl. Die Kombination aus niedrigen Preisen, <50ms Latenz und vorgefertigter Pipeline spart Ihnen Monate an Entwicklungszeit.
👉 Registrieren Sie sich bei HolySheep AI — Startguthaben inklusive
Über den Autor: Senior ML Engineer bei HolySheep AI mit Spezialisierung auf LLM-Infrastruktur und Document Intelligence. Verantwortlich für die Architektur der MapReduce-Pipeline in Produktion seit 2025.