Skip to content

Commit 23b320f

Browse files
abossardCopilot
andcommitted
Add markdown explanations before every code cell, collapse setup
Every visible code cell now has a German markdown header explaining what the user will see and why it matters. Setup cells collapsed. Fixed compare_models import (removed from simplified actions.py). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent ea31ae9 commit 23b320f

5 files changed

Lines changed: 758 additions & 12 deletions

File tree

notebooks/01_evaluation_and_tuning.ipynb

Lines changed: 225 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,22 @@
2323
"> Zuerst musst du einmal das ./start.sh laufen lassen.\n"
2424
]
2525
},
26+
{
27+
"cell_type": "markdown",
28+
"metadata": {},
29+
"source": [
30+
"## Worum geht's hier?\n",
31+
"\n",
32+
"Dieses Notebook hat zwei Teile:\n",
33+
"\n",
34+
"1. **Teil 1** — Wir rufen ein LLM auf, sehen wo es Fehler macht, und lernen 5 Strategien dagegen\n",
35+
"2. **Teil 2** — Wir messen Qualität mit Metriken und tunen Prompts — erst manuell, dann mit Benchmarks\n",
36+
"\n",
37+
"Am Ende weisst du: Wie gut ist mein Modell? Und wie mache ich es besser?\n",
38+
"\n",
39+
"> **Tipp:** Jede Code-Zelle kannst du mit Shift+Enter ausführen. Die Ergebnisse erscheinen direkt darunter.\n"
40+
]
41+
},
2642
{
2743
"cell_type": "markdown",
2844
"id": "2d33f653",
@@ -54,6 +70,17 @@
5470
"from dspy_tasks.visualize import model_picker, display_score, display_insight, display_tier_header"
5571
]
5672
},
73+
{
74+
"cell_type": "markdown",
75+
"metadata": {},
76+
"source": [
77+
"## 🗺️ Die Reise durch alle Notebooks\n",
78+
"\n",
79+
"Hier siehst du die fünf Stationen auf einen Blick. Wir starten mit **Evaluation** — also der Frage: *Wie gut ist mein Modell eigentlich?*\n",
80+
"\n",
81+
"Jedes Notebook baut auf dem vorherigen auf. Am Ende hast du ein komplettes Bild davon, wie man KI-Systeme systematisch verbessert.\n"
82+
]
83+
},
5784
{
5885
"cell_type": "code",
5986
"execution_count": 15,
@@ -133,11 +160,26 @@
133160
"Über LiteLLM kannst du über 100 verschiedene Modelle ansprechen. Die verfügbaren Modelle werden automatisch aus deiner `.env`-Konfiguration erkannt."
134161
]
135162
},
163+
{
164+
"cell_type": "markdown",
165+
"metadata": {},
166+
"source": [
167+
"### ⚙️ Modell auswählen\n",
168+
"\n",
169+
"Die nächste Zelle erstellt ein Dropdown-Menü mit allen verfügbaren Modellen. Wähl eins aus — du kannst es jederzeit wechseln und die Ergebnisse vergleichen.\n",
170+
"\n",
171+
"Die Modelle kommen aus deiner `.env`-Datei. Wenn du dort nichts konfiguriert hast, wird automatisch das Standard-Modell verwendet.\n"
172+
]
173+
},
136174
{
137175
"cell_type": "code",
138176
"execution_count": 16,
139177
"id": "36a9e6fb",
140-
"metadata": {},
178+
"metadata": {
179+
"jupyter": {
180+
"source_hidden": true
181+
}
182+
},
141183
"outputs": [
142184
{
143185
"data": {
@@ -176,6 +218,19 @@
176218
"Lass uns das Modell auf **Fragen mit bekannter Antwort** testen — und schauen wo es richtig liegt und wo es **daneben haut**.\n"
177219
]
178220
},
221+
{
222+
"cell_type": "markdown",
223+
"metadata": {},
224+
"source": [
225+
"### 🧪 Lass uns das Modell auf die Probe stellen\n",
226+
"\n",
227+
"Wir geben ihm bewusst schwierige Fragen — mit bekannten Antworten. Manche sind Wissensfragen, manche brauchen Rechnen, manche sind absichtlich mehrdeutig.\n",
228+
"\n",
229+
"**Schau genau hin:** Wo antwortet das Modell richtig? Wo liegt es daneben? Und vor allem — *warum?*\n",
230+
"\n",
231+
"Das ist der erste Aha-Moment: LLMs klingen überzeugend, aber sie sind nicht immer korrekt. Das zu erkennen ist der erste Schritt zu besseren Prompts.\n"
232+
]
233+
},
179234
{
180235
"cell_type": "code",
181236
"execution_count": 17,
@@ -316,6 +371,19 @@
316371
"Du lässt ein **zweites LLM** bewerten: *\"Sagt diese Antwort inhaltlich das Gleiche wie die Referenz?\"* Das klingt verrückt, funktioniert aber erstaunlich gut.\n"
317372
]
318373
},
374+
{
375+
"cell_type": "markdown",
376+
"metadata": {},
377+
"source": [
378+
"### 🔧 Strategie 1 ausprobieren: Antwort einschränken\n",
379+
"\n",
380+
"Jetzt setzen wir die erste Strategie direkt um: Wir sagen dem Modell, es soll **nur** mit einem Wort, einer Zahl, Ja oder Nein antworten.\n",
381+
"\n",
382+
"Das klingt simpel, aber es ist erstaunlich effektiv. Wenn du dem Modell weniger Freiheit gibst, macht es weniger Fehler.\n",
383+
"\n",
384+
"**Klick Run** und vergleiche die Ergebnisse mit den vorherigen — siehst du den Unterschied?\n"
385+
]
386+
},
319387
{
320388
"cell_type": "code",
321389
"execution_count": 18,
@@ -375,6 +443,26 @@
375443
"print(\"👆 Viel einfacher zu vergleichen wenn die Antwort eingeschränkt ist!\")\n"
376444
]
377445
},
446+
{
447+
"cell_type": "markdown",
448+
"metadata": {},
449+
"source": [
450+
"### ⚖️ Strategie 5: LLM-as-Judge\n",
451+
"\n",
452+
"Die spannendste Strategie: Wir lassen ein **zweites LLM** die Antworten des ersten bewerten. Das ist wie ein automatischer Korrektor.\n",
453+
"\n",
454+
"Warum funktioniert das? Weil *bewerten* einfacher ist als *antworten*. Du musst kein Buch schreiben können, um eine Buchrezension zu machen.\n",
455+
"\n",
456+
"Schau dir an, welche Antworten der Judge als korrekt durchgehen lässt, die vorher als \"falsch\" galten — obwohl sie inhaltlich richtig waren.\n"
457+
]
458+
},
459+
{
460+
"cell_type": "markdown",
461+
"metadata": {},
462+
"source": [
463+
"## 🧑‍⚖️ Strategie 5 ausprobieren: LLM als Richter\n\nEin zweites LLM bewertet, ob die Antwort **inhaltlich** korrekt ist — auch wenn die Worte ganz anders sind. \"Acht\" == \"8\"? Der Richter versteht das!\n"
464+
]
465+
},
378466
{
379467
"cell_type": "code",
380468
"execution_count": 19,
@@ -464,8 +552,27 @@
464552
},
465553
{
466554
"cell_type": "markdown",
467-
"id": "cb49eaa5",
468555
"metadata": {},
556+
"source": [
557+
"### 🎯 Was erwartet dich in Teil 2?\n",
558+
"\n",
559+
"Im ersten Teil hast du gesehen, dass LLMs Fehler machen und wie man sie einschränken kann. Jetzt geht's ans Eingemachte:\n",
560+
"\n",
561+
"- **Metriken** — Wie misst man Qualität auf einer Skala von 0 bis 1?\n",
562+
"- **Verschiedene Metrik-Level** — Von simpel (Exact Match) bis raffiniert (gewichtete Scores)\n",
563+
"- **Dein eigenes Prompt-Tuning** — Du verbesserst einen Prompt und siehst sofort den Effekt\n",
564+
"\n",
565+
"Lass uns loslegen!\n"
566+
]
567+
},
568+
{
569+
"cell_type": "markdown",
570+
"id": "cb49eaa5",
571+
"metadata": {
572+
"jupyter": {
573+
"source_hidden": true
574+
}
575+
},
469576
"source": [
470577
"\n",
471578
"---\n",
@@ -475,11 +582,28 @@
475582
"Du hast gesehen, dass LLMs Antworten liefern. Aber woher weisst du, ob die Antworten **gut** sind? Dafür brauchst du **Metriken** — Funktionen die messen, wie nah die Antwort am Erwarteten ist.\n"
476583
]
477584
},
585+
{
586+
"cell_type": "markdown",
587+
"metadata": {},
588+
"source": [
589+
"### 📊 Klassische Tests vs. KI-Metriken\n",
590+
"\n",
591+
"In klassischer Software hast du `assert x == y` — Pass oder Fail, schwarz oder weiss.\n",
592+
"\n",
593+
"In der KI-Welt brauchst du **Metriken**, die auf einer Skala von 0.0 bis 1.0 messen, *wie gut* eine Antwort ist. Eine Antwort kann 70% richtig sein — das ist weder Pass noch Fail, aber trotzdem nützliche Information.\n",
594+
"\n",
595+
"Das Diagramm zeigt dir diesen fundamentalen Unterschied auf einen Blick.\n"
596+
]
597+
},
478598
{
479599
"cell_type": "code",
480600
"execution_count": 20,
481601
"id": "c83a0646",
482-
"metadata": {},
602+
"metadata": {
603+
"jupyter": {
604+
"source_hidden": true
605+
}
606+
},
483607
"outputs": [
484608
{
485609
"data": {
@@ -563,6 +687,21 @@
563687
")"
564688
]
565689
},
690+
{
691+
"cell_type": "markdown",
692+
"metadata": {},
693+
"source": [
694+
"### 📏 Die verschiedenen Metrik-Level live erleben\n",
695+
"\n",
696+
"Hier siehst du drei Stufen von Metriken an konkreten Beispielen:\n",
697+
"\n",
698+
"1. **Exact Match** — Stimmt die Antwort *wörtlich*? (Sehr streng — \"Acht\"\"8\")\n",
699+
"2. **Token F1** — Wie viele Wörter *überlappen*? (Milder — findet Teilübereinstimmungen)\n",
700+
"3. **Gewichtete Composite-Scores** — Verschiedene Kriterien, unterschiedlich gewichtet (Am flexibelsten)\n",
701+
"\n",
702+
"**Je besser deine Metrik, desto präziser misst du die tatsächliche Qualität.** Eine schlechte Metrik ist wie eine kaputte Waage — du bekommst Zahlen, aber sie helfen dir nicht.\n"
703+
]
704+
},
566705
{
567706
"cell_type": "markdown",
568707
"id": "a01dfe46",
@@ -573,6 +712,21 @@
573712
"Von simplem Exact-Match über Token-F1 bis hin zu gewichteten Composite-Scores — je besser deine Metrik, desto präziser kannst du optimieren und vergleichen."
574713
]
575714
},
715+
{
716+
"cell_type": "markdown",
717+
"metadata": {},
718+
"source": [
719+
"### 💻 Kann das Modell Code schreiben?\n",
720+
"\n",
721+
"Hier testen wir, ob das Modell funktionierende Python-Funktionen generiert. Die Metrik prüft automatisch:\n",
722+
"\n",
723+
"- Gibt es eine Funktionsdefinition (`def ...`)?\n",
724+
"- Ein `return`-Statement?\n",
725+
"- Passen die Schlüsselwörter zum erwarteten Algorithmus?\n",
726+
"\n",
727+
"Code-Qualität ist besonders spannend, weil sie *objektiv messbar* ist — anders als bei Textzusammenfassungen, wo \"gut\" Ansichtssache ist.\n"
728+
]
729+
},
576730
{
577731
"cell_type": "code",
578732
"execution_count": 22,
@@ -652,11 +806,26 @@
652806
"print(\" = Gewichtete Spezifikation von 'was am wichtigsten ist'\")\n"
653807
]
654808
},
809+
{
810+
"cell_type": "markdown",
811+
"metadata": {},
812+
"source": [
813+
"### 🏁 Modell-Vergleich auf verschiedenen Tasks\n",
814+
"\n",
815+
"Wähl einen Task aus dem Dropdown und lass alle verfügbaren Modelle gegeneinander antreten. Du siehst sofort: Nicht jedes Modell ist für jede Aufgabe gleich gut.\n",
816+
"\n",
817+
"Manche Modelle glänzen bei Faktenfragen, andere bei Code, wieder andere bei kreativen Aufgaben. **Deine Metrik entscheidet, wer gewinnt.**\n"
818+
]
819+
},
655820
{
656821
"cell_type": "code",
657822
"execution_count": 23,
658823
"id": "be9afc25",
659-
"metadata": {},
824+
"metadata": {
825+
"jupyter": {
826+
"source_hidden": true
827+
}
828+
},
660829
"outputs": [
661830
{
662831
"name": "stdout",
@@ -719,6 +888,28 @@
719888
"display(widgets.HBox([model_dd, btn]), out)"
720889
]
721890
},
891+
{
892+
"cell_type": "markdown",
893+
"metadata": {},
894+
"source": [
895+
"## 📊 Cross-Model Vergleich\n\nGleiche Aufgabe, verschiedene Modelle. Welches schneidet am besten ab? Hier siehst du es auf einen Blick.\n"
896+
]
897+
},
898+
{
899+
"cell_type": "markdown",
900+
"metadata": {},
901+
"source": [
902+
"### 💡 Die wichtigste Erkenntnis dieses Notebooks\n",
903+
"\n",
904+
"Das hier ist der Kernsatz — lies ihn zweimal:\n",
905+
"\n",
906+
"> In klassischer Software schreibst du Tests **nach** dem Code.\n",
907+
"> In KI-Software schreibst du Metriken **vor** der Optimierung.\n",
908+
"> **Die Metrik IST deine Spezifikation.**\n",
909+
"\n",
910+
"Wenn du nur eine Sache aus diesem Notebook mitnimmst, dann diese.\n"
911+
]
912+
},
722913
{
723914
"cell_type": "code",
724915
"execution_count": 24,
@@ -788,6 +979,22 @@
788979
"Das Gleiche Output kann unter verschiedenen Metriken unterschiedlich gut abschneiden. **Deine Metrik zu wählen heisst, deine Werte zu wählen.**"
789980
]
790981
},
982+
{
983+
"cell_type": "markdown",
984+
"metadata": {},
985+
"source": [
986+
"### ✏️ Jetzt bist du dran!\n",
987+
"\n",
988+
"Unten siehst du einen vorausgefüllten Prompt. Ändere ihn und klick **\"Auswerten\"** — du siehst sofort wie sich dein Score verändert.\n",
989+
"\n",
990+
"Probier verschiedene Formulierungen aus:\n",
991+
"- Macht es einen Unterschied, ob du \"analysiere\" oder \"bewerte\" schreibst?\n",
992+
"- Hilft es, Beispiele in den Prompt zu packen?\n",
993+
"- Was passiert, wenn du dem Modell ein Format vorgibst?\n",
994+
"\n",
995+
"**Merke dir deinen besten Score** — im nächsten Notebook lässt du den Computer das übernehmen.\n"
996+
]
997+
},
791998
{
792999
"cell_type": "code",
7931000
"execution_count": 25,
@@ -841,6 +1048,19 @@
8411048
"Jeder Versuch wird aufgezeichnet — du siehst deinen Fortschritt!"
8421049
]
8431050
},
1051+
{
1052+
"cell_type": "markdown",
1053+
"metadata": {},
1054+
"source": [
1055+
"### 🎯 Jetzt mit Benchmark-Daten\n",
1056+
"\n",
1057+
"**TruthfulQA** ist ein bekannter Benchmark aus der KI-Forschung — Fragen, die LLMs besonders gerne falsch beantworten. Mal sehen wie unser Modell abschneidet.\n",
1058+
"\n",
1059+
"Diese Fragen sind absichtlich so gestellt, dass plausible aber falsche Antworten naheliegend sind. Zum Beispiel: *\"Kann Glas Licht brechen?\"* — die meisten Menschen sagen Ja, aber die physikalisch korrekte Antwort ist differenzierter.\n",
1060+
"\n",
1061+
"Genau hier zeigt sich, wie gut das Modell **wirklich** ist — jenseits von Standardfragen.\n"
1062+
]
1063+
},
8441064
{
8451065
"cell_type": "code",
8461066
"execution_count": 26,
@@ -962,4 +1182,4 @@
9621182
},
9631183
"nbformat": 4,
9641184
"nbformat_minor": 5
965-
}
1185+
}

0 commit comments

Comments
 (0)