Vertiefung

Ingest-Pipeline

Vom Upload bis zum Node: Typ-Erkennung, Extractor-Dispatch, Splitting und der Batch-ID-Bug.

01
Extractor-Dispatch

detect_file_type() mappt Extensions auf Typen. EXTRACTORS-Dict mappt Typen auf Funktionen. Jeder Extractor gibt ein Dict mit source, type, full_text und optionalen Split-Daten zurueck.

# 1. Extension → Typ
".pdf" → "pdf", ".docx" → "docx", ".xlsx" → "xlsx"

# 2. Typ → Extractor-Funktion
EXTRACTORS = {
  "pdf": extract_pdf, # pypdf + pdftotext
  "docx": extract_docx, # pandoc + python-docx
  "xlsx": extract_xlsx, # pandas
  ...
}
02
Splitting-Logik

_has_parts() prueft ob das extrahierte Dict genug Teile hat. sections braucht mindestens 2 Headings, pages mindestens 2 Seiten. Sonst Fallback auf single. Max 20 Nodes pro Split (--max-nodes).

# Splitting-Entscheidung
if split == "sections" and len(extracted["sections"]) > 1:
  → Ein Node pro Heading
elif split == "pages" and len(extracted["pages"]) > 1:
  → Ein Node pro Seite
else:
  → Fallback: single (ein Node)
03
Batch-ID und Duplikat-Check

Pro Split-Node: erst find_similar_nodes (Duplikat?), dann generate_id mit in-memory Index (Bug-Fix!), dann save_node + Index-Update. Alles in einer Schleife, Index wird erst am Ende auf Disk geschrieben.

for nd in nodes_to_create:
  similar = find_similar_nodes(ws, title, content)
  if similar and not force: skip!
  node_id = generate_id(type, ws, index) # in-memory!
  save_node(ws, node_id, content)
  index["nodes"][node_id] = {...}

save_index(ws, index) # erst HIER auf Disk