Ein mittelgroßes B2B-SaaS-Unternehmen mit rund 50 Entwicklern über etwa 30 AWS-Konten hinweg pagt jemanden im Bereitschaftsdienst rund 40 Mal pro Woche, und der Page bekommt erst nach 25 bis 35 Minuten manuellem Kontext-Sammeln eine echte Antwort: welches Konto, welches Dashboard, welches Runbook, und ob dieses Runbook überhaupt noch stimmt. Das passiert vor der eigentlichen Diagnose, nicht anstelle davon. Diese Serie baut die Lösung: eine kleine Plattform aus KI-Agenten, die diesen ersten Durchgang automatisch erledigt, alles liest, was sie lesen darf, nichts verändert ohne die Freigabe eines Menschen, und in dem Moment aufhört nützlich zu sein, in dem sie diese Disziplin verliert.

Das Unternehmen, und was der Aufwand wirklich kostet

Nennen wir das Unternehmen beim Namen: ein mittelgroßer B2B-SaaS-Laden, etwa 50 Entwickler, rund 30 AWS-Konten verteilt über eine Handvoll Produktlinien, jede mit ihrem eigenen Trio aus Dev, Staging und Production. Niemand hat sich absichtlich für 30 Konten entschieden. Es passierte auf die übliche Art: ein Team nach dem anderen verlangte Isolation, bis AWS Organizations eher das Organigramm als die Architektur widerspiegelte.

Der Aufwand ist nicht dramatisch. Er summiert sich, und vier Zahlen aus drei Monaten On-Call-Daten und einem unangenehmen Retro machen das Ausmaß deutlich:

  • Rund 40 Pages pro Woche landen bei wem auch immer gerade in der Rotation ist, ungleich verteilt über die 30 Konten.
  • 25 bis 35 Minuten jedes Pages gehen für das Zusammentragen von Kontext drauf, bevor die Diagnose überhaupt beginnt: das richtige Konto, das richtige Dashboard, das richtige Runbook, und ob dieses Runbook noch der Realität entspricht.
  • Das monatliche FinOps-Review hinkt den tatsächlichen Ausgaben um etwa drei Wochen hinterher, sodass eine falsch konfigurierte Autoscaling-Gruppe oder eine ungenutzte GPU-Instanz fast einen Monat lang Geld verbrennt, bevor es in einem Report auftaucht, den jemand liest.
  • Ein kürzliches Runbook-Audit ergab, dass etwa jedes dritte Runbook auf eine Ressource, eine ARN oder einen Konsolenpfad verwies, die es nicht mehr gab.

Keine dieser vier Zahlen ist für sich genommen ein Notfall. Zusammen sind sie eine dauerhafte Steuer auf das Team: etwa 30 bis 40 Entwickler-Stunden pro Woche für den mechanischen Teil des Betriebs, das Sammeln von Kontext und das erneute Prüfen veralteter Anweisungen, bezahlt von Leuten, die eingestellt wurden, um Produkt zu bauen, nicht um menschliche Kontext-Sammler zu sein.

Warum Agenten, und warum jetzt

Die ehrliche Antwort auf "warum jetzt" ist, dass die Bausteine endlich als Managed Services existieren statt als interne Frameworks, die jemand babysitten muss. Bedrock bietet mit Agents for Amazon Bedrock seit der General Availability im November 2023 einen verwalteten Agenten-Orchestrierungsdienst, mit verbesserter Orchestrierungskontrolle und Einsicht in die Reasoning-Trace. Verändert hat sich die Ebene darüber. Amazon Bedrock AgentCore wurde am 13.10.2025 in neun Regionen allgemein verfügbar und bündelt sieben Komponentendienste (Runtime, Memory, Identity, Gateway, Code Interpreter, Browser, Observability), für die man früher einen Session-Store, einen Credential-Broker und eine Tracing-Pipeline von Grund auf bauen musste. Parallel dazu hat AWS im Mai 2025 das Strands Agents SDK unter Apache 2.0 quelloffen gemacht und am 21.05.2026, eine Woche bevor der Zeitrahmen dieses Beitrags beginnt, eine produktionsreife 1.0-Version für Python veröffentlicht. Die verwaltete Infrastruktur und die offene Orchestrierungsschicht überschritten beide innerhalb weniger Monate die Schwelle zur Produktionsreife. In diesem Fenster entsteht diese Plattform.

Build versus Buy

Das Team hat zuerst geprüft, ob man kauft, wie es sich gehört. Ein fertiges AIOps- oder Incident-Copilot-Produkt wäre schneller einsatzbereit gewesen und hätte kein Terraform gebraucht. Es verlor aus drei Gründen, die spezifisch für dieses Unternehmen sind, nicht für Agenten im Allgemeinen.

  • Die Mutations-Grenze ist nicht verhandelbar. Wer auch immer einen Fix ausführt, muss eine eng begrenzte IAM-Rolle im betroffenen Konto annehmen, abgesichert durch einen internen Freigabeschritt. Ein SaaS-Produkt verlangt entweder breiten kontoübergreifenden Zugriff oder klebt seinen eigenen Freigabe-Flow nachträglich an den eigenen. Die Plattform selbst zu besitzen bedeutet, dass das Freigabe-Gate von Tag eins an nativ ist, nicht später integriert wird.
  • Das Erfahrungswissen aus dreißig Konten lebt in Slack-Threads und in den Köpfen der Entwickler, nicht in einem Format, das die Ingestion-Pipeline eines Anbieters versteht. Eine Bedrock Knowledge Base über den bestehenden Runbook-Korpus, bei der das Team Chunking und Retrieval-Qualität direkt kontrolliert, ist handhabbarer, als dieses Wissen an einen Drittanbieter zu exportieren und zu hoffen, dass dessen Retrieval gut genug ist.
  • Das Unternehmen betreibt AWS bereits in dieser Größenordnung. Das Terraform, die CI, die On-Call-Rotation, die Kontostruktur, all das existiert heute schon. Die Grenzkosten, auf AWS-nativen Bausteinen aufzubauen, sind niedriger als die Kosten einer zweiten Anbieterbeziehung, einer zweiten Rechnungsposition und eines zweiten Security-Reviews.

Das Gegenargument ist real: Kaufen ist schneller, und Geschwindigkeit hat einen Wert, wenn sich der Aufwand wöchentlich aufsummiert. Die Antwort des Teams war, den Build eng zu begrenzen (vier Agenten, ein Freigabe-Muster, zunächst On-Demand-Inferenz, die Sizing-Rechnung folgt in einem späteren Teil), statt daraus das Ewigkeitsprojekt eines Platform-Teams zu machen. Der begleitende Code für die gesamte Serie liegt auf github.com/flightlesstux/agents-on-call; dieser Beitrag ist der Ausgangspunkt für dessen docs/architecture.md.

Die Stack-Entscheidung: drei Wege, einen Agenten auf Bedrock zu betreiben

Sobald das Team sich fürs Bauen entschieden hatte, folgte die nächste Entscheidung: auf welcher Ebene. Es gab drei echte Optionen, und der Trade-off ist bei weitem nicht so einfach wie "nimm das Neueste":

KriteriumBedrock Agents (classic)AgentCore + StrandsEigenbau auf der Converse API
Was man selbst besitztIn der Konsole definierte Action Groups; die Orchestrierung liegt bei AWSVerwaltete Runtime, Identity, Memory und Gateway; die Agenten-Loop ist eigener Python-CodeAlles: Loop, Retries, Memory, Tool-Routing, Tracing
Reifegrad zu diesem ZeitpunktGA seit November 2023, die längste ErfahrungsbasisGA seit 13. Oktober 2025, rund sieben Monate ProduktionserfahrungSo ausgereift wie der eigene Code, nicht mehr
Portabilität über Modelle und AnbieterNur Bedrock-ModelleBedrock, Anthropic direkt, Ollama und über LiteLLM geproxte AnbieterWas auch immer man selbst anbindet
Framework-Lock-inHoch: Die Orchestrierungslogik steckt im Action-Group-Format von BedrockNiedrig: Strands ist Apache-2.0-Python, dasselbe SDK, das Amazon intern für Q Developer, AWS Glue und VPC Reachability Analyzer nutztKeiner, aber auch keine Hilfe
Tool-IntegrationAction Groups, definiert über OpenAPI-SchemasDas AgentCore Gateway macht APIs, Lambda-Funktionen und bestehende Services zu MCP-kompatiblen Tools; MCP selbst ist seit November 2024 ein offener StandardHandgestricktes Tool-Calling gegen die Converse API
ObservabilityEingebaute Reasoning-Trace, begrenzte Kontrolle über den ExportOTEL-Traces in die CloudWatch-Observability für generative KI, auf eigenen DashboardsWas auch immer man selbst instrumentiert
Terraform-AbdeckungSeit Langem etablierte Action-Group-RessourcenNative aws_bedrockagentcore_*-Ressourcen seit 16. Oktober 2025, mit echten verschachtelten HCL-Blöcken statt JSON-förmigen Attribut-MapsKeine servicespezifischen Ressourcen nötig, nur IAM und Compute
Passt am besten fürEine kleine Zahl einfacher Agenten, minimaler Wunsch nach eigener OrchestrierungMehrere Agenten, die Kontrolle über die Loop brauchen, und eine Multi-Provider-ZukunftOrchestrierung, die so speziell ist, dass kein Framework sie gut abbildet

Das Team entschied sich für AgentCore plus Strands. Die verwalteten Bausteine, die man nicht selbst besitzen wollte (Session-Isolation, Credential-Brokering, ein kontoübergreifendes Gateway), kamen zusammen mit einer Orchestrierungsschicht, die man lesen und debuggen konnte, statt einer, die man aus einer Konsole zurückentwickeln musste. AgentCore Runtime bietet zur General Availability jeder Agenten-Session volle Isolation und ein achtstündiges Ausführungsfenster, mit Unterstützung für das Agent2Agent-Protokoll, falls Agenten auf dieser Plattform jemals mit Agenten außerhalb davon sprechen müssen. Die am 22. April 2026 veröffentlichte @aws/agentcore-CLI brachte einen Create-, Dev-, Deploy-, Invoke-, Logs- und Traces-Workflow, der Strands direkt unterstützt (ebenso LangGraph, LangChain, Google ADK, OpenAI Agents oder ein eigenes Setup), was fürs Onboarding wichtig war: Niemand musste mitten im Projekt ein brandneues Deployment-Tool lernen.

Klassische Bedrock Agents blieben aus eigenem Recht attraktiv: zweieinhalb Jahre Produktionserfahrung, weniger eigener Code zu pflegen, und ein einfacheres mentales Modell, wenn eine Action Group für den Anwendungsfall ausreicht. Hier verlor die Option, weil vier Agenten mit einem gemeinsamen Supervisor-Muster über eine harte kontoübergreifende IAM-Grenze hinweg mehr Kontrolle über die Loop brauchten, als Action Groups bieten. Der Eigenbau auf der rohen Converse API wurde aus dem entgegengesetzten Grund verworfen: einen Session-Store, einen Credential-Broker und eine Tracing-Pipeline von Grund auf zu schreiben, für etwas, das AWS bereits als AgentCore Runtime, Memory, Identity und Observability ausliefert, hätte die ersten zwei Projektmonate damit verbracht, Infrastruktur neu zu erfinden statt Agenten zu schreiben.

Zielarchitektur: Hub-and-Spoke über die gesamte Organisation

Die Plattform ist kontoübergreifend, Hub-and-Spoke, und bewusst additiv. Fällt sie aus, fällt die Organisation exakt auf den Status quo zurück: Menschen werden gepagt wie schon immer. Sie sitzt nie im kritischen Alerting-Pfad.

graph TD
  MGMT["management account
org root, SCPs, no workloads"] SEC["security account
org CloudTrail, GuardDuty,
Security Hub delegated admin"] OPS["ops-tooling account
the agent platform"] W1["workload account 1"] W2["workload account 2"] WN["workload account N
~30 total"] MGMT -. SCPs .-> SEC MGMT -. SCPs .-> OPS MGMT -. SCPs .-> W1 MGMT -. SCPs .-> W2 MGMT -. SCPs .-> WN W1 -- alarm events --> OPS W2 -- alarm events --> OPS WN -- alarm events --> OPS OPS -- "assume ops-readonly, read-only tools" --> W1 OPS -- "assume ops-readonly, read-only tools" --> W2 OPS -- "assume ops-readonly, read-only tools" --> WN OPS -. "assume ops-mutate, approved executor only" .-> W1

Jedes Workload-Konto stellt ops-tooling genau zwei Rollen zur Verfügung: ops-readonly, die jede Tool-Lambda annehmen kann, aufgebaut aus AWS Read-only Managed Policies mit expliziten Denies obendrauf; und ops-mutate, die genau eine Lambda annehmen kann, nämlich die, die läuft, nachdem ein Mensch eine vorgeschlagene Aktion freigegeben hat, begrenzt auf eine Allowlist bestimmter SSM Automation Documents. Kein Agent, keine andere Lambda, kein Codepfad außer diesem einen Post-Approval-Executor kann jemals ops-mutate annehmen. Diese Trennung, nicht eine Prompt-Anweisung, ist es, die Read-only zum Standard macht: Sie wird von IAM durchgesetzt, nicht dadurch, dass man ein Modell höflich darum bittet.

Innerhalb von ops-tooling

Ein Blick ins Detail des einen Kontos, in dem der Rest dieser Serie spielt:

graph LR
  subgraph entry["Entry"]
    EB["EventBridge bus
cross-account alarms"] SLACK["Slack app
API Gateway + verifier Lambda"] SCHED["EventBridge Scheduler
daily cost sweep"] end subgraph agents["Agent layer"] SUP["supervisor"] TRI["incident-triage"] RUN["runbook"] COST["cost"] MEM["AgentCore Memory"] ID["AgentCore Identity"] end subgraph models["Model layer"] BR["Bedrock, cross-region
inference profiles"] GR["Bedrock Guardrails"] KB["Knowledge Base
runbook corpus"] end subgraph tools["Tool layer"] GW["AgentCore Gateway"] T1["cloudwatch-read"] T2["logs-read"] T3["cost-read"] T4["ssm-execute"] end subgraph gate["Approval gate"] SF["Step Functions
waitForTaskToken"] EXEC["post-approval executor"] end subgraph obs["Observability"] OTEL["OTEL traces to CloudWatch
GenAI observability"] LOG["invocation logs to S3"] BUD["Budgets + Cost
Anomaly Detection"] end EB --> SUP SLACK --> SUP SCHED --> COST SUP --> TRI SUP --> RUN SUP --> COST TRI --> MEM RUN --> MEM COST --> MEM SUP --> ID TRI --> BR RUN --> BR COST --> BR BR --> GR TRI --> KB RUN --> KB SUP --> GW GW --> T1 GW --> T2 GW --> T3 GW --> T4 T4 --> SF SF -- "context + Slack approval" --> SLACK SF -- approved --> EXEC BR --> OTEL GW --> LOG COST --> BUD

Vier Strands-Agenten laufen auf AgentCore Runtime hinter einem Supervisor: Incident-Triage, Runbook-Ausführung und Kostenoptimierung. AgentCore Memory hält Session- und Langzeitzustand, damit der Supervisor einem Spezialisten nicht bei jedem Hop den Kontext neu erklären muss, und AgentCore Identity vermittelt ausgehende Credentials, damit kein Agenten-Code ein langlebiges Secret mit sich trägt. Jeder Modellaufruf läuft über Cross-Region-Inference-Profiles für Zuverlässigkeit und Burst-Reserve, mit Bedrock Guardrails an jedem Invoke und einer Knowledge Base über den Runbook-Korpus, die Triage- und Runbook-Agent unterstützt. Die Tool-Schicht besteht vollständig aus AgentCore Gateway: Least-Privilege-Lambdas hinter MCP, drei davon read-only und mit Annahme von ops-readonly in einem Spoke, eine davon, ssm-execute, das einzige mutierende Tool, das ein Spoke-Konto nicht direkt erreichen kann. Es kann einen Vorschlag nur an Step Functions übergeben, die bei waitForTaskToken pausiert, den vollständigen Kontext (Diagnose, Blast Radius, genaues SSM-Dokument und Parameter) an Slack postet und erst fortsetzt, wenn ein Mensch zustimmt. Jeder Hop von EventBridge bis Gateway trägt OTEL-Tracing in die CloudWatch-Observability für generative KI, Bedrock-Invocation-Logs landen in S3, und Budgets plus Cost Anomaly Detection beobachten die eigenen Ausgaben der Plattform mit Cost-Allocation-Tags pro Agent.

Read-only ist die oberste Direktive

Jeder Agent auf dieser Plattform kann sich alles Relevante ansehen und nichts verändern, es sei denn, ein Mensch hat bereits zugestimmt. Das ist der eine Satz, dem der Rest dieser Serie treu bleiben muss. Er zeigt sich als drei getrennte, unglamouröse IAM-Entscheidungen statt als ein cleverer Mechanismus: Die Tool-Lambdas nehmen eine Read-only-Rolle an, aufgebaut aus AWS Managed Policies mit expliziten Denies obendrauf; das einzige mutierende Tool kann in einem Spoke-Konto nichts direkt annehmen; und der einzige Weg von "der Agent hat einen Fix vorgeschlagen" zu "der Fix wurde ausgeführt" führt durch einen Step-Functions-Wait-State, den nur ein Klick eines Menschen in Slack fortsetzen kann.

Read-only ist keine Prompt-Anweisung, die einem Modell sagt, vorsichtig zu sein. Modelle, die höflich darum gebeten werden, sind gelegentlich trotzdem nicht vorsichtig. Read-only ist hier eine IAM-Grenze, die ein kompromittierter Prompt, ein halluzinierter Tool-Call oder ein simpler Bug nicht überschreiten kann, weil die dafür nötigen Credentials nirgendwo existieren, wo der Agent sie erreichen könnte.

Wie fertig aussieht

Das Finale dieser Serie kommt auf diese Zahlen zurück. Es sind dieselben, die die Aufwandsbilanz oben aufgestellt hat, jetzt messbar gemacht:

  • Median-Zeit von Page bis zur angereicherten Slack-Zusammenfassung (Logs, Dashboards, wahrscheinliche Ursache) unter 5 Minuten, runter von aktuell 25 bis 35 Minuten manuellem Sammeln.
  • Null mutierende Aktionen laufen ohne eine von Step Functions erfasste menschliche Freigabe, wöchentlich gegen CloudTrail verifiziert.
  • Der monatliche FinOps-Verzug sinkt von etwa drei Wochen auf denselben Tag, über den täglichen Cost-Sweep, der Anomalien aufdeckt, bevor der nächste Abrechnungszyklus schließt.
  • Veraltete Runbooks (kaputte ARNs, tote Konsolenpfade) sinken von etwa jedem dritten auf unter einem von zwanzig, fortlaufend erkannt statt bei einem jährlichen Audit.
  • Ein vierteljährlicher Game Day deaktiviert ops-tooling vollständig und bestätigt, dass Paging und manuelle Runbook-Ausführung genau so funktionieren wie vor dessen Existenz, ohne stillschweigend entstandene Abhängigkeit.
  • Die Incident-Triage-Diagnose trifft die spätere Root Cause oft genug, gemessen an einem numerischen Schwellwert, den das Eval-Harness in einem späteren Teil definiert, dass On-Call aufhört, sie vor dem Handeln manuell nachzuprüfen.

Fehlerbilder, auf die man von Tag eins an achten muss

Drei Dinge, auf die man achten muss, bevor überhaupt jemand Terraform anfasst, denn die Szenario-Phase ist der falsche Ort, sie erst in Produktion zu entdecken. Wenn ein Read-Tool ein Spoke-Konto nicht erreichen kann, egal ob eine Rollenübernahme verweigert wird oder ein Service degradiert ist, muss der Agent das sagen und an einen Menschen zurückgeben, nicht raten: eine falsche Diagnose, selbstbewusst vorgetragen, ist schlimmer als keine Diagnose. Wenn das Freigabe-Gate selbst hängen bleibt, brauchen sowohl der Wait-State als auch die umgebende State Machine explizite Timeouts, sonst altert ein feststeckender Vorschlag still vor sich hin, statt laut zu scheitern. Und wenn ops-tooling komplett ausfällt, muss die Plattform exakt auf den heutigen Prozess zurückfallen, was nur hält, wenn nichts außerhalb von ops-tooling anfängt, still von dessen Existenz abhängig zu werden.

Weiterlesen

Die beiden Diagramme oben und das Konto- und IAM-Layout, das sie beschreiben, liegen auch als Markdown im begleitenden Repository unter github.com/flightlesstux/agents-on-call, neben dem Terraform- und Python-Code, den diese Serie Teil für Teil aufbaut. Für die Datenbank- und Infrastruktur-Seite, eine solche Plattform in diesem Maßstab zu betreiben, gibt es die Field Notes auf ercan.cloud, und der Hub liegt auf ercanermis.com.