Wenn Software nur für den guten Fall gemacht wird

Veröffentlicht am

Bei vielen modernen Softwareprodukten entsteht ein eigentümlicher Eindruck: Solange alles so läuft, wie es vorgesehen ist, funktionieren sie erstaunlich gut. Doch sobald etwas Unvorhergesehenes geschieht, zeigt sich eine ganz andere Seite. Die Internetverbindung bricht ab, ein Server antwortet nicht rechtzeitig oder eine Antwort entspricht nicht dem erwarteten Format – und plötzlich dreht sich ein Kreis endlos, eine Schaltfläche reagiert nicht mehr oder das Programm bleibt in einem undefinierten Zustand stehen.

Der Benutzer erfährt dabei häufig nicht, was eigentlich geschehen ist. Er weiß nicht, ob seine Eingabe verarbeitet wurde, ob er noch warten soll, ob er den Vorgang wiederholen darf oder ob er damit womöglich etwas doppelt ausführt. Irgendwann beendet er frustriert das Programm und versucht es erneut.

Man gewöhnt sich daran. Und vielleicht ist genau das das eigentliche Problem.

Wenn der Ausnahmefall vergessen wird

Gute Software zeichnet sich nicht allein dadurch aus, dass sie im vorgesehenen Fall funktioniert. Das ist lediglich die Grundvoraussetzung. Ihre eigentliche Qualität zeigt sich dort, wo die Wirklichkeit vom vorgesehenen Ablauf abweicht.

Ein Programm kann nach dem einfachen Schema funktionieren:

Benutzer klickt → Anfrage wird gesendet → Server antwortet → Ergebnis wird angezeigt.

Die Wirklichkeit kennt jedoch zahlreiche Abweichungen. Die Verbindung kann während der Übertragung abbrechen. Der Server kann sehr spät antworten. Eine Anfrage kann den Server erreicht haben, während dessen Antwort auf dem Rückweg verloren geht. Der Benutzer kann versehentlich zweimal klicken. Die Anwendung kann während eines Vorgangs beendet werden.

Für all diese Fälle müsste entschieden sein, was anschließend geschieht.

Das ist aufwendig. Der normale Ablauf lässt sich demonstrieren und verkaufen. Die Behandlung eines Fehlers, der vielleicht nur bei einem von zehntausend Vorgängen auftritt, kostet dagegen Entwicklungszeit, ohne dass der Benutzer davon etwas bemerkt – solange alles funktioniert.

Damit entsteht ein wirtschaftlicher Anreiz, vor allem den sogenannten „Happy Path“ zu perfektionieren und die unangenehmen Randfälle auf später zu verschieben.

Der sich ewig drehende Kreis

Besonders problematisch ist eine Entwicklung, bei der Fehler nicht mehr als solche bezeichnet werden.

Statt einer Meldung wie

Die Verbindung zum Server wurde unterbrochen.

erscheint:

Bitte warten…

Das wirkt zunächst benutzerfreundlicher. Der Benutzer soll schließlich nicht mit technischen Einzelheiten belästigt werden.

Doch damit verändert sich etwas Entscheidendes. Aus einem Fehler wird scheinbar ein noch laufender Vorgang. Der Benutzer weiß nun nicht mehr, ob das Programm noch arbeitet. Er weiß auch nicht, wie lange er vernünftigerweise warten sollte. Nach zehn Sekunden? Einer Minute? Fünf Minuten? Irgendwann entscheidet er selbst, dass es wohl nicht mehr weitergeht, und bricht ab.

Damit entsteht eine bemerkenswerte Verschiebung der Verantwortung. Im Protokoll kann nun möglicherweise stehen:

Vorgang durch Benutzer abgebrochen.

Formal stimmt das sogar. Tatsächlich wurde der Benutzer jedoch durch das Verhalten der Software zum Abbruch gezwungen.

Hätte er nur noch ein wenig gewartet, könnte man anschließend behaupten, wäre es bestimmt weitergegangen.

Aus einem technischen Versagen wird damit beinahe ein Bedienungsproblem.

Der Benutzer als Blindflieger

Besonders bedenklich ist dabei die ungleiche Verteilung der Informationen.

Die Software kann durchaus wissen, dass eine Anfrage seit 90 Sekunden unbeantwortet ist, dass die Netzwerkverbindung unterbrochen wurde oder dass ein Timeout eingetreten ist.

Der Benutzer sieht lediglich einen sich drehenden Kreis. Er muss nun eine Entscheidung treffen, obwohl gerade das System, das ihm die notwendigen Informationen geben könnte, sie ihm vorenthält. Das kann sogar neue Fehler erzeugen.

Ein Benutzer bestellt etwas und erhält nach dem Klick auf „Kaufen“ keine Bestätigung. Wurde die Bestellung übermittelt oder nicht? Er versucht es erneut – und erhält später zwei Lieferungen. Bei einer Überweisung wäre dieselbe Situation noch unangenehmer.

Gute Software müsste deshalb einen technischen Fehler nicht unbedingt verhindern können. Aber sie müsste den daraus entstehenden Zustand beherrschbar machen:

Die Verbindung wurde während des Vorgangs unterbrochen. Wir können derzeit nicht feststellen, ob Ihre Bestellung angenommen wurde. Bitte führen Sie die Bestellung nicht erneut aus.

Der Benutzer muss nicht wissen, welcher Netzwerkfehler aufgetreten ist. Er muss aber wissen, **was er jetzt tun soll**.

Das ist ein wesentlicher Unterschied.

Was geschieht, wenn KI aus dieser Welt lernt?

Mit künstlicher Intelligenz bekommt das Problem eine weitere Dimension.

KI lernt aus menschlichen Erzeugnissen der Vergangenheit – und damit nicht nur aus unseren hervorragenden Lösungen, sondern auch aus unseren schlechten Gewohnheiten. Wenn Millionen Programme hauptsächlich für den Normalfall geschrieben wurden, finden sich genau diese Muster auch in Quellcode, Dokumentationen, Tutorials, Diskussionsforen und anderen Trainingsdaten wieder. Eine KI könnte daraus lernen, dass ein bestimmtes Vorgehen üblich ist.

Doch „üblich“ bedeutet nicht zwangsläufig „gut“.

Damit droht ein Rückkopplungseffekt: Menschen schreiben mangelhafte Software. KI lernt aus dieser Software. KI erzeugt ähnliche Software. Menschen übernehmen den erzeugten Code. Dieser wird wiederum Bestandteil der Softwarewelt, aus der zukünftige Systeme lernen.

Schlechte Gewohnheiten könnten dadurch nicht verschwinden, sondern sich vervielfältigen. Das Problem würde zusätzlich dadurch verstärkt, dass KI die Produktion von Software erheblich beschleunigt. Wir könnten dann sehr schnell sehr viel Software erzeugen, die im Normalfall beeindruckend funktioniert – und bei Abweichungen erstaunlich hilflos ist.

Vielleicht müssen wir erst durch das "Tal der Tränen"

Dahinter steckt möglicherweise ein wesentlich allgemeineres menschliches Problem.

Wir sind gut darin, aus eingetretenen Katastrophen zu lernen. Wesentlich schwerer fällt uns das Lernen aus Katastrophen, die nur eintreten könnten.

Vorher heißt es:

Das ist doch bisher noch nie passiert.

Hinterher lautet die Frage:

Warum hat daran niemand gedacht?

Voraussicht befindet sich dabei in einer undankbaren Position. Sie verursacht sichere Kosten, um einen unsicheren zukünftigen Schaden zu verhindern.

Zwei zusätzliche Entwicklungstage für die Behandlung von Verbindungsabbrüchen kosten heute Geld. Der Schaden, den diese Arbeit irgendwann verhindern könnte, ist dagegen hypothetisch. Unterbleibt die Arbeit und geschieht jahrelang nichts, scheint die Entscheidung richtig gewesen zu sein. Erst wenn der Schaden eintritt, wird offensichtlich, wie preiswert die Vorsorge gewesen wäre.

Vielleicht gehört dieses „Tal der Tränen“ tatsächlich häufig zum menschlichen Lernen. Erst wenn etwas schiefgeht, erkennen wir seinen Wert.

Aber müssen wir wirklich jeden Fehler selbst machen?

Es gibt Bereiche, in denen man sich dieses Vorgehen nicht leisten kann. In der Luftfahrt beispielsweise wäre es absurd, ausschließlich aus Abstürzen lernen zu wollen. Deshalb werden auch Zwischenfälle und Beinahe-Unfälle untersucht. Ein Ereignis muss nicht katastrophal enden, um wertvolle Informationen zu liefern.

Genau dieses Prinzip ließe sich stärker auf Software übertragen. Die entscheidende Frage wäre dann nicht nur:

Ist ein Fehler aufgetreten?

sondern:

Gab es eine Situation, in der beinahe etwas schiefgegangen wäre?

Dafür müsste man allerdings lernen, solche Situationen überhaupt wahrzunehmen.

Der unbekannte Schatz der Beinahe-Fehler

Technische Fehler werden bereits heute vielfach automatisch erfasst. Programme können Abstürze, Exceptions, Timeouts oder nicht erreichbare Server protokollieren.

Aber ein Benutzerproblem muss kein technischer Fehler sein.

Vielleicht benötigt ein Vorgang normalerweise zwei Sekunden, dauert bei einigen Benutzern jedoch 45 Sekunden. Vielleicht brechen viele Benutzer genau an derselben Stelle ab. Vielleicht klicken sie mehrfach auf dieselbe Schaltfläche, weil keine erkennbare Reaktion erfolgt.

Technisch kann dabei alles „ordnungsgemäß“ funktionieren.

Trotzdem erzählt das Verhalten der Benutzer eine Geschichte.

Man könnte solche Situationen gezielt erfassen:

Anfrage gestartet → ungewöhnlich lange Wartezeit → keine erkennbare Reaktion → Benutzer versucht es erneut → Benutzer beendet Anwendung.

Das wäre gewissermaßen der Beinahe-Unfall der Softwarewelt.

Noch wertvoller wäre eine einfache Rückmeldung des Benutzers:

Hier scheint etwas nicht funktioniert zu haben. Was ist passiert?

Der Benutzer könnte angeben, dass der Vorgang zu lange dauerte, dass er nicht wusste, ob seine Eingabe verarbeitet wurde oder dass er deshalb abgebrochen hat.

Damit würde aus dem Ärger eines einzelnen Benutzers eine Information, aus der das System lernen kann.

Vom Benutzerproblem zum besseren Programm

Ideal wäre ein geschlossener Lernprozess:

Ein Benutzer erlebt ein Problem. Das Problem wird erkannt oder gemeldet. Es wird klassifiziert und untersucht. Daraus entsteht eine Verbesserung. Und aus dieser Verbesserung wiederum entsteht ein Test, der dafür sorgt, dass derselbe Fehler künftig nicht erneut auftritt.

Aus der Erfahrung

Bei einer Verbindungsunterbrechung wusste der Benutzer nicht, ob seine Bestellung ausgeführt wurde.

würde beispielsweise eine dauerhafte Anforderung:

Wenn während einer Bestellung die Verbindung abbricht, muss das Programm einen unbekannten Transaktionszustand erkennen und dem Benutzer erklären, wie er sich verhalten soll.

Damit hätte ein einzelner Beinahe-Fehler die Software dauerhaft verbessert.

Vielleicht liegt gerade hier die große Chance der KI

Damit bekommt die künstliche Intelligenz noch einmal eine andere Rolle. Vielleicht besteht ihre größte Stärke in der Softwareentwicklung künftig gar nicht darin, möglichst schnell möglichst viel Code zu schreiben. Sie könnte vielmehr ständig die unangenehme Frage stellen:

Was könnte hier schiefgehen?

Eine KI könnte systematisch Verbindungen unterbrechen, Antworten verzögern, falsche Daten erzeugen, Vorgänge abbrechen, Benutzeraktionen wiederholen und ungewöhnliche Zustände provozieren. Und sie könnte gleichzeitig aus tatsächlichen Beinahe-Fehlern lernen. Dann würde KI nicht nur unsere bisherige Softwarekultur reproduzieren. Sie könnte helfen, eine bessere zu entwickeln.

Dafür müssten wir ihr allerdings beibringen, dass Qualität nicht allein bedeutet:

Der vorgesehene Ablauf funktioniert.

Sondern:

Auch wenn etwas Unvorhergesehenes geschieht, bleibt das System verständlich, beherrschbar und sicher.

Intelligenz, Erfahrung und Weisheit

Vielleicht führt die Frage nach schlechter Software deshalb zu einer viel allgemeineren Frage. Warum lernen Menschen so häufig erst aus eingetretenem Schaden?

Intelligenz hilft uns, ein entstandenes Problem zu lösen. Erfahrung hilft uns zu erkennen, welche Probleme wahrscheinlich entstehen werden. Weisheit besteht vielleicht darin, diese Erfahrung zu nutzen, bevor der Schaden überhaupt eintritt.

Die eigentliche kulturelle Leistung besteht deshalb nicht darin, niemals Fehler zu machen. Das wird unmöglich bleiben. Sie besteht darin, **nicht jeden Fehler selbst machen zu müssen und nicht auf die Katastrophe zu warten, wenn der Beinahe-Unfall bereits genügend Informationen geliefert hat.**

Vielleicht sollte genau das auch unser Anspruch an zukünftige Software sein. Nicht Software, die niemals scheitert. Sondern Software, die weiß, wie man vernünftig scheitert – und die aus jedem Beinahe-Scheitern ein wenig besser wird.