Vor vielen Jahren, aber auch Jahre nach der Gründung von Lokad, wurde mir klar, dass keine einzelne App jemals etwas Großartiges im Bereich der Optimierung der Lieferkette liefern würde. Wir haben unser Bestes gegeben, aber es war nicht genug. Egal wie viele Funktionen wir in die frühesten Versionen von Lokad eingebaut haben, jeder neue Kunde schien verzweifelt anders zu sein als alle bisherigen, die wir bisher abgedeckt hatten. Lieferkettenherausforderungen sind einfach zu vielfältig und zu chaotisch, um in eine vernünftige Anzahl von Menüs, Schaltflächen und Optionen eingebunden zu werden.

Eine Python-Schlange, die nichts mit Python, der Programmiersprache, zu tun hat.

Tatsächlich erkennt die Mehrheit unserer Mitbewerber diese Situation an und hat sich auf den Weg gemacht, Softwareprodukte zu entwickeln, die eine unvernünftige Anzahl von Menüs, Schaltflächen und Optionen enthalten, alles in einem verzweifelten Versuch, alle Lieferkettenherausforderungen zu bewältigen. Leider führt dieser Weg zu Software-Monstrositäten, die sich bei der Bereitstellung in großem Maßstab in spektakuläre Fehlschläge verwandeln. Ich bezeichne dieses Antipattern als den nicht-euklidischen Horror.

Angesichts einer Klasse von Problemen - d.h. Lieferkettenherausforderungen -, die einfach nicht mit einer einzigen App gelöst werden konnten, begannen wir, teilweise zufällig1, das Meta-Problem anzugehen: wie man maßgeschneiderte Apps liefert, bei denen jede App der Lösung eines einzelnen Problems für eine bestimmte Situation gewidmet ist, z.B. Auffüllungsoptimierung für ein bestimmtes Unternehmen.

Die Bereitstellung maßgeschneiderter Software für Unternehmen ist nichts Neues. Die Softwareindustrie begann in den 60er Jahren auf diese Weise und entwickelte sich später in den 80er Jahren zum dominierenden Shrinkwrap-Modell, das wir heute kennen. Als Faustregel gilt, dass maßgeschneiderte Software im Vergleich zu Shrinkwrap viele unerwünschte Eigenschaften aufweist: höhere Anfangsinvestitionen, langwierige Einrichtungen, höhere Wartungskosten, höhere Risiken usw.

Dennoch zeigte die Erfahrung, die ich in den ersten Jahren von Lokad gesammelt hatte, dass maßgeschneiderte Software in Bezug auf die Optimierung der Lieferkette einen entscheidenden Vorteil hatte: Sie lieferte tatsächlich großartige Ergebnisse. Tatsächlich lieferte unsere ursprüngliche App bestenfalls akzeptable Ergebnisse2, unabhängig von der Genauigkeit der Prognosen, während diese Prototypen häufig großartige Ergebnisse erzielten. Darüber hinaus bestand der einzige Trick darin, die extreme Spezialisierung der Softwarekomponente, die für das jeweilige Problem vorgesehen war.

Nachdem wir alle Alternativen erschöpft hatten, kamen wir zu dem Schluss, dass die Bereitstellung maßgeschneiderter Apps der einzige Weg war. Doch Skalierbarkeit; wie man viele Apps bereitstellt, und Wartbarkeit; wie man die Wartungskosten unter Kontrolle hält, waren zwei Kernfragen. Zunächst mussten wir eine Programmiersprache wählen. Zu dieser Zeit haben wir viele Optionen in Betracht gezogen: R, Python, JavaScript, Lua, C#, … und die Einführung unserer eigenen domänenspezifischen Programmiersprache (DSL), die später als Envision bekannt wurde. Die Vor- und Nachteile all dieser Optionen zu diskutieren, wäre etwas mühsam3, daher wurde die Diskussion auf die Wahl zwischen Python und Envision beschränkt; wobei Python der stärkste Konkurrent gegen die Einführung unserer eigenen DSL war.

Python war aufgrund seiner Einfachheit und seines umfangreichen Ökosystems von Drittanbieter-Bibliotheken, insbesondere im Bereich des maschinellen Lernens4, attraktiv. Es war auch eine kostengünstige Option für Lokad: Da Python und nahezu alle seine beliebten Bibliotheken Open Source sind, hätten wir nur eine schmale Auswahl von Python neu verpackt, einige Dutzend handverlesene Pakete auf die Whitelist gesetzt und wären fertig gewesen. Die meiste Arbeit für Lokad hätte darin bestanden, eine PaaS-Erfahrung rund um Python ala Heroku zu bieten, die so maßgeschneidert wie möglich auf die Herausforderungen der Lieferkette zugeschnitten ist.

Doch hier ist ein Lackmustest, den wir in Betracht zogen: War es vernünftig zu erwarten, dass ein Business Analyst - später als Supply Chain Scientist bekannt - der 1 Tag pro Woche für 6 Monate arbeitet, eine produktionsreife App entwickelt, um eine geschäftskritische Lieferkettenherausforderung wie die Wiederbeschaffung für ein Unternehmen mit einem Umsatz von 10 Millionen US-Dollar zu lösen? Bei Betrachtung der Python-Option war klar, dass wir niemals auch nur annähernd ein solches Maß an betrieblicher Effizienz erreichen könnten.

Erstens benötigt Python Softwareingenieure. Tatsächlich stellt Python wie jede vollwertige Programmiersprache tonnenweise technische Feinheiten für jeden bereit, der Code in Python schreibt. Obwohl die Rolle des Supply Chain Scientists erst später formalisiert wurde, hatten wir frühzeitig die Intuition, dass es selbst bei intelligenten und talentierten Menschen zu viel verlangt war, dass sie sowohl Experten für Supply Chain Engineering als auch Experten für Software Engineering sein sollten. Wir benötigten programmatische Fähigkeiten, die einem breiten Spektrum technisch versierter Menschen zugänglich waren, nicht nur professionellen Softwareingenieuren.

Daher haben wir Envision als Sprache entwickelt, um ganze Klassen technischer Probleme zu eliminieren, die bei Python unvermeidlich sind. Zum Beispiel:

  • Objekte können null sein, Daten können absurd weit in der Vergangenheit oder Zukunft liegen, NaN kann glücklich durch Ihre Datenpipeline propagieren, Zeichenketten können absurd groß werden… In der Lieferkette sind diese “Features” nichts als Probleme, die nur darauf warten, zu passieren.
  • Objektorientierte Elemente (d.h. Klassen) werden garantiert falsch verwendet5, und dasselbe gilt für benutzerdefinierte Ausnahmen oder Regexes. Die bloße Existenz dieser Elemente ist bestenfalls eine ungesunde Ablenkung.
  • Mehrere grundlegende Operationen wie das Parsen unterschiedlicher tabellarischer Dateien (einschließlich Excel-Tabellenkalkulationen) sind nicht Teil der Sprache und erfordern den Umgang mit vielen verschiedenen Paketen, von denen jedes seine eigenen technischen Feinheiten hat.

Keine dieser Klassen technischer Probleme kann aus Python entfernt werden, ohne die Sprache selbst zu beeinträchtigen. Envision ist als Programmiersprache für Supply Chain-Spezialisten (vs. Software-Spezialisten) zugänglich, nur aufgrund seines scharfen Fokus auf vorhersagbare Optimierungsprobleme in der Lieferkette.

Denken Sie an das letzte Mal, als Sie Berechnungen mit einer Excel-Tabelle durchgeführt haben, und stellen Sie sich vor, Sie diktieren alle Änderungen, die Sie an dieser Excel-Tabelle vorgenommen haben, telefonisch, ohne die Excel-Tabelle selbst sehen zu können. So sieht eine Lieferkettenoptimierungsinitiative aus, die von Praktikern vorangetrieben, aber von Softwareingenieuren (die keine Spezialisten in der Lieferkette sind) implementiert wird. Unternehmen verbringen eine enorme Menge an Zeit damit, zu vermitteln, was sie von der IT wollen; und die IT verbringt eine enorme Menge an Zeit damit, herauszufinden, was das Unternehmen will. Nach einem Jahrzehnt Erfahrung bei Lokad beobachte ich, dass sich die Kosten für eine quantitative Lieferkettenoptimierungsinitiative, die von Softwareentwicklern, die keine Spezialisten in der Lieferkette sind, durchgeführt wird, um mindestens den Faktor 5 multiplizieren, unabhängig davon, wie agil und talentiert das Softwareteam sein kann.

Zweitens steigen die Wartungskosten für hastige Python-Prototypen ins Unermessliche. Außerhalb der Softwarebranche ist vielen Menschen nicht bewusst, dass Softwareentwicklung hauptsächlich darin besteht, die Wartungskosten unter Kontrolle zu halten. Das Knacken von Lieferkettenoptimierungsproblemen ist jedoch ein chaotischer Prozess: Die Daten aus vielen (schlecht) zuverlässigen Systemen müssen zuverlässig gepipelined werden, unvollkommene und sich ständig ändernde Prozesse müssen dokumentiert und modelliert werden, die Optimierungsmetriken spiegeln eine sich ständig ändernde Geschäftsstrategie wider, usw. Als Ergebnis enthält jede geschriebene Software zur Lieferkettenoptimierung immer eine massive Dosis domänenspezifischer Komplexität, die lediglich damit zurechtkommt, was die Welt uns entgegenwirft.

Doch Zeit ist von entscheidender Bedeutung. Es hat keinen Sinn, den perfekten Plan für den Produktionsplan des letzten Jahres zu haben. Als Faustregel gilt, dass der Tag, an dem der Softwareprototyp zu funktionieren beginnt, innerhalb weniger Wochen in die Produktion überführt wird, unabhängig davon, ob der Prototyp gut oder schlecht geschrieben ist.

Die Erwartung, dass das obere Management einer 6-monatigen Verzögerung zustimmt, um den Prototypen aus Wartungssicht produktionsreif zu machen, ist Wunschdenken. Doch einen hastigen Python-Prototypen in die Produktion zu bringen, ist das Rezept für epische Wartungsaufwände, bei denen rund um die Uhr gegen eine endlose Flut von Fehlern gekämpft werden muss, die mit Klebeband behoben werden müssen.

Daher ist der einzige praktikable Weg, die Produktion vernünftig zu halten, den Prototypen mit einer Programmiersprache zu schreiben, die ein hohes Maß an Entwurfskorrektheit gewährleistet. Envision liefert zum Beispiel im Gegensatz zu Python:

  • Endliche Ausführungszeit garantiert zur Kompilierzeit: Wenn mehrere Terabyte an Daten verarbeitet werden, ist es sehr mühsam, stundenlang zu warten, um festzustellen, dass eine Berechnung einfach nie beendet wird.
  • Zur Kompilierzeit garantierte begrenzte Speicherbelegung: Das Ringen mit Out-of-Memory-Fehlern in der nächtlichen Produktionscharge macht keinen Spaß und stört den Betrieb in der Praxis erheblich.
  • Atomare Lese- und Schreibzugriffe: Envision verhindert durch Design gleichzeitige Lese- und Schreibzugriffe im Dateisystem, auch wenn Dateien über FTP übertragen werden, während Skripte ausgeführt werden. Das Envision-Dateisystem ist praktisch ein auf giganormale Flachdateien zugeschnittenes Git. Ohne ordnungsgemäßes Daten-Versionierungssystem verwandeln sich viele Fehler in Heisenbugs: Wenn sich jemand mit dem Problem befasst, wurden die Daten bereits aktualisiert und das Problem kann nicht mehr repliziert werden.
  • Ambiente Skalierung der Programmausführung über eine Cloud von Rechenressourcen, die alle Parallelisierungshürden beseitigt, die unvermeidlich sind, sobald die Daten einige zehn Gigabyte überschreiten.

Generische Programmiersprachen bieten nur wenig Entwurfskorrektheit; und Python, das weit in den Bereich des späten Bindens tendiert, bietet in diesem Bereich außerordentlich wenig. Selbst wenn man bessere Alternativen - aus der Sicht der Entwurfskorrektheit - wie Rust in Betracht zieht, sind diese Alternativen für die Lieferkettenoptimierung bei weitem nicht zufriedenstellend.

Hier sind noch ein paar weitere Bereiche, in denen Envision auf Arten glänzt, die für Python einfach nicht zugänglich sind:

Verteidigung in der Tiefe: Sobald jemand in Ihrer Organisation anfängt, Code zu schreiben, wird dieser Code - sofern nicht sehr spezielle Vorsichtsmaßnahmen getroffen werden - aus einer IT-Sicherheitsperspektive sofort zu einer Haftung. Durch Python ist es praktisch möglich, alles auf der Maschine auszuführen, auf der das Python-Skript läuft. Das ordnungsgemäße Abschotten von Python in der Praxis ist ein teuflisch kompliziertes Problem. Insbesondere ist jeder vom Python-Skript erzeugte String ein potenzieller Injektionsvektor. Während SQL-Injektionen berüchtigt sind, ist vielen Menschen nicht bewusst, dass sogar einfache Textdateien wie CSV anfällig für Injektionsangriffe sind. Envision bietet ein Maß an Sicherheit, das mit Python einfach nicht repliziert werden kann. Datenverstöße nehmen zu, und das Verstreuen von Python-Bits überall wird der IT-Sicherheit nicht guttun.

Transparente Leistung: Wenn ein Programm unpraktisch langsam ausgeführt wird, sollte dieses Programm überhaupt nicht erst kompiliert werden6. Wenn ein Programm um eine Zeile verkürzt wird, sollte das Programm schneller laufen. Wenn nur eine einzige Zeile geändert wird, sollte nur diese Zeile neu berechnet werden7, während das Programm über dieselben Daten erneut ausgeführt wird. Beim Kompilieren sollte der Compiler nicht auf eine bestimmte Maschine abzielen, sondern auf eine Cloud von Rechenressourcen, die automatische datengesteuerte Parallelisierung ermöglicht. Envision geht standardmäßig einen langen Weg, um all diese Eigenschaften ohne jeglichen Programmieraufwand zu liefern. Im Gegensatz dazu erfordert es in Python eine massive Verwendung spezialisierter Bibliotheken, um solche Eigenschaften auch nur annähernd zu approximieren.

Transparentes Upgrade: Der Stand der Technik ist, was die Software betrifft, ein sich ständig bewegendes Ziel. Im Jahr 2010 war das beste Machine-Learning-Toolkit SciPy (arguably). Im Jahr 2013 war es scikit. Im Jahr 2016 war es Tensorflow. Im Jahr 2017 war es Keras. Im Jahr 2019 war es PyTorch. Es gibt einen Spruch in der Softwareentwicklung, dass man das Geburtsjahr eines beliebigen Softwareprojekts anhand seines Software-Stacks und seiner Abhängigkeiten erkennen kann. Tatsächlich werden Sie, sobald Sie Ihre eigenen Python-Skripte bereitstellen, mehrere Abhängigkeiten übernehmen, die möglicherweise nicht gut altern. Im Gegensatz dazu nutzen wir bei Envision umfangreiche automatisierte Code-Umschreibungen8, um die “Legacy”-Skripte auf dem neuesten Stand einer sich ständig ändernden Sprache zu halten.

Gepackter Stack: Python-Skripte können nicht im luftleeren Raum existieren9. Der Code muss versioniert werden (z.B. Git) mit Zugriffsrechten (z.B. GitHub). Sie benötigen eine Umgebung zum Ausführen, die nicht Ihre eigene Maschine ist (z.B. eine Linux-VM in der Cloud). Ein Scheduler ist erforderlich, um die Datenpipeline zu orchestrieren (z.B. AirFlow). Eine verteilte spaltenorientierte Speicherschicht ist erforderlich für die Datenverarbeitung (z.B. Spark). Ein Machine-Learning-Toolkit ist erforderlich für die prädiktive Analyse (z.B. TensorFlow). Ein Optimierungs-Toolkit ist erforderlich, um kombinatorische Probleme in der Lieferkette zu bewältigen (z.B. GLPK). Die Rohergebnisse müssen an einem Ort zur späteren Verwendung verfügbar gemacht werden (z.B. SFTP-Server). Kollegen aus der Lieferkette müssen in der Lage sein, zu überwachen, was passiert (z.B. eine Web-Benutzeroberfläche). Zugriffsrechte müssen durchgesetzt werden (z.B. Active Directory), usw. Envision vereinfacht all dies zu einer einzigen Meta-App und nimmt Ihnen die Last ab, dutzende Softwarekomponenten zusammenzustellen, um selbst die einfachste App bereitzustellen.

Dann, obwohl es eine ausgezeichnete Sprache ist, ist Python nicht unangreifbar:

  • Die Rechenleistung ist schlecht, und es ist ein Kampf, jede einzelne Berechnung durch die richtige Bibliothek (z.B. NumPy) zu leiten, um eine abgrundtief schlechte Leistung bei Datenverarbeitungsaufgaben zu vermeiden. Darüber hinaus erzeugt die Verwendung mehrerer Bibliotheken oft viel Reibung, wenn Daten von einer zur nächsten verschoben werden müssen.
  • Auch die Speicherleistung ist schlecht, insbesondere die referenzzählende Garbage Collection von Python ist veraltet - und alle neueren Programmiersprachen wie Java, C# oder JavaScript verwenden stattdessen Tracing. Bei speicherintensiven Aufgaben mit großen Datenmengen ist dies nachteilig.
  • Das Paketmanagement in Python war ein Durcheinander für eine lange Zeit, und es bedarf eines Paketexperten, um es richtig hinzubekommen. Dieses Problem wurde auch durch schwierige Sprachupgrades verschlimmert.
  • Die meisten (wenigen) Korrektheitsprüfungen finden nur zur Laufzeit statt, wenn das Programm ausgeführt wird, was bei der Datenverarbeitung zu endlosem Frust führt. Offensichtliche Probleme zeigen sich erst nach mehreren Minuten der Ausführung und verringern die Produktivität.

Zusammenfassend lässt sich sagen, dass Python zwar großartig ist (das ist es auch), aber keine zufriedenstellende Lösung für die Optimierung der Lieferkette darstellt. Es ist durchaus möglich, eine ML-Anwendung in Python aufzubauen und zu pflegen, aber die Kosten sind erheblich. Es sei denn, Ihr Unternehmen ist bereit, ein kleines Software-Engineering-Team ausschließlich für die Wartung dieser Anwendung einzusetzen, wird das Ganze keine zufriedenstellenden Ergebnisse für Ihre Lieferkette liefern.

Bei der Entwicklung von Envision, einer domänenspezifischen Programmiersprache für die prädiktive Optimierung der Lieferkette, handelte es sich nicht um unsere erste Wahl. Es war nicht einmal unsere zehnte Wahl. Es war eher die einzige funktionierende Lösung, die wir nach fünf Jahren Erschöpfung einer langen Liste konventioneller Alternativen hatten. Sieben Jahre später und mit vielen Kundenunternehmen später schafft es jeder neue Kunde immer noch, uns auf die eine oder andere Weise mit einer weiteren Wendung in ihrer Lieferkette zu überraschen, die wir mit einem klassischen Unternehmensansatz niemals hätten bewältigen können. Programmierbarkeit war erforderlich, aber Python war nicht die Lösung, die wir brauchten.


  1. Im Jahr 2013 war ich immer noch der Meinung, dass es möglich sei, eine zufriedenstellende App für die Optimierung der Lieferkette zu entwickeln. Tatsächlich war es die Konfrontation mit Preisgestaltungsproblemen, die uns irgendwie dazu zwang, den Weg des Aufbaus unserer eigenen domänenspezifischen Sprache einzuschlagen. Diese Sprache war zunächst nur für die Preisoptimierung gedacht, aber schnell erkannten wir, dass dieser Ansatz auch genau das war, was für die Optimierung der Lieferkette benötigt wurde. ↩︎

  2. Die Vorstellung, dass eine überlegene Prognosegenauigkeit von selbst zu einer überlegenen Leistung der Lieferkette führen würde, war wahrscheinlich eine der größten Fehleinschätzungen, die ich hatte, als ich Lokad gründete. Sehen Sie sich diese Lokad TV-Episode für eine vernünftigere Perspektive zu diesem Thema an. ↩︎

  3. Die meisten Probleme, die wir mit Python identifiziert haben, hatten nichts mit Python per se zu tun, was eine großartige Programmiersprache ist, sondern nur damit, dass Python eine generische Programmiersprache ist. ↩︎

  4. Im Jahr 2013 hatte Python noch nicht die Dominanz erreicht, die es in den folgenden Jahren im Bereich des maschinellen Lernens erlangte. R war immer noch ein starker Konkurrent, aber SciPy und NumPy, zwei ausgezeichnete Bibliotheken, waren zu dieser Zeit bereits vorhanden und florierend. ↩︎

  5. Schauen Sie sich diesen ausgezeichneten Vortrag Stop Writing Classes von der Pycon 2012 an. Selbst erfahrene Softwareingenieure neigen dazu, es falsch zu machen. ↩︎

  6. Aufgrund des Halteproblems könnte der aufmerksame Leser darauf schließen, dass Envision keine Turing-vollständige Sprache ist. Tatsächlich ist Envision das nicht. ↩︎

  7. Envision basiert auf dem Unterschied zwischen Berechnungsgraphen und versucht, die Menge der Neuberechnungen bei inkrementellen Änderungen zu minimieren, um schnelles Prototyping über großen Datensätzen zu ermöglichen. Je nach Situation kann jedoch bereits eine einzige Zeilenänderung eine Neuberechnung des gesamten Skripts erfordern. ↩︎

  8. Automatisierte Code-Umschreibungen sind für eine generische Programmiersprache äußerst schwierig. Sofern die Programmiersprache und ihre gesamte Standardbibliothek nicht genau auf diese Anforderung zugeschnitten wurden, leisten automatisierte Upgrade-Tools in der Praxis wenig. Bei der Entwicklung von Envision wussten wir, dass wir viele Dinge falsch machen würden (und das haben wir auch), und daher haben wir sehr darauf geachtet, dass die Sprache besonders für automatisierte Umschreibungen geeignet ist. Bis heute haben wir über 100 inkrementelle Umschreibungen seit der Entstehung von Envision durchgeführt. ↩︎

  9. Ironischerweise ist “Batteries Included” eines der Mottos von Python. Die schiere Menge an Klebstoff, der benötigt wird, um alle Elemente zusammenzuführen, die für den Aufbau einer App zur Vorhersage der Supply Chain-Optimierung erforderlich sind, ist jedoch entmutigend. ↩︎