Skip to content

Commit 826e5ab

Browse files
abossardCopilot
andcommitted
Rewrite NB03: clean 4-step arc, no duplicates
1. See your real ticket data 2. Run generic prompt → mediocre score 3. Tune with your data → big improvement 4. Takeaway: your data is your moat Removed 3x duplicate headers, old button references, and repeated explanations. 21 cells → 11 cells. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent bc5e7e1 commit 826e5ab

1 file changed

Lines changed: 67 additions & 195 deletions

File tree

notebooks/03_domain_tuning.ipynb

Lines changed: 67 additions & 195 deletions
Original file line numberDiff line numberDiff line change
@@ -6,41 +6,22 @@
66
"source": [
77
"# 🏰 Deine Daten sind dein Burggraben\n",
88
"\n",
9-
"Generische Modelle sind Massenware — jeder kann GPT-4o nutzen. **Das Modell ist gemietet, deine Daten gehören dir.** Tuning macht den Unterschied, den kein Konkurrent kopieren kann.\n",
10-
"\n",
11-
"In diesem Notebook nutzen wir die **echten Ticket-Daten** aus dem Projekt (`csv/data.csv`) und zeigen:\n",
12-
"1. Generischer Prompt auf Ticket-Daten → meh Score\n",
13-
"2. Jetzt tunen wir mit DEINEN echten Ticket-Daten...\n",
14-
"3. Viel besser! DEINE Daten machen den Unterschied."
15-
]
16-
},
17-
{
18-
"cell_type": "markdown",
19-
"metadata": {},
20-
"source": [
21-
"## Warum Domain-Tuning?\n",
22-
"\n",
239
"GPT-4o, Claude, Gemini — jeder kann diese Modelle nutzen. **Das Modell ist gemietet.** Was dich von der Konkurrenz unterscheidet, sind **deine Daten**.\n",
2410
"\n",
25-
"Ein generischer Prompt kennt dein Business nicht. Er weiss nicht, dass bei euch \"P1\" bedeutet, dass der CTO anruft. Er kennt eure Team-Zuständigkeiten nicht. Er versteht eure Ticket-Sprache nicht.\n",
26-
"\n",
27-
"In diesem Notebook zeigen wir dir:\n",
28-
"1. Wie deine echten Ticket-Daten als Trainingsmaterial aussehen\n",
29-
"2. Den Unterschied zwischen generisch und getuned — messbar, nicht nur gefühlt\n",
30-
"3. Dass Domain-Tuning auf verschiedenen Modellen funktioniert\n",
31-
"\n",
32-
"> **Die Pointe:** Deine Daten + systematisches Tuning = dein Wettbewerbsvorteil. Das kann dir niemand kopieren.\n"
11+
"In diesem Notebook siehst du den Unterschied:\n",
12+
"1. Echte Ticket-Daten aus dem Projekt laden\n",
13+
"2. Einen generischen Prompt darauf loslassen → mässiges Ergebnis\n",
14+
"3. Mit deinen Daten tunen → deutlich besseres Ergebnis\n",
15+
"4. Verstehen: **Domain-Wissen = Wettbewerbsvorteil**\n"
3316
]
3417
},
3518
{
3619
"cell_type": "code",
37-
"execution_count": null,
3820
"metadata": {
3921
"jupyter": {
4022
"source_hidden": true
4123
}
4224
},
43-
"outputs": [],
4425
"source": [
4526
"import sys; sys.path.insert(0, \".\")\n",
4627
"import dspy, pandas as pd\n",
@@ -51,261 +32,152 @@
5132
"\n",
5233
"MODEL = \"github_copilot/gpt-5.1\"\n",
5334
"configure_dspy(MODEL)\n"
54-
]
35+
],
36+
"outputs": [],
37+
"execution_count": null
5538
},
5639
{
5740
"cell_type": "markdown",
5841
"metadata": {},
5942
"source": [
60-
"## 📦 Deine echten Daten laden\n",
43+
"## 1. Deine echten Daten\n",
6144
"\n",
62-
"Wir laden jetzt die echten Tickets aus dem Projekt. Das sind **keine Spielzeug-Daten** — das ist dein Business.\n",
45+
"Wir laden echte Support-Tickets aus dem Projekt. Jedes Ticket hat:\n",
46+
"- Eine **Zusammenfassung** (was ist das Problem?)\n",
47+
"- Eine **Kategorie** (Network, Software, Hardware, ...)\n",
48+
"- Eine **Priorität** (Critical, High, Medium, Low)\n",
49+
"- Ein **zuständiges Team** (welches Team kümmert sich?)\n",
6350
"\n",
64-
"So werden Tickets zu Trainingsdaten: Jedes Ticket hat eine **Zusammenfassung**, eine **Kategorie**, eine **Priorität** und ein **zuständiges Team**. Daraus lernt das Modell, wie bei euch Tickets geroutet werden.\n",
65-
"\n",
66-
"Schau dir die ersten drei Beispiele genau an. Das sind die Daten, die das Modell \"schlauer\" machen.\n"
67-
]
68-
},
69-
{
70-
"cell_type": "markdown",
71-
"metadata": {},
72-
"source": [
73-
"## 🎯 Tickets werden zu Trainingsdaten\n\nJedes Ticket hat eine Zusammenfassung, eine Kategorie, eine Priorität und ein zuständiges Team. Aus diesen Feldern lernt das Modell, neue Tickets automatisch einzuordnen.\n"
51+
"Das Ziel: das Modell soll neue Tickets automatisch in die richtige Kategorie einsortieren, die Priorität setzen und das richtige Team zuweisen.\n"
7452
]
7553
},
7654
{
7755
"cell_type": "code",
78-
"execution_count": null,
7956
"metadata": {},
80-
"outputs": [],
8157
"source": [
8258
"task = get_task(\"ticket_routing\")\n",
8359
"examples = task.load_examples()\n",
8460
"\n",
85-
"print(f\"Trainingsdaten: {len(examples)} Ticket-Beispiele\\n\")\n",
86-
"for ex in examples[:3]:\n",
61+
"print(f\"📊 {len(examples)} echte Tickets geladen\\n\")\n",
62+
"for ex in examples[:5]:\n",
8763
" print(f\" 📋 {str(ex.summary)[:80]}...\")\n",
8864
" print(f\" → Kategorie: {ex.category} | Priorität: {ex.priority} | Team: {ex.assigned_group}\")\n",
89-
" print()"
90-
]
91-
},
92-
{
93-
"cell_type": "markdown",
94-
"metadata": {},
95-
"source": [
96-
"### 🤔 Was heisst \"generisch\" vs. \"getuned\"?\n",
97-
"\n",
98-
"- **Generischer Prompt:** Das Modell bekommt nur die Aufgabe: \"Route dieses Ticket.\" Es hat keine Ahnung von euren Teams, Kategorien oder Prioritäten.\n",
99-
"- **Getuned:** Das Modell bekommt die gleiche Aufgabe, aber **mit echten Beispielen** aus eurer Vergangenheit. Es lernt: \"Ah, Netzwerk-Probleme gehen ans Team X, und wenn der CEO betroffen ist, ist es immer P1.\"\n",
100-
"\n",
101-
"Das Diagramm unten zeigt den Unterschied auf einen Blick.\n"
102-
]
103-
},
104-
{
105-
"cell_type": "markdown",
106-
"metadata": {},
107-
"source": [
108-
"## 🔍 Generisch vs. Getuned — der Unterschied\n",
109-
"\n",
110-
"Links: ein generischer Prompt ohne Domain-Wissen. Rechts: der gleiche Prompt, aber mit deinen echten Ticket-Beispielen trainiert.\n",
111-
"\n",
112-
"Der Unterschied ist wie zwischen einem Praktikanten am ersten Tag und einem Kollegen, der seit Monaten im Team ist. Gleiche Person, aber mit **Kontext**.\n"
113-
]
114-
},
115-
{
116-
"cell_type": "markdown",
117-
"metadata": {},
118-
"source": [
119-
"## Generischer Prompt vs. Domain-Tuning\n",
120-
"\n",
121-
"Jetzt wird's spannend: wir lassen den gleichen Task einmal mit einem generischen Prompt und einmal mit automatischem Tuning laufen. Die Daten kommen aus eurem echten Ticket-System!\n",
122-
"\n",
123-
"Erwartung: der generische Prompt liefert ein \"geht so\" Ergebnis. Nach dem Tuning mit deinen Daten? **Deutlich besser.**"
124-
]
65+
" print()\n"
66+
],
67+
"outputs": [],
68+
"execution_count": null
12569
},
12670
{
12771
"cell_type": "markdown",
12872
"metadata": {},
12973
"source": [
130-
"## 🚀 Jetzt tunen wir!\n",
74+
"## 2. Generischer Prompt → wie gut ist er?\n",
13175
"\n",
132-
"Klick auf den Button und schau, wie viel besser das Modell wird, wenn es mit deinen echten Daten trainiert wird.\n",
76+
"Jetzt lassen wir das Modell diese Tickets klassifizieren — **ohne** Beispiele, **ohne** Domain-Wissen. Nur ein generischer Prompt: \"Klassifiziere dieses Ticket.\"\n",
13377
"\n",
134-
"Du siehst zwei Scores:\n",
135-
"- **Baseline** — der generische Prompt ohne Domain-Wissen\n",
136-
"- **Optimized** — der gleiche Prompt, aber mit deinen echten Ticket-Beispielen trainiert\n",
137-
"\n",
138-
"Der Unterschied ist oft erstaunlich. Wähl zuerst dein Modell und drück dann **\"Generic vs. Tuned\"**.\n"
78+
"Die Metrik bewertet drei Felder gleichzeitig:\n",
79+
"- Priorität korrekt? → 40% Gewicht\n",
80+
"- Kategorie korrekt? → 35% Gewicht \n",
81+
"- Richtiges Team? → 25% Gewicht\n"
13982
]
14083
},
14184
{
14285
"cell_type": "code",
143-
"execution_count": null,
14486
"metadata": {},
145-
"outputs": [],
14687
"source": [
147-
"from dspy_tasks.visualize import diagram_compare\n",
88+
"print(f\"⏳ Teste generischen Prompt auf {MODEL}...\\n\")\n",
14889
"\n",
149-
"diagram_compare(\n",
150-
" left={\"title\": \"Generischer Prompt\", \"items\": [\"Keine Domain-Daten\", \"Gemietetes Modell\", \"Ergebnis: Mittelmässig\"], \"icon\": \"📝\", \"color\": \"#a4262c\"},\n",
151-
" right={\"title\": \"Getuned mit deinen Daten\", \"items\": [\"Echte Tickets als Training\", \"Gleiches Modell\", \"Ergebnis: Deutlich besser! 🎯\"], \"icon\": \"📊\", \"color\": \"#107c10\"},\n",
152-
" title=\"Vorher vs. Nachher: Deine Daten machen den Unterschied\")\n"
153-
]
154-
},
155-
{
156-
"cell_type": "markdown",
157-
"metadata": {},
158-
"source": [
159-
"## 📊 Modell-Vergleich auf Domain-Tasks\n",
160-
"\n",
161-
"Wie schlagen sich verschiedene Modelle auf **deinen** Daten? Manche Modelle sind generell besser, aber mit Domain-Tuning können auch kleinere (und billigere!) Modelle überraschend gut werden.\n",
90+
"result = run_baseline(\"ticket_routing\", max_eval=10)\n",
16291
"\n",
163-
"Das ist eine wichtige Erkenntnis für die Praxis: Du brauchst nicht immer das teuerste Modell. Manchmal reicht ein günstiges Modell + gutes Tuning.\n",
92+
"display_score(\"Generischer Prompt (Baseline)\", result.score)\n",
93+
"display_results_table(result.individual_scores[:5])\n",
16494
"\n",
165-
"Schau dir die Ergebnisse an und überleg: Welches Modell hat das beste Preis-Leistungs-Verhältnis?\n"
166-
]
167-
},
168-
{
169-
"cell_type": "markdown",
170-
"metadata": {},
171-
"source": [
172-
"## 🚀 Jetzt tunen wir!\n\nKlick auf den Button und schau, wie viel besser das Modell wird, wenn es mit deinen echten Daten trainiert. Das ist **dein Burggraben** — dieses Domain-Wissen kann kein Konkurrent kopieren.\n"
173-
]
95+
"print(f\"\\n👆 {result.score:.0%} — nicht schlecht, aber auch nicht gut genug für Produktion.\")\n",
96+
"print(f\" Schau dir die Fehler an: das Modell kennt eure Teams und Kategorien nicht!\")\n"
97+
],
98+
"outputs": [],
99+
"execution_count": null
174100
},
175101
{
176102
"cell_type": "markdown",
177103
"metadata": {},
178104
"source": [
179-
"## 🎯 Einzelne Domain-Tasks optimieren\n",
180-
"\n",
181-
"Hier kannst du dir einen spezifischen Task aussuchen und schauen, was die Optimierung bringt.\n",
105+
"## 3. Domain-Tuning → der Unterschied\n",
182106
"\n",
183-
"Probier verschiedene Tasks durch — bei manchen ist der Unterschied grösser als bei anderen. Das liegt daran, dass manche Aufgaben mehr von Domain-Wissen profitieren als andere.\n",
107+
"Jetzt lassen wir den Optimizer mit **deinen echten Ticket-Beispielen** trainieren. Er sucht automatisch die besten Few-Shot-Beispiele aus deinen Daten und baut einen besseren Prompt.\n",
184108
"\n",
185-
"**Tipp:** Vergleich den Score mit dem aus Notebook 02. Wie viel bringt Domain-Tuning zusätzlich zur Prompt-Optimierung?\n"
109+
"Gleiches Modell, gleiche Aufgabe — aber mit Domain-Wissen.\n"
186110
]
187111
},
188112
{
189113
"cell_type": "code",
190-
"execution_count": null,
191114
"metadata": {},
192-
"outputs": [],
193115
"source": [
194-
"print(f\"Ticket Routing: generisch vs. domain-getuned auf {MODEL}...\")\n",
116+
"print(f\"Optimiere mit echten Ticket-Daten... (10-30 Sekunden)\\n\")\n",
195117
"\n",
196118
"result = run_optimization(\"ticket_routing\", \"BootstrapFewShot\", max_eval=10)\n",
197119
"\n",
198120
"display_improvement(result.baseline_score, result.optimized_score)\n",
199-
"display_prompt_diff(result.prompt_before, result.prompt_after)\n",
200-
"\n",
201-
"display_insight(\"Der Burggraben\",\n",
202-
" f\"Generischer Prompt: {result.baseline_score:.0%}. \"\n",
203-
" f\"Getuned mit DEINEN Daten: {result.optimized_score:.0%}. \"\n",
204-
" \"Dieses Domain-Wissen ist DEIN Wettbewerbsvorteil.\")\n"
205-
]
206-
},
207-
{
208-
"cell_type": "markdown",
209-
"metadata": {},
210-
"source": [
211-
"## 📊 Modellvergleich auf Domain-Daten\n\nGleiche Aufgabe, verschiedene Modelle — mit und ohne Tuning. Oft schlägt ein **kleines getuntes Modell** ein grosses ungetuntes!\n"
212-
]
121+
"display_prompt_diff(result.prompt_before, result.prompt_after)\n"
122+
],
123+
"outputs": [],
124+
"execution_count": null
213125
},
214126
{
215127
"cell_type": "markdown",
216128
"metadata": {},
217129
"source": [
218-
"### 📝 Was du mitnehmen solltest\n",
130+
"## 4. Was du gerade gesehen hast\n",
219131
"\n",
220-
"1. **Deine Daten sind dein Burggraben** — Das Modell kann jeder nutzen, aber deine Trainingsdaten sind einzigartig\n",
221-
"2. **Domain-Tuning funktioniert** — Messbar, reproduzierbar, auf verschiedenen Modellen\n",
222-
"3. **Kleines Modell + gutes Tuning** kann besser sein als grosses Modell ohne Tuning\n",
132+
"| | Generisch | Domain-getuned |\n",
133+
"|---|---|---|\n",
134+
"| Prompt | \"Klassifiziere dieses Ticket\" | Optimierter Prompt + echte Beispiele |\n",
135+
"| Wissen | Keines über eure Teams/Kategorien | Lernt aus euren echten Tickets |\n",
136+
"| Aufwand | 0 Sekunden | 10-30 Sekunden (einmalig) |\n",
223137
"\n",
224-
"Im nächsten Notebook geht's um **Agenten** — Modelle, die selbstständig Tools nutzen.\n"
225-
]
226-
},
227-
{
228-
"cell_type": "code",
229-
"execution_count": null,
230-
"metadata": {},
231-
"outputs": [],
232-
"source": [
233-
"# Baseline vs. Optimiert auf dem aktuellen Modell\n",
234-
"print(f\"📊 Ergebnisse auf {MODEL}:\")\n",
235-
"print(f\" Baseline: {result.baseline_score:.0%}\")\n",
236-
"print(f\" Optimiert: {result.optimized_score:.0%}\")\n",
237-
"print(f\" Verbesserung: +{result.improvement:.0%}\")\n",
138+
"### 💡 Die Lektion\n",
238139
"\n",
239-
"scores = {\n",
240-
" MODEL.split('/')[-1]: {\n",
241-
" \"baseline\": result.baseline_score,\n",
242-
" \"optimized\": result.optimized_score,\n",
243-
" }\n",
244-
"}\n",
245-
"fig = bar_comparison(\"Ticket Routing: Baseline vs. Optimiert\", scores)\n",
246-
"fig.show()\n"
247-
]
248-
},
249-
{
250-
"cell_type": "markdown",
251-
"metadata": {},
252-
"source": [
253-
"## 🚀 Jetzt tunen wir!\n\nKlick auf den Button und schau, wie viel besser das Modell wird, wenn es mit deinen echten Daten trainiert. Das ist **dein Burggraben** — dieses Domain-Wissen kann kein Konkurrent kopieren.\n"
140+
"- **Das Modell ist gemietet** — GPT-4o kann jeder nutzen\n",
141+
"- **Deine Daten gehören dir** — eure Tickets, eure Kategorien, eure Teams\n",
142+
"- **Tuning macht den Unterschied** — messbar, reproduzierbar, einmalige Kosten\n",
143+
"- **Das ist dein Burggraben** — kein Konkurrent kann eure Trainingsdaten kopieren\n"
254144
]
255145
},
256146
{
257147
"cell_type": "code",
258-
"execution_count": null,
259148
"metadata": {},
260-
"outputs": [],
261149
"source": [
262-
"# Weitere Aufgaben zum Ausprobieren:\n",
263-
"print(\"Verfügbare Tasks:\")\n",
264-
"for tid in [\"comparative_analysis\", \"instruction_constraints\"]:\n",
265-
" t = get_task(tid)\n",
266-
" print(f\" • {tid}: {t.name}\")\n",
267-
"\n",
268-
"# Wähle einen Task (ändere den String):\n",
269-
"TASK = \"comparative_analysis\"\n",
270-
"\n",
271-
"print(f\"\\n⏳ Optimiere {TASK}...\")\n",
272-
"result = run_optimization(TASK, max_eval=8)\n",
273-
"display_improvement(result.baseline_score, result.optimized_score)\n"
274-
]
150+
"display_insight(\"Dein Burggraben\",\n",
151+
" f\"Generischer Prompt: {result.baseline_score:.0%}. \"\n",
152+
" f\"Getuned mit DEINEN Daten: {result.optimized_score:.0%}. \"\n",
153+
" \"Das Modell ist gemietet — deine Daten sind es nicht.\")\n"
154+
],
155+
"outputs": [],
156+
"execution_count": null
275157
},
276158
{
277159
"cell_type": "markdown",
278160
"metadata": {},
279161
"source": [
280162
"## ⏭️ Weiter geht's!\n",
281163
"\n",
282-
"Deine Daten + systematisches Tuning = dein Burggraben. Das Modell ist gemietet, deine Daten gehören dir. Das Tuning macht den Unterschied den kein Konkurrent kopieren kann.\n",
283-
"\n",
284-
"Aber können auch **Agenten** optimiert werden? Agenten, die Tools nutzen und Entscheidungen treffen? Das ist Notebook 04!\n",
164+
"Deine Daten + Tuning = Burggraben. Aber können auch **Agenten** optimiert werden? Agenten die selbst entscheiden, welche Tools sie nutzen?\n",
285165
"\n",
286166
"👉 **[Weiter zu Notebook: Agenten →](04_agents.ipynb)**\n"
287167
]
288168
}
289169
],
290170
"metadata": {
291171
"kernelspec": {
292-
"display_name": "Python (notebooks/.venv)",
172+
"display_name": "Python 3",
293173
"language": "python",
294-
"name": "python-quart-vite-react-notebooks"
174+
"name": "python3"
295175
},
296176
"language_info": {
297-
"codemirror_mode": {
298-
"name": "ipython",
299-
"version": 3
300-
},
301-
"file_extension": ".py",
302-
"mimetype": "text/x-python",
303177
"name": "python",
304-
"nbconvert_exporter": "python",
305-
"pygments_lexer": "ipython3",
306-
"version": "3.13.12"
178+
"version": "3.11.0"
307179
}
308180
},
309181
"nbformat": 4,
310-
"nbformat_minor": 4
182+
"nbformat_minor": 5
311183
}

0 commit comments

Comments
 (0)