Icking AI-Pipeline — Audit-Report & Verdict
Stand: 2026-05-14. Drei parallele Sub-Agent-Audits + eigene Validierung. Repos lokal: ~/source/a-icking, ~/source/gaeb_converter.
Kurzfassung
Marvin’s drei Beschwerden gegen die Realität:
| Beschwerde | Realität | Quelle |
|---|---|---|
| ”Qualität passt nicht” | Teils richtig. Domain-Modell stimmt (Recall@1 49→85% nach Fine-Tuning, Feb 2026), aber Architektur drumrum ist Over-Engineering. SQL-Injection-Risiko in pg_client.py, drei verschiedene DB-Connection-Patterns, kein CI, ~400 LOC toter Hybrid-Code | architektur-audit |
| ”Dauert zu lange” (12s) | Bestätigt — aber nicht aus den Gründen die im BENCHMARK.md stehen. Hauptursachen: Retry-After: 5 zwingt Client zu 5s Wartezeit + Pipeline-Lambda hat nur 512MB (Cold-Start 2.5-4s) + SQS+Polling-Overhead. Modell-Lambdas sind provisioned, also NICHT Cold-Start-Problem | performance-audit |
| ”Kostet Geld im Monat” | AWS-Kosten zahlt Icking selbst (Account 063507503859, eigene Org). Marvin’s Belastung ist Maintenance-Zeit. Tatsächliche AWS-Idle-Kosten ~119 EUR/Monat, davon ~100 EUR für Provisioned Concurrency auf 2 Modell-Lambdas 24/7 | cost-audit + eigene Recherche |
Verdict: Refactor (2-3 Tage), kein Rewrite. Begründung unten.
Was da ist (Inventur)
Repo a-icking ist ~12k LOC Python, aber produktiver Kern ist nur ~1.500 LOC:
search_pipeline/(1.500 LOC) — Pipeline, DB-Client, Lambda-Handler, async-Reranklambdas/(320 LOC) — API-Handler, Auth-Handler, Status-Handlermodels/embedding+models/reranking(~150 LOC + Dockerfiles) — Container-Lambdas mit BGE-M3 + BGE-Rerankerdb/migrations/— 6 SQL-Files, sauber (pgvector + HNSW)
Der Rest ist Datascience-Material:
fine-tuning/(2.700 LOC) — SageMaker, GAEB-Extractor, Labeling-CLI- Eval-Scripts im Root (2.500 LOC) —
evaluate_baseline.py,evaluate_pipeline_local.py,generate_training_data.py, etc. terraform/mit Modulen + 4 Envs (dev1/prod/shared/global) — Struktur ist solide
Toter Code im Production-Pfad: run_batch, postgres_hybrid_search, SearchMode.HYBRID, build_keyword_boost_query — werden nur in Eval-Scripts aufgerufen, nicht vom Production-Handler. ~350-400 LOC.
Architektur — was wirklich falsch ist
-
SQS+Jobs+Polling für 10s-Workload (handler.py:75-83). Komplette Async-Maschinerie für eine Operation die in 30s-API-Gateway-Timeout passt. Kosten: 3 zusätzliche Hops +
Retry-After: 5= ~5-7s zusätzliche Wahrnehmungs-Latenz. Reason für die Architektur war wohl Erwartung dass Pipeline länger braucht — die Erwartung war falsch. -
Drei Lambdas wo eine reicht — Embedding-Lambda, Rerank-Lambda und Pipeline-Lambda sind getrennte Container. Beide Modell-Lambdas laden PyTorch+SentenceTransformers (~500MB Boot). Zusammen in einer Container-Lambda: ein Cold-Start statt zwei, ein boto3-Hop weniger.
-
Pipeline-Lambda nutzt
run()stattrun_batch()—cli.pyhat eine fertige optimierte Batch-Methode mit async-Rerank. Der Production-Handler ignoriert sie und feuert für jeden Query separat im ThreadPool. Toter Optimierungs-Pfad neben der echten Bahn. -
Drei DB-Connection-Patterns —
pg_client.pymit psycopg3+Pool,pg_jobs.pygreift auf denselben Pool zu aber ruft trotz autocommit einconn.commit(),status_handler/handler.pybenutzt psycopg2 ohne Pool und ohnesslmode=require. Inkonsistent. -
Kein CI —
.github/workflows/fehlt ina-icking(ingaeb_convertervorhanden). Tests existieren (1.770 LOC), laufen aber niemand automatisch. Erklärt warum keiner mehr weiß was funktioniert.
Code-Qualität — Blocker
- SQL-Injection via f-strings (pg_client.py:124,138,158,312,349,407). Aktuell betroffen sind nur Vector + numerische Werte → praktisch unkritisch. Aber:
postgres_hybrid_searchnimmt User-Text mit halbgaremreplace("'", "''"). Wenn Hybrid scharfgeschaltet wird: Injection-Vektor. - Nebeneffekt: Vector als f-string (1024 Floats ~10-20KB Query-Text) macht Postgres’ Prepared-Statement-Cache nutzlos. Jede Query ist neuer Parse+Plan → ~30-100ms unnötig.
pg_jobs.pynebenan macht es korrekt mitpsycopg.sql— das Muster existiert im Repo, wurde nur nicht angewendet.
Kosten — was wirklich abfließt
Account 063507503859 gehört Icking selbst (separate AWS-Org). Marvin zahlt nichts direkt. Aber Icking zahlt aktuell:
| Posten | EUR/Monat | Abschaltbar? |
|---|---|---|
| Provisioned Concurrency Embedding (2 × 3GB, 24/7) | ~33 | Ja, 1-Zeilen-Fix |
| Provisioned Concurrency Reranking (2 × 6GB, 24/7) | ~67 | Ja, 1-Zeilen-Fix |
| RDS db.t4g.micro Single-AZ + 20GB | ~16 | Nur durch Pause |
| Secrets/ECR/CloudWatch/Rest | ~3 | Egal |
| Idle-Summe | ~119 |
Top-Quick-Win: models_concurrency = -1 in app.tf:21. Spart 100 EUR/Monat. Cold-Start kommt zurück bei seltenen Requests — für Pilot-Phase akzeptabel.
Bei 50+ EUR/Monat Ersparnis könnte das ein gutes Argument an Icking sein wenn Marvin ein Phase-2-Festpreis-Angebot für den Refactor macht.
Performance — wo die 12s herkommen
Realer Breakdown (Annahme: Modell-Lambdas warm via Provisioned Concurrency, Pipeline-Lambda kalt):
| Phase | ms |
|---|---|
Retry-After: 5 zwingt Client zu 5s Wartezeit vor erstem Poll | 5.000 |
| Pipeline-Lambda Cold-Start (512MB, VPC) | 2.500-4.000 |
| Polling-Round-Trips (Client → Status-Handler) | 1.000-2.000 |
| SQS-Hop + Init | 500-1.000 |
| Embedding+Search+Rerank warm zusammen | 800-1.500 |
Wenn Retry-After: 5 raus, Pipeline-Memory auf 2GB, Models eager im Init geladen → realistisch 3-5s ohne Architektur-Refactor. Bei Refactor (sync Path, kombinierte Modell-Lambda): 500-900ms.
Phasen-Empfehlung
Phase 0 — Quick-Win-PR (1-2h, heute machbar)
Wirkung: 12s → 3-5s, Kosten 119 → 18 EUR/Monat. Ein einzelner PR.
- handler.py:79:
Retry-After: 5→Retry-After: 1 - app.tf:21:
models_concurrency = -1(Provisioned Concurrency aus, Lambda-Warmer übernimmt) - app.py:15-28:
_get_model()in Modul-Top-Level ziehen (eager Load in Lambda-Init-Phase, gratis) - app.py:30-35: dito
- main.tf: Pipeline-Lambda-Memory 512 → 2048 MB
- HNSW Query-Time-Recall:
SET hnsw.ef_search = 100inpg_client.pysetzen (bessere Recall-Qualität, ~0ms Latenz-Cost)
Phase 1 — Architektur-Refactor (2-3 Tage)
Wirkung: 3-5s → 500-900ms, Code-Komplexität halbiert, debuggbar in 5min.
- SQS + Jobs-Tabelle + Status-Handler + Polling raus. Sync Path: API Gateway → Pipeline-Lambda → Response. Bei Bedarf später WebSocket — aber nicht prophylaktisch.
- Embedding + Rerank in eine Container-Lambda mergen (~8GB Memory, 1 Cold-Start statt 2)
pg_client.pyneu mitpsycopg.sql+ Parameter-Binding (SQL-Injection + Prepared-Statement-Cache)- Toten Hybrid-Code +
run_batchlöschen (~400 LOC weg) status_handlerauf psycopg3 + Pool umstellen,sslmode=requireüberall- GitHub Actions: pytest auf PR, Terraform-plan auf main, Container-Build via CodeBuild bleibt
Phase 2 — Operations (1 Tag)
Wirkung: Pipeline ist in 5min debuggbar.
- X-Ray-Tracing über alle Lambdas
- Structured Logging mit
job_id(eigentlichrequest_idnach Sync-Umbau) als Correlation-ID - Health-Endpoint prüft Embedding-Lambda + DB + (falls noch da) SQS, nicht nur DB
- CloudWatch-Alarms im Terraform: p99-Latenz > 3s, Error-Rate > 1%, RDS-Connections > 80%
- ONBOARDING.md im Repo: ein 1h-Einstieg für neue Augen
Was NICHT zu tun ist
- Kein Rewrite from Scratch. Schema, Container-Modelle, Terraform-Module,
query_preprocessor(Maß-Extraktion DN/mm/m²),auth_handlersind keep-worthy. Rewrite kostet 2-3 Wochen statt 3-4 Tage Refactor. - Nicht das Fine-Tuned-Modell wegwerfen. Recall@1 49→85% ist real (
docs/fine-tuning-guide.md, Commits1669bb5). Daten + Training-Loop neu aufzubauen kostet Tage. ABER: prüfen ob das deployte Lambda-Image-Tag wirklich das fine-tuned Modell verwendet — Env-Variable inmodels/embedding/app.py:11zeigt hardcodedBAAI/bge-m3, fine-tuned kann nur über CodeBuild-Bake-Step im Image gelandet sein. - Nicht Mistral-Lambda als Judge einbauen (so im Vault als Phase 1 geplant). Die Pipeline braucht keinen LLM-Judge — der Cross-Encoder-Reranker macht das schon, und ein LLM-Call würde Latenz um 1-3s erhöhen. Falls Icking expliziten Wunsch hat: separates Feature, nicht in Phase 1.
Wirtschaftliche Einordnung
Im Vault stand die AI-Pipeline als Festpreis-Projekt 5.500 EUR in 2 Phasen (Phase 1: 3.000 EUR MVP, Phase 2: 2.500 EUR Tuning). MVP ist offensichtlich längst gebaut — Phase 2 wäre genau der Refactor oben. Phase-Status im Vault muss korrigiert werden (projekte/icking-heyjulia/_index.md + kunden/icking.md).
Realistisches Vorgehen: Phase 0 als Vertrauens-Beweis (1-2h, kostenlos im Rahmen), dann Phase 2 für 2.500 EUR mit konkretem Plan (siehe Phase 1+2 oben). Oder Phase 2 in zwei Hälften aufteilen — Phase-1-Notausgang-Pattern (siehe festpreis-phase1-notausgang) anwenden.
Open Questions (für Marvin zu klären)
- Ist die Pipeline aktuell überhaupt im aktiven Einsatz? Letzter Commit 12.02.2026, kein CI, keiner schaut drauf. Wenn niemand sie nutzt: Quick-Win-PR überflüssig, alles abschalten bis Smart Dach Next live ist.
- Was hat Florian für eine Position dazu? Er ist der einzige technische Ansprech bei Icking. Refactor-Plan muss er mit-tragen oder zumindest verstehen.
- Wer hat Image-Build-Rechte und wie wird neu deployed? CodeBuild läuft, aber Trigger ist unklar. Vor Phase 0 muss klar sein: wie kommt der Code nach Production?
- Vertragslage Phase 2: Existiert ein Festpreis-Angebot oder müsste das neu gemacht werden? Vault sagt nicht eindeutig ob versendet/akzeptiert.
Referenzen
- Detail-Audits: architektur-audit, cost-audit, performance-audit
- Vault: icking, _index
- Pattern: festpreis-phase1-notausgang
- Account-Topo: accounts (Icking-Account außerhalb unserer Org)