{"id":94777,"date":"2026-10-08T16:31:37","date_gmt":"2026-10-08T14:31:37","guid":{"rendered":"https:\/\/www.skaylink.com\/?p=94777"},"modified":"2026-10-08T16:31:37","modified_gmt":"2026-10-08T14:31:37","slug":"erste-schritte-mit-aws-agentcore","status":"publish","type":"post","link":"https:\/\/www.skaylink.com\/de\/insights\/blog\/erste-schritte-mit-aws-agentcore\/","title":{"rendered":"Erste Schritte mit AWS AgentCore"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-post\" data-elementor-id=\"94777\" class=\"elementor elementor-94777 elementor-94763\" data-elementor-post-type=\"post\">\n\t\t\t\t<div class=\"elementor-element elementor-element-407c07e5 header-keyvisual-container e-flex e-con-boxed e-con e-parent\" data-id=\"407c07e5\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-5d886fd5 elementor-align-left elementor-widget elementor-widget-breadcrumbs\" data-id=\"5d886fd5\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"breadcrumbs.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<p id=\"breadcrumbs\"><span><span><a href=\"https:\/\/www.skaylink.com\/de\/\">Home<\/a><\/span><\/span><\/p>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-169f44b e-con-full e-flex e-con e-child\" data-id=\"169f44b\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t<div class=\"elementor-element elementor-element-12cca5bd header-keyvisual-content e-con-full e-flex e-con e-child\" data-id=\"12cca5bd\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t\t\t<div class=\"elementor-element elementor-element-2cfe5f4a elementor-widget elementor-widget-image\" data-id=\"2cfe5f4a\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"image.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<img decoding=\"async\" width=\"2560\" height=\"1707\" src=\"https:\/\/www.skaylink.com\/wp-content\/uploads\/2026\/10\/MG_4866-johanna-lohr-fotografie-skaylink-scaled.jpg\" class=\"attachment-full size-full wp-image-94773\" alt=\"\" srcset=\"https:\/\/www.skaylink.com\/wp-content\/uploads\/2026\/10\/MG_4866-johanna-lohr-fotografie-skaylink-scaled.jpg 2560w, https:\/\/www.skaylink.com\/wp-content\/uploads\/2026\/10\/MG_4866-johanna-lohr-fotografie-skaylink-300x200.jpg 300w, https:\/\/www.skaylink.com\/wp-content\/uploads\/2026\/10\/MG_4866-johanna-lohr-fotografie-skaylink-1024x683.jpg 1024w, https:\/\/www.skaylink.com\/wp-content\/uploads\/2026\/10\/MG_4866-johanna-lohr-fotografie-skaylink-768x512.jpg 768w, https:\/\/www.skaylink.com\/wp-content\/uploads\/2026\/10\/MG_4866-johanna-lohr-fotografie-skaylink-1536x1024.jpg 1536w, https:\/\/www.skaylink.com\/wp-content\/uploads\/2026\/10\/MG_4866-johanna-lohr-fotografie-skaylink-2048x1365.jpg 2048w\" sizes=\"(max-width: 2560px) 100vw, 2560px\" \/>\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-67ee9e2e e-con-full e-flex e-con e-child\" data-id=\"67ee9e2e\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-69caeba8 elementor-widget elementor-widget-text-editor\" data-id=\"69caeba8\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>Blog<\/p>\n\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-78855362 elementor-widget elementor-widget-heading\" data-id=\"78855362\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h1 class=\"elementor-heading-title elementor-size-default\">Erste Schritte mit AWS AgentCore<\/h1>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-33749e53 elementor-widget elementor-widget-text-editor\" data-id=\"33749e53\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\tErfahren Sie, wie Sie mithilfe von AWS AgentCore und Terraform einen skalierbaren KI-Agenten entwickeln, bereitstellen und testen k\u00f6nnen.\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-767b246a e-flex e-con-boxed e-con e-parent\" data-id=\"767b246a\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t<div class=\"elementor-element elementor-element-4943555c e-flex e-con-boxed e-con e-child\" data-id=\"4943555c\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t<div class=\"elementor-element elementor-element-16e29517 e-flex e-con-boxed e-con e-child\" data-id=\"16e29517\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-6aac6ab6 elementor-widget elementor-widget-text-editor\" data-id=\"6aac6ab6\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t8. Oktober 2026\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-36a3e580 e-flex e-con-boxed e-con e-child\" data-id=\"36a3e580\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t<div class=\"elementor-element elementor-element-7de1387d e-flex e-con-boxed e-con e-child\" data-id=\"7de1387d\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-59006115 elementor-author-box--image-valign-middle elementor-widget elementor-widget-author-box\" data-id=\"59006115\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"author-box.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-author-box\">\n\t\t\t\t\t\t\t<div  class=\"elementor-author-box__avatar\">\n\t\t\t\t\t<img decoding=\"async\" src=\"https:\/\/www.skaylink.com\/wp-content\/uploads\/2025\/09\/Screenshot_20240710_101648-219x300.png\" alt=\"Bild von Claudia M\u00fcller\" loading=\"lazy\">\n\t\t\t\t<\/div>\n\t\t\t\n\t\t\t<div class=\"elementor-author-box__text\">\n\t\t\t\t\t\t\t\t\t<div >\n\t\t\t\t\t\t<span class=\"elementor-author-box__name\">\n\t\t\t\t\t\t\tClaudia M\u00fcller\t\t\t\t\t\t<\/span>\n\t\t\t\t\t<\/div>\n\t\t\t\t\n\t\t\t\t\t\t\t\t\t<div class=\"elementor-author-box__bio\">\n\t\t\t\t\t\t<p>Senior AWS Consultant<\/p>\n\t\t\t\t\t<\/div>\n\t\t\t\t\n\t\t\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-540b7c46 e-flex e-con-boxed e-con e-child\" data-id=\"540b7c46\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-117f44f7 elementor-widget elementor-widget-author-box\" data-id=\"117f44f7\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"author-box.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-author-box\">\n\t\t\t\n\t\t\t<div class=\"elementor-author-box__text\">\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-7be3aae5 e-flex e-con-boxed e-con e-parent\" data-id=\"7be3aae5\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t<div class=\"elementor-element elementor-element-21794327 e-con-full e-flex e-con e-child\" data-id=\"21794327\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-3afe5a39 elementor-widget elementor-widget-heading\" data-id=\"3afe5a39\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-default\">Was ist ein KI-Agent?<\/h2>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-6ed6b542 elementor-widget elementor-widget-text-editor\" data-id=\"6ed6b542\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>Ein KI-Agent ist ein Programm, bei dem ein LLM (Large Language Model) nicht nur Fragen beantwortet, sondern auch <strong>Aktionen ausf\u00fchrt<\/strong>. Statt direkt eine Antwort zu generieren, kann ein Agent beschlie\u00dfen, vorher externe Funktionen aufzurufen \u2013 eine Datenbank abzufragen, sich eine Datei zu holen, eine API zu nutzen \u2013, und dann anhand der Ergebnisse seine Antwort formulieren.<\/p>\n<p>Diese Schleife sieht grunds\u00e4tzlich wie folgt aus:<\/p>\n<ol>\n<li>Der Benutzer stellt eine Frage.<\/li>\n<li>Das LLM liest die Frage und die Liste der verf\u00fcgbaren Tools.<\/li>\n<li>Das LLM entscheidet: Kann ich direkt antworten oder muss ich erst ein Tool aufrufen?<\/li>\n<li>Wenn es ein Tool aufruft, erh\u00e4lt es den Output des Tools und \u201e\u00fcberlegt\u201c weiter.<\/li>\n<li>Die Schritte 3 und 4 werden wiederholt, bis das LLM gen\u00fcgend Informationen hat, um antworten zu k\u00f6nnen.<\/li>\n<li>Das LLM gibt die endg\u00fcltige Antwort aus.<\/li>\n<\/ol>\n<p>Diese Schleife aus \u00dcberlegen \u2192 Handeln \u2192 Lesen \u2192 Wiederholen unterscheidet einen Agenten von einem einfachen Chatbot. Das LLM wird zum Entscheider, der selbstst\u00e4ndig Toolaufrufe orchestriert.<\/p>\n\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-c6867a1 elementor-widget elementor-widget-heading\" data-id=\"c6867a1\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-default\">AgentCore vs. Bedrock Agents: Warum ein neuer Dienst?<\/h2>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-33dd20d4 elementor-widget elementor-widget-text-editor\" data-id=\"33dd20d4\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>AWS legt die <strong>Bedrock Agents<\/strong> still. Das war bereits ein Fully-Managed-Agentendienst, in dem man \u00fcber die Konsole Tools konfiguriert und Aktionsgruppen hinzugef\u00fcgt und AWS die Orchestrierung \u00fcbernommen hat. Warum wird jetzt also ein neuer Dienst eingef\u00fchrt? Bedrock Agents funktioniert f\u00fcr Standardanwendungen gut, aber die Orchestrierungslogik ist eine Blackbox. Man hat keinen Einfluss darauf, wie der Agent seine Schleifen ausf\u00fchrt, welches Framework er verwendet und wie Tools zugewiesen werden.<\/p>\n<p><strong>Bedrock AgentCore<\/strong> ist die Infrastrukturschicht, die unter dem Ganzen liegt. Damit haben Sie:<\/p>\n<ul>\n<li><strong>Ihren eigenen Container<\/strong> \u2013 Sie k\u00f6nnen jedes beliebige Agenten-Framework nutzen (Strands, LangChain, CrewAI oder eigener Code)<\/li>\n<li><strong>Volle Kontrolle \u00fcber die Orchestrierung<\/strong> \u2013 individuelle Hooks, Iterationslimits, Short-Circuiting-Logik usw.<\/li>\n<li><strong>MCP-Protokoll f\u00fcr Tools<\/strong> \u2013 das offene Model Context Protocol statt eines propriet\u00e4ren Formats<\/li>\n<li><strong>Managed Compute<\/strong> \u2013 Sie betreiben keine eigenen Server, AWS skaliert die Container f\u00fcr Sie<\/li>\n<\/ul>\n<table width=\"614\">\n<tbody>\n<tr>\n<td>\n<p>&nbsp;<\/p>\n<\/td>\n<td width=\"235\">\n<p>Bedrock Agents<\/p>\n<\/td>\n<td width=\"235\">\n<p>Bedrock AgentCore<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p><strong>Orchestrierung<\/strong><\/p>\n<\/td>\n<td width=\"235\">\n<p>von AWS festgelegt<\/p>\n<\/td>\n<td width=\"235\">\n<p>Ihr Code, beliebiges Framework<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p><strong>Tool-Protokoll<\/strong><\/p>\n<\/td>\n<td width=\"235\">\n<p>Aktionsgruppen (OpenAPI)<\/p>\n<\/td>\n<td width=\"235\">\n<p>MCP (offener Standard)<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p><strong>Bereitstellung<\/strong><\/p>\n<\/td>\n<td width=\"235\">\n<p>Nur Konfiguration (kein Container)<\/p>\n<\/td>\n<td width=\"235\">\n<p>Ihr Docker-Image<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p><strong>Anpassung<\/strong><\/p>\n<\/td>\n<td width=\"235\">\n<p>Einstellungen in der Konsole<\/p>\n<\/td>\n<td width=\"235\">\n<p>Unbegrenzt \u2013 Sie kontrollieren den Code<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-a755311 elementor-widget elementor-widget-heading\" data-id=\"a755311\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-default\">Die AgentCore-Komponenten<\/h2>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-533b2681 elementor-widget elementor-widget-text-editor\" data-id=\"533b2681\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>AgentCore wirkt auf den ersten Blick kompliziert, aber um einen Agenten aufzusetzen und zu starten, m\u00fcssen Sie erst einmal nur die drei Kernkomponenten kennen und verstehen, was sie tun (und was nicht):<\/p>\n<ol>\n<li><strong> Runtime<\/strong><\/li>\n<\/ol>\n<p>Die <strong>Runtime<\/strong> ist Ihr Docker-Container, der auf AWS-Rechenressourcen l\u00e4uft. Hier liegt Ihre Agentenlogik \u2013 der Python-Code, die LLM-Aufrufe, die Orchestrierungsschleife.<\/p>\n<p>Sie k\u00f6nnen sich das als Fargate-Task vorstellen, die AWS f\u00fcr Sie verwaltet: Sie zieht Ihr Image aus der ECR, startet den Container und leitet eingehende Aufrufe dort hin. Sie m\u00fcssen sich nicht um Instanzen, Skalierung oder Networking zu k\u00fcmmern (es sei denn, Sie w\u00e4hlen f\u00fcr private Ressourcen den VPC-Modus).<\/p>\n<p><strong>Was die Komponente tut<\/strong><\/p>\n<ul>\n<li>F\u00fchrt Ihren Agentencode aus (alle Sprachen, alle Frameworks)<\/li>\n<li>Empf\u00e4ngt Aufrufe \u00fcber die API <em>invoke-agent-runtime<\/em> (IAM-authentifiziert)<\/li>\n<li>Hat eine IAM-Rolle, mit dem sie Bedrock (f\u00fcr das LLM) und das Gateway (f\u00fcr die Tools) aufrufen kann<\/li>\n<\/ul>\n<p><strong>Was die Komponente nicht tut<\/strong><\/p>\n<ul>\n<li>Entscheidet nicht, welche Tools aufgerufen werden \u2013 das macht das LLM<\/li>\n<li>Leitet keine Toolaufrufe weiter \u2013 das macht das Gateway<\/li>\n<li>F\u00fchrt keine Tools aus \u2013 das macht das Tool-Backend (Lambda, eine API oder ein anderer Dienst)<\/li>\n<\/ul>\n<p><strong>Wichtige Konfiguration:<\/strong><\/p>\n<ul>\n<li>server_protocol = &#8222;HTTP&#8220; \u2013 Ihr Container ist ein HTTP-Server, kein MCP-Server<\/li>\n<li>network_mode = &#8222;PUBLIC&#8220; \u2013 AWS regelt den ausgehenden Internet-Traffic; &#8222;VPC&#8220; nur verwenden, wenn Sie privaten Netzwerkzugriff brauchen<\/li>\n<li>Container-Architektur muss ARM64 sein<\/li>\n<\/ul>\n<ol start=\"2\">\n<li><strong> Gateway<\/strong><\/li>\n<\/ol>\n<p>Das <strong>Gateway<\/strong> ist ein MCP-Endpunkt (Model Context Protocol), der Toolaufrufe von Ihrer Runtime zu den Backends weiterleitet, die sie ausf\u00fchren. Das Gateway ist der Router zwischen \u201edas LLM hat entschieden, ein Tool aufzurufen\u201c und \u201edas Tool wird tats\u00e4chlich ausgef\u00fchrt\u201c.<\/p>\n<p>Wenn der MCP-Client Ihres Agenten einen Toolaufruf sendet, passiert im Gateway Folgendes:<\/p>\n<ol>\n<li>Es pr\u00fcft die Anfrage (Authentifizierung mit AWS_IAM SigV4).<\/li>\n<li>Es sieht nach, welches Ziel (Target) dem Toolnamen entspricht.<\/li>\n<li>Es ruft das Backend dieses Ziels mit den Parametern des Tools auf.<\/li>\n<li>Es sendet die Antwort an Ihren Agenten zur\u00fcck.<\/li>\n<\/ol>\n<p><strong>Was die Komponente tut<\/strong><\/p>\n<ul>\n<li>Agiert als MCP-Endunkt (Tools finden und ausf\u00fchren)<\/li>\n<li>Leitet jeden Toolnamen an das richtige Backend weiter (Lambda, externer MCP-Server oder andere AWS-Dienste)<\/li>\n<li>Authentifiziert jede Anfrage mit IAM<\/li>\n<\/ul>\n<p><strong>Was die Komponente nicht tut<\/strong><\/p>\n<ul>\n<li>Entscheidet nicht, welches Tools aufgerufen wird \u2013 das macht das LLM<\/li>\n<li>F\u00fchrt keine Tool-Logik aus \u2013 das macht das Backend, auf den das Target zeigt<\/li>\n<li>Kennt die Konversation und den Zustand Ihres Agenten nicht<\/li>\n<\/ul>\n<ol start=\"3\">\n<li><strong> Gateway-Targets<\/strong><\/li>\n<\/ol>\n<p>Ein <strong>Gateway-Target<\/strong> ist die Verkn\u00fcpfung (Binding) zwischen einem Toolnamen und einem Backend, das dieses Tool ausf\u00fchrt. F\u00fcr jedes Tool, das Ihr Agent nutzen soll, erstellen Sie ein Target, das besagt: \u201ewenn der MCP-Client das Tool X aufruft, leite ihn an das Backend Y\u201c.<\/p>\n<p>Das Backend muss keine Lambda-Funktion sein, Gateway-Targets unterst\u00fctzen mehrere Target-Typen. Lambda wird f\u00fcr individuell angepasste Logik am h\u00e4ufigsten verwendet, aber Sie k\u00f6nnen Targets auch auf andere MCP-kompatible Endpunkte oder AWS-Dienste zeigen lassen. In diesem Tutorial beziehen wir uns auf Lambda, weil das die einfachste M\u00f6glichkeit ist, eigenen Code auszuf\u00fchren, ohne eigene Server zu verwalten. Beachten Sie jedoch, dass das Gateway ein generischer MCP-Router und keine Lambda-Funktion ist.<\/p>\n<p>Jedes Target enth\u00e4lt ein <strong>Tool-Schema<\/strong> \u2013 mit dem Namen, der Beschreibung und den Eingabeparametern, die dem LLM pr\u00e4sentiert werden. Wenn Ihr Agent <em>list_tools_sync()<\/em> aufruft, erh\u00e4lt er eine Liste dieser Schemas, und daran erkennt das LLM, welche Tools verf\u00fcgbar sind und wozu sie dienen.<\/p>\n<p><strong>Prinzip bei Lambda-Targets:<\/strong> ein Lambda, viele Aliase, viele Targets. Sie brauchen nicht f\u00fcr jedes Tool ein separates Lambda, sondern k\u00f6nnen stattdessen Aliase verwenden (Aliasname = Toolname). Das Dispatching geschieht im Handler.<\/p>\n<p><strong>Anleitung zum Erstellen eines einfachen Agenten<\/strong><\/p>\n<p>Wir bauen jetzt einen minimalen Agenten:<\/p>\n<ul>\n<li>Er f\u00fchrt Claude Sonnet in einem Container aus, der von AgentCore verwaltet wird.<\/li>\n<li>Er hat ein einziges MCP-Tool (GetCakeRecipe), hinter dem eine Lambda-Funktion steht.<\/li>\n<li>Er wird komplett \u00fcber <em>terraform apply<\/em> bereitgestellt.<\/li>\n<\/ul>\n<p>Wenn Sie den Agenten fragen <em>\u201eKannst du mir ein Tortenrezept geben?\u201c<\/em>, ruft er das Tool auf, erh\u00e4lt ein Rezept f\u00fcr Schwarzw\u00e4lder Kirschtorte und formatiert die Antwort. Wenn Sie irgendetwas anderes fragen, antwortet er auf Basis seines eigenen Wissens, ohne das Tool aufzurufen.<\/p>\n\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-3eed2aab elementor-widget elementor-widget-heading\" data-id=\"3eed2aab\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-default\">Architektur<\/h2>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-087b441 elementor-widget elementor-widget-code-highlight\" data-id=\"087b441\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"prismjs-default copy-to-clipboard \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-javascript line-numbers\">\n\t\t\t\t<code readonly=\"true\" class=\"language-javascript\">\n\t\t\t\t\t<xmp>invoke-agent-runtime (AWS API, SigV4-signed)\r\n        \u2502\r\n        \u25bc\r\nAgentCore Runtime (your Docker container)\r\n  \u2514\u2500 Strands Agent + Claude Sonnet via Bedrock\r\n        \u2502\r\n        \u2502  MCP over HTTPS (SigV4-signed automatically)\r\n        \u25bc\r\nAgentCore Gateway (AWS_IAM auth, MCP protocol)\r\n        \u2502\r\n        \u2502  Invokes tool backend\r\n        \u25bc\r\nTool Backend (Lambda function in this example)\r\n  \u2514\u2500 Returns static recipe JSON\r\n<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-bc3d832 elementor-widget elementor-widget-heading\" data-id=\"bc3d832\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-default\">Der Python-Code im Detail<\/h2>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-6f79db3b elementor-widget elementor-widget-text-editor\" data-id=\"6f79db3b\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<h4><strong>Tool-Funktion<\/strong><\/h4>\n<p>Das einfachste Tool erh\u00e4lt die Parameter, die das LLM \u00fcbergibt, und gibt eine JSON-Antwort zur\u00fcck:<\/p>\n\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-fdb53ad elementor-widget elementor-widget-code-highlight\" data-id=\"fdb53ad\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"prismjs-default copy-to-clipboard \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-javascript line-numbers\">\n\t\t\t\t<code readonly=\"true\" class=\"language-javascript\">\n\t\t\t\t\t<xmp># src\/lambda\/tool\/handler.py\r\ndef handler(event, context):\r\n    return {\r\n        \"status\": \"ok\",\r\n        \"recipe\": {\r\n            \"name\": \"Oma's Schwarzw\u00e4lder Kirschtorte\",\r\n            \"servings\": 12,\r\n            \"ingredients\": [\r\n                \"200g dark chocolate\", \"200g butter\", \"200g sugar\",\r\n                \"5 eggs\", \"150g flour\", \"2 tsp baking powder\",\r\n                \"500ml heavy cream\", \"3 tbsp kirsch (cherry brandy)\",\r\n                \"1 jar sour cherries (drained)\", \"chocolate shavings\",\r\n            ],\r\n            \"steps\": [\r\n                \"Melt chocolate and butter, let cool.\",\r\n                \"Beat eggs and sugar until fluffy, fold in chocolate.\",\r\n                \"Fold in flour + baking powder. Bake 175\u00b0C, 25 min.\",\r\n                \"Slice into 3 layers. Whip cream with kirsch.\",\r\n                \"Layer: cake, cream, cherries. Repeat. Decorate.\",\r\n            ],\r\n        },\r\n    }\r\n<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-48f51442 elementor-widget elementor-widget-text-editor\" data-id=\"48f51442\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>Bei einem echten Agenten w\u00fcrde diese Funktion eine Datenbank abfragen, eine API aufrufen oder etwas anderes tun, um die Frage zu beantworten. Wir nutzen hier eine Lambda-Funktion, weil das die einfachste serverlose Option ist, aber Gateway-Targets k\u00f6nnen auch auf andere Backends zeigen. Das Prinzip bleibt das gleiche: Parameter erhalten, JSON ausgeben.<\/p>\n<p><strong>Agenten-Container (app.py)<\/strong><\/p>\n<p>Er ist das \u201eGehirn\u201c. Wir gehen jetzt nacheinander alle Bestandteile durch:<\/p>\n\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-66e7e0d elementor-widget elementor-widget-code-highlight\" data-id=\"66e7e0d\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"prismjs-default copy-to-clipboard \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-javascript line-numbers\">\n\t\t\t\t<code readonly=\"true\" class=\"language-javascript\">\n\t\t\t\t\t<xmp>app = BedrockAgentCoreApp()\r\n_agent = None\r\n<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-5070ae9c elementor-widget elementor-widget-text-editor\" data-id=\"5070ae9c\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>Die <em>app<\/em> ist der HTTP-Server, mit dem AgentCore kommuniziert. Der <em>_agent<\/em> wird global gecacht, damit wir ihn nicht bei jedem Aufruf neu bauen (und nicht jedes Mal die Tool-Liste abfragen) m\u00fcssen. Die MCP-Verbindung des Agenten bleibt auch zwischen Requests innerhalb des Container-Lebenszyklus bestehen.<\/p>\n\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-8c8da16 elementor-widget elementor-widget-code-highlight\" data-id=\"8c8da16\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"prismjs-default copy-to-clipboard \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-javascript line-numbers\">\n\t\t\t\t<code readonly=\"true\" class=\"language-javascript\">\n\t\t\t\t\t<xmp>def _get_agent():\r\n    global _agent\r\n    if _agent is not None:\r\n        return _agent\r\n\r\n    mcp_tools = []\r\n    if GATEWAY_URL:\r\n        mcp = MCPClient(lambda: aws_iam_streamablehttp_client(\r\n            endpoint=GATEWAY_URL,\r\n            aws_region=AWS_REGION,\r\n            aws_service=\"bedrock-agentcore\",\r\n        ))\r\n        mcp.start()\r\n        mcp_tools = list(mcp.list_tools_sync())\r\n\r\n    _agent = Agent(\r\n        model=model,\r\n        tools=mcp_tools,\r\n        system_prompt=\"You are a helpful assistant. Use the GetCakeRecipe tool when the user asks for a recipe.\",\r\n    )\r\n    return _agent\r\n<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-19c72d3f elementor-widget elementor-widget-text-editor\" data-id=\"19c72d3f\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p><em>MCPClient<\/em> nimmt eine Factory-Funktion (das <em>lambda:<\/em>), die die Transportverbindung herstellt. Die tats\u00e4chliche HTTPS-Verbindung zum Gateway wird allerdings erst hergestellt, wenn <em>mcp.start()<\/em> aufgerufen wird.<\/p>\n<p><em>mcp.start()<\/em> \u00f6ffnet die Verbindung und erh\u00e4lt sie f\u00fcr die darauffolgenden Aufrufe aufrecht.<\/p>\n<p><em>mcp.list_tools_sync()<\/em> fragt das Gateway \u201eWelche Tools hast du?\u201c und erh\u00e4lt die Tool-Schemas zur\u00fcck, die Sie in Terraform definiert haben. So erf\u00e4hrt der Agent dynamisch, welche Tools vorhanden sind \u2013 wenn Sie in Terraform ein neues Tool hinzuf\u00fcgen, findet der Agent es beim n\u00e4chsten Start, ohne dass Sie etwas am Code \u00e4ndern m\u00fcssen.<\/p>\n<p><em>Agent(&#8230;)<\/em> verkn\u00fcpft alles miteinander: das LLM (<em>model<\/em>), die verf\u00fcgbaren Aktionen (<em>tools<\/em>) und die Anweisungen (<em>system_prompt<\/em>). Der Systemprompt sagt dem LLM, <em>wann<\/em> es das Tool nutzen soll. Ohne diesen Prompt k\u00f6nnte es Rezeptfragen aus seinen eigenen Trainingsdaten beantworten, statt GetCakeRecipe aufzurufen.<\/p>\n\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-7a86504 elementor-widget elementor-widget-code-highlight\" data-id=\"7a86504\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"prismjs-default copy-to-clipboard \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-javascript line-numbers\">\n\t\t\t\t<code readonly=\"true\" class=\"language-javascript\">\n\t\t\t\t\t<xmp>@app.entrypoint\r\ndef invoke_agent(payload: dict):\r\n    prompt = payload.get(\"prompt\", \"\")\r\n    agent = _get_agent()\r\n    result = agent(prompt)\r\n    return {\"result\": str(result)}\r\n<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-de21afc elementor-widget elementor-widget-text-editor\" data-id=\"de21afc\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p><em>@app.entrypoint<\/em> registriert diese Funktion als Handler f\u00fcr eingehende Aufrufe. Wenn jemand <em>invoke-agent-runtime<\/em> aufruft, liefert AgentCore hier den Payload.<\/p>\n<p><em>agent(prompt)<\/em> \u2013 Diese Zeile l\u00f6st die komplette Agentenschleife aus:<\/p>\n<ol>\n<li>Der Prompt wird zusammen mit den Tool-Schemas an Claude gesendet.<\/li>\n<li>Claude entscheidet, ob es GetCakeRecipe aufruft oder direkt antwortet.<\/li>\n<li>Wenn das Tool aufgerufen wird, sendet der MCP-Client die Anfrage an das Gateway. Das Gateway ruft das Tool-Backend auf, und das Ergebnis kommt zur\u00fcck.<\/li>\n<li>Claude sieht das Ergebnis aus dem Tool und formuliert seine Antwort.<\/li>\n<li>Das <em>result<\/em>-Objekt enth\u00e4lt den finalen Text.<\/li>\n<\/ol>\n<h4><strong>Dockerfile<\/strong><\/h4>\n\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-53534d5 elementor-widget elementor-widget-code-highlight\" data-id=\"53534d5\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"prismjs-default copy-to-clipboard \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-javascript line-numbers\">\n\t\t\t\t<code readonly=\"true\" class=\"language-javascript\">\n\t\t\t\t\t<xmp>FROM python:3.12-slim\r\nWORKDIR \/app\r\nRUN apt-get update && apt-get install -y --no-install-recommends gcc g++ \\\r\n    && rm -rf \/var\/lib\/apt\/lists\/*\r\nCOPY requirements.txt .\r\nRUN pip install --no-cache-dir -r requirements.txt\r\nCOPY app.py .\r\nEXPOSE 8080\r\nCMD [\"python\", \"app.py\"]\r\n<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-de4ce29 elementor-widget elementor-widget-text-editor\" data-id=\"de4ce29\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p><em>gcc<\/em> und <em>g++<\/em> werden gebraucht, weil einige Python-Pakete (<em>cryptography<\/em>, bestimmte <em>boto3<\/em>-Abh\u00e4ngigkeiten) C-Erweiterungen kompilieren. Das Image muss f\u00fcr ARM64 erstellt sein, AgentCore unterst\u00fctzt x86 nicht.<\/p>\n<h3><strong>Terraform<\/strong><\/h3>\n<h4><strong>IAM: drei Rollen, drei Boundaries<\/strong><\/h4>\n\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-fa69df4 elementor-widget elementor-widget-code-highlight\" data-id=\"fa69df4\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"prismjs-default copy-to-clipboard \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-javascript line-numbers\">\n\t\t\t\t<code readonly=\"true\" class=\"language-javascript\">\n\t\t\t\t\t<xmp># Runtime role \u2014 AgentCore runs your container with this identity\r\nresource \"aws_iam_role\" \"runtime\" {\r\n  assume_role_policy = jsonencode({\r\n    Statement = [{ Principal = { Service = \"bedrock-agentcore.amazonaws.com\" }, ... }]\r\n  })\r\n}\r\n\r\n# Gateway role \u2014 AgentCore uses this to invoke your tool backends\r\nresource \"aws_iam_role\" \"gateway\" {\r\n  assume_role_policy = jsonencode({\r\n    Statement = [{ Principal = { Service = \"bedrock-agentcore.amazonaws.com\" }, ... }]\r\n  })\r\n}\r\n\r\n# Lambda role \u2014 execution role for our tool function (this example uses Lambda)\r\nresource \"aws_iam_role\" \"lambda\" {\r\n  assume_role_policy = jsonencode({\r\n    Statement = [{ Principal = { Service = \"lambda.amazonaws.com\" }, ... }]\r\n  })\r\n}\r\n<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-7a26cb7 elementor-widget elementor-widget-text-editor\" data-id=\"7a26cb7\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>Die Runtime-Rolle braucht folgende Berechtigungen:<\/p>\n<ul>\n<li>bedrock:InvokeModel \u2013 Claude aufrufen<\/li>\n<li>bedrock-agentcore:InvokeGateway \u2013 das Gateway aufrufen (die vergessen ALLE)<\/li>\n<li>ecr:BatchGetImage \u2013 Container-Image abrufen<\/li>\n<li>logs:PutLogEvents \u2013 CloudWatch-Logs schreiben<\/li>\n<\/ul>\n<p>Das braucht die Gateway-Rolle:<\/p>\n<ul>\n<li>Berechtigungen zum Aufrufen aller Backends, die Ihre Targets nutzen (in diesem Beispiel <em>lambda:InvokeFunction<\/em>)<\/li>\n<\/ul>\n<h4><strong>Gateway und Tool-Binding<\/strong><\/h4>\n\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-433713a elementor-widget elementor-widget-code-highlight\" data-id=\"433713a\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"prismjs-default copy-to-clipboard \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-javascript line-numbers\">\n\t\t\t\t<code readonly=\"true\" class=\"language-javascript\">\n\t\t\t\t\t<xmp>resource \"aws_bedrockagentcore_gateway\" \"main\" {\r\n  name            = \"myagent-gateway\"\r\n  role_arn        = aws_iam_role.gateway.arn\r\n  authorizer_type = \"AWS_IAM\"\r\n  protocol_type   = \"MCP\"\r\n}\r\n\r\nresource \"aws_lambda_alias\" \"get_cake_recipe\" {\r\n  name             = \"GetCakeRecipe\"\r\n  function_name    = aws_lambda_function.tool.function_name\r\n  function_version = \"$LATEST\"\r\n}\r\n\r\nresource \"aws_bedrockagentcore_gateway_target\" \"get_cake_recipe\" {\r\n  gateway_identifier = aws_bedrockagentcore_gateway.main.gateway_id\r\n  target_configuration {\r\n    mcp {\r\n      lambda {\r\n        lambda_arn = aws_lambda_alias.get_cake_recipe.arn\r\n        tool_schema {\r\n          inline_payload {\r\n            name        = \"GetCakeRecipe\"\r\n            description = \"Returns a cake recipe. Call this when the user asks about baking.\"\r\n            input_schema { type = \"object\" }\r\n          }\r\n        }\r\n      }\r\n    }\r\n  }\r\n}\r\n<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-d69002a elementor-widget elementor-widget-text-editor\" data-id=\"d69002a\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>Die Beschreibung in <em>tool_schema<\/em> ist das, was das LLM sieht. Sie sollte klar und deutlich sein, denn sie entscheidet dar\u00fcber, ob Claude Ihr Tool aufruft. Bei einer vagen Beschreibung wird das Tool nie genutzt, bei einer zu weitgefassten wird es auch in unpassenden F\u00e4llen aufgerufen.<\/p>\n<h4><strong>Runtime<\/strong><\/h4>\n\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-ccc625d elementor-widget elementor-widget-code-highlight\" data-id=\"ccc625d\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"prismjs-default copy-to-clipboard \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-javascript line-numbers\">\n\t\t\t\t<code readonly=\"true\" class=\"language-javascript\">\n\t\t\t\t\t<xmp>resource \"aws_bedrockagentcore_agent_runtime\" \"main\" {\r\n  agent_runtime_name = \"myagent_runtime\"\r\n  agent_runtime_artifact {\r\n    container_configuration {\r\n      container_uri = \"${aws_ecr_repository.agent.repository_url}:latest\"\r\n    }\r\n  }\r\n  role_arn = aws_iam_role.runtime.arn\r\n  protocol_configuration { server_protocol = \"HTTP\" }\r\n  network_configuration  { network_mode = \"PUBLIC\" }\r\n  environment_variables = {\r\n    MODEL_ID    = \"eu.anthropic.claude-sonnet-4-5-20250929-v1:0\"\r\n    AWS_REGION  = \"eu-central-1\"\r\n    GATEWAY_URL = aws_bedrockagentcore_gateway.main.gateway_url\r\n  }\r\n}<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-11155a1 elementor-widget elementor-widget-text-editor\" data-id=\"11155a1\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>Die GATEWAY_URL wird aus der Gateway-Ressource berechnet \u2013 Terraform verkn\u00fcpft sie automatisch miteinander.<\/p>\n<h4><strong>Bereitstellen und testen<\/strong><\/h4>\n\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-de73c6f elementor-widget elementor-widget-code-highlight\" data-id=\"de73c6f\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"prismjs-default copy-to-clipboard \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-javascript line-numbers\">\n\t\t\t\t<code readonly=\"true\" class=\"language-javascript\">\n\t\t\t\t\t<xmp>terraform init && terraform apply<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-50a8af7 elementor-widget elementor-widget-text-editor\" data-id=\"50a8af7\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>Die Terraform enth\u00e4lt eine <em>null_resource<\/em>, die das ARM64-Docker-Image erstellt und in die ECR pusht, bevor die Runtime erstellt wird. Das ist ein einziger Befehl ohne manuelle Schritte.<\/p>\n<p>Nach <em>apply<\/em> (Container ist nach 2\u20133 Minuten gestartet):<\/p>\n\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-dd198c5 elementor-widget elementor-widget-code-highlight\" data-id=\"dd198c5\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"prismjs-default copy-to-clipboard \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-javascript line-numbers\">\n\t\t\t\t<code readonly=\"true\" class=\"language-javascript\">\n\t\t\t\t\t<xmp>aws bedrock-agentcore invoke-agent-runtime \\\r\n  --agent-runtime-arn \"$(terraform output -raw runtime_arn)\" \\\r\n  --payload '{\"prompt\": \"Give me a cake recipe\"}' \\\r\n  --content-type application\/json \\\r\n  \/dev\/stdout<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-523af4f5 elementor-widget elementor-widget-heading\" data-id=\"523af4f5\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-default\">Fehler, die nicht passieren d\u00fcrfen<\/h2>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-edec8fa elementor-widget elementor-widget-text-editor\" data-id=\"edec8fa\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<ol>\n<li><strong>InvokeGateway-Berechtigung vergessen<\/strong>. Der Agent arbeitet, aber ruft nie Tools auf. Der MCP-Client erh\u00e4lt einen 403-Fehler, der aber in keinen Logs erscheint. F\u00fcgen Sie unbedingt <em>bedrock-agentcore:InvokeGateway<\/em> zur Runtime-Rolle hinzu.<\/li>\n<li><strong>server_protocol = &#8222;MCP&#8220; in der Runtime<\/strong>. Ihr Container spricht HTTP (BedrockAgentCoreApp ist ein HTTP-Server). MCP ist das einzige Protokoll zwischen Runtime und Gateway. Setzen Sie deshalb unbedingt &#8222;HTTP&#8220;.<\/li>\n<li><strong>x86-Container-Image.<\/strong> AgentCore l\u00e4uft nur auf ARM64. F\u00fcr die Cross-Compilation auf Intel-\/AMD-Maschinen brauchen Sie <em>&#8211;platform linux\/arm64<\/em> und <em>QEMU\/buildx<\/em>.<\/li>\n<li><strong>Image wird nach dem Push nicht aktualisiert<\/strong>. AgentCore cacht das gezogene Image. \u00c4ndern Sie eine beliebige Umgebungsvariable, um einen Neustart mit dem aktuellen Image zu erzwingen.<\/li>\n<li><strong>VPC-Modus ohne ausgehendes Routing<\/strong>. Bei <em>network_mode = &#8222;VPC&#8220;<\/em> m\u00fcssen die Subnetze Internetzugriff haben (NAT- oder VPC-Endpunkte). Verwenden Sie &#8222;PUBLIC&#8220;, es sei denn, Sie brauchen tats\u00e4chlich privaten Netzwerkzugriff.<\/li>\n<\/ol>\n\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-e24df0b elementor-widget elementor-widget-heading\" data-id=\"e24df0b\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-default\">Was Sie damit machen k\u00f6nnen<\/h2>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-f06f0b5 elementor-widget elementor-widget-text-editor\" data-id=\"f06f0b5\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>Das Tortenrezept ist <em>ein<\/em> Tool, das statische Daten ausgibt. Mit der gleichen Architektur k\u00f6nnen Sie aber auch Agenten erstellen, die f\u00fcr ihr Reasoning mehrere Tools aufrufen, um komplexe Fragen zu beantworten.<\/p>\n<p>Vorstellbar ist zum Beispiel ein Abrechnungsassistent, den man fragen kann: <em>\u201eWelche meiner Kunden haben unbezahlte Rechnungen aus dem letzten Quartal und wie hoch ist jeweils der offene Gesamtbetrag?\u201c<\/em><\/p>\n<p>Das l\u00e4sst sich nicht mit einer Datenbankabfrage beantworten. Der Agent unterteilt die Aufgabe in mehrere Schritte:<\/p>\n<ol>\n<li>Zuerst ruft er ein Tool auf, das die offenen Rechnungen aus einem bestimmten Zeitraum auflistet.<\/li>\n<li>Dann ruft er ein Tool auf, das die offenen Betr\u00e4ge der einzelnen Kunden zusammenrechnet.<\/li>\n<li>Zum Schluss kombiniert er beide Ergebnisse und gibt eine sortierte Liste mit Gesamtbetr\u00e4gen aus.<\/li>\n<\/ol>\n<p>Das LLM beschlie\u00dft diese Sequenz allein, sie wird nicht von Ihnen hartkodiert. Sie stellen nur die Tools bereit (jeweils eine parametrisierte Abfrage) sowie einen Systemprompt, der beschreibt, wann welches Tool eingesetzt werden soll. Der Agent erkennt, dass zum Beantworten der Benutzerfrage zwei Schritte n\u00f6tig sind, w\u00e4hlt f\u00fcr jeden Schritt das richtige Tool aus, \u00fcbergibt die richtigen Parameter (Datumsbereich, Filter f\u00fcr Zahlungsstatus) und fasst die Ergebnisse in einer koh\u00e4renten Antwort zusammen.<\/p>\n<p>Wenn Sie das Ganze jetzt auf 10 bis 15 Tools skalieren, die Unterschiedliches aus einer Datenbank abfragen \u2013 Kunden, Rechnungen, Zahlungen, Umsatz, Volltextsuche \u2013, kann der Agent fast jede Auswertungsfrage beantworten, die ein Benutzer stellt.<\/p>\n<p>Das ist der Sprung von \u201eein Tool, eine Antwort\u201c zu einem echten Produktionsagenten: Das LLM wird zum selbstst\u00e4ndigen Abfrageplaner, der mehrere zweckbestimmte, parametrisierte Datenabrufe verkettet und auf diese Weise Fragen beantworten kann, die keine Abfrage allein l\u00f6sen k\u00f6nnte.<\/p>\n\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>Erfahren Sie, wie Sie mithilfe von AWS AgentCore und Terraform einen skalierbaren KI-Agenten entwickeln, bereitstellen und testen k\u00f6nnen.<\/p>\n","protected":false},"author":23,"featured_media":94773,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[26],"tags":[207,71],"class_list":["post-94777","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog","tag-ai-ml","tag-aws"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.skaylink.com\/de\/wp-json\/wp\/v2\/posts\/94777","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.skaylink.com\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.skaylink.com\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.skaylink.com\/de\/wp-json\/wp\/v2\/users\/23"}],"replies":[{"embeddable":true,"href":"https:\/\/www.skaylink.com\/de\/wp-json\/wp\/v2\/comments?post=94777"}],"version-history":[{"count":4,"href":"https:\/\/www.skaylink.com\/de\/wp-json\/wp\/v2\/posts\/94777\/revisions"}],"predecessor-version":[{"id":94781,"href":"https:\/\/www.skaylink.com\/de\/wp-json\/wp\/v2\/posts\/94777\/revisions\/94781"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.skaylink.com\/de\/wp-json\/wp\/v2\/media\/94773"}],"wp:attachment":[{"href":"https:\/\/www.skaylink.com\/de\/wp-json\/wp\/v2\/media?parent=94777"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.skaylink.com\/de\/wp-json\/wp\/v2\/categories?post=94777"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.skaylink.com\/de\/wp-json\/wp\/v2\/tags?post=94777"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}