Startseite / Artikel

Ein LangGraph Agent auf AWS Bedrock AgentCore schrittweise einrichten

Umhüllen Sie einen bestehenden LangGraph-Agent für AgentCore, strukturieren Sie das Projekt mit der CLI, testen Sie es lokal, deployen Sie es auf AWS und rufen Sie es mit intakten Sessions und Speicher auf.

Verlag: REACTAPP.TOP8 Min. Lesezeit1792 Wörter

Quellen: How to Deploy a LangGraph Agent on AWS Bedrock AgentCore

Viele LangGraph-Agenten funktionieren gut auf einem Laptop, stocken jedoch beim Übergang in die Produktivumgebung. AWS Bedrock AgentCore schließt diese Lücke durch serverloses Hosting, das skaliert und keine Neugestaltung erfordert. Die folgenden Abschnitte behandeln das Umhüllen eines bestehenden Agenten für AgentCore, die Erstellung eines Projekts, den lokalen Betrieb, den Versand an AWS sowie den Aufruf des Agenten, sobald er online ist.

Was AgentCore ist

AgentCore ist ein von AWS bereitgestellter Hosted-Runtime, in dem Agenten ohne Serververwaltung bereitgestellt, skaliert und ausgeführt werden. Frameworks wie LangGraph, Strands, CrewAI und LlamaIndex funktionieren genauso wie Modelle von OpenAI, Google und Anthropic – dadurch bleibt der Agentencodex unverändert. Sitzungsisolation, persistente Speicherung, Überwachungsfunktionen sowie Identitätsmanagement sind bereits integriert.

Alles wird durch die AgentCore CLI gesteuert. Es handelt sich um ein Node.js-Programm, das das Projektgerüst erstellt, den Agent lokal bereitstellt und ihn unter Verwendung von CDK auf AWS deployt.

Voraussetzungen

  • Python 3.12 oder neuer
  • uv oder pip zur Verwaltung von Python-Paketen
  • Node.js 20 oder neuer, da die CLI über npm verteilt wird
  • AWS CDK, das global mit npm install -g aws-cdk installiert ist
  • Ein AWS-Konto mit Anmeldedaten, die lokal über aws configure konfiguriert sind
  • Bestehender LangGraph-Code, der einen kompilierten StateGraph erzeugt

Schritt 1: Die CLI installieren

Ein einziges Befehlszeilenwerkzeug steuert alles: die Erstellung des Projekts, den lokalen Betrieb der Anwendung sowie das Deployment auf AWS.

npm install -g @aws/agentcore

Bestätigen Sie, dass die Installation erfolgreich war:

agentcore --help

Schritt 2: Abhängigkeiten hinzufügen

Zwei Pakete müssen zu den Abhängigkeiten des Agents hinzugefügt werden. bedrock-agentcore ist die Python-SDK, die die Wrapper-Klasse BedrockAgentCoreApp bereitstellt, und aws-opentelemetry-distro ist die von AWS erstellte Version der OpenTelemetry-Instrumentierung für Python.

# pyproject.toml
[project]
name = "my-agent"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = [
    "aws-opentelemetry-distro==0.17.0",
 "bedrock-agentcore>=1.6.3",
    "boto3>=1.42.0",
    "langgraph>=1.1.0",
    "langchain-core>=1.2.0",
    # ... your other existing dependencies
]

Installieren Sie es mit dem für das Projekt üblichen Workflow:

uv sync
# or: pip install -e .

Schritt 3: Der Eingangspunkt in main.py schreiben

AgentCore erwartet eine Python-Datei als Eingangspunkt, die eine BedrockAgentCoreApp-Instanz sowie eine mit @app.entrypoint dekorierte Funktion enthält. Die Logik von LangGraph ändert sich kaum – sie wird lediglich in einen kleinen Laufzeit-Eingangspunkt eingebettet.

# main.py
from langchain_core.messages import HumanMessage
from bedrock_agentcore.runtime import BedrockAgentCoreApp
from graphs.my_agent_graph import build_my_agent  # your existing graph builder

# 1. Instantiate the AgentCore app and logger
app = BedrockAgentCoreApp()
log = app.logger

# 2. Build your graph at module load time (startup)
#    AgentCore initialises the module once, then handles concurrent invocations.
#    Any failure here will prevent a broken agent from going live.
def create_agent():
    log.info("Initialising agent...")
    graph = build_my_agent()   # returns your compiled LangGraph StateGraph
    log.info("Agent ready")
    return graph
try:
    graph = create_agent()
except Exception as e:
    log.error(f"Critical failure during agent initialisation: {e}")
    raise  # fail fast - don't let a broken agent start serving requests

# 3. Async helper that drives the LangGraph streaming loop
async def run_agent(user_input: str, session_id: str = "default-session") -> str:
    responses = []
    config = {"configurable": {"thread_id": session_id}}
    async for chunk in graph.astream(
        {"messages": [HumanMessage(content=user_input)]},
        config=config,
        stream_mode="values",
    ):
        messages = chunk.get("messages", [])
        if messages:
            last = messages[-1]
            if getattr(last, "type", None) == "ai":
                responses.append(last)
    if not responses:
        return "No response"
    content = getattr(responses[-1], "content", "")
    return content if isinstance(content, str) else str(content)

# 4. The entrypoint - this is what AgentCore calls on every invocation
@app.entrypoint
async def invoke(payload, context):
    try:
        log.info("Invoke received")
        user_input = payload.get("prompt", "")
        session_id = payload.get("session_id", "default-session")
        if not user_input.strip():
            return {"error": "Prompt cannot be empty"}
        response = await run_agent(user_input, session_id)
        return {"response": response}
    except Exception as e:
        log.error(f"Error: {e}")
        return {"error": str(e)}

# 5. Run the app (only executed when running locally using agentcore dev)
if __name__ == "__main__":
    app.run()

Was in dieser Datei wichtig ist

  • BedrockAgentCoreApp() liefert dem Laufzeitumfeld seine Grundstruktur: einen HTTP-Server, Health-Check-Routen sowie strukturierte Protokolle – alles bereits vorkonfiguriert.
  • Das Graphen wird im Modulbereich erstellt, einmal bei der Importierung und nicht bei jedem Aufruf. Dadurch treten alle Startprobleme sofort zutage, und eine fehlerhafte Anwendung erhält niemals Traffic.
  • @app.entrypoint kennzeichnet den Handler für eingehende Anfragen. Ihm wird payload, der decodierte JSON-Body, zusammen mit context für die AgentCore-Anfrage übergeben. Das zurückgegebene Ergebnis muss ein einfaches Dictionary sein, das in JSON serialisierbar ist. Einfache Zeichenketten oder benutzerdefinierte Klassen reichen nicht aus.
  • Die übergebene session_id wird zu LangGraphs thread_id; dadurch behält MemorySaver für jede Sitzung ein eigenes Speicherpuffer.

Schritt 4: Projekt erstellen

Danach kommt die Projektstruktur. Führen Sie den Initialisierungs-Assistenten von einem sauberen Root-Verzeichnis aus und lassen Sie ihn das Skelett erstellen:

agentcore create

Der Assistent fragt nach Details wie dem Projektnamen, der Sprache, der Python-Version sowie der Eingabestellen-Datei. Die Eingabestelle und die Python-Version müssen der Anwendung entsprechen. Anschließend entsteht eine agentcore.json-Datei im agentcore-Ordner, die AgentCore mitteilt, wo sich der Code befindet und wie er ausgeführt werden soll.

{
  "name": "MyAgentOnAgentcore",
    "runtimes": [
    {
      "name": "my-agent",
      "build": "CodeZip",
      "entrypoint": "main.py",
      "codeLocation": "app/my-agent/",
      "runtimeVersion": "PYTHON_3_12",
      "networkMode": "PUBLIC",
      "protocol": "HTTP",
	  "envVars": []
	}
  ]
}

Schritt 5: Platziere den Code an der Stelle, an der AgentCore nachschaut

Verlege oder kopiere die Quelldatei des Agents in das Verzeichnis, das in agentcore.json unter codeLocation angegeben ist. Es ist leicht, einen Fehler zu machen, und eine falsche Position macht die Bereitstellung unnötig schwierig. Ein häufiger Fehler ist es, den Code direkt in das agentcore-Verzeichnis selbst zu legen, was viel Zeit kosten kann. Die Struktur sollte wie folgt aussehen:

MyAgentOnAgentcore/
├──agentcore
	└── agentcore.json
├──app/
	└──my-agent/          			 ← codeLocation
		├── main.py                  ← entrypoint (matches agentcore.json)
		├── pyproject.toml           ← or requirements.txt
		├── src/
		│   └── my_agent_graph.py    ← your LangGraph graph builder
		│   └── tools.py             ← your tools, utilities, etc.
		└── .env					 ← your configuration variables

main.py muss sich auf der obersten Ebene von codeLocation befinden und exakt mit dem Eingangspunkt in agentcore.json übereinstimmen.

Umgebungsvariablen

AgentCore kann Umgebungsvariablen an den Laufzeitcontainer weitergeben. Lokal ist eine .env-Datei der einfachste Weg. In der Produktion können die Werte in agentcore.json unter envVars gespeichert werden, wobei auch eine .env-Datei funktioniert. Geheime Informationen wie Passwörter und API-Schlüssel sollten besser im AWS Secrets Manager aufbewahrt und zur Laufzeit geladen werden; in diesem Fall benötigt die Ausführungsrolle von AgentCore Berechtigungen zum Lesen dieser Daten. Beachten Sie, dass envVars ein Array von JSON-Objekten ist, von denen jedes über die Felder name und value verfügt.

Schritt 6: Überprüfen

Lassen Sie die CLI vor dem Ausführen irgendetwas die Konfiguration überprüfen:

agentcore validate

Einfache Fehler wie ein fehlendes Eingangspunkt-Datei oder ein falscher Pfad in der Konfiguration werden genau hier erkannt.

Schritt 7: Lokal ausführen und testen

Starten Sie die lokale Laufzeitumgebung mit:

agentcore dev

Es startet einen lokalen HTTP-Server, der der Produktionsumgebung sehr ähnlich ist. Wenn alles richtig konfiguriert ist, zeigt die Ausgabe an, dass die Anwendung bereit ist und auf einem lokalen Port lauscht.

Aufruf des lokalen Servers

Ein Aufruf kann über die CLI erfolgen:

agentcore invoke "Summarise last month sales"

oder über curl:

curl -X POST http://localhost:8080/invocations \
  -H "Content-Type: application/json" \
  -d '{"prompt": "Summarise last month sales", "session_id": "test-001"}'

Eine gute Antwort ist JSON mit der Antwort des Agents darin:

{"response": "Last month, total sales were $1.2M across 3 regions..."}

Schritt 8: Deployment auf AWS

Sobald die lokalen Tests erfolgreich waren, führen Sie das Deployment auf den AgentCore Runtime durch:

agentcore deploy

Hinter den Kulissen packt die CLI den Code zusammen, stellt einen S3-Bucket für die direkte Code-Deployment bereit, erstellt eine IAM-Exekutionsrolle und deployt den AgentCore Runtime mit CDK. Die erste Deployment dauert einige Minuten, während spätere Deployment in der Regel schneller ablaufen.

Sobald die Deployment abgeschlossen ist, überprüfen Sie den Status des Runtimes. Die Ausgabe zeigt den ARN des Runtimes sowie die HTTP-URL zur Aufrufung des deployten Agents an.

agentcore status

Schritt 9: Den bereitgestellten Agent aufrufen

Die CLI ist die einfachste Möglichkeit, die bereitgestellte Version auszuprobieren:

agentcore invoke --prompt "Who are the top 5 customers by revenue?" --session-id "session-id-with-length-greater-than-or-equal-33"

Der Aufruf über HTTP erfordert die Signierung der Anfrage mit AWS SigV4:

curl -X POST "https://bedrock-agentcore.us-east-1.amazonaws.com/runtimes/arn-of-MyAgentOnAgentcore-xxxx/invocations" \
  --user "$AWS_ACCESS_KEY_ID:$AWS_SECRET_ACCESS_KEY" \
  --aws-sigv4 "aws:amz:us-east-1:bedrock-agentcore" \
  -H "Content-Type: application/json" \
  -H "x-amzn-bedrock-agentcore-runtime-session-id: session-id-with-length-greater-than-or-equal-33" \
  -d '{"prompt": "Who are the top 5 customers by revenue?"}'

Verwenden Sie die HTTP-URL aus agentcore status.

Für Aufrufe aus anderem Python-Code ist das SDK in der Regel die beste Option. Speichern Sie den Laufzeit-ARN in einer Umgebungsvariable, übergeben Sie die Anweisung und senden Sie die vorherige Sitzungs-ID bei jedem weiteren Aufruf erneut.

# invoke_agent.py
import json
import boto3
import os
from dotenv import load_dotenv

load_dotenv()

client = boto3.client("bedrock-agentcore", region_name="us-east-1")
runtime_arn = os.getenv("AGENTCORE_RUNTIME_ARN")

def invoke(prompt: str, session_id: str) -> str:
    payload = json.dumps({"prompt": prompt, "session_id": session_id})
    response = client.invoke_agent_runtime(
        agentRuntimeArn=runtime_arn,
        payload=payload,
        contentType="application/json"
    )
    body = json.loads(response["response"].read().decode())
    return body["response"]

if __name__ == "__main__":
    session_id = ""
    print("Ready. Type 'exit' to quit.")

    while True:
        prompt = input("Your question: ").strip()
        if prompt == "exit":
            break

        if not prompt:
            continue

        params = {
            "agentRuntimeArn": runtime_arn,
            "payload": json.dumps({"prompt": prompt}),
            "contentType": "application/json"
        }
        if session_id:
            params["runtimeSessionId"] = session_id

        try:
            response = client.invoke_agent_runtime(**params)
            body = json.loads(response["response"].read().decode())
            session_id = response.get("runtimeSessionId", session_id)
            print(f"Agent: {body['response']}\n")
        except Exception as e:
            print(f"Error: {e}")

Setzen Sie AGENTCORE_RUNTIME_ARN in der .env-Datei:

AGENTCORE_RUNTIME_ARN=arn:aws:bedrock-agentcore:us-east-1:123456789012:agent-runtime/MyAgentOnAgentcore-xxxx

Beibehaltung des Sitzungszustands über mehrere Aufrufe hinweg

Betrachten Sie runtimeSessionId im boto3-Beispiel. AgentCore gibt diesen Wert bei jeder Antwort zurück. Durch die Übermittlung dieses Wertes im nächsten Anfrage wird der weitere Austausch im selben Sitzungskontext abgewickelt. In Kombination mit LangGraphs MemorySaver behält der Agent somit das gesamte Gesprächsmemory über getrennte HTTP-Aufrufe hinweg.

Häufige Fallstricke

  • Startfehler sind beabsichtigt. Wenn create_agent() zur Zeit der Importierung Fehler auslöst, startet AgentCore den Laufzeitbetrieb nicht. Dieses Verhalten schützt davor, dass ein falsch konfigurierter Agent, beispielsweise mit fehlenden Zugangsdaten oder einer fehlerhaften Datenbank-URL, stillschweigend in Betrieb genommen wird.
  • Es müssen Berechtigungen hinzugefügt werden. Die von der Ausführungsrolle AgentCore erstellte Rolle benötigt expliziten Zugriff auf alle von dem Agenten genutzten AWS-Dienste, einschließlich Secrets Manager und S3. Fügen Sie diese Berechtigungen nach der ersten Bereitstellung hinzu.
  • Die Versionen müssen übereinstimmen. Die in pyproject.toml angegebene Python-Version muss mit der Laufzeit-Einstellung in agentcore.json übereinstimmen.
  • Es müssen einfache Wörterbücher zurückgegeben werden. Wenn der Eingangspunkt einen String oder ein benutzerdefiniertes Objekt zurückgibt, wird dies von der Laufzeitumgebung abgelehnt.

Was tatsächlich ändert sich

Um von einem lokalen LangGraph-Agenten zu AgentCore überzugehen, sind nur wenige Änderungen notwendig: Zwei zusätzliche Pakete installieren, das Graph in BedrockAgentCoreApp einpacken, ein Projekt erstellen, lokal testen und anschließend bereitstellen sowie aufrufen. Das Graph, die Tools, die Modellaufrufe sowie die Speicherkonfiguration bleiben größtenteils unverändert. AgentCore kümmert sich um die Infrastruktur, während LangGraph weiterhin für die Agentenlogik verantwortlich ist.

Verwandte Artikel

  • Validierungstüren und Mehr-Agenten-Routing für einen LangGraph-Support-Bot — Fügen Sie einem LangGraph-Agenten für den E-Commerce deterministische Geschäftslogik-Türen, einen selbstkorrigierenden Validierungszyklus sowie einen Supervisor mit drei spezialisierten Subgraphen hinzu.