Wie Sie Ihr eigenes Agent-Harness erstellen

@mfpiccolo
ENGLISCHvor 2 Monaten · 28. Mai 2026
339K
1.9K
242
35
4.9K

TL;DR

Der Autor argumentiert, dass herkömmliche Agent-Frameworks zu starr sind, und schlägt einen modularen „iii“-Engine-Ansatz vor, bei dem jede Komponente des Harness – von Anmeldedaten bis hin zu Policy-Engines – ein unabhängiger, austauschbarer Worker ist.

Die meisten Agententeams bauen kein Grundgerüst. Sie übernehmen eines. LangChain, LangGraph, OpenAI Agents SDK, Anthropic SDK, CrewAI, AutoGen – die Schleife, die Tools, der Speicher und die Orchestrierung werden als eine einzige Entscheidung von der Stange genommen. Das Grundgerüst ist ein Framework, das man importiert. Wenn etwas darin nicht passt, forkt man es, kämpft damit oder umgeht es.

Mike Piccolo - inline image

Ich glaube, diese Form ist falsch, und sie ist der Grund, warum jedes länger laufende Agententeam irgendwann sein Grundgerüst von Grund auf neu schreibt. Das Grundgerüst ist nicht eine Sache. Es sind zehn oder zwölf verschiedene Dinge, die zusammengepackt werden, weil das umgebende Ökosystem keine Möglichkeit bietet, sie zu komponieren. Pi Agent-Pakete sind auf dem richtigen Weg, aber sie sind immer noch im Paradigma „Füge einen weiteren Dienst hinzu und integriere ihn mit allen anderen“. Die iii-Engine behandelt alle Worker gleich und entfernt die Integrationslogik vollständig. Der Provider-Router, der Credential-Vault, die Policy-Engine, das Approval-Gate, der Modellkatalog, der Session-Speicher, der Budget-Tracker, der After-Call-Hook-Fanout und die dauerhafte Turn-Schleife sind unabhängige Belange. Sie sind alle mit Ihrer Queue, Ihrem HTTP/API-Server, Streaming und sogar Browser-Workern interoperabel. Ein Framework, das sie als einen Block ausliefert, verkauft Ihnen einen Kompromiss, den Sie nicht eingehen mussten.

Die Wette hinter iii ist, dass sie nicht ein Block sein sollten. Es sollte eine Reihe von Workern auf einer gemeinsamen Engine geben, jeder austauschbar, jeder unabhängig versioniert, jeder verbunden durch ein einziges Primitive: einen Trigger (iii.trigger()), den auch jeder andere Worker verwendet. Das Grundgerüst wird zu einem Stapel installierbarer Worker, und „bau dir dein eigenes“ bedeutet nicht mehr „Forke ein Framework“. Es bedeutet „Tausche ein paar Worker aus“.

Dieser Beitrag zeigt, wie das tatsächlich aussieht. Der vollständige Stack, der heute einen iii-Agenten-Turn antreibt, warum jede Ebene ihr eigener Worker ist und wie Sie jeden einzelnen ersetzen können.

Die 15 Aufgaben, die ein Agenten-Grundgerüst erledigen muss

Wenn man ein produktionsreifes Agenten-Grundgerüst auf seine Aufgaben zurückführt, erhält man eine Liste, die in etwa so aussieht:

  1. Eine Turn-Anfrage von einem Client annehmen und persistieren
  2. Credentials für den jeweiligen Modellanbieter auflösen
  3. Nachschlagen, was das ausgewählte Modell tatsächlich kann (Vision, Tools, Streaming, Kontextfenster)
  4. Die zustandsbehaftete Maschine pro Turn steuern: Provisioning, Stream-Assistant, Tools ausführen, Steuern, Abbau
  5. Skill-Körper laden und bereitstellen, die die Anfrageform, Fehlercodes und Nutzungshinweise jeder Funktion beschreiben
  6. Den System-Prompt, den Modus-Absatz, die Identitäts-Präambel, das Arbeitsverzeichnis und den Anhang der Standard-Skills zusammensetzen
  7. Tokens zurück an den Client streamen, während das Modell sie produziert
  8. Jeden Tool-Aufruf (das ist nur eine Funktion) vor der Ausführung gegen eine Richtlinie prüfen
  9. Tool-Aufrufe pausieren, die eine menschliche Entscheidung benötigen, und die Antwort an den richtigen Turn zurückleiten
  10. LLM-Ausgaben gegen Budgets pro Arbeitsbereich oder Agent verfolgen
  11. Hooks vor und nach Tool-Aufrufen ausführen (Logging, Schwärzung, benutzerdefinierte Seiteneffekte)
  12. Die Session als verzweigten Baum persistieren, damit Forks und Fortsetzungen funktionieren
  13. Den Session-Verlauf komprimieren, wenn das Kontextfenster voll ist
  14. Einen Ereignisstrom ausgeben, den die UI abonniert
  15. Fehlendes Stück, das ich bei jedem Unternehmen sehe, das Agenten baut. Eine einzige OpenTelemetry-Spur über jeden Schritt hinweg tragen, damit Sie debuggen können

Jedes ernsthafte Agenten-Grundgerüst macht die meisten davon. Die teuren machen alle. Die billigen schneiden Ecken ab und bauen die Ecken später wieder ein, wenn sie in Produktion gehen. Die Frameworks bündeln sie zu einem Monolithen und liefern eine Version von jedem aus. Dieser letzte Teil ist der, der Sie etwas kostet, denn nach einem Jahr stellen Sie fest, dass die Policy-Engine, die Sie wollen, nicht die Policy-Engine ist, die das Framework ausliefert, und das Ersetzen bedeutet, das gesamte Grundgerüst zu ersetzen.

Das iii-Grundgerüst liefert jede dieser dreizehn Aufgaben als separaten Worker auf der workers.iii.dev-Registry aus. Jeder spricht das gleiche WebSocket-Protokoll. Jeder registriert Funktionen und Trigger auf demselben Engine-Bus. Jeder ist mit iii worker add hinzufügbar, austauschbar und in jeder Sprache mit einem SDK schreibbar.

Der Stack, nach Worker

Hier ist der tatsächliche Produktionsstack aus dem iii-hq/workers-Monorepo, mit der Aufgabe jedes Workers in einer Zeile. Das gesamte Paket befindet sich unter github.com/iii-hq/workers/harness:

Mike Piccolo - inline image

Elf Worker. Eine Engine. Jeder befindet sich in einer veröffentlichten Version. Jeder ist als eigenständiger Prozess ausführbar (pnpm dev:<worker> in der Entwicklung, iii worker add <spezifischer-worker> als Release-Binary) oder als Teil des zusammengesetzten Einstiegspunkts, der sie gemeinsam startet.

Der Grund, warum das wichtig ist: Jede Box in dieser Tabelle ist ein Ort, an dem Ihnen jemand einen anderen Worker geben kann, und Sie behalten den Rest. Gefällt Ihnen der statische Modellkatalog nicht? Stecken Sie einen Worker ein, der models::list registriert und von einer Live-API liest. Mögen Sie dateibasierte Credentials nicht? Stecken Sie einen Worker ein, der auth::get_token registriert und von einem Secrets-Manager liest. Möchten Sie eine andere Turn-FSM für einen Workflow, der anders verzweigt? Ersetzen Sie turn-orchestrator – jeder Abhängige ruft run::start auf und liest turn_state über denselben Bus, sodass sich der Rest des Stacks nicht ändert.

Wie die Schleife tatsächlich läuft

Die Form eines Turns sieht so aus, wobei die Worker in der Reihenfolge ihres Feuerns durchlaufen werden.

Ein Browser/CLI/Chat sendet einen Turn per POST an harness::trigger mit {session_id, message_id, payload}. Der Harness-Meta-Worker leitet payload an run::start weiter. Dieser Hop existiert, damit der OpenTelemetry-Spann-Wrapper die Session- und Message-IDs als Baggage setzen kann, die sich auf jeden verschachtelten iii.trigger-Aufruf über jeden Worker im Stack ausbreitet. Der Trace-Baum auf der anderen Seite ist ein einziger verbundener Graph.

run::start landet auf dem turn-orchestrator. Er persistiert die Run-Anfrage, legt den initialen TurnStateRecord im iii-Status unter session/<sid>/turn_state an und kehrt sofort zurück. Die eigentliche Arbeit geschieht innerhalb der dauerhaften, zustandsbehafteten Maschine, die durch Veröffentlichungen in der turn-step-FIFO geweckt wird.

Die beiden Endzustände sind stopped (sauberer Ausstieg über finishSession()) und failed (ein unerwarteter Handler-Wurf landet hier, bestätigt die Queue, damit sie nicht mehr wiederholt, und zeigt message_complete{stop_reason:'error'} plus agent_end an, damit die UI den Grund anzeigt). Der Abbau ist ein eingebauter finishSession()-Port, der von jedem Turn-End-Pfad aufgerufen wird, nicht ein separater, in die Queue eingereihte Schritt.

provisioning macht drei Dinge. Es startet eine iii-Sandbox-Mikro-VM, wenn der Run isolierte Ausführung benötigt. Es ruft directory::skills::download für jeden Namespace in system_default_skills auf (Standard ["iii://iii-directory/index"]), damit iii-directory die Skill-Körper, mit denen der Run beginnt, vorab zwischenspeichert. Und es setzt den System-Prompt in drei Schichten zusammen: einen Modus-Absatz, der aus run_request.mode (plan, ask oder agent) ausgewählt wird, die iii-Identitäts-Präambel, die dem Modell die agent_trigger-Konvention und das On-Demand-Erkennungsmuster directory::skills::get beibringt, und einen angehängten Index der Standard-Skills, mit denen der Agent startet. Der Aufrufer kann den gesamten Prompt überschreiben, indem er system_prompt bei run::start übergibt; andernfalls baut ihn der Orchestrator. Funktionsschemata stammen aus dem Live-Engine-Katalog.

assistant_streaming ruft provider::<name>::stream auf demjenigen Provider-Worker auf, der zum provider-Feld des Runs passt. Der Provider-Worker zieht Credentials über auth::get_token (auth-credentials), streamt die SSE-Antwort des Modells in einen iii-Kanal, und der Orchestrator entleert diesen Kanal und gibt message_update-Ereignisse auf agent::events für den UI-Fanout aus. Die Kanalserstellung und die Leseschleife befinden sich hinter einer pull-basierten MessagePump in provider-stream.ts, sodass der Streaming-Zustand auf Übergänge fokussiert bleibt.

Wenn der Assistant Tool-Aufrufe zurückgibt, wechselt die FSM in function_execute. Jeder Tool-Aufruf durchläuft dispatchWithHook, den einzigen Engpass im Orchestrator. consultBefore ruft policy::check_permissions direkt mit einem 5-Sekunden-Timeout auf. Der Policy-Worker (der Harness-Meta-Worker im Standard-Stack) liest iii-permissions.yaml, gleicht die function_id des Aufrufs gegen das Regelwerk ab und gibt eines von drei Ergebnissen zurück:

  • allow: Der Dispatch wird fortgesetzt; der Orchestrator triggert die Zielfunktion und schreibt das Ergebnis
  • deny: Der Dispatch wird mit einer DenialEnvelope kurzgeschlossen, das Ergebnis wird zu einem Verweigerungsdatensatz
  • needs_approval: Der einzelne Aufruf wird in die awaiting_approval-Liste des Turns gestellt. Der Rest des Batches dispatched weiter. Der Turn wechselt nur dann zu function_awaiting_approval, wenn ein oder mehrere Einträge ausstehen.

Der Aufwachmechanismus für Genehmigungen ist reaktiv und gemeinsam genutzt. Der Orchestrator registriert genau einen turn::on_approval-Zustandstrigger auf dem Scope approvals. Wenn die Konsole approval::resolve aufruft, schreibt der approval-gate-Worker approvals/<sid>/<cid> = {decision, reason} in den iii-Status. Dieser Schreibvorgang feuert turn::on_approval, was die betroffene Session fortschaltet. function_awaiting_approval liest nur die Entscheidungen, die gerade eingetroffen sind, dispatched jede, sobald sie eintrifft (allow wird zu einem vorab genehmigten Dispatch, deny oder aborted wird zu einer synthetischen Verweigerung) und schaltet weiter, wenn awaiting_approval[] leer ist. Keine Pro-Call-Resume-Funktionen zum Registrieren. Kein Startup-Rescan, um ausstehende Genehmigungen wiederherzustellen. Ein Trigger deckt jede Session ab.

Fail-Close by Construction: Wenn der Policy-Worker nicht erreichbar ist oder das 5-Sekunden-Timeout auslöst, verweigert consultBefore den Aufruf mit einer gate_unavailable-Envelope. Wenn iii::durable::publish selbst fehlschlug, gibt der Hook-Fanout publish_failed: true zurück und der Orchestrator behandelt es als Verweigerung.

Aus dieser Form ergeben sich einige Latenzgewinne. Der After-Function-Call-Hook verkürzt publish_collect über einen Subscriber-Präsenz-Cache, wenn kein dauerhafter Subscriber für das Thema registriert ist, was etwa 500 ms pro ausgeführter Funktion einspart. tearing_down ist in finishSession() inline eingefügt, was einen dauerhaften Queue-Hop pro Turn entfernt. context-compaction abonniert einen dedizierten agent::turn_end-Stream, den der Orchestrator an Turn-Grenzen ausgibt, sodass Aufwachvorgänge des Kompaktierers pro Turn und nicht pro Ereignis erfolgen. Der session-create-Fanout-Zustandstrigger filtert nur nach Scope und gleicht prozessintern ab, sodass der vorherige Pro-Write-Aufruf harness::session::is_create_event aus dem RPC entfernt wurde.

Nach Abschluss des Batches entscheidet steering_check, ob fortgesetzt, gestoppt oder max_turns erreicht wird. Bei Fortsetzung zurück zu assistant_streaming. Bei Stop oder max läuft finishSession() inline: agent_end ausgeben, die Sandbox freigeben, zu stopped wechseln.

Während des gesamten Laufs gibt jeder teilnehmende Worker OTel-Spans aus, die mit iii.session.id, iii.message.id und iii.function.id getaggt sind. Diese Tags liest engine::traces::group_by der Engine, um „Gruppieren nach Session“ / „Gruppieren nach Message“ / „Gruppieren nach Funktion“ in der Trace-UI zu füllen. Die Instrumentierung ist automatisch: src/runtime/worker.ts umschließt jedes registerFunction in einem Proxy, sodass kein Worker-spezifischer Code daran denken muss, Spans hinzuzufügen.

Bau dir dein eigenes

Der interessante Teil ist, dass keiner der obigen Worker besonders ist. Jeder ist ein Prozess, der eine WebSocket-Verbindung zur Engine öffnet, einige Funktionen und Trigger registriert und läuft. Der Vertrag ist derselbe Vertrag, den jeder Anwendungs-Worker verwendet. Das Grundgerüst basiert auf demselben Primitive wie Ihre Geschäftslogik.

Was bedeutet, dass „bau dir dein eigenes Grundgerüst“ in dieselbe Operation zerfällt wie „schreibe einen beliebigen Worker“. Sie wählen die Ebene aus, die Sie ersetzen möchten, Sie schreiben einen Worker, der dieselben Funktionen auf dem Bus registriert, Sie führen iii worker add aus, und der Rest des Stacks beginnt, Ihren Worker zu verwenden.

Zwei Ebenen tauchen in der obigen Worker-Tabelle nicht auf, sind aber wichtig für das Verhalten des Grundgerüsts. Skills sind die Art und Weise, wie jeder Worker bewirbt, was seine Funktionen tun. Jeder Worker kann einen Skill unter iii://<worker>/<function> veröffentlichen, den der Agent über directory::skills::get abruft, bevor er diese Funktion zum ersten Mal aufruft. Der System-Prompt wird pro Turn aus einem Modus-Absatz, der iii-Identitäts-Präambel und den Standard-Skill-Körpern, mit denen der Run konfiguriert wurde, zusammengesetzt. Beide sind Bus-gesteuert: Skills werden vom iii-directory-Worker bereitgestellt, der System-Prompt wird vom turn-orchestrator zusammengesetzt. Beide sind austauschbar.

Fünf konkrete Beispiele.

Ersetzen Sie den Modellkatalog durch eine Live-API. Schreiben Sie einen Worker, der models::list, models::get, models::supports registriert. Lassen Sie ihn alle N Minuten vom Katalogendpunkt Ihres Anbieters abrufen und zwischenspeichern. Veröffentlichen Sie ihn. iii worker add your-org/dynamic-models-catalog. Stoppen Sie den statischen models-catalog-Worker. Der turn-orchestrator merkt nie den Unterschied. Er ruft iii.trigger('models::list') auf und die Engine leitet an den Worker weiter, der diese Funktions-ID zuletzt registriert hat.

Fügen Sie einen neuen Anbieter hinzu. Die Form wird bereits von provider-kimi und provider-lmstudio bewiesen. Jeder ist ein Worker, der provider::<name>::stream und provider::<name>::complete registriert, einen SSE-Stream von der Upstream-API in einen iii-Kanal entleert und seine Modellnutzung über budget::record an llm-budget schreibt. Einen fünften Anbieter hinzuzufügen bedeutet, einen Ordner mit einer iii.worker.yaml und einer register.ts zu schreiben. Veröffentlichen Sie ihn in der Registry oder behalten Sie ihn lokal. Der turn-orchestrator wählt den Anbieter anhand des provider-Felds des Runs aus; neue Anbieter werden verfügbar, sobald der Worker sich verbindet.

Bereitstellung von Skills aus einem privaten Artefakt-Store. Schreiben Sie einen Worker, der directory::skills::get und directory::skills::list registriert, unterstützt von Ihrem internen Dokumentationssystem oder einem privaten S3-Bucket. Trennen Sie den Standard-iii-directory-Worker oder benennen Sie ihn um. Der Bootstrap des Orchestrators ruft directory::skills::download pro Namespace auf; Ihr Worker antwortet. Das Muster des Agenten, „den Pro-Funktion-Skill vor dem Aufruf einer neuen Funktion abzurufen“, funktioniert unverändert weiter, da die Drahtform dieselbe ist.

Überschreiben Sie den System-Prompt vollständig. run::start akzeptiert ein optionales system_prompt-Feld. Übergeben Sie es, und der Orchestrator verwendet Ihre Zeichenfolge wörtlich und überspringt die Zusammenstellung von Modus-Absatz + Identitäts-Präambel + Skills-Anhang. Nützlich, wenn Sie ein vorhandenes Prompt-Asset haben, das das Grundgerüst unverändert verwenden soll. Der Skill-Download läuft weiterhin im Bootstrap, sodass der Agent auch mit einem benutzerdefinierten Prompt die On-Demand-Erkennung directory::skills::get behält.

Ersetzen Sie die Approval-Gate-UI-Oberfläche. Der Standard-approval-gate-Worker registriert approval::resolve. Das Drahtschema ist ein Funktionsaufruf:

Der Handler persistiert approvals/<sid>/<cid> = {decision, reason} im iii-Status. Der einzelne turn::on_approval-Zustandstrigger des Orchestrators nimmt diesen Schreibvorgang auf und weckt die richtige Session. Wenn Sie Genehmigungen stattdessen über Slack steuern möchten, schreiben Sie einen Slack-Worker, der auf /approve <id> und /deny <id>-Slash-Befehle hört und dann approval::resolve mit der richtigen Nutzlast aufruft. Der Orchestrator merkt nie den Unterschied. Der gesamte approval-gate-Worker bleibt unberührt. Sie haben einen neuen Worker hinzugefügt; Sie haben den vorhandenen nicht ersetzt.

Wenn Sie eine andere Policy-Engine möchten (OPA, Cedar, Ihre eigene DSL), schreiben Sie einen Worker, der policy::check_permissions registriert und { decision, rule_id?, matched_constraint? } zurückgibt. Trennen Sie den Standard-Policy-Worker (der im Harness-Meta-Worker enthalten ist, Sie würden also diesen Handler deaktivieren oder einen abgespeckten Meta-Worker ausführen). Der consultBefore des turn-orchestrator merkt den Unterschied nicht. Gleiches 5-Sekunden-Timeout, gleiche Fail-Close-Semantik, gleiche Drahtform.

Der Punkt dieser Beispiele sind nicht die spezifischen Ersetzungen. Es ist die Form der Operation. Jede Grundgerüst-Schicht im iii-Stack ist über ein oder zwei Funktions-IDs auf dem Bus erreichbar. Das Ersetzen einer Schicht bedeutet, einen Worker zu schreiben, der diese IDs registriert. Der Rest des Systems bleibt.

Das Grundgerüst ist ein Schieberegler, keine Weggabelung

Die klassische Grundgerüst-Debatte stellt sich als dünn vs. dick dar. Anthropics dünne Schleife gegen LangGraphs explizites DAG. Diese Darstellung setzt voraus, dass Sie sich für eine Seite entscheiden und mit ihr leben.

Wenn das Grundgerüst aus Workern auf demselben Bus besteht, ist dünn vs. dick nur eine Zählung, wie viele Worker Sie installieren. Ein dünnes Grundgerüst ist turn-orchestrator plus provider-anthropic plus auth-credentials plus ein minimaler Harness-Meta-Worker. Das ist alles. Keine Genehmigungen, keine Budgets, keine Policy-Engine, kein Hook-Fanout. Lassen Sie alles laufen. Vertrauen Sie dem Modell. Nützlich für autonome Forschungsagenten, experimentelle Schleifen, alles Interne.

Ein dickes Grundgerüst besteht aus allen dreizehn Workern plus context-compaction plus einem benutzerdefinierten Policy-Worker plus einem benutzerdefinierten approval-gate plus einer Slack-integrierten Genehmigungsoberfläche plus dem Budget-Worker, der Limits pro Arbeitsbereich durchsetzt. Nützlich für einen Agenten, der Kunden-Workflows ausführt, bei denen jeder Tool-Aufruf prüfbar sein muss und jede Modellausgabe in ein Finanz-Dashboard einfließen muss.

Der architektonische Abstand zwischen dünn und dick ist kein Rewrite. Es ist eine Konfigurationsänderung. Gleiches Drahtprotokoll, gleiche Trace-Form, gleiche Observability-Story. Der Schieberegler bewegt sich durch Hinzufügen und Entfernen von Workern in Ihrer config.yaml. Alles andere bleibt gleich.

Es gilt auch innerhalb eines einzelnen Workers. Der turn-orchestrator hat gerade ein Refactoring ausgeliefert, das seine FSM von elf auf sieben Zustände reduziert, den Pro-Call-Mechanismus turn::approval_resume::<sid>/<cid> zugunsten eines einzigen reaktiven turn::on_approval-Zustandstriggers auf dem Scope approvals entfernt und tearing_down in einen finishSession()-Port eingefügt hat. Jeder andere Worker im Stack (approval-gate, session, llm-budget, Provider, models-catalog, auth-credentials, hook-fanout, context-compaction) blieb unverändert. Die Drahtform von approval::resolve hat sich nicht bewegt. Die Verträge hielten. Das ist die Eigenschaft, die Ihnen die Komposition gibt: Ein großes internes Rewrite eines Workers ist eine in sich geschlossene Änderung, weil jeder Nachbar durch Bus-Level-Funktions-IDs mit ihm spricht.

Das ist der Teil, den das Framework-Modell Ihnen nicht bieten kann. Ein Framework wählt eine Position auf dem Schieberegler für Sie aus und schließt Sie ein. Das Worker-Modell lässt den Schieberegler in Ihrer Hand.

Was das in der Praxis bedeutet

Wenn Sie einen Agenten auf einem Framework betreiben und dieselben Grenzprobleme spüren, die die meisten Teams im großen Maßstab treffen, ist die Antwort wahrscheinlich nicht „Schreibe das Grundgerüst in unserem eigenen Framework neu.“ Die Policy-Engine lässt sich nicht so erweitern, wie Sie es brauchen. Die Genehmigungs-UI ist in die Chat-Oberfläche des Frameworks eingebaut. Der Credential-Store kann nicht mit Ihrem Secrets-Manager sprechen. Der Budget-Tracker befindet sich in einer Sidecar-Datenbank, die der Trace nicht sehen kann. Die Antwort ist, auf ein Substrat umzusteigen, bei dem das Grundgerüst von Grund auf dekomponiert ist.

Der schnellste Weg, das Argument zu spüren, ist, github.com/iii-hq/workers zu klonen, pnpm install, pnpm build auszuführen und den zusammengesetzten Einstiegspunkt zu starten. Sie erhalten das vollständige Vierzehn-Worker-Grundgerüst, das auf eine iii-Engine zeigt. Sie können jeden Worker deaktivieren, indem Sie seinen Eintrag aus der Startliste entfernen. Sie können jeden Worker austauschen, indem Sie einen Ersatz schreiben, der dieselben Funktions-IDs registriert. Sie können jeden Worker erweitern, indem Sie einen Subscriber zu seinen Hook-Themen hinzufügen. hook-fanout::publish_collect ist die generische Basis, auf der jeder iii-Hook aufbaut.

Die Dokumentation lebt unter iii.dev/docs. Die Engine ist unter github.com/iii-hq/iii. Die Worker-Registry ist unter workers.iii.dev. Das Grundgerüst-Paket ist unter github.com/iii-hq/workers/harness.

Die Wette

Ein Grundgerüst ist nicht etwas, das Sie installieren. Ein Grundgerüst ist eine Reihe von Aufgaben, die Ihr System erledigen muss, damit ein Agent dauerhaft, sicher und beobachtbar läuft. Die Framework-Ära hat diese Aufgaben zusammengepackt, weil nichts darunter Ihnen eine Möglichkeit gab, sie zu komponieren.

iii's Wette ist, dass ein einziges Primitive – ein Worker, der sich über WebSocket mit der Engine verbindet und Funktionen und Trigger registriert – klein genug ist, um jede dieser Aufgaben separat zu absorbieren, und dass der resultierende Stack nützlicher ist als jedes Framework, weil jede Ebene unabhängig austauschbar ist.

Sie übernehmen nicht das iii-Grundgerüst. Sie installieren die Worker, die Sie wollen, schreiben die, die Sie brauchen, und erhalten ein Grundgerüst, das genau wie Ihr System geformt ist. Gleiches Protokoll auf jeder Ebene. Gleicher Trace über jeden Aufruf. Gleiches iii worker add für die Teile, die Sie aus der Registry nehmen, wie für die, die Sie selbst veröffentlichen.

So sieht „bau dir dein eigenes Agenten-Grundgerüst“ aus, wenn das Substrat die richtige Form hat. Wählen Sie die Worker. Schreiben Sie die fehlenden. Komponieren Sie. Das Grundgerüst ist die Komposition.

Mach mit beim Bau des perfekten Agenten-Grundgerüsts, das die moderne Welt braucht: discord.gg/iiidev

iii ist Open Source. Los geht's unter iii.dev/docs. Die Grundgerüst-Worker sind unter github.com/iii-hq/workers und die Engine ist unter github.com/iii-hq/iii.

– Mike Piccolo, Gründer & CEO @iiidevs

Mit einem Klick speichern

Virale Artikel mit YouMind per KI tief lesen

Speichere die Quelle, stelle gezielte Fragen, fasse die Argumentation zusammen und verwandle einen viralen Artikel in wiederverwendbare Notizen in einem einzigen KI-Arbeitsbereich.

YouMind entdecken
Für Creator

Verwandle dein Markdown in einen sauberen 𝕏-Artikel

Wenn du eigene Langtexte veröffentlichst, wird die 𝕏-Formatierung von Bildern, Tabellen und Codeblöcken mühsam. YouMind macht aus einem ganzen Markdown-Entwurf einen sauberen, sofort postbaren 𝕏-Artikel.

Markdown zu 𝕏 testen

Mehr Muster zum Entschlüsseln

Aktuelle virale Artikel

Mehr virale Artikel entdecken