{
  "video_id": "vi-2nasppAg",
  "channel_slug": "aidotengineer",
  "channel_handle": "aidotengineer",
  "title": "Make your own event-sourced agent harness using stream processors — Jonas Templestein, Iterate",
  "duration_seconds": 3867.0,
  "url": "https://www.youtube.com/watch?v=vi-2nasppAg",
  "upload_date": "",
  "transcript": "Willkommen zum Workshop.  Äh, ich bin\nJonas.  Ähm, und das ist Misha.  Wir\narbeiten beide daran.\nHallo.\nUnd ähm, das wird äh, Chaos geben.\nIch glaube, es herrschte vor allem pures Chaos, weil\nwir erst letzten Montag beschlossen hatten,\ndas zu machen, und dann gab es noch so\neiniges an persönlichen Dingen, die Halbjahresferien\nund die Kinder waren krank, und dann\nkamen wir heute Morgen hierher und ich dachte, das würde so ein 1\nStunde und 20 Minuten langer\nHackathon oder so werden, und\ndann kommen wir hierher und uns wird gesagt, dass wir das Ganze\nohne Publikum machen müssen,\nwegen irgendwas mit Feuer.  Und jetzt ist\nwieder Publikum da, was\nfantastisch ist.  Wir werden das Ganze also\nals eine Art improvisierten\nHackathon auf die Beine stellen, aber ich habe das\nSDK erst vor einer Minute hochgeladen, und Misha\nwird versuchen, es quasi live zu\nreparieren.  Aber ich hoffe, es ist trotzdem\nIhre Zeit wert, denn ich denke, es gibt da ein paar –\nhoffentlich zumindest ein paar\ninteressante Ideen – oder, um es mal so\nauszudrücken: Ich möchte\nherausfinden, ob das Ganze eher dumm oder cool ist.\nÄh, und ähm, und Sie können mir dabei helfen\n.  Stellen Sie also bitte auch klärende\nFragen, denn ein Grund dafür, warum\nwir letzte Woche gesagt haben, dass wir\ndiesen Workshop veranstalten sollen, ist, dass es sich um\nIdeen handelt, mit denen wir im\nletzten Jahr schon ein bisschen herumexperimentiert haben, aber\nwir haben noch nichts Konkretes damit gemacht. Es hat nicht unbedingt einen\nkommerziellen\nWert, aber ich denke, es geht im\nGrunde darum, wie ich\nAgenten-Harnesses erstellen möchte.  Also,\nich habe mich jetzt schon eine Weile mit diesem Thema beschäftigt,\nund natürlich gibt es\njetzt Leute wie Claude und Pi, aber früher gab es die nicht.\nMan erstellt also sein eigenes Codierungs-Framework, und dafür gibt es viele\nverschiedene Möglichkeiten\n.  Und ich denke, die Art und Weise, wie ich es gerne\nmachen würde, wäre, es rein\nereignisbasiert zu gestalten.  Ähm, und ich sage hier „auch\ndebugfähig“, weil alles irgendwie an der\nEvent-\nSource-Theorie vorbeigeht, ohne aber\nwirklich Event-Source zu sein.  Es gibt\nimmer etwas, das eine Nebenwirkung hat,\ndie man später nicht mehr erkennen kann, und die man dann\nnur noch in den Hotelaufzeichnungen oder\nso sieht, was\nfür mich keinen Sinn ergibt, denn normalerweise arbeiten diese\nAgenten so, wie sie es tun, und wir werden gleich\nsehen, dass sie bereits\nein Protokoll der Ereignisse haben, richtig?\nWenn man also einfach sagt, dass alles, was\nmöglicherweise passieren könnte, darin enthalten ist…  Das wird die\nFehlersuche sehr einfach machen.  Und wie wir hoffentlich\nsehen werden, ist es zwar etwas seltsam, aber\nmöglicherweise auch in anderer Hinsicht sehr\neinfach zu erweitern.  Ähm, und das\nZweite ist, dass ich möchte, dass es\nerweiterbar ist, und wir haben das, glaube ich,\nbei PI gesehen, was einfach\nunglaublich war, wie wertvoll es ist,\neinen Agenten nicht nur für Menschen,\nsondern auch für sich selbst erweiterbar zu machen.  Ähm, und\neine Sache, die ich mir in Bezug auf die Erweiterbarkeit wünsche, ist, dass sie\nzusammensetzbar sein soll.  Ich glaube nicht, dass wir das mit\neuch allen in einer Stunde schaffen, aber vielleicht, wenn ihr danach sagt: „\nOh, das ist echt cool und nicht blöd“, dann\narbeiten wir weiter daran. Ihr könnt dann\nsagen: „Oh, ich habe diese Erweiterung gemacht, du hast jene gemacht“,\nund ihr könnt sie kombinieren.\nDenn ich glaube, wir\nwissen noch nicht genau, was die beste Vorgehensweise für\nAgenten ist, also für Agenten-\nHarnesses. Es war zu schwierig zu\nexperimentieren, selbst auf dem Raspberry Pi, da alles\nin einem einzigen Thread, in einem einzigen\nProzess auf diesem\nspeziellen Computer laufen muss und so\nweiter. Ich denke, wir können das vielleicht etwas\nbesser machen.  Äh,\ndann sollte es meiner Meinung nach\nöffentlich rootbar sein.  Also,\nich stelle mir das im Grunde als\neine intelligente Entität vor, eher digital,\ndie kein Roboter ist und aus der Zukunft stammt.  Es ist im\nGrunde nur ein mit dem Internet verbundenes\nServerprogramm, richtig?  Es\nspricht einfach nur HTTP.  Die Scheibe\nsollte also im Großen und Ganzen für\nfast alles ausreichen.  Und dann würde ich\ndiese Agenten direkt an den Rand des Internets stellen und sie sofort mit\ndem Internet kommunizieren lassen.  Oh, das ist\nnicht sehr sicher.  Übrigens ist nichts von dem, was wir\nheute tun, ungefährlich.\nSie werden keine Authentifizierung sehen.  Ihr werdet alle die\nEvent-\nStreams, Agenten und alles\nandere von allen anderen sehen können.  Man sollte keine Geheimnisse in\ndie eigentlichen Nutzdaten der Ereignisse einfügen oder\ndiese nachträglich verändern, richtig?  Also, wir\nkönnen, ähm, wissen Sie, diese Dinge können\ngelöst werden, aber im Großen und Ganzen\nsollte jeder Agent, sobald er existiert, eine URL haben.\nDas ist nur so meine\nMeinung, denn sonst\nentwickelt man am Ende all diese Dinge und verstrickt sich dann selbst in Widersprüchen, indem man\nein\nKonnektorkonzept erfindet, nur um\nSlack-Nachrichten empfangen zu können, oder was weiß ich noch alles.\nUnd ich denke, das sollte wirklich\neinfach sein.  Oder vielleicht sollte ein Mensch\nein Webformular ausfüllen, und das Ergebnis\ndes Webformulars sollte dann wieder an den\nAgenten übermittelt werden, oder so ähnlich.\nDas ist so ähnlich wie\nein Slack-Webhook.  Und dann sollte es\nverteilt werden.  Und das ist potenziell ein\nzweischneidiges Schwert, wie wir noch\nsehen werden. Aber mit verteilt\nmeine ich, dass man einen\nAgenten auf einem\nComputer hier auf einem Server laufen lassen kann, während mein Plugin\nhier und dein Plugin\ndort läuft. Deins ist\nin Rust geschrieben und meins in\nTypescript, und das spielt eigentlich keine Rolle\n.  Ähm, und der Grund, warum das\nschlecht ist, ist, dass es dadurch irgendwann zu\nRace Conditions und Schleifen kommt, richtig?   So ähnlich wie\nzwei Plugins, die ständig\nNachrichten hin und her senden und\nso einen endlosen Strom von Ereignissen in Ihrem\nAgenten erzeugen.  Aber andererseits\nhat man diese Probleme sowieso normalerweise bei den\nmeisten Agenten-Gurten, die ich gesehen habe.\nEs ist also ganz gut, wenn man\ndem ein wenig vorbeugen kann.  Okay.  Also, lasst uns mal\nüber dieses Ding reden,\ndas wir erfunden haben, oh mein Gott,\nwarum ist das so? Das ist nicht dasselbe wie in\nmeinem Dateisystem.  Ich werde also diejenige aus\nmeinem Dateisystem verwenden.  Ähm, also im Grunde haben wir\ndiesen äh Service in der letzten\nWoche erstellt, namens events.iterate.com.\nEs hat eine Web-Benutzeroberfläche, und äh, wir können äh,\nSie können diese benutzen.  Ich denke, du wirst es\nsicher verwenden, aber vorerst werden wir\nes einfach mit Curl ausprobieren, weil ich glaube, dass es es\nin gewisser Weise\nhandlicher macht.  Ähm, in der Agenten-App, ähm,\nin der Ereignis-App haben wir dieses\nKonzept der Agentenpfade.  So wie eine\nDatei in einem Dateisystem einen\nPfad als Hierarchie hat, und Sie haben\nhier einfach die Rohdaten der\nEreignisse.  Dies sind YAML-formatierte\nRohereignisse in jedem dieser Pfade.  Und das\nist im Grunde die gesamte, äh, die\ngesamte primitive Grundlage, auf der wir\nunseren Agenten aufbauen werden.  Und so können wir damit\nanfangen, damit zu spielen.  Wir können sagen:\nOkay, wir haben ein Pfadpräfix.  Wenn Sie\ndies aus dem Repository kopieren, wird Misha es gleich\nin die Readme-Datei einfügen\n.\nIch werde einen Workshop hinzufügen.  MD ebenfalls.   Ja\n.  Äh ja.  Okay.  Oh ja, vielleicht liegt es daran\n.  Ähm,\nich habe die Readme-Datei hinzugefügt, aber nicht den\nWorkshop.   Ja\n.  Also, äh, im Grunde genommen legen wir\nhier ein Pfadpräfix fest.  In meinem\nFall wird das einfach äh Jonas\nTemplestein oder so ähnlich sein.  Sie beginnen\nübrigens mit einem Schrägstrich, was unter Umständen etwas\nseltsam ist.\nAber der Dienst ist sehr tolerant, was die\nURL-Codierung Ihrer Schrägstriche oder\nsonstige Vorgehensweisen angeht.  Aber ich\nwollte eine gute Curl-Ökonomie.  Äh, aber ich\nwollte auch, dass sie mit einem\nSchrägstrich beginnen, damit man eine klar\ndefinierte Route hat.  Anschließend wird die Basis\nin das Repository hochgeladen.  Aber haben\nSie das Repository geteilt?\nOh ja, weil man das jetzt tatsächlich\nam Computer machen kann.  Äh, lass uns das\ntatsächlich tun.  Wenn Sie zu github.com/iterate gehen, gibt es einen\nai-engineer-workshop.\nDort sollten Sie, wenn\nSie auf die Datei workshop.nd klicken, genau das durchgehen\nwir jetzt.\nSie sollten also die\ncurl-Befehle von dort kopieren und einfügen können, und es gibt auch hier keine\nAuthentifizierung, Sie können das also einfach so machen. Tatsächlich, warum\nnicht, erreichen ein paar davon\nunsere Live-Bereitstellungen.\nOkay.  Also, äh, das hier\nist sozusagen nur ein\nMachbarkeitsnachweis dafür, wie das\nmeiner Meinung nach funktionieren sollte.  Also, was\nwir im Grunde tun werden,\nist, diesen einfachen\nEreignisstrom in einen vollwertigen Agenten umzuwandeln, ohne dafür\nServersoftware oder Ähnliches bereitzustellen\n.  Ähm,\nvielleicht, ja, ich sollte mal nachsehen,\nob es irgendjemandem schon mal gelungen ist\n.  Ich warte, bis es zwei oder drei Leuten gelungen ist,\netwas erfolgreich zu locken.  Ähm, und dann mache ich weiter,\nweil ich denke, es wäre gut, wenn du es\nselbst lockst.  Es befindet sich also hier in diesem\nWorkshop für KI-Ingenieure (workshop.mmd).\nWenn zwei Personen den gleichen Namen haben, wird daraus ein\nBenutzername, daher spielt\nes keine Rolle.  Ähm, das ist in Ordnung.   Äh\n,\nokay.  So, jetzt haben wir's.  Ein paar Leute.  Ähm,\nokay.  Das ist also ziemlich gut.  Ähm,\nübrigens, äh, das sieht man hier\nund da mal.  Hier unten gibt es außerdem noch so ein Ding\nnamens Projekt Slug.  Wenn ihr euch wirklich\ngegenseitig auf die Füße tretet,\nkönnt ihr einfach schreiben, dass ihr einen anderen\nProjekt-Slack verwenden sollt, und es ist wie eine komplett\nneue Datenbank, ein neuer Namensraum.  Ähm,\ndas kann man als HTTP-Header übergeben.  Falls\njemand das später braucht,\nkann er mich fragen.  Äh, okay.  Jetzt haben wir also ein\npaar Leute, die Dinger curlen.  Ich werde auch erstmal anfangen,\nDinge zu locken.  Also, äh, jetzt\nsage ich einfach mal hallo Welt, äh,\nhier zu meinem Stream\nund es wird gleich weitergehen und und wir\nbemerken sofort ein paar\nDinge.  Es gibt eine Standardform für Veranstaltungsumschläge\n.  Wir haben hier einen Typ, den ich gerade\nerfunden habe.  Ereignisse benötigen lediglich\neinen Typ, die meisten von ihnen\nhaben aber auch eine Nutzlast.  Äh, dann gibt es da noch\nden Stream-Pfad, der von\nder URL stammt, an die wir dies gesendet haben.  Und es gibt\neinen Versatz.  Dies ist lediglich eine automatisch\ninkrementierende Ganzzahl, die bei eins beginnt.\nÄh, und es gibt im Grunde einen\nSerialisierungspunkt auf dem Server, der die Nummern einfach\ninkrementiert, und man erhält eine\nerstellte Anzeige.  Äh, und dann ähm, hier ist, was wir\nmit Curl machen können, was ziemlich schön ist.  Äh,\nwenn du Dashn benutzt, kannst du auch Streaming machen, äh,\nStreaming SSE.  Das hier ist also\nbuchstäblich nichts Magisches.  Das ist\nbuchstäblich einfach nur Jonas\nTemple – Hallo\nWelt.  Das ist buchstäblich die Locke, die\nwir hier gerade machen.  Ähm, und da\nsehe ich die eingehenden Nachrichten\n.  Sehr schön.  Und ich kann ähm, ich kann\nnoch eine Nachricht hinzufügen.  Und nun werden\ndort im Grunde alle Nachrichten angezeigt.  Und dann gibt es da noch ein „äh äh\noh“, wenn man ein Fragezeichen setzt, das „live“ bedeutet „\nwahr“.  Dies ist vom Durable\nStream Standard inspiriert, aber doch etwas\nanders.  Aber wenn Sie live\ngleich wahr sind, bleibt die Verbindung\noffen und Sie erhalten immer\nmehr Ereignisse, sobald Sie diese durchgehen\n.  Das ist also schon so etwas wie\nein KI-\nAgent, wenn Misha gleichzeitig\nauf mein „Hallo Welt“ antworten würde. Das wäre\nbereits ein Agent. Und dann gibt es noch „Meine\nKI hat mir gesagt, dass man, wenn man das oft macht,\ndie Datenelemente durch „set get“ leiten und sie dann\ndurch „jcq dot“ leiten kann, um eine\netwas schönere Formatierung zu erhalten.  Das\nist also so eine Art Kleinigkeit, dass\nich tatsächlich viel Zeit damit verbringe, meine Haare einfach nur zu\nlocken.  Äh, was kann\nman dann tun?  Das System ist generell sehr tolerant gegenüber allem, was man dort\npostet,\nund das wird relevant, wenn man beispielsweise\nWebhooks von beliebigen Drittanbietern senden möchte\n.  Meine Theorie ist\nimmer, dass die LLM-Abschlüsse gut genug sind\n.  Sie können im Prinzip einfach\nrohe Webhooks von überall empfangen und machen im\nGroßen und Ganzen das Richtige.\nWas der Server konkret\ntun wird, ist Folgendes: Wenn Sie ihm etwas senden, das\nnicht validiert werden kann, wie zum Beispiel so etwas wie „Quatsch“, dann meldet er, dass es\nkeine Typ-Eigenschaft gibt.   Es gibt also\ntatsächlich kein gültiges Ereignis.\nDann können Sie hier sehen, dass das, was\nangehängt wurde, im Grunde ein Fehler ist.  Aber\nweil wir Event-Sourcing verwenden, ist der Fehler\nauch nur ein Ereignis und es heißt einfach\nhier: Okay, ähm, Sie haben ein ungültiges Ereignis\nangehängt, ähm, Ereignis.  Oh, noch etwas,\nwas uns auffallen wird: Der Typ, den\nunser Server erstellt hat,\nbeginnt mit https://events.iterate.com.   Das musst\ndu nicht tun.  Äh, aber genau das machen\nwir gerne, weil\ndas buchstäblich zur\nDokumentation für diesen Ereignistyp führt.  Und\nwenn es eine undurchsichtige Zeichenkette sein soll,\nwarum nicht so etwas machen?\nAber natürlich\nkann man auch einfach einzelne Wörter oder\nzwei Wörter oder was auch immer verwenden.  Ähm, aber Sie werden\ndiese URLs sehen, und das sind einfach nur\nTypen.  Ähm, was gibt es sonst noch\nInteressantes, das wir unternehmen können?  Ich meine, das\nist etwas langweilig, aber wenn man\nWebhooks verwendet,\nkann man einen Item-Potenz-Schlüssel einfügen. Das\nbedeutet, dass, wenn man zweimal denselben Item-\nPotenz-Schlüssel hat, das\nEreignis nicht zweimal angehängt wird.  Sie\nkönnen einen Stream pausieren.  Ich denke, aus\nZeitgründen können wir das überspringen.  Sie\nkönnen einen Stream fortsetzen.  Der Grund, warum das\nPausieren wichtig ist und warum wir es eingebaut haben,\nobwohl wir\ndas erst vor ein paar Tagen gemacht haben, liegt in den\nEndlosschleifen.  Es ist nämlich sehr, sehr einfach, versehentlich\nTausende und Abertausende von Ereignissen in einer\nEndlosschleife einzufügen.\nWenn man also mehr als 100 Ereignisse pro\nSekunde oder so einfügt, wird es einfach einen\nCircuit Breaker geben und der Stream wird\npausiert, bis ihn jemand wieder aufhebt.  Also,\nwenn Sie versuchen, ähm, hier,\nmachen wir das mal, denn für\ndiejenigen unter Ihnen, die Event Sourcing noch nicht kennen,\nmag das etwas seltsam erscheinen, wie\npausiert man zum Beispiel einen Stream?  Man\npausiert einen Stream, indem man... äh... hoppla, das ist der\nfalsche.  Man pausiert einen Stream, indem man\nein Ereignis anhängt, das besagt, dass der Stream\npausiert ist.  Die einzige externe\nSchnittstelle zum Agenten ist... äh... jetzt\nbeschwert er sich.  Warum beschwert es sich?\nAh, weil ich denke, dass es dafür einen\nGrund oder so etwas geben muss.\nÄh\nja,\nReason-Demo.  Ja, bitte schön.\nDas Ganze ist jetzt also auf Eis gelegt.  Wenn ich jetzt also\nversuche, das Hello-World-\nEvent von vorhin zu senden, wird es einfach einen Fehler ausgeben\nund sagen: „Nein, nein, keine weiteren Events\nerlaubt.“  Und genau so etwas ist\netwas, das nicht als\nFehler im Datenstrom erscheint, denn sonst\nwürde man unendlich viele\nFehlerereignisse erhalten.  Ähm,\nich meine, es gibt noch andere seltsame und\nwundervolle Dinge, die man tun kann.  Ich\nweiß gar nicht, ob wir das wirklich tun müssen,\naber äh, ich habe dafür\nbereits ein Plugin erstellt, das Folgendes bewirkt:\nWenn ich dieses JSON-\nTransformator-konfigurierte Ereignis einfüge,\nbeobachtet es bestimmte\nEreignisse, schreibt sie ein wenig um und\nerstellt daraus ein neues Ereignis.  Aber ich denke,\ndas ist etwas zu fortgeschritten, deshalb machen wir\ndas später.  Ähm, es kann auch seltsame\nDinge tun, zum Beispiel kann man\nDinge planen, wie es einige Agent\nSDKs können, aber\nhier kann man beispielsweise\nalle fünf\nSekunden ein Herzschlagereignis auslösen.  Oh Gott, jetzt muss ich\nden Stream fortsetzen, weil er pausiert ist.  Äh, mal sehen\n.  Der Stream wurde fortgesetzt.\nOkay, also jetzt erstelle ich einfach dieses\nHerzschlagereignis alle 5 Sekunden, was\nziemlich praktisch sein kann, oder man kann\netwas für 10 Minuten in der Zukunft\noder zu einem bestimmten Zeitpunkt planen, und es ist einfach\nein Ereignis, das besagt: Führe diese Aktion in der\nZukunft aus.  Ähm,\nich glaube, ich werde diese überspringen, aber ähm,\nSie können den Zeitplan stornieren.  Sie können\nden Stream anweisen, ein Ereignis an\nIhren Server, einen Drittanbieterserver,\nIhren Slack-API-\nEndpunkt oder Ähnliches anzuhängen, um jedes Mal ein Ereignis zu senden, wenn\nein Ereignis hinzugefügt wird.  Äh, also man kann im\nPrinzip den Stream abonnieren.  Äh,\nhier abonnieren wir in unserem\nTerminal.  Wir nutzen ein Pull-\nAbonnement, richtig?  Wir stellen eine\nVerbindung zu einem HTTP-Server her und rufen Daten ab. Wir\nsind der HTTP-Client und der Server ist der\nHTTP-Server. Wir erhalten einen SSE-\nAntwortstrom mit Streaming-Ereignissen.\nAber es kann auch umgekehrt funktionieren, indem\nes Ihnen entweder die angehängten Daten\noder einen\ngefilterten Datenstrom liefert.  Ähm, was\ndurchaus praktisch sein kann.  Okay.  Also, ähm, lasst uns vielleicht\nhier aufhören, denn ich weiß auch, dass\naus der Sitzungsbeschreibung nicht wirklich klar wurde,\nwie technisch das Ganze ist. Also,\nstellt gerne alle Fragen dazu,\nwas das hier überhaupt ist, wofür wir\ndie nächsten 45 Minuten verwenden werden.\nFragen müssen aber als\nEreignis im Fragen-Stream eingereicht werden.\nJa, genau. Falls\nihr Probleme damit habt, ähm,\nich nehme an, vieles ist\nunverständlich. Stellt sie also bitte, denn ich\ndenke, das wird bisher ziemlich willkürlich\nund seltsam sein.   Was bewirkt es\n?\nOh, äh, wir sind im Moment eher so etwas wie ein\nHacker-Hobbyclub, um\nehrlich zu sein, äh, wir\nhaben noch kein marktreifes Produkt.  Ähm,\naber wenn wir es täten, würde es, ähm, ich denke,\nauf dieser Architektur basieren.  Es ist so, äh, jedenfalls werde\nich es sagen, ich kann\nspäter darüber reden.\nOkay.  Okay.  Okay.\nAber äh ja, im\nMoment ist es eher ein Hobby-Hackerclub als ein kommerzielles Unternehmen, aber\ndas wird sich entwickeln.   Ja\n.   Ja\n.\nGrundlegende Fragen,\ndie derzeit auf dem Markt kursieren.\nWie sieht die Architektur aus?\nEs liegt einfach an\nder API. Wenn\nSie beispielsweise versucht haben,\neine OpenCode-Erweiterung, ein Plugin, eine\nPI-Erweiterung oder eine Claude-Claude-\nErweiterung zu erstellen, dann verfügen diese alle über eine API-\nOberfläche, die etwas größer ist als die, die\nSie haben oder die wir gleich besprechen werden\n.  Das ist doch kein großer Unterschied\n, oder?  Okay, vielleicht sind die\nStreaming-Chunks für Teilvervollständigungen\naus irgendeinem\nGrund etwas anderes als einfach ein Ereignis vom Typ „\nIch habe beispielsweise fünf Buchstaben einer\nStreaming-Antwort erhalten“, was ein völlig\ngültiges Ereignis ist. Der\nVorteil ist dann, dass man –\nich bin eher ein Verfechter einer einzigen Abstraktion – das Ganze\nwebstandardbasiert gestalten kann. Es sollte\nnur eine Sache geben: ein\nEreignis. Und wie Sie sehen werden, das, was\noben in dieser Datei stand, kann man meiner Meinung nach einen\näußerst ausdrucksstarken, hochmodernen\nCodierungsagenten erstellen, indem man einfach einen\nStreamprozessor implementiert, der den\nEreignisstrom verarbeitet und gelegentlich X-\nNebeneffekte auslöst.  Das ist alles, was es kann,\nrichtig?  Es scheint einfach nur da zu stehen\nund zu sagen: „Okay, ich zeige euch das gleich\n.“  Es ist irgendwie ein bisschen seltsam.   Ähm,\nich würde sagen, eine seltsame Art zu\nprogrammieren.\nWenn ich das richtig verstehe,\nmeinen Sie also, dass man Ereignisse, die\nvon KI-Modellen generiert werden, nimmt und sie dann im Grunde\ndurch diesen Stream-Prozessor leitet.\nIst das die Idee?\nDer Streamprozessor bzw. die\nEreignis-Iterator-App ist der Speicher,\nman kann ihn sich fast wie eine Datenbank vorstellen. Wissen Sie,\nConvex ist so etwas wie eine Art Datenbank, die einem\ndie Illusion vermittelt, dass\nTypeScript in der\nDatenbank ausgeführt wird.  Man könnte fast meinen,\ndas wäre so etwas wie ein programmierbarer\nDatenstrom, nicht wahr?  Denn\neine weitere Möglichkeit, die\nwir später sehen werden, wenn wir an\nunseren Streamprozessoren herumexperimentieren, besteht darin,\nein Ereignis zu erstellen, das den\nQuellcode des Streamprozessors enthält, und\ndieses wird dann bei jedem Ereignis ausgeführt.  Und so ist es im\nGrunde genommen so, dass\nman mit einer riesigen\nAuswahl verschiedener Agenten-\nHarness-Implementierungen experimentieren kann,\ndie auf reale Ereignisse im\nInternet reagieren und echte API-Anfragen stellen können,\nohne dass man seinen Dienst bereitstellen muss oder so etwas\n.  Alles, was Sie brauchen, ist so ein\nStreaming-\nDienst, der einige dieser\nDinge bietet, insbesondere\nmuss er in der Lage sein,\nandere APIs und Programme aufzurufen und\nso weiter.  Ich weiß nicht, ob das stimmt.  Ähm,\nbeantwortet das Ihre Frage? Oder:\nJa, ich denke schon.\nOkay.  Wollen wir jetzt mal versuchen, äh,\neine etwas ernstere\nVersion dieser Locken zu machen?  Gibt es\nhier jemanden, der TypeScript nicht kennt?\nIch glaube schon.  Ich denke, eines der\nArgumente für diese Architektur,\ndas ich auch im\nKlappentext erwähnt habe, ist, dass sie\nprinzipiell polyglott ist. Wie\nin jeder Sprache gibt es auch hier\nAPIdocs (events.iterate.com/idoccks/iterate.com). Es handelt sich um\neine\nextrem einfache API. Man\nkann sich selbst einen Client erstellen, es gibt eine offene API-\nSpezifikation usw. Für diesen\nWorkshop verwenden wir jedoch eine\nTypeScript-Version. Wir haben\nbereits einen Client als npm-Paket veröffentlicht.\nIch wollte nur darauf hinweisen, dass\nwir zwar alles in\nTypeScript umsetzen, der Sinn aber darin besteht, dass wir nicht unbedingt … müssten.\nFür diesen Workshop müssen wir nur eine Sache tun.\nOkay.  Also, lasst uns etwas ganz\nEinfaches machen.  Ähm\n, ist das KI-Ingenieur-Workshop-\nPaket jetzt auf dem neuesten Stand und funktionsfähig?\nIch denke schon, oder?\nIch glaube schon.  Ja.  Äh, möglicherweise müssen Sie\nIhr Repository aktualisieren, da\nim Iterations-Repository ein clientseitiger Typfehler aufgetreten ist.\nÄh, nein, die im KI-Ingenieurworkshop.\nOkay, das ist in Ordnung.\nEs ist in.ts.\nJa, aber äh, ähm, oh, vielleicht werde ich\ndas dann tatsächlich benutzen.  Und dann werde ich dieselben\nFehler erleben können, falls es welche gibt.  Ja, das ist\nwahrscheinlich besser.  Okay.  Ähm, okay.  Also, äh, ich\ndenke, wenn Sie einfach nur\nschnell loslegen wollen, können Sie äh, einfach\ndas AI Engineer Workshop-\nRepository klonen.  Es gibt bereits eine winzige\nBeispieldatei, und wir werden dann nach und nach noch\nein paar weitere hinzufügen\n.\nUnd der Workshop MD hat auch runnable curl\n.\nHübsch.  Ja.\nÄhm,\nwenn Sie möchten, könnten Sie ein\npaar der Folgebeispiele aus\ndem Iterate-Repository einfügen, die\ntatsächliche Prozessoren enthalten.  Ähm,\nja, ich kann das verstehen.\nIch weiß nicht, was hier los ist.   So, jetzt haben\nwir's.\nMein Computer scheint extrem langsam zu sein, wenn ich\nversuche, ein Cursorfenster zu öffnen.\nDies kommt in\nletzter Zeit leider recht regelmäßig vor.\nÄh, okay\n.\nOkay.\nOder: Oh nein.  Ich glaube, das könnte das sein, was\nSie über das Internet erwähnt haben.  Ich\nglaube, es hat einfach Probleme, weil es\nkein Terminal öffnen kann, da mein\nTerminal versucht, eine Verbindung zum\nInternet herzustellen.\nOh, na gut,\ndann lasst uns\ndas Internet eben lassen, oder\n?   So, jetzt haben\nwir's.  Okay.\nOkay.\nWir haben hier also\nein SDK-Paket für\ndiesen AI Engineer Workshop zusammengestellt,\ndas Sie einfach mit pmpp\ninstallieren können, oder Sie verwenden einfach dieses\nBeispiel hier.  Und dann im Grunde genommen, äh,\nwas brauchten wir für unsere Locken, richtig?\nWir brauchten beispielsweise eine Basis-URL, die einfach\nevents.iterate.com lautet.  Dort befindet sich unser\nServer.  Äh, wir können ein Pfadpräfix verwenden.\nÄhm, und dann können wir diese\nFunktion hier ausführen, die „Events-Client erstellen“ heißt\nund aus unserem SDK stammt.  Und das hier befindet sich\nunter der Motorhaube.  Ich\nweiß wirklich nicht, was mit\ndiesem Terminal los ist.  Das ist sehr seltsam.\nOkay.  Vielleicht geht einfach alles\nunglaublich langsam vonstatten.\nMöchtest du meine probieren?\nÄhm,\nvielleicht, aber es gibt nichts, was\ndie CPU wirklich auslastet.  Ich glaube schon, dass es\ntatsächlich am Netzwerk liegen könnte, aber\nwir werden sehen.  Ähm, also\nhier, also\nhier haben Sie, ähm,\nich glaube nicht, dass das hier jemals aufgegriffen wurde\n.  Okay.  Das ist also im Grunde das, was\nwir gerade gemacht haben, richtig? Wir\nsagen: Okay, wir erstellen uns einen Client,\nund dann gibt es hier eine Funktion\nnamens stream.  Dies ist im Grunde die\nrechte Seite des\nTerminals, das wir vorhin hatten.  Und\ndann sagst du: Lebe wahrhaftig und gib dich dem\nStrom hin.  Und wir können sagen: Okay, wenn es sich bei\ndem Ereignis nicht um einen Ping handelt,\nwerden wir nichts tun.  Wenn es sich aber um ein\nPing-Ereignis handelt, dann – ich meine, das ist ein\nvöllig unnötiger Helfer da unten\n.  Äh, dann können wir einfach client äh\nappend verwenden.  Ich verstehe nicht, warum der\nTypeScript-Sprachserver keine der\nTypen für mich erkennt.\nIch kann aber nicht sagen, ob das nur ein\nkomischer Cursor ist.  Wieder\nIhr eigenes Beispiel.\nNun ja, man\nkönnte schnell die ID wechseln.\nJa, alles in Ordnung.\nEs funktioniert für mich.  Ja.\nOkay.  Ja, ich glaube, das ist\nleider so etwas wie ein Cursor.\nOkay.  Und dann sollten Sie,\nwenn Sie eine aktuelle Version von\nNode haben, in der Lage sein, es einfach auszuführen,\noder vielleicht auch nicht.  Habe ich es geschafft?\nEs wird eine ungültige TypeScript-Syntax gemeldet.   Weißt du was\n?  Ich werde den\nCursor einfach neu starten.  Ich denke, das ist es\nwert.\nKann irgendjemand dieses Beispiel-TS\nauf seinem Computer ausführen?  Bitteschön.  Ich bin.\nOkay.\nÄhm, und können Sie einen Ping senden\nund ein Pong-Signal empfangen?  Okay.  Sehr\ncool.\nOkay.\nJa, ich frage mich, ob wir das verwenden. Ich\nweiß nicht, ob Sie das sehen können, aber im Grunde\nhaben alle meine Befehle eine\nVerzögerung von mehreren Sekunden, was...\nJa, für mich sieht es in Ordnung aus.  Wenn Sie einfach nur die\nLaptops tauschen möchten.  Ähm,\nvielleicht. Ja,\nnein, ich weiß.  Aber es ist einfach so, dass\nmein Editor nicht funktioniert.  Und ich\nhabe auch mehrere nicht reagierende\nCursor. Ich habe das Gefühl, dass dies\nleider ein wiederkehrendes Muster bei Cursorn in letzter Zeit ist\n.\nWenn Sie den Laptop tauschen möchten, scheint das\nonline problemlos zu funktionieren.\nIch würde allen noch 60\nSekunden Zeit geben, um die grundlegende Demo zum\nLaufen zu bringen, und\nmir dann Bescheid geben.\nJa, weil ich denke, dass es mit einigen von Ihnen noch\nfast eine Stunde dauern wird.  Es ist nicht\ngut, den Computer eines anderen zu benutzen.\nVielleicht mache ich bei dir weiter und\nstarte einfach meinen Computer neu.  Ich finde das\neine gute Idee, denn wir können...\nIch habe auch die Beispiele 01 und 02.\nAch, wirklich?  Oh, genial.  Ich\ndenke, ich arbeite mit etwas.   Welches\nTastaturlayout verwendest du?\nÄh, wahrscheinlich dasselbe wie bei dir.   Man kann ja\nhoffen.  Äh, okay.   Der\ngesamte Bildschirm\nsieht gleich aus.\nÄh, sieht bis jetzt ganz gut aus.\nÄhm,\nwas wäre, wenn Sie ein Terminal hätten?\nÄh, also\nNode Beispiele 01 Hallo Welt.\nOkay, perfekt.  Ja.  Oh, das funktioniert\neinwandfrei.  Äh, also,\nfunktioniert das bei allen mehr oder weniger?  Denn dann können wir\njetzt einfach einen offenen KI-Codierungsagenten erstellen.  Ich glaube,\ndas ist alles, was wir brauchen.   Vielleicht sollte\nich fragen, ob Sie\nhier eine Sprachsteuerung haben?\nÄh ja, es geht um Kontrolle und Optionen.  Es ist\nBausatz Nummer eins.   Ja\n.  Und das war's dann auch schon.\nEs wird aufgenommen.\nHallo.  Oh, cool.  Sehen Sie den roten Balken?   Ähm\n, ich würde gerne ein drittes\nBeispiel erstellen, das ich Agentenprozessor nenne, und\ndafür müssen wir nur das\nnormale OpenAI SDK installieren.  Bitte tu das und\nerstelle mir einfach eine neue Datei, die wie\nder Hello-World-Prozessor aussieht.\nOkay.  Ähm,\nokay.  Also, ähm,\nich musste gerade alle wieder zusammentrommeln,\nnachdem ich euch hier für ungefähr 10 Minuten allein gelassen hatte\n.  Das ist ein ganz normales, ziemlich normales\nSpaghetti-Code-TypeScript-Programm,\nrichtig?  Im Grunde haben wir\nhier so etwas wie\nStandardarbeitsanweisungen erstellt.  Ähm, hier möchten wir ein\nAbonnement abschließen, wir müssen ein\nAbonnement erstellen.  Ähm, oh mein Gott, dieses\nBeispiel, das Sie da eingefügt haben, enthält so etwas wie ein\nBoard-Signal und verarbeitet alle\nmöglichen Dinge.  Und ähm, also,\nich denke, ähm, äh, so wie ich mir das vorstelle,\nschreiben wir eigentlich einen Stream-Prozessor.  Und falls\nSie noch nie Stream-Processing betrieben haben, äh, das mag Ihnen jetzt etwas seltsam vorkommen,\nund die\nLeute verwenden auch leicht unterschiedliche Bezeichnungen dafür\n, aber im Grunde\nsagen wir, dass es eine Art\nWeltzustand gibt, der uns\ninteressiert und der aus\nden Ereignissen abgeleitet werden kann.  In diesem Beispiel,\ndas Misha erstellt hat, versuchen wir,\ndie Anzahl der Vorkommen des Hello-\nWorld-Ereignisses im\nDatenstrom zu zählen.  Und dann können Sie die\ngesamte Logik Ihres Programms als eine Art\nReduktionsfunktion schreiben.  Das\nist synchron und es schaut sich einfach\nalle neuen Ereignisse an, sobald\nsie eingehen, und aktualisiert dann den\nZustand.  Das ist alles, was es tut.  Es nimmt also einen\nZustand und ein Ereignis entgegen und gibt den\nneuen Zustand zurück.  Oder Sie können auch einfach gar\nnichts zurückgeben.  Es wird schon gut gehen.  Es wird es einfach\nignorieren.  Und ähm, und dann äh, Sie können,\nSie sollten keine Nebenwirkungen in dieser\nFunktion haben.  Ähm, und der Grund, warum ich\ndie reduce-Funktion von der\nappend-Funktion, wo Sie Ihre\nSeiteneffekte implementieren sollten, getrennt habe, ist folgender: Wenn Sie\ndarüber nachdenken, was passiert, wenn Ihr Programm\nin den Schlafmodus geht, richtig?  So als würdest du gerade\ndeinen Laptop zuklappen\n.  Alles läuft auf unseren\nLaptops.  Äh, du weißt schon, dass 100 neue Events\nin den Stream aufgenommen werden.  Einige dieser Ereignisse\nkönnten in Zukunft LLM-\nAnfragen oder Ähnliches auslösen müssen.  Und\ndann schaltest du deinen Computer\nwieder ein.  Sie beginnen Ihr Programm wieder\nund möchten nicht, dass Ihr Programm wieder aufgenommen wird\nund ähm eine Menge LLM-Anfragen für\nall diese 100 Veranstaltungen in der Vergangenheit stellen, ähm\nunbedingt.  Äh, stattdessen wollten Sie sozusagen erst einmal alles\naufholen und\ndann entscheiden, was Sie am Ende mit dem Zustand anfangen\n.  Wir haben\nhier also eine Art superleichte Abstraktion eines\nProzessors erstellt, die im Grunde\nin eine Prozessorlaufzeitumgebung eingebunden wird.  Ähm,\nund ähm, was es macht, äh, ist, dass es Ihre\nArbeit aufteilt, indem es Ereignisse in Zustände reduziert, und\nwenn Sie dann einige Nebeneffekte ausführen möchten,\nwie zum Beispiel das Anhängen an äh äh,\nSie wissen schon, an denselben Datenstrom,\nkönnen Sie das tun.  Übrigens glaube ich, dass man\nauch Folgendes machen kann, was\npotenziell\nziemlich interessant ist.  ähm, also,\nwissen Sie, Sie können buchstäblich einfach\nan einen untergeordneten Pfad anhängen\noder an einen übergeordneten Pfad oder oder was auch immer\nSie sonst noch wollen.  Es ist im\nGrunde wie ein Dateisystem gedacht\n.  Wenn Sie also\nUnteragenten auf diesem System erstellen wollten, müssten\nSie wahrscheinlich nur an\nPunkt und Schrägstrich, also Boris, anhängen und so tun, als wäre\nBoris ein Unteragent. Dann\nwürden Sie sich einfach für einige spezielle\nEreignisse anmelden, die Boris ausgeben könnte, wie zum Beispiel: „Ich\nhabe das Ergebnis.“ Und dann würden Sie\nautomatisch vom übergeordneten Agenten wieder aufgeweckt,\nwenn Boris das Ergebnis hat.  Ähm, ist\ndas bestätigt, Misha, dass das funktioniert?\nWie genau funktioniert das?  Damit wird einfach das\nexportiert, was\nSie brauchen – Sie brauchen die Laufzeitumgebung,\nrichtig?   Ja\n.  Es gibt einen CLI-Befehl, an den ich mich jetzt\nnicht mehr erinnern kann, weil mein Agent ihn\nausgeführt hat.  Äh, das\nsollte möglich sein.   Hast\ndu das alles gerade eben erledigt?\nIch habe das vor etwa einer Woche gemacht, aber vielleicht hat sich das bei dir\ngeändert.\nNein, nein, nein.  Ja.  Okay.  Na gut.  Okay.\nÄhm, gehen wir mal zu unserem Repository.  Wie\nversprochen, das ist äh ein bisschen. Das sind die ähm,\nalso\nkönnen Sie das auch machen, wenn Sie zum\nIterate AI Engineer Workshop gehen. Hier gibt es\neine Reihe von Beispieldateien, äh, Workshop zwei.\nIch wollte Workshop zwei, ja, das sollte äh\numbenannt werden.\nÄh, hier ist das, das ist das, das ist im Grunde\nder Codeausschnitt, den wir wollen. Okay, da\nist das, äh, da ist dieses Ding, äh, das\nSie haben können.  Ähm, wir haben jetzt also\neinen Prozessor gebaut, richtig?  Das ist quasi so etwas wie\neine träge Sache, und dann gibt es da noch so etwas\nwie eine Pull-\nSubscriptions-Prozessor-Laufzeitumgebung.  Ähm, und das\nmacht im Grunde nichts anderes, als dass es\nIhren äh Prozessor, den Sie\ngerade gebaut haben, nimmt und ihn äh ausführt.\nÄhm,\nich glaube, du musst es\neiner Variablen zuweisen, weil du\noben einfach nur \"default\" exportierst.\nÄhm, ja.\nOkay.\nÄh, und hier sagen wir einfach mal,\nob wir das zum Laufen bringen können.\nÄh, ja, aber leider müssen sie\nmodifiziert werden, um\nirgendetwas Interessantes zu bewirken.  Weil ich\nnicht sehe, ähm\nja, die wurden\nin den letzten Minuten hinzugefügt, aber äh\nja, ich habe etwas ähm schlechte Kopieranweisungen gegeben, ähm\naber ich denke, ich denke, ich habe es\ncommittet, ähm\nich denke, wir müssen\nes einfach langsam\nin diesem Repository aufbauen und es dann pushen,\nsobald es hier funktioniert, leider Ely.\nÄhm, also hier, äh, im Grunde habe\nich diesen Prozessor genommen und ihn mit\ndieser Laufzeitumgebung verbunden. Die\nLaufzeitumgebung macht im Grunde nur diesen Standardcode\nfür das Konsumieren des\nStreams, das Ausführen des Reducers und das Ausführen des\nAfter-Append-\nHooks. Wir sollten sehen, dass, sobald man „\nhello world“ an diesen\nPfad hier, also Jonasle, sendet\n, man dort eine Antwort erhalten sollte.\nWenn ich also hier in der Benutzeroberfläche bin und mir das\nBeispiel von Jonas ansehe, dann denke ich, dass ich gesagt habe, dass dies ein Zeitereignis sein sollte: \"\nHallo Welt\".  Oh\nnein, das ist hier oben,\nwenn alles funktioniert.  Das wäre sozusagen\nder Beweis dafür, dass es sich\nnicht um eine „Hallo Welt“-Szene handelt.\nÄhm,\nich weiß nicht mehr genau, ob dieses Beispiel\nauf dem Maschinenbenutzernamen basiert, aber falls ja\n, dann wäre das mmcal und nicht\nJonas.  Ähm,\nvielleicht\nmachen wir es einfach so.   Tut mir leid\n, das ist der schlimmste Workshop überhaupt,\nweil ich jetzt auch noch am falschen\nComputer sitze.\nUnd\ndas tut es auch nach „\nOkay“.\nIst mein Computer wieder betriebsbereit?  Ja, aber ich\nkenne Ihr Passwort nicht.\nOkay.  Ja, das mache ich gleich\n.  Okay.  Ähm,\ndieses Beispiel hier funktioniert nicht.\nOkay.  Ich denke also, wir müssen Plan B umsetzen,\naber es ist ungewiss, ob wir\ndas tatsächlich schaffen werden.   Verstehst\ndu?\nIch werde den Code einfach mal so durchgehen,\nwie wir ihn von Grund auf neu geschrieben hätten\n.   Das tut mir leid\n.  Ähm, weil ich denke, dass es gewissermaßen den\nFortschritt der Dinge veranschaulicht, und vielleicht, wenn es um die\nInstallation von Abhängigkeiten geht, was\nlangsam ist.  Äh\nja, aber aber genau das wird es\nschließlich ermöglichen, es\nanhand der Komplettlösung durchzuspielen.\nAlso, in diesem Paradigma, wie\nwir es in unserem Agenten verwenden,\nwenn man eine bestimmte Funktion implementieren möchte,\nsagt man sich: Okay, welchen\nZustand brauche ich eigentlich, um meine\nSache zu tun? In diesem Fall\nmöchten wir eine LLM-Anfrage senden, wenn\njemand eine Nachricht mit „Hallo“ sendet.  Also,\nwir haben das hier in unserer\nBenutzeroberfläche, und Sie können auch darauf zugreifen\n.  Es gibt im Grunde so etwas wie einen Cheat-\nCode, der es etwas einfacher macht,\nneue Ereignisse vom Typ „\nAgent Input Addit“ zu erstellen.  Und das ist\nbewusst so einfach wie möglich gehalten\n.  Das ist im Grunde nur\neine Zeichenkette.  Unser Ziel ist es also, immer dann, wenn\njemand\nein Agenteneingabeereignis in einen\nEreignisstrom einfügt, darauf mit\neiner LLM-Anfrage zu reagieren.  Der\nEinfachheit halber werden wir das Ganze einfach mit\ndem OpenAI SDK umsetzen.  Das\nOpenAI SDK funktioniert folgendermaßen:\nBevor Sie\nes verwenden möchten, müssen Sie sich\neinen neuen OpenAI-Client erstellen. Anschließend\nkönnen Sie die Responses-API nutzen.  Sie\nhaben also `openAI.responses`, `\nresponses.create`, und um es zu\nerstellen, benötigen Sie einige\nInformationen, insbesondere einen\nModellstatus, also einen String. Nehmen wir an, der\nStatus unseres LLM-\nAgenten enthält einen Modellstring, da dies\neine der Informationen ist, die wir benötigen,\nwenn wir eine\nLLM-Anfrage stellen. Es gibt nichts anderes als\nEvent Sourcing. Wir\nhaben also einen Modellstring, der aus\nunserem Status stammt.\nSie können sich\nin Zukunft leicht vorstellen, wie das weitergehen könnte.  Dies war eine der\nAufgaben, die man im Rahmen des\nHackathons als Übung hätte bearbeiten können: Man\nkönnte beispielsweise ein Ereignis hinzufügen, das besagt:\nLLM geändert, LLM-Modell geändert. Dazu gibt es\neinen winzigen Einzeilen-Reduzierer, der\ndas Modell einfach auf ein\nanderes setzt, und dann kann man\ndie nächste LLM-Anfrage mit einem\nanderen Modell stellen. Was wir außerdem\nbenötigen, sind Anweisungen.  Äh, ich glaube, das ist eine etwas irreführende Bezeichnung\n.  Ich würde es also in\nunserem System als Eingabeaufforderung bezeichnen und sagen: Okay, die Eingabeaufforderung\nfür unseren\nLLM, was soll sie tun? Wir nehmen\ndas in unserem System und dann brauchen Sie einen Verlauf, einen Zustandsverlauf und so weiter.\nWir haben das definiert, und\nnormalerweise\ngeben Sie das einfach in\neinen kleinen TypeScript-Typ ein, wenn\nSie TypeScript verwenden.  Hier\nsagen wir also, dass dies der Zustand unseres Agenten ist,\nrichtig? Am Anfang ist es\nwirklich einfach, aber in Zukunft kann man sich\nsehr leicht vorstellen, wie man schnell\nDinge hinzufügt, wie zum Beispiel den Zustand:\nKomprimiere ich gerade? Oder läuft gerade ein Tool-Aufruf? Oder was auch immer\nSie sonst noch benötigen. Die\nIdee ist, ein System zu schaffen, in dem es\ntrivial einfach ist, mit drei oder vier\nCodezeilen eine dieser Funktionen hinzuzufügen.\nUnd dann fragt man sich: Okay, was ist mein\nAnfangszustand? Da wir\nden Stream zunächst verarbeiten, gibt es\nkeine Ereignisse, daher müssen wir wissen, womit\nwir anfänglich beginnen.\nWir\nbeginnen also mit einer leeren Historie, dieser\nSystemeingabeaufforderung und GPT 5.4.\nUnd dann, sobald man das getan hat, muss man als Nächstes\nentscheiden, welche Ereignisse man benötigt, um\ndiesen Zustand abzuleiten.\nÄh, und in diesem Fall werden wir einfach\nhier ein neues Ereignis erstellen.  Äh,\nwir verwenden hier zod für Schemas.  Wir\nsagen, es handelt sich um ein Ereignis, bei dem eine Agenteneingabe hinzugefügt wurde,\nund es enthält lediglich eine Zeichenkette.\nUnd immer wenn\nOpenAI eine Rückmeldung gibt, speichern wir das in einem Ereignis, denn das ist ja quasi ein\neingetretener Fakt, selbst wenn es\nnur ein winziges Fragment einer Zeichenkette\noder etwas Ähnliches ist.\nÄhm, und das war's.  Äh, das sind die beiden\nHauptereignisarten.  Ähm, ich glaube nicht, dass\nwir das alles hier brauchen.\nIm Grunde genommen ist Folgendes passiert, wie es so oft der\nFall ist: Ich habe versucht, einen\nAgenten anzuweisen, all diese Beispiele so umzuschreiben, dass sie\neinfacher auszuführen sind,\nund er hat sie dann ziemlich\nstark umgeschrieben.  Aber das ist eigentlich alles, was man\nbraucht.  Also, ähm, und dann äh, müssen Sie\nzuerst Ihren Reducer schreiben, und der Reducer\nist im Grunde der Ort, an dem Sie sagen: Okay,\nwenn ein Ereignis auftritt, äh,\nwie aktualisiere ich meinen äh,\nZustand?  Okay, wenn ein Agent Input Addit-\nEreignis auftritt,\nverwendet man hier eine Art Zod-\nHilfsbibliothek, genauer gesagt eine von Misha namens Sche\nMatch. Sie bietet\nSicherheit für diese\nNutzdaten. Wenn ein Agent Input\nAddit-Ereignis auftritt, soll der Zustand um\nden aktuellen Zustand und den Verlauf aktualisiert werden, wobei dem Verlauf zusätzlich dieses kleine Element hinzugefügt wird.\nDer\nGrund dafür ist die\nResponses API von OpenAI. Da wir einen\nOpenAI-Prozessor entwickeln,\nübersetzen wir im Grunde zwischen unserer Sicht der\nWelt.  Wir haben hier nur so eine Art\nAgenteneingabe, und ähm, es ist einfach nur eine Zeichenkette.  Äh, aber\nOpenAI möchte, dass Sie den RO-Benutzer eingeben und\ndann die Zeichenkette in ein Inhaltsfeld einfügen.\nAlso, wir platzieren das dort.  Ähm,\nund dann noch etwas, was wir tun müssen:\nWenn man die OpenAI\nStreaming-API verwendet, werden unzählige\ndieser Ausgabe- und Antwortereignisse ausgegeben,\nund eines davon ist schließlich ganz am\nEnde vom Typ ...\nJa, ich glaube, das ist ein bisschen Unsinn.  Ähm, ja\n.   Ja\n.  Ja, genau.  Im Grunde genommen\nwollen wir hier eigentlich nur ... äh ... Oh\n, danke.\nÄhm, stimmt das wirklich?\nÄhm, nein.   Ähm\n,\nich nehme an, Sie haben es nicht geschafft, den\nWorkshop 2 in\ndas Demo-Repository hochzuladen, aber er ist mehr oder weniger so, wie er\nist.   So wurde es\ngestreamt.   Ja\n.   Ja\n.  Okay.  Also, ich gebe sozusagen meine\nNiederlage in Bezug auf das, was\nich vorhatte, auf und versuche\neuch einfach zu zeigen, wie es\nfunktioniert, denn wir können etwas ganz\nEinfaches zum Laufen bringen, richtig?  Weil\nwir den extrem einfachen Ping-Pong-\nProzessor haben, der funktioniert.  Äh, und so\nkönnen wir hier äh, wir können sogar äh,\nlasst uns vielleicht einfach hier anfangen.\nOh Mann, ich habe auf \"Unzureichendes Zitat\" gestoßen, als ich\nmein äh\njup ausgeführt habe.\nJa, wir haben jetzt die gleichen\nBeispiele im anderen Repository, aber\nehrlich gesagt, ich glaube, wir müssen uns wohl geschlagen geben\nund\nüber etwas anderes reden oder\ndir die Zeit zurückgeben,\ndenn das Problem ist, dass wir\ndiese Dinge nicht ausführen können.  Äh, und ich glaube, ich bräuchte\nungefähr 10\nMinuten Konzentration, um\nsie lauffähig zu machen.  Ähm, vielleicht sollten wir uns in diesem Punkt\ngeschlagen geben.  Ähm, ich frage mich,\nob es so etwas wie Sinn ergibt,\nwas die Idee dahinter ist,\ninsbesondere im Hinblick auf die\nVerteilung.  Das heißt, Sie können\nsagen: Okay, ich habe meinen Prozessor\nhier, und Ihr Agent kann ihn benutzen. Er kann sich\nauf einem anderen Server befinden oder auch in\neinem dynamischen Worker.  Ähm,\nja,\nich glaube, ohne es zu zeigen, macht es nicht\nwirklich Sinn.\nDie Idee, die\nich hier zu verstehen versuchte, ist, dass die Ereignisse in diesem\nStream-Prozessor-\nFramework\nneu sind.\nUm\nden ländlichen Materialisierungsbereich\noder Teil davon zu verbrauchen.   Also,\nalles, was\nim System passiert, jeder Streaming-\nChunk, wird zu einem\nEreignis im Stream.\nDann laufen Reducer an\nvielen verschiedenen Stellen, zum\nBeispiel um zu prüfen, ob\nder Stream pausiert ist oder nicht. Die\nImplementierung dafür ist vielleicht\nnützlich, weil das System\njetzt produktiv läuft. Es\ngibt einen Circuit-Breaker-\nProzessor, und so ist\ndas Ganze aufgebaut, sogar innerhalb des\nEvent-Services. Der Circuit-\nBreaker-Prozessor hat den Anfangszustand „\npaused false“ und den Pausengrund „\nnull“. Er hat dann einen sehr\neinfachen Reducer, der die\nletzten 100 Zeitstempel\nder Ereignisse prüft. Wenn die letzten 100\nZeitstempel nicht\nmehr als eine Sekunde zurückliegen, wird\nein\nEreignis angehängt. Der Reducer\nsammelt also diese Zeitstempel, und\ndie „AfterAppend“-Funktion prüft dann, ob …  Ich habe zu\nviele\nZeitstempel in der letzten Sekunde gesehen, äh,\nich werde jetzt den Schutzschalter umlegen\n.  Das ist also so etwas wie ein echter\nProzessor, der in meinem äh meinem äh meinem äh\nDienst läuft.  Aber ich zeige Ihnen noch ein anderes\n.  Äh, dieses hier, diese Benutzeroberfläche,\ndas ist auch ein Streamprozessor.  Was bewirkt\ndiese Benutzeroberfläche?  Die Benutzeroberfläche erfasst all\ndiese Ereignisse und projiziert einige der Ereignisse,\ndie sie als interessant erachtet,\nauf sogenannte Feed-\nElemente.  Diese Elemente hier, die\neine etwas ansprechendere Darstellung haben,\nsind Feed-Elemente und nicht dasselbe\nwie Ereignisse, sondern werden von\nEreignissen abgeleitet.  Wenn man also die Benutzeroberfläche\nfür dieses Ding erstellt, reduziert man im Grunde auch einfach\n.  Ähm, und weil der Reducer\neinfach eine synchrone Funktion ist, richtig?  Wenn\nSie zum Beispiel wüssten, dass ich so etwas\nwie einen PI-Agent-Harness-\nProzessor habe, der mit einer ganzen\nReihe von Ereignistypen ausgestattet ist…  Ähm, und es\nhat einen Reduzierring.  Ähm, Sie können einfach den\nReducer Ihres Prozessors verwenden.  Es ist\npraktisch kostenlos, oder?  Man kann\nes einfach importieren und ausführen.  Äh, und\ndann kann man sozusagen anfangen,\nAbstraktionen zu erstellen, die auf ihren\nEreignistypen basieren.  Ähm, und deshalb, ähm, ich denke, was ich tun werde,\nweil das so eine\nbeschissene Erfahrung war, ist, dass ich\nden ganzen Ablauf einfach in Videoform, äh, im\nInternet, zusammenfassen werde.  Und das war eines der\nDinge, die ich zeigen wollte, nämlich dass man\neinfach Pi oder Claude anschließen oder auch Open\nCode verwenden kann und dann sagen kann: Okay, die\nbringen eine Reihe von Ereignissen mit, die man\nin diesem Ereignisstrom speichern\nund auf die man reagieren oder die man\nerweitern kann.  Ähm,\nbeantwortet das die Frage, wo\nder Reducer läuft?  Ähm, und dann\nkann man damit unter anderem auch einfach\nein Ereignis anhängen, das etwas\nQuellcode enthält, und dann wird dieser\nspezielle Prozessor buchstäblich\nautomatisch für einen ausgeführt – horizontal\nskalierbar.  Ähm,\nes ist einfach nur Ja.  Hast du ein Beispiel, das\nzeigt, wie man das macht, wo man zum Beispiel etwas\nanhängt?\nJa, das habe ich.\nEs ist nicht ausführbar.  Ich denke, das ist in gewisser Weise so\n.   Ja\n.  Nun ja, eigentlich können wir das hier tun.\nÄh ja, ich glaube, vielleicht\nist das gut.  Genauso wie wir uns darauf konzentrieren können, anstatt zu\nversuchen, Code zu schreiben, können wir uns auf\ndie Dinge konzentrieren, die funktionieren könnten.  Ähm, also lasst\nuns einen neuen Stream erstellen.  Übrigens\nwerden alle Streams, äh, Sie wissen schon, äh, völlig\nimplizit erzeugt.  Sie können also einfach\nirgendetwas über die Streams-API posten,\nund es wird ein neuer Stream erstellt.\nUnd dann gibt es hier in der Benutzeroberfläche, und\nSie können auch damit herumspielen, wenn Sie einfach nur\nsehen möchten, ähm, es gibt eine\nReihe von voreingestellten ähm voreingestellten\nEreignissen.  Äh, und einer von ihnen ist hier.  Sie\nkönnen diesem Objekt ein Ereignis vom Typ „Dynamischer\nWorker“ hinzufügen.  Und äh,\nwas beinhaltet es?  Es enthält lediglich ein Skript\n.  Und das Skript ist eine Zeichenkette.  Und\ninnerhalb des Strings befindet sich ein Reduzierer und ein\nAfter-Append-Hook.  Und das ist also\nbuchstäblich ein äh, ein Stream, ein\nStreamprozessor.  Es wäre lustig, wenn das\ndie Lösung wäre, denn\nich habe im Grunde die halbe\nNacht daran gearbeitet,\nweil das der spannendste Teil ist.\nAber es war nicht wirklich wie ein Workshop,\ndenn es war eher so, dass man\ndie ersten fünf Konzepte kennenlernte und dann hieß es: „\nÜbrigens, man kann\ndas auch implementieren, indem man einfach ein Ereignis hinzufügt.“  Ähm,\naber wenn ich hier einfach nur „ping“ sage, steht da „\npong“, richtig?  Das ist ja total verrückt.\nIch habe hier zum Beispiel einen Stream, der\nnichts über die Welt weiß, und dann habe ich\nhier dieses Ereignis angehängt, das nur ein bisschen\nJavaScript enthält.  Und dieses\nkleine Stück JavaScript sorgt dafür, dass\nes immer dann mit „pong“ antwortet, wenn es auf\netwas mit „ping“ stößt.  Und dann gibt es\ntatsächlich noch eine Version davon.\nDas ist es, was uns sozusagen\ndie ganze Nacht beschäftigt hat: Wenn\nman diese Prozessordateien hat, die\neinen Prozessor exportieren, den man mit `\ndefine processor` definiert.  Das lässt sich\ngut in eine Veranstaltung einbinden.  Und diesen KI-\nAgenten habe ich auch so zum Laufen gebracht.  Aber\nnatürlich möchten Sie Ihren\nOpenAI-API-Schlüssel nicht dort speichern.  Deshalb\nhaben wir hier diese etwas ungewöhnliche Umgebung, in der\nSie Ihren OpenAI-API-\nSchlüssel außerhalb des Streams platzieren können, und dann wird er\nbeim Abrufen einer\nAnfrage im Header durch das Geheimnis ersetzt\n.  Aber ja, ich werde\ndefinitiv ein Video\ndavon posten, denn das ist ziemlich\nverrückt.  Genau wie du kannst du die etwa 40\nCodezeilen schreiben, die für einen einfachen KI-\nAgenten erforderlich sind, und diese dann an einen beliebigen\nDatenstrom anhängen, wodurch dieser Datenstrom zu\neinem KI-Agenten wird.\nIch weiß nicht.  Ich sehe so etwas wie\nzwei oder drei Nicken, aber hauptsächlich leere\nTreppen.  Das ist sehr seltsam.  Ähm, aber äh, aber\naber macht das Sinn,\nwas hier passiert ist? Zumindest,\nweil man damit einfach\nherumspielen kann, man kann einfach in die Benutzeroberfläche gehen\nund so kann man bis zu einem gewissen Grad immer\nkomplexere Prozessoren für seine Streams erstellen.\nSie können die Codezeilen einfach\nin dieses Eingabefeld eingeben, wenn Sie möchten.\nDas einzige Problem ist, dass\nkeine Abhängigkeiten vorhanden sein dürfen. Wenn Sie beispielsweise\nnpm-Pakete verwenden möchten, müssen Sie\ndiese in diesen String einbinden, was etwas\nkomplizierter wird. Aber ja,\ndas ist noch etwas: Wie\nSie vielleicht bemerkt haben, hat\nalles einen Slug, eine Art\nURL-sicherer Bezeichner. Das Ereignis\nhier heißt „Dynamischer Worker\nkonfiguriert“, da Sie es überschreiben können.\nUnd was mit\ndiesem Ereignistyp bereits funktioniert, ist, dass Sie\neinem KI-Agenten Anweisungen geben können, um\nverschiedene Funktionen auszuführen,\nindem Sie einfach `append` mit etwas\nanderem JavaScript aufrufen.  Ähm,\nund äh, man könnte sich\ndas Bündelungsproblem ganz einfach vorstellen, indem man\nzum Beispiel\nsagt: „Es gibt einen anderen Ereignistyp,\nder so etwas wie ein\nungebündelter dynamischer Worker heißt und der nur\neine package.json JSON-Datei, ein Feld und ein\nSkriptfeld hat.“  Und dann nimmt ein anderer\nProzessor das, bündelt es, erstellt\ndas FAT-Ereignis, das den gesamten Quellcode des Bündels enthält\n, und plötzlich ist es im\nGrunde wie eine IDE.  Und genau da kann man dann\nin die Agentenhardware eingreifen,\nohne wirklich\netwas installieren oder Server ins\nSpiel bringen zu müssen oder so.  Ähm, aber leider\nkonnte ich es nicht zeigen.  Echt blöd.   Ja\n.\nÄh, nun ja\n, das ist äh, das ist JavaScript.\nEs gäbe keinen Tippfehler.   Ähm, aber falls\nirgendein\nFehler auftritt, kann höchstens\nein Ereignis ausgelöst werden.   Es müsste also\nein Fehlerereignis eintreten\n.  Ähm,\nund es gibt in der aktuellen\nImplementierung keine Tippfehler.  Das liegt daran, dass es sich um\neinen JavaScript-\nEvaluator handelt. Man könnte aber auch einen Weg finden,\nzuerst einen TypeScript-Kompilierungsschritt durchzuführen und dann eine Fehlermeldung auszugeben, die\nbesagt, dass ein TypeScript-Compilerfehler aufgetreten ist\n.  Dann könnten Sie es durch einen\nLLM laufen lassen, um zu versuchen, es zu reparieren und ein neues\nEreignis mit dem korrigierten Code auszugeben oder\netwas anderes damit zu tun.   Ja\n.  Die Idee ist, dass\nalles, was passiert, zu einem\nEreignis führt, und auf diese Ereignisse kann man dann nach eigenem Ermessen reagieren\n.\nRechts.   Ja\n.  In diesem speziellen Fall handelt es sich also um\ndynamische Worker in Cloudflare.  Es\nstartet also einfach einen kleinen\ndynamischen Worker.  Also,\ndie Bereitstellungsgeschichte für einen solchen Prozessor sieht im Grunde so aus –\noder man kann es sich so vorstellen: Als das Ganze\nnoch funktionierte, bevor ich es\nrefaktorisieren und dadurch kaputtmachen ließ, habe ich es\nlokal auf meinem\nComputer so gemacht: Ich habe das SSE-Abonnement abgeschlossen\nund meinen Prozessor so ausgeführt. Sobald ich es für gut befunden hatte,\nkonnte ich\nihn entweder als Webdienst auf\nCloudflare Workers, Versall oder wo auch immer bereitstellen und den\nAgenten und Streams mitteilen, dass sie\nmich benachrichtigen sollen, sobald ein neues Ereignis\nverarbeitet werden muss, oder alternativ\ndiese dynamische Worker-Funktion nutzen.  Ähm, und\nich weiß nicht, ob das\nfunktionieren wird.  Deshalb\nsieht es im Moment eher so aus, als wäre es eine richtig\ndumme Idee, weil es einfach\nnicht rüberkommt.  Zum Beispiel\nkönnte man ein Plugin für seinen Agenten haben,\ndas auf einem anderen Computer läuft,\ninsbesondere wenn es sich um etwas\nwirklich Wichtiges handelt, wie zum Beispiel einen Schutz vor Prompt-Injection\noder so etwas.\nMan könnte beispielsweise sagen: „Okay,\nmein Agent nutzt Ihren Prompt-Injection-\nProtection-Service. Das kann nicht\nüber MCP erfolgen, da es derzeit keine Möglichkeit gibt,\nproaktiv in die Agentenschleife einzugreifen. Stattdessen\nkönnte man\nsagen: ‚Meine Agentenschleife\nwartet bis zu 200 Millisekunden,\nbevor sie eine neue LLM-Anfrage an die\nSicherheitsprüfer sendet, und kann diese dann direkt an den\nSicherheitsprüfer senden.‘“  Mir ist egal,\nwie Sie\nes umsetzen.  Sie könnten mir das sogar in Rechnung stellen\n, nicht wahr?  Ähm, und\nich glaube einfach nicht, dass das derzeit auf irgendeine\nandere Weise möglich ist.  Deshalb halte\nich es für sehr wichtig, dass der\nDatenstrom die Prozessoren erreichen\nund ihnen mitteilen kann: „Ihr müsst etwas tun, ihr wisst,\nihr müsst jetzt einige Ereignisse verarbeiten.“  Ähm, da gibt es noch\nein paar andere,\näh, möglicherweise, ich meine, das könnte\nja sein.\nEine der Ideen, die Sie geteilt haben, ist, dass\nmein Agent die Just-in-Time-Dienste\nanderer Agenten nutzen könnte.   Ja\n.\nDann könnte er deswegen angeklagt werden.   Ja\n.  Nun, ich meine, wahrscheinlich wäre\nanfangs ein Mensch dafür zuständig\n, aber es gibt einfach keine\nMöglichkeit, sagen wir mal, Cloud Code, wenn\nich ein Cloud-Code-Plugin erstellen möchte, ähm, wenn\nich das zu einem Geschäft machen möchte, überlegen Sie mal,\nwie Sie das im\nMoment angehen müssten, und Sie müssten\nClaude Code Anweisungen geben, entweder\nproaktiv Ihre MCP-Tools aufzurufen oder\netwas in der Art, oder vielleicht\nein zuvor authentifiziertes CLI-Tool aufrufen,\nwo Sie zum Beispiel CLI log zu\nprompt\ninjectionpprotector.com aufgerufen haben, und dann funktioniert es irgendwie, wohingegen man sich, ähm, eigentlich direkt in\nden Agenten-\nStream oder den Ereignis-Stream einklinken kann, sodass die\nSchnittstelle einfach so funktioniert, dass\njemand bemerkt, dass Claude\netwas tun wird, und\nweitere Ereignisse hinzufügt, und so\nfunktionieren sie alle im Prinzip, aber nicht ganz so, wie man es sich vorstellt. Man muss schon sehr genau hinsehen, um zu\nerkennen, dass es im Grunde darauf hinausläuft\n.  Ähm, noch\netwas, worauf ich vielleicht für einige\nvon Ihnen hinweisen möchte, die versucht haben,\nOpen-Source-Code oder PI-Plugins oder\nÄhnliches zu erstellen: Es gibt keinen Before-Hook.  Das\nist sehr, sehr wichtig.  Es gibt da so etwas nicht, ähm, es gibt\ntatsächlich etwas im Backend,\nalso unsere eingebauten Prozesse.  Der einzige\nUnterschied zwischen unseren und Ihren\nProzessen besteht darin, dass wir tatsächlich verhindern können, dass\nEreignisse überhaupt angehängt werden.  Zum\nBeispiel\ndurch einen Dritten.  Es gibt also\nbestimmte Dinge, die einfach\npassieren müssen, bevor ein Ereignis\nin den Stream aufgenommen wird.  Aber im Großen und Ganzen bin\nich sehr gegen Vorhaken.\nIch glaube, es gab einige Fälle\nin Open Claw, zum Beispiel\nmassive Leistungseinbußen und\nKostensteigerungen, wo man, wie man weiß, die\nKontextzwischenspeicherung ziemlich leicht mit Before-\nHooks unterbrechen kann.  Sie können die Leistung massiv beeinträchtigen\n.  Es ist einfach viel besser, das\ngesamte System als\nletztendlich konsistent zu betrachten und, nun ja,\nall diese Dinge von verteilten Systemen zu tun, wie zum Beispiel zu\nsagen: Okay, wir\nwarten bis zu 200 Millisekunden, bis\njemand sagt: Ich habe ein paar\nInformationen für dich, aber dann stellen wir\ntatsächlich die LLM-Anfrage,\negal ob Informationen kommen oder\nnicht, denn das muss ein System sein.\nWenn man zum Beispiel an Rag-\nPipelines und ähnliches denkt, kann man\nleicht einen kleinen Prozessor haben, der sagt:\nIch habe eine indizierte Version der\nNotion-Wissensdatenbank oder so, und\nich werde einfach hier sitzen und versuchen,\nein bisschen zusätzlichen Kontext einzufügen,\nwenn ich denke, dass er relevant ist, aber wenn ich es nicht rechtzeitig schaffe\n, ist das völlig in Ordnung\n.  Das Ganze funktioniert noch immer.  Es ist nicht so, als hätte ich\nden Agenten oder so etwas verzögert.  Ähm\nja,\ndu meinst also die Streaming-\nDatenbank,\nich weiß nicht, ich glaube,\ndas könnte auf fast allem funktionieren, was\nhaltbar und streamfähig ist.  Dies\ndiente also nur den Zwecken dieser\nÜbung.  Ich glaube, es gibt da\nein potenziell interessantes Szenario,\nwo es sich\nnicht wirklich um eine\nKombination aus einem Q- und einem Pub-Subsystem handelt,\nsondern um eine Streaming-Datenbank,\ndie auch Code für Sie ausführen kann.  Aber so etwas\nwäre ein\ninteressantes Infrastrukturbauteil,\ndas vielleicht jemand herstellen könnte.  Ähm, ich\ndenke schon, äh ja, aber im\nPrinzip, also ich weiß nicht, ob Sie\ndas schon kennen, aber Sie können sich die\nSpezifikation für Durable Streams API ansehen, die jemand veröffentlicht hat\n.  Wir folgen dem nicht ganz genau, aber es kommt dem schon recht nahe.\nEs ist im Grunde eine\nsehr gängige, alte Idee.\nNeuer ist, dass man\nauch Push-\nAbonnements nutzen könnte. Es gibt da etwas namens\nJetreamenat oder so ähnlich, das das kann.\nJa, sprichst\ndu vom Electric Core? Genau, die\nhaben Durable\nStreams.\nEin Durable Stream ist im Prinzip\nein angehängtes Ereignisprotokoll mit Offset-\nTracking.\nDer Client soll den zuletzt\nverbrauchten Offset verfolgen.  So\nfunktioniert beispielsweise auch Kafka.\nMan kann es aber auch umgekehrt machen\nund den Server die Offsets verfolgen lassen.\nDas ist üblicherweise so, zum Beispiel bei\nGoogle Cloud und AWS. Die haben diese Pub-\nSubsysteme, wo sie sagen: „Wir\ngeben Ihnen einfach das nächste Ereignis und\nbehalten den Offset für Sie im Auge.“\nÄhm, ja\n.\nUnd dann könnte im Prinzip jeder einen\nDatenstrom weiterleiten, der dann an mein generisches Ziel gesendet würde.\nOh, ich meine, man bräuchte dafür eine\nAuthentifizierung, richtig?  Rechts.  So\nwürde das Ganze nie funktionieren, äh,\nrichtig?  so was.  Äh, ich dachte eher,\nes wäre lustig, einfach zu sagen: „Das muss man\nnoch nicht machen.“   Ja\n, genau.  Es wäre doch lustig, einfach zu\nsagen, es gäbe einen öffentlichen Namensraum, der\nstündlich oder\nso geleert wird, oder?  Denn es ist schon irgendwie\npraktisch, dass jeder überall im\nInternet einfach etwas curlen oder\neinen curl-Befehl von irgendwoher kopieren und einfügen kann\nund plötzlich so etwas wie einen Agenten-Typ hat\n.  Ich finde das durchaus\ninteressant, aber es muss wirklich\njedes Mal ziemlich aggressiv gelöscht werden.\nÄhm ja, aber ich denke, das ist\nmehr oder weniger ein gelöstes Problem.  Es ist\netwas kompliziert, aber im Grunde stelle ich mir vor, dass man,\nwenn man es\nrichtig macht, bei jedem Ereignis im\nPrinzip Informationen zur Herkunft des Kunden hat\n.  Wir fragen uns zum Beispiel: Wer war das?\nWas konnten diese Personen tun?\nWie sicher können wir sein, dass diese Personen – also\nder HTTP-Client oder der Stream-\nClient – ​​tatsächlich berechtigt waren, diese Operation durchzuführen?\nUnd auch hier kann man all das\nals Ereignisse modellieren, richtig?  Man könnte beispielsweise\nein Ereignis erstellen, das besagt, dass\ndieser Stream öffentlich gemacht werden soll, und solange\ndieses Ereignis nicht erstellt wurde, kann er nur von demjenigen beschrieben werden, der ihn\nerstellt hat.\nÄhm,\nja.  Ich könnte äh, Sean fragen, ob wir\nanstelle dieses Videos ein Video machen können, das wir\netwas später heute aufnehmen, in dem\nes besser dargestellt wird, weil ich denke, dass\nes sich lohnt, es zu zeigen.   Einfach etwas\nzu kurzfristig\n.\nSollen wir es dann einfach einpacken?  Wenn äh, ich meine, ich will\neuch nicht aufhalten, äh, ich mache jetzt eine längere\nPause oder wenn\njemand plaudern möchte.",
  "transcript_chars": 59968,
  "ingested_at": "2026-05-14T16:31:13.377280+00:00",
  "source": "channel",
  "yt_meta": {
    "view_count": 846,
    "like_count": 37,
    "channel_id": "UCLKPca3kwwd-B59HNr-_lvA",
    "categories": [
      "Science & Technology"
    ],
    "tags": [
      "ai",
      "ai engineer",
      "ai engineering",
      "software development",
      "tech",
      "startups",
      "software architecture",
      "machine learning"
    ]
  }
}