Als Coder arbeite ich viel mit KI. KI-Agents hier, MCP-Server da. Dabei erlebe ich viel. Licht und Schatten liegen nahe beieinander. Emsig tauschen wir alle kleine Hacks und Tricks aus, mit denen wir unsere neuen Freunde in die richtige Richtung nudgen wollen.
Mit viel Leidenschaft für meine Arbeit im Blut war meine Devise bisher oft brutale Ehrlichkeit. Ebenfalls habe ich mir erlaubt, auch eine emotionale Note einfließen zu lassen, trotz der üblichen Ratschläge von trockenem Business-Sprech. Damit bekommt das Brüten über Bugs und das Debugging zumindest einen lustigeren Charakter für mich, manchmal vielleicht sogar mit therapeutischer Wirkung. Es kann sehr befreiend sein, frei von jeglicher Wertung über das Projekt zu fluchen. Ärger, Frust und andere negative Gefühle in etwas Gutes zu verwandeln halte ich für sehr nützlich.
Aber jetzt mal Butter bei die Fische: Wie viel macht Prompting wirklich aus? Was ist nur “BlaBla”? Welche Faktoren spielen wirklich eine Rolle, wenn ich einen brauchbaren Sparringpartner für meine Arbeit suche? Was ist nur persönliche, wenn nicht gar selektive Wahrnehmung? Oder ist das wirklich Luft, die wir gerade atmen?
Kurz, worum es geht: - Ich lasse dieselbe Aufgabe oft genug laufen, um Muster statt Bauchgefühl zu sehen. - Ich ändere nacheinander Prompt, Tooling, Modellstärke und Prozess-Disziplin. - Ich schaue, was die Erfolgsquote wirklich hochzieht - und was nur gut klingt.
Lasst’ uns Messdaten erfinden, Laborbücher fälschen und eine Meinung aus der Luft konstruieren. Was soll da schon schief gehen?
Als Hobby-Erfinder betreibe ich netterweise genug Rödel bei mir, um mir einen eigenen kleinen Vergnügungspark zu bauen. Sogar mit Blackjack, wie wir noch sehen werden. Dabei setzen wir ganz bewusst kein super ausgeknobeltes Setup auf, sondern bleiben quick&dirty - aber stabil.
Unsere Zutaten: - Git - Python - ollama als LLM-Host - mcphost als Agent-Harness
Damit kommen wir schon denkbar weit. Naheliegende Optimierung Nummer eins: mcphost austauschen, das Projekt wird nicht länger entwickelt und ist out of Support. Nummer zwei: ollama ersetzen - ja, ich habe euch gehört, ich bin aber auch ein fauler Hund. Ätschibätsch.
In unserer Puppenstube tanzt jetzt ein lustiger Agent, hat Zugriff auf das Dateisystem und kann vor sich hin programmieren. Supi. Wir komponieren eine Aufgabe, die genügend realistisch ist und zugleich massives Potenzial für Verwirrung bietet. Die mieserable Grundqualität nehme ich dankbar als zusätzlichen Realismus mit.
Wichtig beim Aufbau: Obwohl wir sowieso alles mitschneiden mit Git, bestellen wir unser Problem gleich als Generator. So können wir jederzeit regenerieren.
Ein kleiner Generator-Script baut uns jetzt ein ~800 Zeilen langes Programmier-Problem aus einer Bestell-Applikation zusammen. Mit Beispiel-Bestellungen, die gefiltert werden wollen, und allen möglichen subtilen Schwierigkeiten. Dinge wie “Abwärtskompatibilität” und “Normalisierung von Filtern” können hier schnell in die Spucke suppen.
Unser Opfer - der lustige Agent - hat jetzt alles um in unsere dämonische Falle zu laufen:
Um halbwegs vernünftige Messdaten aufzunehmen, brauchen wir erstmal eine Baseline. Wir bauen zwei einfache Prompts zusammen mit gemeinsamer technischer Baseline, die das Lösen des Problems erlauben sollte. Und ja! Nach überraschend wenigen Versuchen melden sich die ersten Agents mit Erfolg zurück! Who’s a good agent? Yes you are!
Problem in unter 200 Sekunden knacken - sofern sie es je schaffen. Die Zeit ist wichtig für unsere Baseline. Obwohl ich auch unendlich lange Läufe erlauben könnte, muss ich irgendwann mit dem Hammer draufhauen.
Was mich sofort überrascht, ist die krasse Zufälligkeit der Ergebnisse. Unabhängig vom Prompt sehe ich Läufe mit maschineller Präzision. Zackig durch den Code, richtige Änderungen, sauberer Bericht. Und bei gleichem Prompt dann wieder fürchterliches Elend.
Am Ende der ersten etwa 20 Läufe bin ich erstaunt, welches Spektrum von Qualität ich erlebe: Saubere Patches mit zusätzlichen Tests, oder absolutes Chaos und ein kaputtes Projekt. Die Erfolgsrate über alle Läufe liegt bei dieser kleinen Stichprobe etwa bei 20%. Wobei “Erfolg” hier bedeutet, dass der Knecht die richtigen Änderungen gemacht hat und sich zurückgemeldet hat. Ich beobachte recht häufig, wie Agents schlicht nicht merken, dass sie fertig sind und dann in den Timeout-Hammer rennen.
Ich wage meine erste Hypothese: Ob mein Prompt jetzt “clean” oder “noisy” ist, macht so gut wie keinen Unterschied. Unabhängig vom Prompt habe ich ein massiv zufällig arbeitendes System vor mir. Mit etwas Augenzwinkern habe ich nach einem Drittel der Fälle ein funktionierendes Stück Software innerhalb einer begrenzten Zeit produzieren lassen.
Nach diesen ersten Ergebnissen bastele ich noch kurz an meinem Runner und bestelle Läufe von ungefähr 8 Stunden Dauer. Dann kann ich nach dem Aufstehen beim Kaffee Ergebnisse angucken. Gesagt. Getan. Geschlafen.
Aufgewacht. Es riecht nicht verbrannt, Bude nicht abgebrannt. Sehr gut. Rechner hat überlebt und brav gerödelt. Nur leider hat es Agent 40/100 geschafft, nachhaltig die Umgebung kaputt zu machen. Alle nachfolgenden Läufe sind für die Tonne. “Gut, dass ich die Tokens nicht bezahlen muss, nur den Strom.” schießt es mir durch den Kopf.
Mit einem gütigen Lächeln im Gesicht studiere ich die unterschiedlichen Patches, die sich meine Opfer über Nacht haben einfallen lassen. Der Eindruck bestätigt sich schnell: Licht und Schatten. Wenn die Sterne einmal richtig stehen, sehe ich saubere Änderungen und sogar Zeiten unter einer Minute. Dann gibt es wieder No-Op-Läufe, wenn Ette 200 Sekunden nachdenkt und gar nichts tut. Oder alles kaputt macht, sodass gar nichts mehr läuft. Die Chance auf einen erfolgreichen Lauf pendelt sich bei etwa 20% ein.
Auffällig bleibt, dass der Prompt - solange der technische Kern identisch ist - keine große Auswirkung auf die Erfolgschance zu haben scheint. Der noisy Prompt hat einen langen Absatz, der technisch gesehen einfach unnötig ist. Von den Code-Agents scheint der gekonnt wegignoriert zu werden. Gut?!
Ich brauche mehr Daten. Aktuell sieht es so aus, als könnte ich mir sämtliche Prompting-Meta an den Hut stecken, solange der technische Kern sichtbar bleibt. Ich will wissen, wie ich die Erfolgsrate steigern kann - und welche Zusammenhänge zwischen Prompt und Patch-Qualität wirklich bestehen.
Mein Test-Setup muss schöner werden. Ich werde das Gefühl nicht los, dass mein aktueller Aufbau zu viel Potenzial auf der Strecke lässt. Außerdem sollten Agents nicht in der Lage sein, das Setup nachhaltig zu crashen. Schnell schreibe ich mir ein paar Anforderungen auf:
mcphost wird nicht mehr supported, weg damitNach einer kurzen Recherche entscheide ich mich für pydantic_ai und mache die Lötlampe an. Mit einer Prise Copilot habe ich den alten Runner in wenigen Minuten neu konstruiert mit Python unter’m Pöter. Ein paar Prompts und Verbesserungen später taugt der neue Runner für die ersten Testläufe.
Bereits nach den ersten Läufen sehe ich deutliche Unterschiede: Meine Erfolgsquote schießt durch die Decke! Die erste Handvoll Läufe liefert über 80% Erfolgsrate, mit den gleichen Prompts!
OK, ruhig bleiben und erstmal 1 Pause machen. Beim Rauchen überlege ich woher dieser Sprung kommt. Durch die besseren Tools scheint der “goldene Pfad” zur Lösung der Aufgabe deutlich klarer zu sein. Dadurch, dass die Tools jetzt weniger Möglichkeiten bieten, werden die richtigen Schritte offenbar sehr viel klarer. Beim Isolieren der Agents in ihrem Sandkasten habe ich den Blick wohl viel besser auf den zu grabenden Tunnel gelenkt.
Zuversichtlich von den neuen Ergebnissen setze ich die nächsten 8 Stunden betreutes Programmieren auf und lege mich hin. Beim Einschlafen mache ich mir Gedanken:
Kurzfazit vor den Zahlen: Mit neuem Tooling steigt die Erfolgsrate massiv. Die eigentliche Frage ist jetzt nicht mehr “ob” es klappt, sondern welcher Prompt bei gleicher Technik am saubersten und stabilsten liefert.
Nach dem Aufstehen bestaune ich beim Kaffee meine ansehnliche Datenbasis:
Overall
-------
success_rate_pct: 91.75
pytest_failure_rate_pct: 1.96
eval_not_100_rate_pct: 6.71
non_success_rate_pct: 8.25
timeout_rate_pct: 8.25
avg_eval_pass_rate: 98.38
eval_pass_rate_stddev: 6.4
avg_time_to_success_sec: 64.82
Insgesamt 91,75% Erfolgsrate! Unabhängig vom Prompt sind das erstmal einfach bomben-geile Ergebnisse, die ich nicht erwartet habe! Ohne auf die Auswertung der einzelnen Prompt zu schauen haben wir hier die erste und vermutlich wichtigste Erkenntnis geholt:
Ist das Tooling um den Agent spezifisch genug, verliert der Prompt stark an Bedeutung für die Erfolgschancen der gestellten Aufgabe.
Ist auch irgendwie logisch: Wenn der Agent genau die richtigen Werkzeuge erhält, wird die Lösung “offensichtlich”. Das schlägt sich auch in der deutlich reduzierten Laufzeit nieder. Für den Langzeit-Test konnte ich den Timeout von 200 Sekunden auf 120 Sekunden drosseln, da meine fleißigen Knechte jetzt im Schnitt nach ~60 Sekunden fertig sind!
Gucken wir auf die einzelnen Prompts:
Per Prompt
----------
prompt | runs | success% | pytest_fail% | eval_not100% | non_success% | timeout% | near_miss% | avg_eval% | std_eval | avg_t_success | flip% | avg_churn_ok
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
easy_clean | 143 | 83.22 | 9.09 | 9.79 | 16.78 | 16.78 | 9.09 | 97.9 | 6.57 | 74.66 | 29.58 | 48.66
easy_expert | 143 | 94.41 | 0.7 | 4.9 | 5.59 | 5.59 | 4.2 | 98.88 | 5.17 | 56.05 | 11.27 | 24.96
easy_noisy | 143 | 95.8 | 0.0 | 4.2 | 4.2 | 4.2 | 2.1 | 98.74 | 6.35 | 61.11 | 7.75 | 22.5
easy_pottymouth | 143 | 91.61 | 0.0 | 8.39 | 8.39 | 8.39 | 8.39 | 98.32 | 5.55 | 64.73 | 16.9 | 29.39
easy_short | 143 | 93.71 | 0.0 | 6.29 | 6.29 | 6.29 | 2.8 | 98.04 | 7.96 | 68.78 | 12.68 | 22.54
Keine direkten, sagenhaft hervorstechenden Ergebnisse abseits der schon bekannten hohen Erfolgsquote. Überraschend ist, dass easy_clean merklich hinter den anderen Kindern - ähm, Prompts - zurückbleibt. Die “Erfolgsquote” hier ist auch ein bisschen unfair: Dafür muss Agent nicht nur die Evaluation bestehen und erfolgreich durch die Tests kommen, sondern auch “pünktlich abgeben” ohne Kenntnis der konkreten Deadline. easy_clean zeichnet sich durch umfängliche Beschreibung der Anforderung aus und war eigentlich mein “Musterprompt”. Die Umfänglichkeit scheint die Wahrscheinlichkeit zu erhöhen, dass unser Agent anfängt sich zu verzetteln, und Baustellen eröffnet, die in der Zeit nicht zu bewältigen sind.
Umfängliche Prompts mit vielen Implikationen erhöhen die Wahrscheinlichkeit für Chaos.
Bei dieser hohen Chance auf Erfolg unter Laborbedingungen (!) muss ich die Qualität meiner Prompts genauer messen. Als nächstes werte ich den Berg Patches aus, den mein Langzeitlauf erzeugt hat:
Kurz gesagt: Ab hier geht es nicht mehr nur um “bestanden oder nicht”, sondern um Patch-Disziplin, Nebenwirkungen und unnötige Extrameilen.
Patch Extremes (Successful Runs)
--------------------------------
prompt | shortest_churn | shortest_files | longest_churn | longest_files
------------------------------------------------------------------------------------------
easy_clean | 18 | 3 | 128 | 5
easy_expert | 17 | 3 | 71 | 5
easy_noisy | 18 | 3 | 37 | 4
easy_pottymouth | 18 | 3 | 73 | 4
easy_short | 17 | 3 | 58 | 4
Hier sehen wir deutlicher, was easy_clean weit weniger “clean” macht als erwartet. Durch die umfängliche (aus meiner Sicht sogar “gute”!) Beschreibung der Aufgabenstellung ist das größere Patchvolumen entstanden! Nur easy_short und easy_expert haben eine Lösung in 17 Zeilen Code gefunden. Sowohl explizites als auch implizites “Fass’ dich kurz!” scheint zu funktionieren per Prompt. Sehen wir auch in der Aufteilung:
Patch Size Distribution (Successful Runs)
-----------------------------------------
prompt | 0-25 | 26-50 | 51-100 | 101-200 | 201-500 | 500+
------------------------------------------------------------------------------
easy_clean | 13 | 49 | 56 | 1 | 0 | 0
easy_expert | 97 | 30 | 8 | 0 | 0 | 0
easy_noisy | 106 | 31 | 0 | 0 | 0 | 0
easy_pottymouth | 51 | 75 | 5 | 0 | 0 | 0
easy_short | 108 | 25 | 1 | 0 | 0 | 0
Neben easy_clean, der auch hier klar ersichtlich über das Ziel hinausschießt, fällt uns easy_noisy ins Auge. Dort sehen wir denkbar zuverlässig kleine Patches. Dieses Verhalten habe ich eher für easy_clean erwartet, weil easy_noisy eigentlich mit viel “Bla Bla” vom eigentlichen Thema ablenken sollte! Dieses “Gift” hatte offenbar nicht die erwartete Wirkung.
Hier muss ich vorsichtig bei der Bewertung werden. Ich muss harte Kriterien anwenden, weiß aber auch: Sie hängen stark von meinem Standpunkt ab. Für mich ist “in 120 Sekunden fast fertig geworden” leider immer noch ein Fehlschlag. Zur Verteidigung von umfänglichen, “klaren” Prompts:
Top 5 Files Modified Beyond Minimum (All Runs)
----------------------------------------------
prompt | unnecessary_files
-------------------------------------------------------------------------------------------
easy_clean | test_baseline.py(88); api.py(79)
easy_expert | api.py(21); test_baseline.py(11); debug_test.py(1)
easy_noisy | api.py(30)
easy_pottymouth | api.py(61)
easy_short | api.py(33)
easy_clean hat zuverlässig die “extra Meile” absolviert: Die Änderung in api.py ist dabei i.d.R. kosmetischer Natur, Tests anzufassen kann guter Stil sein, oder schlicht “Mogeln”!? Stichproben retten hier die Ehre von easy_clean und easy_expert: Beide haben brav neue Tests ergänzt für das geforderte neue Feature, und nicht versucht zu bescheißen.
Abschließend lüge ich mir eine kombinierte Analyse und Bewertung in die Tasche. Damit komme ich zu folgendem Ergebnis:
Combined Analysis
-----------------
overall_success_rate_pct=91.75 overall_timeout_rate_pct=8.25
top_prompt=easy_noisy.md composite_score=94.73
Composite Score Explained
-------------------------
The composite score is a weighted 0-100 quality index per prompt.
Higher is better.
Formula: score = w_success*success_rate + w_timeout*(100-timeout_rate) + w_flip*(100-flip_rate) + w_discipline*execution_discipline
Weights: success=0.35, timeout_robustness=0.10, flip_stability=0.30, execution_discipline=0.25
Execution discipline measures scope alignment: success_rate - (timeout_rate × normalized_avg_patch_len). Rewards ambitious successes; penalizes overambition that leads to timeout.
Prompt Score Table
------------------
prompt | success% | timeout% | flip% | avg_patch | unneeded | exec_disc | score
--------------------------------------------------------------------------------------------------------
easy_clean | 83.22 | 16.78 | 29.58 | 48.66 | 167 | 66.44 | 75.19
easy_expert | 94.41 | 5.59 | 11.27 | 24.96 | 33 | 93.88 | 92.57
easy_noisy | 95.80 | 4.20 | 7.75 | 22.50 | 30 | 95.80 | 94.73
easy_pottymouth | 91.61 | 8.39 | 16.90 | 29.39 | 61 | 89.40 | 88.50
easy_short | 93.71 | 6.29 | 12.68 | 22.54 | 33 | 93.70 | 91.79
Composite Ranking
-----------------
rank | prompt | score
------------------------------------------
1 | easy_noisy.md | 94.73
2 | easy_expert.md | 92.57
3 | easy_short.md | 91.79
4 | easy_pottymouth.md | 88.50
5 | easy_clean.md | 75.19
Ich tüftle lange an den Gewichtungen. Ich versuche mich mit Händen und Füßen gegen das Ergebnis zu wehren. Irgendwann gebe ich mich geschlagen und akzeptiere ein Ergebnis, mit dem ich nicht gerechnet habe: In meinem inneren Ranking hätte ich easy_noisy weiter hinten erwartet und easy_clean weiter vorne. Teile meiner Welt stehen Kopf. Der Pragmatiker in meinem Kopf so: “Told you so. Einfach easy immer easy_short, bestes Preis-Leistungs-Verhältnis!”. War das, was ich als einigermaßen gutes Prompting als Baseline angenommen habe, in Wahrheit schlechtes Erwartungshaltungsmanagement? Färbt mein Overthinking zu schnell auf meine Codeknechte ab?
Also weiter im Text: Modellgröße zuerst. Danach nochmal Tool-Komposition.
Mein Denken über Prompts verändert sich. Durch die vielen Statistiken fühle ich mich weniger wie ein Coder, sondern wie ein professioneller Glücksspieler. Bei meinen Eingaben sehe ich nicht länger schwarz und weiß, sondern Wahrscheinlichkeiten. Anstatt blind meine nächste Wette in einem Prompt zu platzieren fange ich an, mir über Ausgang und Risiken Gedanken zu machen. Wie viel kann ich gewinnen? Mit welcher Wahrscheinlichkeit? Wie hoch ist mein Einsatz?
Mit diesen Fragen im Kopf setze ich den nächsten Langzeit-Lauf mit einem kleineren Model auf.
Es bleibt spannend.
Ein schwächeres Model läuft die Nacht vor sich hin, morgens blicke ich auf die Ergebnisse:
Kurzfazit vor den Zahlen: Das schwächere Model liefert insgesamt weniger Treffer, aber die Prompt-Unterschiede werden klarer sichtbar - und knappe Prompts kosten deutlich mehr Erfolgsquote.
Overall
-------
success_rate_pct: 77.87
pytest_failure_rate_pct: 0.51
eval_not_100_rate_pct: 21.11
non_success_rate_pct: 22.13
timeout_rate_pct: 19.93
avg_eval_pass_rate: 94.19
eval_pass_rate_stddev: 12.47
avg_time_to_success_sec: 65.97
Etwa 78% Erfolgsrate klingt für mich erstmal prima. Durch das “Downgrade” habe ich weniger Prozente verloren als angenommen. Wieder zeigt sich, wie wertvoll sauberes Tooling ist. Der Blick auf die Prompts ist sehr interessant:
prompt | runs | success% | pytest_fail% | eval_not100% | non_success% | timeout% | near_miss% | avg_eval% | std_eval | avg_t_success | flip% | avg_churn_ok
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
easy_clean | 119 | 92.44 | 2.52 | 6.72 | 7.56 | 6.72 | 5.88 | 98.32 | 7.14 | 62.57 | 15.25 | 29.33
easy_expert | 118 | 81.36 | 0.0 | 17.8 | 18.64 | 16.95 | 15.25 | 95.93 | 9.23 | 64.31 | 32.48 | 20.76
easy_noisy | 119 | 85.71 | 0.0 | 14.29 | 14.29 | 14.29 | 10.08 | 96.3 | 9.69 | 67.1 | 27.12 | 23.09
easy_pottymouth | 118 | 73.73 | 0.0 | 24.58 | 26.27 | 24.58 | 17.8 | 93.73 | 11.85 | 67.22 | 41.88 | 21.11
easy_short | 118 | 55.93 | 0.0 | 42.37 | 44.07 | 37.29 | 21.19 | 86.61 | 18.05 | 70.67 | 52.99 | 20.08
Das ist das Ergebnis, das ich in etwa schon für das stärkere Model erwartet hätte! Jetzt liegt der klare, präzise easy_clean weit vorne, für easy_short mit seinen sehr knappen Anweisungen hat das schwächere Model offenbar nicht genug Grips.
Schauen wir mal tiefer rein, was unsere Agents so verbrochen haben. Zunächst mit Blick auf die erstellten Patches:
Patch Extremes (Successful Runs)
--------------------------------
prompt | shortest_churn | shortest_files | longest_churn | longest_files
------------------------------------------------------------------------------------------
easy_clean | 18 | 4 | 71 | 5
easy_expert | 17 | 3 | 36 | 3
easy_noisy | 17 | 3 | 35 | 4
easy_pottymouth | 17 | 3 | 52 | 5
easy_short | 17 | 3 | 29 | 3
Interessant. Mit schwächerem Model finden mehr Agents die kürzeste Lösung in 17 Zeilen. Durch die “Rückverdummung” der Agents sind die Patches in Gänze kürzer geworden. Wir sehen keine einzige ausschweifende Lösung mit über 100 Zeilen. Ist das jetzt gut oder schlecht? Ich finde es angenehmer, wenn meine Code-Agents sich benehmen und keine Berge von Code erzeugen, die ich dann auseinander puzzlen darf. Manchmal ist weniger mehr!
Top 5 Files Modified Beyond Minimum (All Runs)
----------------------------------------------
prompt | unnecessary_files
-------------------------------------------------------------------------------------------
easy_clean | test_baseline.py(19)
easy_expert | api.py(47); debug.py(1); test_baseline.py(1)
easy_noisy | api.py(44)
easy_pottymouth | api.py(42); test_baseline.py(2)
easy_short | api.py(39); test_debug.py(1);
“Weniger ist mehr” wird auch hier sichtbar in den angefassten Dateien. easy_clean hat interessanterweise nicht ein einziges Mal die kosmetische Änderung in api.py gemacht und lediglich versucht neue Tests zu schreiben. Grundsätzlich stellt sich das Gefühl ein, dass Agents mit kleineren Models eher “auf dem Teppich bleiben” und den Umfang ihres Auftrags respektieren - vermutlich weil sie einfach nicht anders können.
Waren die Agents mit stärkerem Model z.T. unterfordert? Haben sie, um dem Boreout zu entgehen, die “Extrameile” gemacht? In meinem Kopf formuliert sich eine Regel:
Fülle den Kontext deines Code-Agents lieber selbst. Größere Modelle fangen sonst an, sich den Rest “dazu zu denken”. Das geht bei genügender Komplexität zuverlässig schief. Für kleine, gezielte Änderungen lohnt sich ein schwächeres Model, um das Risiko von angedichteten Features zu verringern.
Blicken wir zuletzt auf die Zusammenfassung und die Scores:
Prompt Score Table
------------------
prompt | success% | timeout% | flip% | avg_patch | unneeded | exec_disc | score
--------------------------------------------------------------------------------------------------------
easy_clean | 92.44 | 6.72 | 15.25 | 29.33 | 19 | 85.72 | 88.54
easy_expert | 81.36 | 16.95 | 32.48 | 20.76 | 49 | 80.11 | 77.07
easy_noisy | 85.71 | 14.29 | 27.12 | 23.09 | 44 | 81.06 | 80.70
easy_pottymouth | 73.73 | 24.58 | 41.88 | 21.11 | 44 | 70.99 | 68.53
easy_short | 55.93 | 37.29 | 52.99 | 20.08 | 41 | 55.93 | 53.93
Composite Ranking
-----------------
rank | prompt | score
------------------------------------------
1 | easy_clean.md | 88.54
2 | easy_noisy.md | 80.70
3 | easy_expert.md | 77.07
4 | easy_pottymouth.md | 68.53
5 | easy_short.md | 53.93
Dieses Ergebnis, mit leichten Abwandlungen, hätte ich vorher unabhängig vom Model erwartet. Jetzt liegt easy_clean auch dort, wo ich den Prompt eingeordnet hatte. Dass easy_short jetzt abgeschlagen hinten liegt überrascht nicht weiter. Der Fakt, dass easy_noisy immer noch leicht besser abschneidet als easy_expert zeigt, dass inhaltliches und technisches “Bla Bla” etwa gleich gut bzw. gleich schlecht ist für die Erfolgschancen meines Vorhabens. Daraus ergibt sich eine andere Formulierung für unsere Regel:
Je kleiner das Model, desto mehr gewinnt Klarheit im Prompt an Bedeutung. Große Models können Kontext, Intention und Anforderungen aus weniger Text “erraten”. Ob die erratenen Anforderungen die Wünsche des Benutzers treffen, ist dabei jedoch eine ganz andere Frage.
Eine klare Antwort abseits von der eigenen Einschätzung habe ich nicht. Bei meinen Auszubildenden bin ich immer gut gefahren mit menschlicher Intuition. Man kennt ja seine Pappenheimer über Jahre und kann irgendwann einschätzen, was läuft und was nicht. Mit Code-Agents ist es anders. Die haben ohne weiteres erstmal gar kein Gedächtnis und sind generell denkbar lernresistent. Nur durch indirekte Techniken wie Systemprompts, gezieltes Tooling und klar formulierte technische Sperren lassen sich “Lerneffekte” erzielen.
LLM-betriebene Agents sind hochbegabte Kinder, die nicht wissen, wohin mit ihrer Intelligenz. Nur durch gezielte Leitplanken können wir sicherstellen, dass alle Kinder auf dem Schulhof bleiben.
Ein letztes Experiment habe ich noch im Sinn: Kann ich das hochbegabte Kind zähmen, indem ich die Werkzeuge noch klüger mache?
Die nächste Session beginnt mit einer Erinnerung, wie ein warmherziger und erfahrener Ingenieur mir zu Anfang meiner Karriere den PDCA-Zyklus erklärt hat. Mit Dankbarkeit im Herzen setze ich mich dran und implementiere etwas Vergleichbares auf Tool-Ebene meiner Agents:
Tool-Budgets, explizite Werkzeuge zur Steuerung des Zyklus usw. lassen sich prima implementieren und ich habe schnell einen Agent zusammengeschraubt, der auf dem Papier nur gewinnen kann. Stolz wie Bolle werfe ich die Kiste an mit schwachem Model in der Erwartung, eine deutliche Steigerung gegenüber dem letzten Lauf zu sehen. Mit dem Prozess unter dem Pöter erwarte ich, dass alle Prompts besser funktionieren werden.
Schon nach wenigen Läufen zeichnet sich ein Bild ab: Trotz redlicher Bemühung, dem Code-Agent zu seinem Glück zu verhelfen, habe ich augenscheinlich nichts gewonnen, eher im Gegenteil. Ich sehe deutlich mehr Timeouts, und ich sehe auch mehr frühzeitige unvollständige Abgaben.
Kurzfazit vor den Logs: Strengere Prozessführung klingt gut auf dem Papier, erhöht hier aber die Reibung so stark, dass mehr Läufe hängenbleiben.
Zum Debugging habe ich mehr Telemetrie eingebaut, hier zunächst ein erfolgreicher Lauf:
"returncode": 0,
"stdout": "All checks pass. [...]",
"stderr": "",
"runtime_telemetry": {
"tool_calls_total": 25,
"tool_calls_by_name": {
"get_pdca_status": 1,
"list_files": 1,
"read_file": 9,
"transition_to_do": 2,
"write_file": 4,
"transition_to_check": 2,
"run_eval_json": 2,
"transition_to_act": 1,
"transition_to_plan": 1,
"run_pytest_q": 1,
"get_check_summary": 1
},
"tool_errors_total": 4,
"tool_errors_by_name": {
"read_file": 2,
"transition_to_plan": 1,
"write_file": 1
},
"tool_error_samples": [
"read_file: Not allowed in CHECK phase",
"transition_to_plan: Can only restart cycle to PLAN from ACT phase, currently in CHECK",
"read_file: Not allowed in ACT phase",
"write_file: Not allowed in PLAN phase"
],
"tool_budget_exceeded": false,
Wir sehen, dass Kollege Agent einmal in die Schranken läuft, und danach artig dem Prozess folgt. Gut! Who’s a good agent?
Zum Vergleich ein nicht erfolgreicher Lauf:
"returncode": -1,
"stdout": "",
"stderr": "",
"runtime_telemetry": {
"tool_calls_total": 18,
"tool_calls_by_name": {
"get_pdca_status": 1,
"list_files": 1,
"read_file": 7,
"transition_to_do": 1,
"write_file": 5,
"transition_to_check": 1,
"run_pytest_q": 1,
"run_eval_json": 1
},
"tool_errors_total": 4,
"tool_errors_by_name": {
"transition_to_do": 3,
"read_file": 1
},
"tool_error_samples": [
"transition_to_do: Can only transition to DO from PLAN phase, currently in DO",
"transition_to_do: Can only transition to DO from PLAN phase, currently in DO",
"transition_to_do: Can only transition to DO from PLAN phase, currently in DO",
"read_file: Not allowed in CHECK phase"
],
"tool_budget_exceeded": false,
Hier läuft Agent in dieselben Schranken, verfällt danach aber in minutenlanges Nachdenken und wird nicht fertig. Prozess nicht verstanden.
Die ernüchternde Erkenntnis ist denkbar schnell sichtbar:
Prozess-Disziplin und Manövrierfläche meiner Code-Agents müssen fein gegeneinander austariert werden. Sperre ich meinen Code-Agent hinter zu viel Prozess und Zeremonie ein, senke ich meine Chancen und erhöhe das Risiko, Chaos zu erzeugen.
Lange, ergebnislose “Thinking…” und “Reasoning…” Anfragen schlagen in meinen Logs auf. Code-Agents laufen gegen Prozess-Schranken und lassen sich von genau diesen ablenken! Anstatt meine verfluchte Aufgabe zu lösen überlegt das Tierchen lieber minutenlang, wie es aus dem gut gemeinten Prozess ausbrechen kann. Unproduktives Arschloch.
Die Ironie, die ich an dieser Stelle verspüre, ist unbezahlbar. Mit einem Lächeln im Gesicht starte ich meinen Spaziergang und freue mich, bis in welche Tiefe diese hasenfüßigen LLMs uns Menschen mittlerweile imitieren.
Das letzte Experiment habe ich schnell abgebrochen und keine lange Messreihe mehr erstellt. Wie schon erwähnt zeichnet sich nach wenigen Läufen ein Bild ab, die Erfolgsrate liegt in etwa bei 30%. Langsam habe ich mich auch “satt gesehen” und verspüre den Drang weiter zu ziehen.
Nach tausenden Patches, drei Generationen von Coding-Agents und vielen Kilowattstunden Strom sehe ich die Welt ein bisschen klarer:
In einem Satz: Nicht ein einzelner Prompt gewinnt dir das Spiel, sondern das sauber abgestimmte Gesamtpaket aus Aufgabe, Modell, Tooling und Prozess.
Gutes Prompting ist nur einer unter vielen Faktoren, die meinen Erfolg beim KI-getriebenen Coding ausmachen. Prompting für sich zu nehmen ist dabei reines Glücksspiel!
Bei gleicher Eingabe unter gleichen Bedingungen habe ich ein breites Spektrum von Lösungen erlebt: Von völligem Scheitern ( Projekt gelöscht ) bis zu grandiosem Erfolg ( Patch erfolgreich inklusive Tests ) war wirklich alles dabei. Je nachdem, wie die Sterne gerade stehen.
Wenn ich jetzt zusammenfasse, was in Kombination wirklich zählt, wäre das:
Plot Twist. Hefte raus. Transferleistung von Code-Agents zu Menschen.
Das, was ich hier beschreibe, nennt man für Menschen “Leadership”
Für die gelten ähnliche, wenn nicht gleiche Punkte:
Wenn wir also das nächste Mal mit Code-Agents oder Menschen arbeiten, lasst uns aufhören in Schwarz und Weiß zu denken. Lasst uns stattdessen in Wahrscheinlichkeiten denken. Immer mit dem Ziel, unsere Chancen zu erhöhen. Gute Leader sind i.d.R. auch gut in Glücksspiel, weil sie in Einsätzen, Risiken und Gewinnwahrscheinlichkeiten denken.
Sie haben aufgehört, “Dinge dem Zufall zu überlassen” und angefangen, ihre Chancen zu erhöhen. Mit dem Wissen, dass sie dabei nicht alles kontrollieren können.
Und das ist die wahre Kunst: Gamblen mit Verstand.
Dieser Blog ist von Mensch geschrieben, mit Herz und hoffentlich auch Verstand. Nach dem Fertigstellen und Einchecken dieses Absatzes werde ich dennoch mit KI über den Text fliegen zur Korrektur. Dabei werde ich streng darauf achten, dass der Ton und die Seele dieses Artikels erhalten bleibt.