O problema: quando sessões serverless não são suficientes
À medida que as arquiteturas de Inteligência Artificial (IA) evoluem de agentes únicos para sistemas multi-agentes, os requisitos de infraestrutura mudam significativamente. Um agente solitário respondendo a consultas de clientes funciona bem em ambiente serverless com sessões curtas. Mas quando três agentes precisam colaborar em um fluxo de trabalho criativo que se estende por vários dias, compartilhando contexto e construindo sobre os resultados uns dos outros, sessões limitadas a poucas horas simplesmente não resolvem.
Para endereçar esse cenário, a AWS publicou um guia detalhado mostrando como implantar um pipeline de produção musical com o Amazon Bedrock AgentCore. O exemplo é prático: um agente roda um modelo generativo de áudio diretamente na Unidade de Processamento Gráfico (GPU) da instância, e outros dois agentes abrem o arquivo .wav gerado a partir de um volume compartilhado. O resultado final é uma faixa de áudio reproduzível — e uma arquitetura que serve de modelo para workloads muito além da música.
MicroVM vs. Runtime Instances: qual a diferença?
O Amazon Bedrock AgentCore oferece duas opções de computação para hospedar agentes. As MicroVMs são a opção serverless: inicialização rápida, isolamento de sessão e precificação baseada em consumo. As Runtime Instances são a opção mais recente: infraestrutura EC2 gerenciada pela AWS para fluxos de trabalho persistentes e de longa duração.
Ambas as opções suportam frameworks customizados (CrewAI, LangGraph, LlamaIndex, Strands Agents), funcionam com o modelo fundacional de sua escolha e integram com MCP e A2A. A diferença está no modelo de computação subjacente:
- Duração da sessão: MicroVM suporta até 8 horas; Runtime Instances suporta até 14 dias.
- Agentes por instância: MicroVM hospeda um agente por runtime (1:1); Runtime Instances permite múltiplos agentes por instância EC2 (1:N).
- Acesso a GPU: não disponível em MicroVM; disponível em Runtime Instances em famílias de instâncias compatíveis.
- Persistência de sessão: MicroVM usa armazenamento com escopo de sessão; Runtime Instances usa armazenamento persistente via Amazon Elastic Block Store (EBS).
- Precificação: MicroVM é baseada em consumo; Runtime Instances usa instâncias EC2 na sua conta, com suporte a AWS Savings Plans e Reservas de Capacidade sob Demanda (ODCRs).
Um detalhe importante sobre a colocação: quando dois runtimes de agentes compartilham o mesmo capacity provider e são invocados com o mesmo runtimeSessionId, o AgentCore os coloca na mesma instância EC2. Ali, eles compartilham um sistema de arquivos e podem colaborar na mesma tarefa.
Visão geral da solução: três agentes, uma instância GPU
A solução demonstrada pela AWS é um sistema de produção musical com três agentes especializados, todos rodando na mesma instância GPU:
- Agente de Composição (equipe de Audio AI): transforma a solicitação do produtor em um briefing musical usando o Claude Sonnet 4.6, depois renderiza o áudio real com o modelo generativo ACE-Step — um modelo fundacional de código aberto para geração de música — diretamente na GPU da instância. Empacotado como imagem de container no Amazon Elastic Container Registry (ECR).
- Agente de Entrega (equipe de Engenharia de Áudio): lê a faixa renderizada do sistema de arquivos compartilhado, mede suas características técnicas, consulta o Claude Sonnet 4.6 para definir uma cadeia de processamento (equalização, compressão, limitação) baseada nessas medições, aplica o Processamento Digital de Sinal (DSP) real e mede novamente para confirmar que o resultado atingiu o alvo de entrega. Também empacotado como container no ECR.
- Agente de Conformidade (equipe de Engenharia de Release): re-mede de forma independente a entrega finalizada, verifica os alvos declarados pelo agente de entrega e rastreia similaridade harmônica com o catálogo do estúdio. Se detectar uma correspondência, chama de volta o agente de composição para gerar uma alternativa. Entregue como arquivo zip no Amazon Simple Storage Service (S3).
O que torna isso possível nas Runtime Instances é a combinação de quatro características: colocação via ID de sessão compartilhado, acesso a GPU (NVIDIA L4), persistência multi-dia com volumes EBS, e implantação independente por equipe.
Pré-requisitos
Antes de começar, é necessário ter:
- Uma conta AWS com credenciais para criar infraestrutura (Funções de Gerenciamento de Identidade e Acesso (IAM), bucket S3, repositórios ECR, capacity provider e runtimes AgentCore).
- Interface de Linha de Comando da AWS (AWS CLI) instalada e configurada.
- Uma Nuvem Privada Virtual (VPC) com pelo menos uma sub-rede e grupo de segurança.
- Acesso ao modelo Anthropic Claude Sonnet 4.6 habilitado no console do Amazon Bedrock.
- Finch ou outra ferramenta de container compatível com OCI instalada localmente.
- Python 3.10+ e boto3 ≥ 1.36.0 (versões anteriores não possuem
create_capacity_provider).
O código completo está disponível no repositório de exemplos do AgentCore no GitHub.
Passo 1: Definindo os agentes
O AgentCore Runtime Instances suporta qualquer framework de agentes. Neste exemplo, cada agente é uma aplicação Python construída com Strands Agents. Dois detalhes são frequentemente configurados incorretamente:
Primeiro, o parâmetro do entrypoint deve se chamar context — o SDK faz dispatch pelo nome do parâmetro:
@app.entrypoint
def invoke(payload, context): # the parameter must be NAMED "context"
session_id = getattr(context, "session_id", None) or "local-session"
Segundo, o agente deve ser construído dentro do handler, não no escopo do módulo — um agente no escopo do módulo é compartilhado entre requisições concorrentes, e o Strands rejeita invocações reentrantes:
def build_agent(session_id: str, track_id: str) -> Agent:
return Agent(
name=AGENT_NAME,
model=BedrockModel(model_id=MODEL_ID, region_name=REGION),
system_prompt=SYSTEM_PROMPT,
session_manager=FileSessionManager(
session_id=f"{session_id}-{AGENT_NAME}",
storage_dir=str(track_path(track_id) / f".sessions-{AGENT_NAME}"),
),
)
O histórico da sessão persiste no volume via FileSessionManager, o que permite que uma sessão retomada dias depois lembre as decisões anteriores.
Passo 2: Criando o capacity provider
Um capacity provider informa ao AgentCore qual infraestrutura de computação provisionar. São necessárias duas funções IAM com propósitos distintos: uma função de operador (que o AgentCore assume para provisionar EC2) e uma função de execução (que o processo do agente assume em tempo de execução para chamar Bedrock e S3). Ambas devem ter bedrock-agentcore.amazonaws.com como entidade confiável.
Um detalhe importante: nomes de capacity providers devem usar underscores — hífens não são permitidos.
control = boto3.client("bedrock-agentcore-control", region_name=REGION)
resp = control.create_capacity_provider(
name="music_production_capacity",
permissionsConfiguration={"capacityProviderOperatorRoleArn": operator_arn},
computeConfiguration={
"ec2Configuration": {
"launchTemplateSource": {
"launchParameters": {
"operatingSystem": "LINUX_X86_64",
"instanceRequirements": {"allowedInstanceTypes": ["g6.xlarge"]},
}
},
"vpcConfiguration": {"subnets": subnets, "securityGroups": groups},
"volumes": [
{"ebsConfiguration": {"name": "tracks", "sizeGiB": 20, "volumeType": "gp3", "encrypted": True}},
{"ebsConfiguration": {"name": "models", "sizeGiB": 60, "volumeType": "gp3", "encrypted": True, "throughput": 500}},
],
"rootVolume": {"freeSpaceGiB": 30, "volumeType": "gp3"},
"lifecycleConfiguration": {"idleInstanceTimeout": 600, "maxLifetime": 86400},
}
},
)
⚠️ Capacidade de GPU: se houver InsufficientInstanceCapacity em múltiplas Zonas de Disponibilidade (AZs) ao tentar alocar uma instância GPU, é possível alternar para outro tipo, como g5.xlarge, atualizando allowedInstanceTypes.
Passo 3: Implantando os runtimes de agentes
Cada agente recebe seu próprio runtime. Quando dois runtimes compartilham um capacity provider e são invocados com o mesmo runtimeSessionId, o AgentCore os coloca na mesma instância EC2, onde compartilham um sistema de arquivos — é assim que o agente de entrega lê o .wav escrito pelo agente de composição.
composition = control.create_agent_runtime(
agentRuntimeName="music_production_composition",
roleArn=execution_arn, # required
agentRuntimeArtifact={"containerConfiguration": {"containerUri": image_uri}},
protocolConfiguration={"serverProtocol": "HTTP"},
capacityProviderConfiguration={"capacityProviderArn": cp_arn},
filesystemConfigurations=[
{"capacityProviderVolume": {"volumeName": "tracks", "mountPath": "/mnt/tracks"}},
{"capacityProviderVolume": {"volumeName": "models", "mountPath": "/mnt/models"}},
],
lifecycleConfiguration={"idleRuntimeSessionTimeout": 600, "maxLifetime": 86400},
environmentVariables={"AWS_REGION": REGION, "WORKSPACE_DIR": "/mnt/tracks", "MODELS_DIR": "/mnt/models", "MODEL_ID": MODEL_ID},
)
O agente de conformidade usa um artefato diferente — um zip em vez de uma imagem de container — demonstrando que tipos de artefatos mistos coexistem no mesmo capacity provider:
agentRuntimeArtifact={"codeConfiguration": {
"code": {"s3": {"bucket": bucket, "prefix": key}},
"runtime": "PYTHON_3_12",
"entryPoint": ["compliance_agent.py"],
}},
Passo 4: Orquestrando o pipeline com sessão compartilhada
A orquestração é feita passando o mesmo runtimeSessionId para cada invocação. A primeira chamada é a mais lenta, pois provisiona a instância. Todas as chamadas subsequentes são roteadas para a instância já em execução:
session_id = f"music-production-{uuid.uuid4()}" # 33-100 characters
invoke_agent(COMPOSITION_ARN, {"mode": "prepare"})
invoke_agent(COMPOSITION_ARN, {"mode": "catalogue", "track_id": track_id, "duration_s": 20})
invoke_agent(COMPOSITION_ARN, {"mode": "compose", "track_id": track_id, "duration_s": 30, "prompt": "Create an upbeat electronic track with heavy bass and synth melodies."})
invoke_agent(DELIVERY_ARN, {"track_id": track_id, "platform": "spotify", "prompt": "Prepare this for streaming delivery."})
result = invoke_agent(COMPLIANCE_ARN, {"track_id": track_id, "prompt": "Screen this delivery for release."})
print(result["outcome"]) # cleared | review_required | not_cleared
Em execução real em uma instância g6.xlarge na região us-east-2, o resultado observado foi:
1. prepare model stack (GPU instance + torch + weights) 239s
host : ip-172-31-11-83.us-east-2.compute.internal
stack : ready=True in 125s
2. render back-catalogue 66s
3. compose (renders audio on the GPU) 25s
rendered : NVIDIA L4 in 8.98s (peak VRAM 7.63 GiB)
audio 20.062s 48000Hz 2ch -7.5 LUFS peak 0.42 dBTP
4. delivery (real DSP, verified by measurement) 41s
read : composition.wav <- written by another agent
before -7.5 LUFS peak 0.42 dBTP
after -14.0 LUFS peak -3.2 dBTP
targets : loudness met, true peak held
5. compliance screen 28s
verdict : REVIEW REQUIRED
screen : 2 reference(s), closest catalogue_00.wav distance 0.0665 (review)
-- collocation --
All 5 steps were served by one instance, as intended.
Ao chamar StopRuntimeSession, a instância entra em modo ocioso automaticamente. Não há cobranças de computação enquanto estiver ociosa. Ao invocar a sessão novamente, o AgentCore a retoma — desde que o roteamento aconteça na mesma Zona de Disponibilidade, pois volumes EBS são bloqueados por AZ.
Passo 5: Atualizando agentes de forma independente
Um dos pontos fortes dessa arquitetura é a implantação independente. Quando a equipe de Audio AI precisa enviar uma nova versão do agente de composição, ela atualiza apenas seu próprio runtime — os agentes de entrega e conformidade continuam rodando sem interrupção, sem necessidade de coordenação:
control.update_agent_runtime(
agentRuntimeId=composition_id, # all three are required
roleArn=execution_arn,
agentRuntimeArtifact={"containerConfiguration": {"containerUri": new_uri}},
capacityProviderConfiguration={"capacityProviderArn": cp_arn},
)
Limpeza dos recursos
O caminho mais direto para interromper cobranças de EC2 e EBS é excluir a sessão primeiro. Excluir uma sessão desprovisiona os recursos EC2: instância, interface de rede e volume EBS. Excluir o capacity provider também encerra e exclui suas sessões associadas, mas é necessário primeiro desassociar todos os runtimes — e essa desassociação é assíncrona:
data = boto3.client("bedrock-agentcore", region_name=REGION)
data.delete_capacity_provider_session(capacityProviderId=cp_id, sessionId=session_id)
for rid in runtime_ids:
control.delete_agent_runtime(agentRuntimeId=rid)
control.delete_capacity_provider(capacityProviderId=cp_id)
Em seguida, é necessário excluir os repositórios ECR, artefatos no S3, funções IAM e grupos de logs no Amazon CloudWatch.
Padrões que vão além da música
A música foi apenas um veículo conveniente para demonstrar padrões de arquitetura que se aplicam a qualquer workload que exija processamento pesado, persistência e colaboração entre agentes. Os mesmos princípios se encaixam em renderização 3D, simulação, inferência de modelos, processamento de mídia — ou qualquer pipeline onde um agente produz um artefato grande, um segundo agente o transforma, e um terceiro verifica o resultado antes de publicar.
Para saber mais, consulte a documentação do Amazon Bedrock AgentCore. O código completo está disponível no repositório de exemplos do AgentCore. Para padrões avançados de orquestração como Graph, Swarm ou Workflow, consulte a documentação do Strands Agents.
Fonte
Build a multi-agent music production pipeline on Amazon Bedrock AgentCore Runtime Instances (https://aws.amazon.com/blogs/machine-learning/build-a-multi-agent-music-production-pipeline-on-amazon-bedrock-agentcore-runtime-instances/)
Leave a Reply