Развертывание агента 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, поэтому код агента остаётся прежним. Встроены функции изоляции сессий, постоянной памяти, мониторинга и управления идентичностями.
Всё управляется средством командной строки AgentCore. Это программа на Node.js, которая создаёт скелет проекта, запускает агента локально и развертывает его в AWS с использованием подкладки CDK.
Предварительные требования
- Python 3.12 или новее
uvилиpipдля управления пакетами Python- Node.js 20 или новее, поскольку средство командной строки распространяется через npm
- AWSCDK, установленный глобально с помощью команды
npm install -g aws-cdk - Учётная запись AWS с установленными локально учётными данными через команду
aws configure - Существующий код LangGraph, генерирующий скомпилированный StateGraph
Шаг 1: установка средства командной строки
Всё управляется одним инструментом командной строки: созданием проекта, запуском приложения локально и его развертыванием в 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: компиляция графа LangGraph из 17 агентов при запуске — как небольшой движок компилирует один YAML-спецификацию в LangGraph StateGraph: генерация состояний, плагины importlib, маршрутизаторы меток, адаптивные вызовы и замена узлов в рамках сессии.