Ich betreibe nebenbei Freelancerpilot, ein Werkzeug für Freiberufler: Es durchsucht mehrere Projektbörsen, bewertet jedes gefundene Projekt mit einem Sprachmodell und schickt Treffer per E-Mail. Es ist kostenlos, ohne Kontozwang, ohne Abo, ohne Gewinnabsicht.
Genau daraus ergibt sich die interessanteste Randbedingung, die ich in den letzten Jahren hatte: Das System darf im laufenden Betrieb praktisch nichts kosten. Kein Budget, das man erhöhen kann, wenn es eng wird. Keine Rechnung, die man an einen Kunden weitergibt. Was die kostenlosen Kontingente der Anbieter hergeben, ist das Budget.
Die laufenden Kosten liegen entsprechend nahe null: Der Server läuft ohnehin, die Domain kostet ein paar Euro im Jahr, und die Modellaufrufe bleiben in den kostenlosen Stufen. Was das Projekt wirklich kostet, ist Arbeitszeit. Dieser Unterschied ist wichtig, sonst liest sich der Rest des Artikels wie „KI ist umsonst", und das wäre die falsche Botschaft.
Diese Regel hat mich zu Entscheidungen gezwungen, die ich in bezahlten Projekten oft erst nach der ersten überraschenden Rechnung treffe. Und rückblickend sind es fast alle Entscheidungen, die ich Kunden ohnehin empfehlen würde. Deshalb dieser Artikel: nicht als Produktvorstellung, sondern als Sammlung von sechs Entscheidungen und drei Fehlern, die ich dabei gemacht habe.
Die Aufgabe: Klassifizieren, nicht dichten
Bevor es um Architektur geht, lohnt der Blick auf die Aufgabe. Das Modell bekommt Projektausschreibungen und liefert für jede drei Dinge:
- Ist das überhaupt ein Freelance-Projekt? Ein Ja/Nein, das sitzen muss
- Eine Zusammenfassung in zwei bis drei Sätzen
- Stichworte mit Gewichtung: welche Technologien vorkommen und wie zentral sie sind
Das ist Textklassifikation mit strukturierter Ausgabe. Es ist keine Aufgabe, die ein Spitzenmodell braucht, und es ist keine Aufgabe, bei der Kreativität hilft. Diese Einordnung ist die wichtigste Entscheidung von allen, denn sie bestimmt jede weitere.
Wer das überspringt und reflexhaft das stärkste verfügbare Modell nimmt, zahlt den zehn- bis fünfzigfachen Preis für eine Aufgabe, die ein kleines Modell genauso gut löst. In einem Nebenprojekt merkt man das sofort, weil das Kontingent nach einer Stunde erschöpft ist. In einem Firmenprojekt merkt man es nach dem ersten Monatsabschluss.
Entscheidung 1: Das kleinste Modell, das die Aufgabe löst
Im Code steht die Modellwahl als Liste mit Vorrang, nicht als einzelner Name:
// Bevorzugte Gemini-Modelle, falls der konfigurierte Name wegfällt.
// Die Lite-Varianten zuerst: Sie haben die großzügigsten kostenlosen
// Kontingente, und die Aufgabe braucht kein Spitzenmodell.
var geminiModelPreferences = []string{
"gemini-2.5-flash-lite",
"gemini-2.5-flash",
"gemini-2.0-flash",
"gemini-flash-latest",
}Die Reihenfolge ist die eigentliche Aussage: erst das kleinste, dann aufwärts. Nicht umgekehrt.
Dass in der Liste auch ein älteres Modell steht, ist kein Versehen. Ein Name dort ist eine Präferenz, keine Zusage: Verschwindet er aus dem Angebot, überspringt ihn die Auflösung aus Entscheidung 4 und nimmt den nächsten, den es wirklich gibt. Eine solche Liste darf deshalb altern, ohne dass jemand sie pflegt. Das ist der Unterschied zu einem einzelnen fest verdrahteten Namen, und genau daran ist dieses System schon einmal stehen geblieben.
Die verbreitete Herangehensweise ist die andere: Man startet mit dem größten Modell, weil es „auf jeden Fall reicht", und optimiert später. Später kommt selten. Der umgekehrte Weg kostet einen Nachmittag: kleinstes Modell nehmen, an fünfzig echten Beispielen prüfen, ob die Ausgabe taugt, und nur bei belegbaren Fehlern eine Stufe hochgehen.
Der Nebeneffekt ist Geschwindigkeit. Kleine Modelle antworten schneller, und bei einer Verarbeitung, die tausende Ausschreibungen je Durchlauf abarbeitet, ist das kein Komfortthema, sondern entscheidet, ob der Durchlauf in Minuten oder Stunden fertig ist.
Entscheidung 2: Bündeln statt einzeln fragen
Der zweite Hebel ist noch banaler und noch wirksamer: Nicht jedes Projekt einzeln fragen, sondern mehrere in einem Aufruf.
func (s *AIService) ProcessProjects() {
batchSize := 19
projects, err := s.repo.GetUnprocessedProjects(batchSize)
...
}Statt neunzehn Anfragen eine. Das spart nicht nur neunzehnmal den Verbindungsaufbau, sondern vor allem neunzehnmal den Systemteil des Prompts. Und der ist bei einer Klassifikationsaufgabe mit klaren Regeln der längere Teil: Die Anweisung, was ein Freelance-Projekt ausmacht, ist mehrere hundert Wörter lang, die einzelne Ausschreibung oft nur wenige Dutzend.
Wer einzeln fragt, bezahlt diese Anweisung bei jedem Projekt erneut. Bei Anbietern, die nach Token abrechnen, ist Bündeln damit die günstigste Optimierung überhaupt – und bei kostenlosen Kontingenten, die pro Anfrage und pro Minute begrenzt sind, entscheidet sie darüber, ob die Verarbeitung überhaupt hinterherkommt.
Warum ausgerechnet neunzehn? Der Anlass war ein Anfragelimit pro Minute, und die Zahl ist seitdem so geblieben. Das ist ehrlicher als jede nachträgliche Herleitung, und es beschreibt den Normalfall: Solche Konstanten entstehen aus einer konkreten Begrenzung und überleben deren Ursache.
Die Grenzen nach oben sind trotzdem klar benennbar. Das Kontextfenster muss alle Projekte plus Antwort fassen. Und je größer das Bündel, desto teurer ein Fehlschlag, weil dann die ganze Gruppe betroffen ist statt eines einzelnen Projekts. Wer die Größe erhöht, sollte deshalb beides messen: ob die Antworten noch vollständig sind, und was ein Fehlversuch kostet.
Entscheidung 3: Drei Anbieter statt einem
Das System spricht nicht mit einem Anbieter, sondern mit einer Kette: Groq, dann Mistral, dann Gemini. Jeder mit eigenem kostenlosen Kontingent, jeder als vollwertiger Ersatz für die anderen.
Der Grund ist zunächst banal: Drei kostenlose Kontingente sind mehr als eines. Der wichtigere Grund ist Verfügbarkeit. Ein Modellanbieter ist ein Fremdsystem, dessen Erreichbarkeit man nicht kontrolliert – und die kostenlosen Stufen sind erwartungsgemäß die ersten, die gedrosselt werden. Wer nur einen hat, steht still, sobald dieser eine ein Limit meldet.
Voraussetzung dafür ist, dass die Anwendung nicht anbieterspezifisch programmiert ist. Im Code ist jeder Anbieter hinter derselben schmalen Schnittstelle versteckt: rein ein Prompt, raus eine JSON-Antwort. Was ein Anbieter an Eigenheiten mitbringt, bleibt in seiner Datei. Der Rest des Systems weiß nicht, mit wem er spricht.
Das ist derselbe Gedanke, den ich Kunden bei Zahlungsanbietern predige, und er gilt hier genauso: Die Abstraktion ist nicht Selbstzweck, sie ist die Voraussetzung dafür, den Anbieter überhaupt wechseln zu können – geplant oder mitten in der Nacht.
Fehler 1: Ein Fallback, der nur einen Fehlertyp abfängt
Die Kette gab es von Anfang an. Trotzdem stand die Verarbeitung eines Tages still.
Groq hatte das Modell llama-3.3-70b-versatile aus dem Angebot genommen. Die Anfrage kam mit 404 model_not_found zurück. Und die Kette – so war sie gebaut – wechselte nur bei Rate-Limits zum nächsten Anbieter. Ein 404 ist kein Rate-Limit. Also brach sie ab. Mistral und Gemini waren verfügbar, wurden aber nie gefragt.
Im Code steht die Lehre heute direkt über der Kette:
// Die Kette wechselt bei JEDEM Fehler zum nächsten Provider, nicht nur bei
// Rate-Limits. [...] Ein Fallback, der nur einen Fehlertyp abfängt, schützt
// genau dann nicht, wenn ein Anbieter tatsächlich ausfällt. Welcher Fehler
// vorliegt, ist für die Entscheidung unerheblich: Wenn ein Provider nicht
// liefert, ist der nächste an der Reihe.Das ist der allgemeine Punkt hinter dem konkreten Fehler: Ausfallsicherung, die nur den erwarteten Fehler kennt, ist keine. Man baut sie gegen das Szenario, das man sich vorgestellt hat – Rate-Limit – und der Ernstfall kommt in einer anderen Form.
Nur: Die Antwort im Code ist die grobe. Sie war für den Vorfall richtig und ist als allgemeine Regel zu schlicht, denn nicht jeder Fehler ist ein Anbieterproblem. Wenn die eigene Anfrage kaputt ist, ungültiges JSON, ein zu großer Text, ein abgelaufener Schlüssel, dann scheitert sie bei Anbieter B genauso. Die Kette verdeckt dann den eigenen Fehler hinter drei Versuchen, und was am Ende im Protokoll steht, ist die Meldung des letzten Anbieters statt der Ursache.
Die Regel, die ich einem Kunden mitgeben würde, unterscheidet deshalb nach Fehlerklasse, nicht nach Einzelfall:
| Was passiert ist | Richtige Reaktion |
|---|---|
| Zeitüberschreitung, Serverfehler, Limit | Nächster Anbieter. Der aktuelle kann gerade nicht. |
| Modell nicht mehr verfügbar | Modell neu auflösen, sonst nächster Anbieter. |
| Fehlerhafte Anfrage, kaputte Anmeldung | Laut scheitern. Der nächste Anbieter sagt dasselbe, nur später. |
Die dritte Zeile ist die, die man beim Bauen vergisst, und die einzige, bei der ein Fallback schadet: Er verwandelt einen sofort sichtbaren Programmierfehler in ein diffuses „irgendwas mit der KI klappt nicht".
Wer aufmerksam liest, wird gleich sehen, dass Entscheidung 4 genau diese Grenze schon zieht: Dort löst nur „Modell nicht gefunden" eine Neuauflösung aus, ausdrücklich kein Netzwerkfehler und kein Limit. Die Feinheit war also schon da, nur an einer Stelle. Die Kette selbst arbeitet bis heute grob, und in diesem System ist das vertretbar, weil alle drei Anbieter dieselbe Anfrage bekommen und ein Anfragefehler am Ende ohnehin durchschlägt. Vertretbar heißt nicht vorbildlich.
Nebenbei zeigt der Fall noch etwas: Der Fallback wird jetzt bei jedem Übernehmen protokolliert.
log.Printf("✅ %s hat übernommen, nachdem vorherige Provider fehlschlugen", p.Name())Ohne diese Zeile bleibt ein dauerhaft defekter Primäranbieter unbemerkt, weil ja alles weiterläuft. Stille Ausfallsicherung ist ein schleichender Ausfall.
Fehler 2: „generate" enthält „rate"
Der zweite Fehler ist kleiner, peinlicher und lehrreicher.
Die Erkennung eines Rate-Limits war ursprünglich eine Teilstring-Suche nach "rate" in der Fehlermeldung. Das funktioniert – bis eine Meldung failed to generate content lautet. Darin steckt „generate". Jeder beliebige Erzeugungsfehler wurde damit als Limit behandelt und löste die Logik aus, die für Drosselung gedacht war.
Solche Fehler entstehen nicht aus Unwissen, sondern aus Bequemlichkeit im richtigen Moment: Eine Teilstring-Suche ist in dreißig Sekunden geschrieben, eine saubere Fehlerklassifikation kostet zwanzig Minuten. Die Rechnung geht so lange auf, bis sie es nicht mehr tut.
Die allgemeine Regel, die ich daraus mitnehme: Fehler von Fremdsystemen gehören klassifiziert, nicht durchsucht. Und wo man doch auf Textmuster angewiesen ist – weil der Anbieter keine sauberen Codes liefert –, dann auf vollständige Marker, nicht auf Fragmente. Im heutigen Code steht dafür eine ausdrückliche Liste, und der Kommentar daneben sagt, warum sie eng gefasst ist:
// Bewusst eng gefasst: Ein Netzwerkfehler oder ein Limit darf keine
// Neuauflösung auslösen, sonst tauscht das System bei jeder Störung sein
// Modell.Entscheidung 4: Modellnamen sind Verbrauchsmaterial
Aus dem Groq-Vorfall folgte noch eine zweite Änderung, und die halte ich für die interessanteste Architekturentscheidung des Projekts.
Fest im Code stehende Modellnamen sind eine Zeitbombe, besonders bei kostenlosen Anbietern: Dort werden Modelle schnell eingeführt, umbenannt und wieder abgekündigt. Die naheliegende Antwort wäre, den Namen in eine Umgebungsvariable zu ziehen. Das verschiebt das Problem nur – jemand muss den Ausfall bemerken und den Wert austauschen.
Stattdessen heilt sich das System selbst: Kommt genau der Fehler „Modell existiert nicht", fragt der Anbieter seine eigene Modellliste ab und wählt daraus das erste, das zur Aufgabe passt.
// Die API liefert Namen als "models/gemini-2.5-flash".
ids = append(ids, strings.TrimPrefix(m.Name, "models/"))
...
picked := pickModel(ids, geminiModelPreferences)Zwei Details entscheiden darüber, ob das eine gute oder eine gefährliche Idee ist.
Erstens die enge Auslösebedingung. Nur „Modell nicht gefunden" löst die Neuauflösung aus. Ein Netzwerkfehler oder ein Limit darf es nicht, sonst wechselt das System bei jeder Störung sein Modell – und niemand weiß hinterher, womit welche Ausgabe erzeugt wurde.
Zweitens der Filter. Aus der Modellliste kommen auch Modelle, die keine Chat-Anfragen beantworten, etwa reine Einbettungsmodelle. Berücksichtigt wird deshalb nur, was generateContent unterstützt. Ein Selbstheilungsmechanismus, der sich das falsche Modell aussucht, ist schlimmer als gar keiner: Er ersetzt einen lauten Ausfall durch einen leisen.
Und der konfigurierte Name bleibt weiterhin die bevorzugte Wahl. Die Auflösung greift nur, wenn er nicht mehr existiert. Selbstheilung ersetzt nicht die Konfiguration, sie fängt deren Verfall ab.
Entscheidung 5: Der Prompt ist ein Filter mit Voreinstellung
Ein Sprachmodell trifft hier eine Entscheidung, die der Nutzer direkt spürt: Ist das ein Freelance-Projekt oder eine Festanstellung? Beide Fehlerrichtungen sind möglich, aber sie sind nicht gleich schlimm.
Ein übersehenes Projekt merkt niemand. Eine Festanstellung in einer Freelance-Benachrichtigung merkt jeder – und nach der dritten meldet sich niemand mehr ab, sondern liest die Mails einfach nicht mehr.
Deshalb ist der Prompt bewusst asymmetrisch gebaut. Er listet nicht nur, was für ein Freelance-Projekt spricht, sondern ebenso ausdrücklich, was sofort dagegen spricht – und legt eine Voreinstellung fest:
Wenn KEINE klaren Freelance-Signale vorhanden sind → FALSE
Wenn Text mehrdeutig ist → FALSE (Sicherheit geht vor)
"Remote" oder "Homeoffice" allein ist KEIN Freelance-Signal → FALSE
Bei Zweifel → FALSEDas ist im Kern dasselbe, was in klassischer Software eine Positivliste ist: Im Zweifel ablehnen. Nur steht die Regel hier in Prosa statt in Code – was sie nicht weniger zu Programmlogik macht. Sie entscheidet über das Verhalten des Systems, sie ändert sich häufig, und sie muss zurücknehmbar sein. Deshalb gehört ein solcher Prompt in die Versionsverwaltung und nicht in ein Textfeld in irgendeiner Oberfläche.
Ein zweiter, unscheinbarer Punkt derselben Art: Vor dem Modell wird das HTML aus den Ausschreibungen entfernt. Markup kostet Token, trägt zur Bedeutung nichts bei und lenkt das Modell im Zweifel ab. Bei tausenden Ausschreibungen je Durchlauf ist das kein Detail.
Entscheidung 6: Stille Ausfälle laut machen
Die letzte Entscheidung ist die, die am wenigsten mit KI zu tun hat und im Betrieb am meisten wert ist.
Wenn die KI-Verarbeitung ausfällt, passiert nichts Dramatisches. Die Website läuft, die Anmeldung funktioniert, das Scraping sammelt weiter Projekte. Nur: Unverarbeitete Projekte lösen keine Benachrichtigungen aus. Für den Nutzer sieht das nicht nach einem Ausfall aus, sondern nach einer ruhigen Woche am Projektmarkt.
Das ist die gefährlichste Sorte Störung – die, die niemand meldet. Deshalb zählt das System aufeinanderfolgende Fehlschläge und schlägt beim Erreichen einer Schwelle Alarm, mit genau den Angaben, die man nachts um drei braucht:
Die KI-Verarbeitung schlägt seit %d Durchläufen in Folge fehl.
Provider-Kette: %s
Unverarbeitete Projekte: %s
Letzter Fehler: %v
Solange die Verarbeitung steht, werden für neue Projekte keine
Benachrichtigungen verschickt.Drei Dinge daran sind Absicht:
Die Schwelle. Ein einzelner Fehlschlag ist Normalbetrieb, gerade bei kostenlosen Kontingenten. Wer bei jedem Fehler alarmiert, erzieht sich selbst dazu, Alarme zu ignorieren.
Die Sperrfrist. Nach einer Warnung bleibt es für eine Weile still, auch wenn es weiter fehlschlägt. Zwanzig identische Mails helfen niemandem.
Die Entwarnung. Läuft es wieder, kommt eine zweite Nachricht. Ohne sie weiß man nie, ob ein Problem behoben ist oder nur die Warnungen aufgehört haben.
Und die letzte Zeile der Warnung ist die wichtigste: Sie sagt nicht, was kaputt ist, sondern was das für den Nutzer bedeutet. Genau daran bemisst sich, wie dringend man aufsteht.
Fehler 3: Zu lange kein fester Testsatz
Der dritte Fehler hat mich am längsten begleitet, weil er nie weh tat. Es gab keinen festen Satz von Beispielen mit bekannter richtiger Antwort. Änderungen am Prompt habe ich an einzelnen Ausschreibungen beurteilt: eine ansehen, die neue Fassung ausprobieren, „sieht besser aus", weiter.
Das funktioniert, solange ein Modell die Aufgabe bearbeitet. Hier bearbeiten sie drei. Ein Prompt, der bei Groq sauber klassifiziert, kann bei Gemini vorsichtiger oder großzügiger ausfallen, weil die Modelle dieselbe Anweisung unterschiedlich streng lesen. Wer an fünf Beispielen prüft, prüft im Zweifel beim falschen Anbieter, denn welcher gerade antwortet, entscheidet die Fallback-Kette.
Dazu kommt die Selbstheilung aus Entscheidung 4. Sie hält das System am Leben, wenn ein Modellname verschwindet, und sie tauscht dabei das Modell aus, ohne dass jemand eingreift. Genau dann ändert sich möglicherweise auch die Qualität der Ausgabe. Ohne Testsatz merkt man davon nichts: Das System läuft, die Metriken sind grün, und die Klassifikation verschiebt sich still. Eine Selbstheilung ohne Messung tauscht einen sichtbaren Ausfall gegen eine unsichtbare Verschlechterung.
Der Aufwand wäre lächerlich gering gewesen: fünfzig Ausschreibungen, von Hand als Freelance oder Festanstellung eingeordnet, ein Nachmittag Arbeit. Danach ist jede Prompt-Änderung und jeder Modellwechsel eine Zahl statt einer Meinung, und man sieht sofort, ob eine Verbesserung für alle Anbieter gilt oder nur für einen. Genau das meint LLM-Evaluation, und sie ist deutlich weniger aufwendig, als der Begriff klingt.
Es ist die Arbeit, die man in Nebenprojekten am liebsten aufschiebt, und in Kundenprojekten macht sie den Unterschied zwischen „wir glauben, es ist besser geworden" und „es ist besser geworden".
Woran man merkt, dass es funktioniert
Alles bisher Beschriebene ist wertlos, wenn niemand sieht, ob das System gute Arbeit leistet. Bei KI ist das schwerer als bei klassischer Software: Ein Dienst, der antwortet, gilt technisch als gesund. Ob er sinnvoll antwortet, steht auf einem anderen Blatt.
Die technische Seite ist der einfache Teil. Der Dienst liefert Prometheus-Metriken, ein Grafana-Dashboard zeigt Durchsatz und Fehlerquote. Das beantwortet: Läuft die Verarbeitung, wie schnell, wie oft schlägt sie fehl.
Die fachliche Seite beantwortet es nicht. Dafür braucht es andere Größen, und die interessanteste ist kostenlos zu haben: der Rückstau. Wie viele Projekte warten gerade auf Verarbeitung? Diese eine Zahl fängt fast jede Störung ein, ohne dass man sie einzeln modellieren muss – ein ausgefallener Anbieter, ein erschöpftes Kontingent, ein zu klein gewordenes Zeitfenster, ein Zustrom, der schneller wächst als die Verarbeitung. Deshalb steht sie auch in der Warnmail: Nicht nur „es hakt", sondern „es hakt, und so viel liegt schon da".
Diese beiden Sichten beantworten unterschiedliche Fragen und ersetzen einander nicht. Die Metriken sagen, ob das System arbeitet. Der Testsatz aus dem vorigen Abschnitt sagt, ob es richtig arbeitet. Wer nur das erste hat, sieht einen gesunden Dienst, der zuverlässig Unsinn produziert.
Wo der Ansatz an Grenzen stößt
Damit der Artikel nicht wie eine Empfehlung für alle Fälle klingt: Drei Dinge trägt diese Bauweise nicht.
Sie taugt nicht für harte Antwortzeiten. Eine Kette aus drei Anbietern kann im schlechtesten Fall drei Fehlversuche machen, bevor eine Antwort kommt. Für eine Hintergrundverarbeitung ist das gleichgültig. Hinter einer Nutzeroberfläche, die in unter einer Sekunde antworten soll, wäre es untragbar – dort braucht es enge Zeitlimits pro Versuch und einen Schutzschalter, der einen dauerhaft kaputten Anbieter für eine Weile ganz überspringt.
Sie taugt nicht für Daten, die das Haus nicht verlassen dürfen. Kostenlose Kontingente bedeuten in der Regel andere Bedingungen zur Datenverarbeitung als bezahlte Stufen. Bei öffentlich ausgeschriebenen Projekttexten ist das unkritisch. Bei Kundendaten, Verträgen oder Personaldaten ist die erste Frage nicht, welches Modell gut ist, sondern wo es läuft und was mit den Eingaben passiert.
Und sie ersetzt keine Zusage. Ein System, das auf kostenlosen Kontingenten fährt, hat keine Verfügbarkeitszusage – bei keinem der drei Anbieter. Für ein kostenloses Werkzeug ist das ehrlich und angemessen. Wer seinen Kunden Verfügbarkeit zusichert, muss dafür bezahlen, und zwar bei mindestens einem Anbieter der Kette.
Was davon für bezahlte Systeme gilt
Die Randbedingung war künstlich – ein Nebenprojekt, das nichts kosten darf. Die Schlussfolgerungen sind es nicht:
| Entscheidung im Nebenprojekt | Warum sie auch mit Budget richtig ist |
|---|---|
| Kleinstes Modell zuerst | Die Kostenkurve zwischen Modellstufen ist steil, der Qualitätsunterschied bei Klassifikation gering |
| Bündeln statt einzeln | Die Anweisung wird einmal statt zwanzigmal bezahlt |
| Mehrere Anbieter hinter einer Schnittstelle | Ein Anbieter, den man nicht kontrolliert, ist ein Klumpenrisiko |
| Fallback nach Fehlerklasse statt nach Einzelfall | Der Ernstfall kommt in der Form, an die man nicht gedacht hat, und der eigene Fehler gehört nicht dahinter versteckt |
| Selbstheilung bei toten Modellnamen | Modellnamen sind kurzlebig, Konfiguration verfällt |
| Prompt mit Voreinstellung „ablehnen" | Falsche Treffer kosten Vertrauen, verpasste kosten wenig |
| Alarm mit Schwelle, Sperrfrist, Entwarnung | Stille Ausfälle sind teurer als laute |
Wenn ich eine davon herausheben müsste, wäre es die einfachste: Ein KI-System hat einen Preis pro Vorgang, und den sollte man kennen, bevor die Menge steigt. Bei kostenlosen Kontingenten erfährt man ihn sofort, weil das Kontingent nach einer Stunde leer ist. In einem Firmenprojekt erfährt man ihn nach dem ersten Monatsabschluss – und dann ist die Architektur schon gebaut.
Das ist der eigentliche Grund, warum sich das Nebenprojekt gelohnt hat: Es hat jede Entscheidung sofort bestraft, die in einem bezahlten Projekt erst Monate später weh getan hätte.

