Розгортання агента LangGraph у AWS Bedrock AgentCore: крок за кроком
Загорніть існуючого агента LangGraph для AgentCore, створіть структуру проекту за допомогою CLI, протестуйте його локально, розгорніть на AWS та запустіть його зі збереженими сеансами та пам’яттю.
Джерела: How to Deploy a LangGraph Agent on AWS Bedrock AgentCore
Багато агентів LangGraph добре працюють на ноутбуці, але зупиняються на етапі впровадження в продакшн. AWS Bedrock AgentCore подолує цю проблему завдяки безсерверному хостингу, який дозволяє масштабуватися та не вимагає переробки коду. У наступних розділах розглядається процес інтеграції існуючого агента в AgentCore, створення проекту, його запуск локально, передача на AWS та виклик після того, як він почне працювати.
Що таке AgentCore
AgentCore — це сервіс хостингу від AWS, де агенти розгортаються, масштабуються та запускаються без необхідності керування серверами. Фреймворки на кшталт LangGraph, Strands, CrewAI та LlamaIndex, а також моделі від OpenAI, Google та Anthropic працюють у цьому середовищі, тож код агента залишається незмінним. Функції ізоляції сеансів, постійної пам’яті, моніторингу та керування ідентичностями є вбудованими.
Усе керується інструментом CLI AgentCore. Це програма на Node.js, яка створює скелет проекту, запускає агента локально та розгортає його на AWS за допомогою CDK, який працює в фоновому режимі.
Попередні вимоги
- Python 3.12 або новіша версія
uvабоpipдля керування пакетами Python- Node.js 20 або новіша версія, оскільки CLI розповсюджується через npm
- AWSCDK, встановлений глобально за допомогою команди
npm install -g aws-cdk - Обліковий запис AWS із обліковими даними, налаштованими локально за допомогою команди
aws configure - Існуючий код LangGraph, який генерує скомпільований StateGraph
Крок 1: встановлення CLI
Усе керується одним інструментом командного рядка: створення проекту, запуск додатку локально та розгортання на AWS.
npm install -g @aws/agentcore
Підтвердіть, що встановлення пройшло успішно:
agentcore --help
Крок 2: додавання залежностей
До залежностей агента потрібно додати два пакети. bedrock-agentcore — це Python SDK, який надає клас-обгортку BedrockAgentCoreApp, а aws-opentelemetry-distro — це версія інструментарію OpenTelemetry для Python, створена компанією AWS.
# 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
]
Встановіть за тим процесом роботи, який є звичайним для проекту:
uv sync
# or: pip install -e .
Крок 3: написати точку входу у main.py
AgentCore очікує один файл на Python як точку входу, який містить екземпляр BedrockAgentCoreApp та функцію, прикрашену атрибутом @app.entrypoint. Логіка LangGraph майже не змінюється — вона просто обгортається у невелику точку входу під час виконання.
# 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()
Що має значення у цьому файлі
BedrockAgentCoreApp()надає середовищу виконання його „шкаралупу“: HTTP-сервер, маршрути перевірки стану та структуровані журнали, усе це вже підключено заздалегідь.- Граф будується у межах модуля, один раз під час імпорту, а не з кожним викликом. Тому будь-яка проблема під час запуску проявляється негайно, а несправний додаток ніколи не отримує трафіку.
@app.entrypointпозначає обробник вхідних викликів. Йому передаєтьсяpayload— розшифроване тіло у форматі JSON — разом ізcontextдля запиту AgentCore. Результатом має бути звичайний словник, який можна серіалізувати у JSON. Проста рядок чи власний клас не підійдуть.- Вхідний
session_idстаєthread_idу LangGraph, томуMemorySaverзберігає окрему пам’ять для кожної сесії.
Крок 4: створення проекту
Далі йде план проекту. Запустіть майстра ініціалізації з чистої кореневої папки та дозвольте йому створити каркас:
agentcore create
Чарівник просить надати таку інформацію, як назва проекту, мова, версія Python та файл вхідної точки. Вхідна точка та версія Python мають збігатися з програмою. Після цього у папці agentcore з’являється файл agentcore.json, який вказує AgentCore, де знаходиться код та як його запустити.
{
"name": "MyAgentOnAgentcore",
"runtimes": [
{
"name": "my-agent",
"build": "CodeZip",
"entrypoint": "main.py",
"codeLocation": "app/my-agent/",
"runtimeVersion": "PYTHON_3_12",
"networkMode": "PUBLIC",
"protocol": "HTTP",
"envVars": []
}
]
}
Крок 5: розмістіть код там, де шукає AgentCore
Перемістіть або скопіюйте вихідний код агента у каталог, вказаний у codeLocation у файлі agentcore.json. Легко припуститися помилки, а неправильне розташування ускладнює процес розгортання. Поширеною помилкою є розміщення коду безпосередньо у папці agentcore, що може забрати багато часу. Структура має виглядати ось так:
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 має знаходитися на верхньому рівні codeLocation та точно відповідати точці входу в agentcore.json.
Змінні середовища
AgentCore може передавати змінні середовища контейнеру часу виконання. У локальних умовах найпростішим способом є використання файлу .env. У продакшені значення можуть знаходитися в agentcore.json у розділі envVars, хоча файл .env також підходить. Конфіденційні дані, такі як паролі та ключі API, краще зберігати в AWS Secrets Manager та завантажувати їх під час виконання; у цьому випадку роль виконання AgentCore потребує дозволу на їх читання. Зауважте, що envVars — це масив об’єктів JSON, кожен з яких має поля name та value.
Крок 6: перевірка
Перш ніж щось запустити, дозвольте CLI перевірити конфігурацію:
agentcore validate
Прості проблеми, такі як відсутній файл вхідної точки чи неправильний шлях у конфігурації, виявляються саме тут.
Крок 7: запустіть та протестуйте локально
Запустіть локальний середовище виконання за допомогою:
agentcore dev
Він запускає локальний HTTP-сервер, який точно відтворює умови продакшну. Якщо все налаштовано правильно, у виводі буде показано, що додаток готовий та прослуховує на локальному порту.
Виклик локального сервера
Виклик можна здійснити через CLI:
agentcore invoke "Summarise last month sales"
або за допомогою curl:
curl -X POST http://localhost:8080/invocations \
-H "Content-Type: application/json" \
-d '{"prompt": "Summarise last month sales", "session_id": "test-001"}'
Хорошою відповіддю є JSON із відповіддю агента всередині:
{"response": "Last month, total sales were $1.2M across 3 regions..."}
Крок 8: розгортання на AWS
Коли локальні тести пройдені успішно, розгорніть проект у AgentCore Runtime:
agentcore deploy
На задньому плані CLI пакетує код, створює бакет S3 для прямої розгортки коду, формує роль виконання IAM та розгортає AgentCore Runtime за допомогою CDK. Перша розгортка займає кілька хвилин, а наступні, як правило, відбуваються швидше.
Як тільки це завершиться, перевірте статус рунтайму. У результаті відображаються ARN рунтайму та HTTP-адреса для виклику розгорнутого агента.
agentcore status
Крок 9: запустити розгорнутий агент
CLI — це найпростіший спосіб спробувати розгорнуту версію:
agentcore invoke --prompt "Who are the top 5 customers by revenue?" --session-id "session-id-with-length-greater-than-or-equal-33"
Для виклику через HTTP необхідно підписати запит за допомогою 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?"}'
Використовуйте HTTP-адресу з agentcore status.
Для викликів з іншого коду на Python SDK зазвичай є найкращим варіантом. Зберігайте ARN часу виконання у змінній середовища, передавайте відповідний запит та надсилайте попередній ідентифікатор сеансу з кожним наступним викликом.
# 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}")
Встановіть AGENTCORE_RUNTIME_ARN у файлі .env:
AGENTCORE_RUNTIME_ARN=arn:aws:bedrock-agentcore:us-east-1:123456789012:agent-runtime/MyAgentOnAgentcore-xxxx
Зберігання стану сесії між викликами
Подивіться на runtimeSessionId у прикладі boto3. AgentCore повертає його з кожною відповіддю. Надсилання його у наступному запиті дозволяє спрямовувати подальші дії у межах тієї самої сесії, а у поєднанні з MemorySaver від LangGraph агент зберігає повну пам’ять про розмову навіть під час окремих HTTP-викликів.
Поширені проблеми
- Помилки під час запуску є навмисними. Коли
create_agent()викидає помилку під час імпорту, AgentCore не запускає робочий процес. Така поведінка запобігає тому, щоб неправильно налаштований агент, наприклад з відсутніми обліковими даними чи некоректною URL бази даних, почав працювати без проблем. - Потрібно додати дозволи. Роль виконання AgentCore вимагає прямого доступу до будь-яких сервісів AWS, які використовує агент, включаючи Secrets Manager та S3. Додайте ці дозволи після першого розгортання.
- Версії мають збігатися. Версія Python, вказана в
pyproject.toml, повинна збігатися з налаштуванням часу виконання вagentcore.json. - Повертайте звичайні словники. Якщо точка входу повертає рядок або власний об’єкт, механізм виконання відхиляє її.
Що насправді змінюється
Щоб перейти від локального агента LangGraph до AgentCore, потрібно здійснити лише кілька змін: встановити два додаткові пакети, обгорнути граф у BedrockAgentCoreApp, створити основу проекту, протестувати його локально, а потім розгорнути та скористатися ним. Граф, інструменти, виклики моделей та налаштування пам’яті залишаються майже недоторканими. AgentCore керує інфраструктурною частиною, тоді як LangGraph продовжує керувати логікою агента.
Пов’язана література
- Ваш граф агента має бути у форматі YAML: компіляція 17-агентного LangGraph під час запуску — як невеликий движок компілює один YAML-специфікаційний файл у LangGraph StateGraph: генерований стан, плагіни importlib, маршрутизатори міток, адаптивні виклики та заміна вузлів за сеансом.