Author: Make.com Service User

  • Retrofit, não reconstrução: overlays agênticos para modernizar serviços legados

    O problema: sistemas REST em um mundo agêntico

    As arquiteturas corporativas foram construídas ao longo de anos sobre APIs REST e microsserviços. Esses sistemas são estáveis, bem testados e estão profundamente enraizados em ambientes produtivos. O problema é que eles não foram projetados para o modelo de comunicação Agent-to-Agent (A2A) — o padrão emergente para agentes autônomos que colaboram, raciocinam e se coordenam por meio de mensagens estruturadas.

    Com a consolidação do A2A como padrão, as empresas se veem diante de um desafio duplo: não só precisam integrar serviços REST tradicionais a esse novo modelo, como também precisam trazer agentes que já existem — mas foram construídos como APIs REST — para dentro do ecossistema A2A. Reconstruir tudo do zero não é viável. É aí que entra o conceito de agentic overlay.

    REST vs. A2A: paradigmas diferentes

    Para entender o problema, vale diferenciar os dois modelos. Uma API REST é projetada para integração determinística cliente-servidor: o cliente chama um endpoint bem definido, passa parâmetros e recebe uma resposta previsível, geralmente em um fluxo stateless baseado em HTTP. Isso torna o REST excelente para expor capacidades de negócio com contratos claros e simplicidade operacional.

    Já o A2A foi projetado para interoperabilidade entre agentes autônomos. Os agentes se descobrem por meio de metadados (como um “agent card”), negociam capacidades e trocam mensagens estruturadas — frequentemente via JSON-RPC (Notação de Objeto JavaScript para Chamada de Procedimento Remoto) — para coordenar tarefas em múltiplos passos. Enquanto o REST otimiza para interfaces de serviço estáveis e execução direta, o A2A otimiza para coordenação orientada a raciocínio, mensagens orientadas a tarefas e colaboração entre agentes.

    A solução: agentic overlays

    Um agentic overlay é uma camada fina de encapsulamento que permite que serviços baseados em REST participem de comunicações A2A. Essa camada realiza duas funções principais:

    O ponto central é que o A2A não é uma nova API — é uma nova interface para uma API que já existe. O serviço REST subjacente permanece intocado.

    Abordagens alternativas (e por que são problemáticas)

    Antes de detalhar o overlay, a AWS compara essa abordagem com outras alternativas comuns:

    Manter stacks REST e A2A separados

    Essa abordagem significa manter dois conjuntos de endpoints (/api/v2/... e /a2a/...), duas implementações de autenticação e validação, dois pipelines de deploy e duplo trabalho de observabilidade. O risco de inconsistência entre os dois caminhos é alto, e o custo operacional cresce com o tempo.

    Stacks separados com lógica de negócio compartilhada

    Aqui, a ideia é refatorar os endpoints existentes para que a lógica de negócio possa ser reutilizada por uma nova interface A2A. Embora pareça mais limpa, essa abordagem pode introduzir regressões, desvios de comportamento e uma carga de testes considerável — mesmo que os caminhos REST externos permaneçam os mesmos.

    Implementando um overlay dentro da aplicação

    Nessa abordagem, a aplicação passa a ter dois conjuntos de endpoints (/api/v2/... e /a2a/...), mas mantém um único pipeline de build, teste e deploy. Endpoints REST tradicionais são transformados em endpoints agênticos sem reescrever a lógica central. Novas rotas são adicionadas no mesmo host e porta. As próprias skills do agente podem ser usadas para roteamento interno, sem necessidade de um servidor MCP separado.

    A AWS apresenta um exemplo de prova de conceito usando um serviço de calculadora legado em Flask, convertido para o padrão A2A com um overlay. O fluxo de tradução de mensagens A2A funciona assim:

    • Recebe requisições JSON-RPC 2.0
    • Mapeia tarefas A2A para endpoints REST
    • Repassa cabeçalhos de autenticação
    • Chama endpoints REST internamente
    • Traduz respostas REST para o formato JSON-RPC

    Comparação de formatos: REST vs. A2A

    Para ilustrar a diferença, veja como a mesma operação de soma é representada nos dois protocolos.

    Requisição de entrada — REST vs. A2A:

    REST:
    { "operation": "add", "operands": [5, 3] }
    
    A2A:
    {
      "jsonrpc": "2.0",
      "method": "SendMessage",
      "params": {
        "message": {
          "role": "user",
          "parts": [
            {
              "kind": "data",
              "data": { "operation": "add", "operands": [5, 3] }
            }
          ]
        }
      },
      "id": 1
    }

    Resposta de saída — REST vs. A2A:

    REST:
    {"result": 8}
    
    A2A:
    {
      "jsonrpc": "2.0",
      "result": {
        "messageId": "uuid",
        "contextId": "uuid",
        "role": "agent",
        "parts": [{"kind": "data", "data": {"result": 8}}],
        "kind": "message",
        "metadata": {}
      },
      "id": 1
    }

    Estrutura do overlay em Flask

    O overlay é composto por componentes bem definidos. O agent card é construído dinamicamente e expõe as capacidades e skills do agente:

    A2A_API_URL = "http://localhost:5000/a2a"
    EXECUTE_TIMEOUT_SECONDS = 30
    
    _SKILLS_FILE = Path(__file__).parent / "skills.json"
    _SKILLS_CACHE: Optional[List[Dict[str, Any]]] = None
    
    def _load_skills() -> List[Dict[str, Any]]:
        global _SKILLS_CACHE
        if _SKILLS_CACHE is not None:
            return _SKILLS_CACHE
        try:
            with open(_SKILLS_FILE) as f:
                _SKILLS_CACHE = json.load(f)
                return _SKILLS_CACHE
        except FileNotFoundError:
            logger.error(f"Skills file not found: {_SKILLS_FILE}")
            return []
        except json.JSONDecodeError as e:
            logger.error(f"Invalid JSON in skills file: {e}")
            return []
    
    def build_agent_card(api_url: Optional[str] = None) -> Dict[str, Any]:
        if api_url is None:
            api_url = A2A_API_URL
        return {
            "name": "Calculator Agent",
            "description": "Simple calculator supporting basic arithmetic operations",
            "supportedInterfaces": [
                {"url": api_url, "protocolBinding": "JSONRPC", "protocolVersion": "0.3"},
            ],
            "provider": {"organization": "Example Organization", "url": ""},
            "version": "1.0.0",
            "capabilities": {
                "streaming": False,
                "pushNotifications": False,
                "extendedAgentCard": False,
            },
            "defaultInputModes": ["text/plain", "application/json"],
            "defaultOutputModes": ["text/plain", "application/json"],
            "skills": _load_skills(),
        }
    
    AGENT_CARD = build_agent_card()

    O chamador REST interno repassa autenticação e trata erros de rede:

    def invoke_rest_endpoint(
        endpoint: str,
        json_data: Optional[Dict] = None,
        http_method: str = "POST"
    ) -> Tuple[Optional[Dict], int]:
        try:
            base_url = request.host_url.rstrip("/")
            url = f"{base_url}{endpoint}"
            headers = {"Content-Type": "application/json"}
            auth_header = request.headers.get("Authorization")
            if auth_header:
                headers["Authorization"] = auth_header
            logger.info(f"Adapter: Delegating to REST {http_method} {url}")
            if http_method.upper() == "POST":
                response = http_requests.post(url, json=json_data, headers=headers, timeout=EXECUTE_TIMEOUT_SECONDS)
            elif http_method.upper() == "GET":
                response = http_requests.get(url, headers=headers, timeout=EXECUTE_TIMEOUT_SECONDS)
            else:
                response = http_requests.request(http_method, url, json=json_data, headers=headers, timeout=EXECUTE_TIMEOUT_SECONDS)
            logger.info(f"Adapter: REST returned {response.status_code}")
            return response.json(), response.status_code
        except http_requests.RequestException as e:
            logger.error(f"Adapter: Error calling REST endpoint: {e}", exc_info=True)
            return {"error": "Internal server error"}, 500

    A extração do payload da mensagem A2A e a construção da resposta seguem o formato da Spec 0.3:

    def extract_message_payload(message: Dict) -> Optional[Dict]:
        try:
            parts = message.get("parts", [])
            for part in parts:
                if isinstance(part, dict) and part.get("kind") == "data":
                    return part.get("data")
            return None
        except Exception as e:
            logger.error(f"Error extracting message payload: {e}")
            return None
    
    def build_a2a_message(message_id: str, context_id: str, content: Any) -> Dict:
        if isinstance(content, dict):
            parts = [{"kind": "data", "data": content}]
        else:
            parts = [{"kind": "text", "text": str(content)}]
        return {
            "messageId": message_id,
            "contextId": context_id,
            "role": "agent",
            "parts": parts,
            "kind": "message",
            "metadata": {}
        }

    Os construtores de resposta JSON-RPC seguem a especificação 2.0:

    class JsonRpcError:
        PARSE_ERROR = -32700
        INVALID_REQUEST = -32600
        METHOD_NOT_FOUND = -32601
        INVALID_PARAMS = -32602
        INTERNAL_ERROR = -32603
    
    def jsonrpc_error(code: int, message: str, data: Any = None, request_id: Any = None) -> Dict:
        response = {
            "jsonrpc": "2.0",
            "error": {"code": code, "message": message},
            "id": request_id
        }
        if data is not None:
            response["error"]["data"] = data
        return response
    
    def jsonrpc_success(result: Any, request_id: Any = None) -> Dict:
        return {
            "jsonrpc": "2.0",
            "result": result,
            "id": request_id
        }

    O handler do método SendMessage delega diretamente para o endpoint REST:

    def handle_send_message(data: Dict) -> Tuple[Any, int]:
        request_id = data.get("id")
        params = data.get("params", {})
        message = params.get("message", {})
        context_id = message.get("contextId") or generate_id()
        message_id = generate_id()
        payload = extract_message_payload(message)
        if not payload:
            return jsonify(jsonrpc_error(
                JsonRpcError.INVALID_PARAMS,
                "Invalid params: No data found in message.parts.",
                request_id=request_id
            )), 400
        rest_response, status = invoke_rest_endpoint(
            endpoint="/api/v1/calculate",
            json_data=payload,
            http_method="POST"
        )
        if 200 <= status < 300:
            a2a_message = build_a2a_message(message_id, context_id, rest_response)
            return jsonify(jsonrpc_success(a2a_message, request_id)), 200
        else:
            error_message = "Operation failed"
            if isinstance(rest_response, dict):
                error_message = (rest_response.get("error") or rest_response.get("details") or "Operation failed")
            error_code = (JsonRpcError.INVALID_PARAMS if 400 <= status < 500 else JsonRpcError.INTERNAL_ERROR)
            return jsonify(jsonrpc_error(
                error_code,
                error_message,
                data=rest_response,
                request_id=request_id
            )), status
    
    def generate_id() -> str:
        return str(uuid.uuid4())

    As rotas A2A são registradas na aplicação Flask:

    def setup_a2a_routes(app: Flask) -> None:
        app.add_url_rule("/.well-known/agent-card.json", "get_agent_card", get_agent_card, methods=["GET"])
        app.add_url_rule("/a2a/capabilities", "get_capabilities", get_capabilities, methods=["GET"])
        app.add_url_rule("/a2a/health", "a2a_health", a2a_health, methods=["GET"])
        app.add_url_rule("/a2a", "a2a_jsonrpc", _handle_jsonrpc, methods=["POST"])
        logger.info("A2A Protocol v0.3 routes registered")

    E a inicialização da aplicação une as duas partes:

    # app/main.py
    from flask import Flask
    from app.rest_api import rest_api
    from app.a2a_adapter import setup_a2a_routes
    
    def create_app():
        app = Flask(__name__)
        app.register_blueprint(rest_api)
        setup_a2a_routes(app)
        app.logger.info("A2A Protocol enabled via Request Translator Pattern")
        return app

    Para rodar a aplicação:

    python -m venv venv
    source venv/bin/activate  # On Windows: venv\Scripts\activate
    pip install -r requirements.txt
    python -m app.main

    Escala corporativa com Amazon Bedrock AgentCore Gateway

    Para cenários de maior escala, a AWS apresenta o Amazon Bedrock AgentCore como alternativa para desacoplar o overlay da aplicação. O AgentCore Runtime atua como ponto de acesso único para endpoints e serviços, permitindo que um único overlay agêntico sirva múltiplos serviços — não apenas um.

    O AgentCore Gateway suporta até 10 targets por gateway, com integração nativa a serviços AWS e suporte a endpoints OpenAPI. Isso é especialmente útil em aplicações corporativas que orquestram múltiplos serviços para tarefas complexas: em vez de adicionar um overlay a cada serviço individualmente, é possível unir vários serviços em um único overlay que orquestra as chamadas conforme necessário.

    Além do Gateway, o ecossistema AgentCore oferece:

    • AgentCore Identity: gerencia autenticação para componentes de agente e gateway, com suporte a provedores OAuth 2.0 e integrações gerenciadas para Okta, GitHub e Slack.
    • AgentCore Observability: monitora a performance dos agentes por meio de métricas, logs e visualizações de span. Permite visualizar dados de alto nível como chamadas de ferramentas e latência, ou inspecionar caminhos de execução granulares entre componentes, com integração nativa ao Amazon CloudWatch.
    • AgentCore Runtime: realiza o deploy de modelos via imagem de container — sejam open-source, customizados ou Modelos de Linguagem de Grande Escala (LLMs) do Amazon Bedrock como Nova e Anthropic Claude — sem exigir que o time gerencie a infraestrutura de LLM.

    Próximos passos recomendados

    A AWS sugere três ações práticas para quem quer explorar esse padrão:

    • Avalie sua arquitetura: faça um levantamento dos serviços REST candidatos à habilitação A2A. Overlays dentro da aplicação são indicados para agentes de serviço único; o AgentCore Gateway é mais adequado para fluxos multi-serviço.
    • Revise a implementação de referência: o exemplo da calculadora em Flask demonstra o padrão de tradução com configuração do agent card, extração de mensagens, invocação REST e construção de respostas.
    • Explore o Amazon Bedrock AgentCore: Gateway, Identity e Observability oferecem infraestrutura para overlays agênticos em produção. A especificação e a documentação do SDK do protocolo A2A estão disponíveis em a2a-protocol.org, com bibliotecas para Flask, FastAPI e Starlette.

    Conclusão

    O padrão de agentic overlay oferece às empresas um caminho pragmático para adotar comunicação Agent-to-Agent sem abandonar os investimentos em APIs REST. A ideia central é simples e poderosa: o A2A não é uma nova API — é uma nova interface para a API que já existe. Essa perspectiva muda o desafio de reconstruir tudo para uma modernização incremental, permitindo que as organizações capturem valor de IA mais rapidamente enquanto gerenciam riscos de forma eficaz.

    Fonte

    Retrofit, don’t rebuild: Agentic overlays for transforming legacy enterprise services (https://aws.amazon.com/blogs/machine-learning/retrofit-dont-rebuild-agentic-overlays-for-transforming-legacy-enterprise-services/)

  • Modelos OpenAI GPT e NVIDIA Nemotron no Amazon Bedrock recebem aprovação FedRAMP High e DoD IL-4/5 no AWS GovCloud (US)

    O que foi anunciado

    A AWS anunciou que os modelos OpenAI GPT, OpenAI GPT OSS e NVIDIA Nemotron, disponíveis no Amazon Bedrock, receberam aprovação para os padrões FedRAMP High e Guia de Requisitos de Segurança de Computação em Nuvem do Departamento de Defesa dos Estados Unidos (DoD CC SRG) nos níveis de impacto (IL) 4 e 5 — e tudo isso dentro das regiões do AWS GovCloud (US).

    Essa é uma movimentação relevante para o mercado de inteligência artificial generativa voltado ao setor público norte-americano. Com essa certificação, agências federais, organizações do setor público e empresas que precisam atender às exigências de conformidade FedRAMP High e DoD CC SRG IL-4/5 passam a ter acesso oficial e aprovado a esses modelos dentro do Amazon Bedrock.

    O que isso significa na prática

    Para quem atua no setor governamental ou em projetos que exigem conformidade rigorosa com padrões de segurança norte-americanos, essa aprovação representa um passo importante. Significa que é possível construir e escalar aplicações de IA generativa usando esses modelos com a garantia de que eles atendem aos padrões de segurança e conformidade exigidos para cargas de trabalho governamentais.

    Em outras palavras: as equipes não precisam mais abrir mão de modelos de ponta como os da OpenAI e da NVIDIA para manter a conformidade com as exigências do governo dos EUA. Agora é possível usar os dois ao mesmo tempo.

    A tecnologia por trás: o Mantle

    Vale destacar que esses modelos são executados com suporte do Mantle, descrito pela AWS como um mecanismo de inferência distribuída de nova geração dentro do Amazon Bedrock. O Mantle oferece:

    • Inferência serverless de alto desempenho
    • Zero acesso por operadores (reforço de isolamento e segurança)
    • Gerenciamento automatizado de capacidade
    • Compatibilidade nativa com as especificações da API da OpenAI

    Esse conjunto de características é especialmente relevante no contexto governamental, onde o controle de acesso e o isolamento de dados são requisitos críticos.

    Para quem é relevante

    Embora o anúncio seja voltado ao contexto regulatório dos Estados Unidos, ele é importante para profissionais e empresas brasileiras que:

    • Prestam serviços ou têm operações em território norte-americano sujeitas a regulamentações federais
    • Desenvolvem soluções para clientes do setor público dos EUA
    • Acompanham o avanço da conformidade regulatória em IA como referência para outros mercados

    Saiba mais

    Para se aprofundar no tema, a AWS disponibiliza recursos de consulta: a página do produto Amazon Bedrock, a documentação do Amazon Bedrock e a página de conformidade do AWS GovCloud (US) são os pontos de partida recomendados.

    Fonte

    OpenAI GPT, OpenAI GPT OSS, and NVIDIA Nemotron models on Amazon Bedrock receive FedRAMP High and DoD IL-4/5 approval in AWS GovCloud (US) (https://aws.amazon.com/about-aws/whats-new/2026/06/addl-bedrock-model-fedramp-il-5-govcloud)

  • Amazon EC2 anuncia AMI Watermarks para melhor governança de imagens

    O que são os AMI Watermarks?

    A AWS anunciou o lançamento dos AMI Watermarks (Marcas d’água de AMI), um novo recurso do Amazon EC2 voltado para melhorar a rastreabilidade e a governança de Imagens de Máquina da Amazon (AMI — Amazon Machine Image). A proposta é simples e poderosa: você pode incorporar identificadores personalizados diretamente em suas AMIs privadas, criando uma cadeia de confiança que persiste independentemente de quantas cópias ou derivações sejam feitas a partir da imagem original.

    Como funciona a propagação das marcas

    Um dos pontos mais relevantes do recurso é o comportamento automático de propagação. Uma vez que uma marca d’água é aplicada a uma AMI, ela se mantém presente em todas as imagens derivadas — seja ao copiar a AMI para outra região, seja ao criar uma nova AMI a partir de uma instância em execução. As marcas também permanecem visíveis quando a AMI é compartilhada com outras contas AWS.

    Cada marca d’água carrega metadados como: ID da AMI, ID do proprietário, região e timestamps de criação. Essas informações formam uma trilha de proveniência confiável que não se perde ao longo do ciclo de vida da imagem.

    Benefícios para rastreamento e governança

    Com os AMI Watermarks, as equipes ganham a capacidade de filtrar e localizar AMIs relacionadas entre diferentes contas, facilitando o gerenciamento em ambientes multi-conta. Do ponto de vista de governança, o recurso se torna ainda mais poderoso quando combinado com as AMIs Permitidas (Allowed AMIs): é possível restringir o lançamento de instâncias apenas para AMIs que carreguem marcas d’água aprovadas, garantindo que somente imagens confiáveis sejam utilizadas na organização. Essa restrição pode ser aplicada em escala por meio de Políticas Declarativas (Declarative Policies).

    Como começar a usar

    A AWS disponibilizou o recurso para uso imediato. As marcas d’água podem ser adicionadas a AMIs privadas pelo Console de Gerenciamento da AWS, pela Interface de Linha de Comando (AWS CLI) ou por meio dos Kits de Desenvolvimento de Software (SDKs). Para mais detalhes técnicos, a AWS disponibilizou a documentação oficial do recurso.

    Também é possível incorporar as marcas d’água durante o processo de construção de imagens por meio do EC2 Image Builder, serviço dedicado à criação e ao gerenciamento de AMIs, integrando o recurso diretamente ao pipeline de build.

    Disponibilidade e custos

    Os AMI Watermarks estão disponíveis para todos os clientes AWS sem custo adicional, em todas as regiões AWS — incluindo as regiões da China (Beijing, operada pela Sinnet, e Ningxia, operada pela NWCD) e as regiões AWS GovCloud (EUA).

    Fonte

    Amazon EC2 announces AMI Watermarks for improved AMI governance (https://aws.amazon.com/about-aws/whats-new/2026/06/ec2-image-watermarks-allowed-images)

  • AWS IoT Device SDK para Swift está disponível para uso em produção

    O que foi anunciado

    A AWS anunciou a disponibilidade geral do AWS IoT Device SDK para Swift, uma novidade relevante para times de desenvolvimento que trabalham com o ecossistema Apple. A partir de agora, desenvolvedores Swift podem construir aplicações IoT seguras e escaláveis de forma nativa em plataformas como macOS, iOS e tvOS, além do Linux.

    Antes desse lançamento, havia uma lacuna importante: não existia suporte nativo à linguagem Swift para os serviços de Tecnologia de Internet das Coisas (IoT) da AWS. Esse SDK chega para preencher exatamente esse espaço, oferecendo APIs estáveis e prontas para produção, pensadas especialmente para times que gerenciam frotas de dispositivos IoT e precisam de soluções que funcionem de forma consistente em todo o ecossistema Apple.

    Principais capacidades do SDK

    O SDK entrega um conjunto abrangente de funcionalidades para gerenciamento de dispositivos em tempo real e comunicação segura. Veja os destaques:

    • AWS IoT Device Shadow: permite sincronizar o estado dos dispositivos entre as aplicações e o AWS IoT Core, mantendo consistência mesmo quando o dispositivo está offline.
    • AWS IoT Jobs: possibilita gerenciar operações remotas em dispositivos conectados em escala, facilitando atualizações e tarefas programadas.
    • AWS IoT Fleet Provisioning: automatiza a criação de certificados e políticas para o cadastramento seguro de novos dispositivos na frota.
    • Segurança de Camada de Transporte 1.3 (TLS 1.3) integrado: garante que as aplicações IoT em iOS e tvOS utilizem o padrão de segurança mais recente da indústria para proteger os dados em trânsito.

    Por que isso importa para desenvolvedores brasileiros

    Times que desenvolvem produtos conectados para o ecossistema Apple — seja um app iOS que se comunica com sensores, um painel macOS para monitoramento de dispositivos ou soluções embarcadas em Linux — agora contam com um SDK oficial, estável e mantido pela AWS. Isso reduz a necessidade de gambiarras ou bibliotecas de terceiros para integrar dispositivos ao AWS IoT Core usando Swift.

    A inclusão do TLS 1.3 nativo para iOS e tvOS é um ponto que merece atenção: significa que a camada de segurança já vem configurada segundo as melhores práticas do setor, sem exigir configurações adicionais do desenvolvedor.

    Como começar

    A instalação do SDK é feita diretamente pelo Swift Package Manager, o gerenciador de pacotes nativo da linguagem Swift. Para quem quer explorar mais, a AWS disponibiliza a documentação oficial do AWS IoT Device SDK e também exemplos de código no GitHub para acelerar o aprendizado e a implementação.

    Fonte

    AWS IoT Device SDK for Swift is now generally available (https://aws.amazon.com/about-aws/whats-new/2026/06/aws-iot-device-sdk-swift/)

  • Como construir um agente de agendamento médico com Amazon Nova 2 Sonic

    O problema das consultas não realizadas

    Quem trabalha com gestão de clínicas ou redes hospitalares conhece bem o impacto das faltas não avisadas. A taxa média de ausências no sistema de saúde americano varia entre 5% e 30%, dependendo da especialidade. Cada horário vazio representa receita perdida, tempo ocioso do profissional de saúde e atraso no atendimento ao paciente.

    A solução tradicional — ligar para cada paciente individualmente para confirmar ou reagendar — simplesmente não escala. É aí que entra a proposta da AWS: um agente de voz baseado em Inteligência Artificial (IA) capaz de conduzir essas conversas de forma autônoma e natural.

    A AWS publicou um tutorial detalhado mostrando como construir esse tipo de solução usando o Amazon Nova 2 Sonic em conjunto com o Amazon Bedrock AgentCore. O resultado é um agente que autentica pacientes por voz, gerencia agendamentos (confirmar, cancelar ou reagendar), coleta informações de saúde pré-consulta e escala para atendimento humano quando necessário.

    Vale destacar que o tutorial foca no lado conversacional e de orquestração de ferramentas. Para conectar o agente a linhas telefônicas reais para discagem ativa, seria necessário integrar um serviço de telefonia como o Amazon Connect.

    Por que o Amazon Nova 2 Sonic muda a abordagem

    A abordagem convencional para agentes de voz encadeia três serviços separados: um modelo de transcrição converte a fala em texto, um Modelo de Linguagem de Grande Escala (LLM) gera a resposta, e um modelo de síntese de voz lê o texto em voz alta. Cada transferência entre etapas introduz latência e perde contexto — especialmente os sinais vocais como tom, hesitação e urgência.

    No contexto da saúde, isso importa. A ansiedade ou confusão de um paciente deveria influenciar como o agente responde. Com a abordagem encadeada tradicional, o LLM só sabe o que o paciente disse, não como disse.

    O Amazon Nova 2 Sonic resolve isso com processamento de voz nativo em um único modelo, disponível no Amazon Bedrock. Em vez de transcrever e depois raciocinar, o modelo processa a fala diretamente, preservando o contexto vocal ao longo de toda a conversa. Para mais detalhes sobre como o Nova 2 Sonic processa fala e se adapta ao contexto acústico, a AWS publicou o post Introducing Amazon Nova Sonic.

    As principais capacidades do modelo relevantes para esse caso de uso são:

    • Processamento nativo de voz para voz, sem perda de nuances entre turnos de conversa
    • Precisão na chamada de ferramentas para manter fluxos de trabalho complexos em saúde no trilho certo
    • Streaming bidirecional de baixa latência para conversas responsivas
    • Resistência a ruídos de fundo comuns em ambientes domésticos e clínicos, incluindo sotaques em inglês
    • Suporte multilíngue com troca de idioma no meio da conversa, sem necessidade de reconfiguração — consulte a documentação do Amazon Nova 2 Sonic para os idiomas suportados

    Arquitetura da solução

    A solução completa combina os seguintes componentes:

    • Um frontend React que captura o áudio do microfone no navegador e transmite via WebSocket
    • Autenticação de usuários via Amazon Cognito, que emite credenciais temporárias AWS e assina cada requisição com o protocolo SigV4
    • Amazon Bedrock AgentCore Runtime hospedando o agente em container, gerenciando infraestrutura e escalabilidade
    • O Amazon Nova 2 Sonic recebendo o áudio, raciocínando sobre a conversa, invocando ferramentas quando necessário e gerando respostas em áudio
    • Três tabelas no Amazon DynamoDB armazenando registros de pacientes, detalhes de agendamentos e horários disponíveis
    • O Serviço de Notificação Simples da Amazon (Amazon SNS) publicando notificações de escalonamento quando um paciente solicita falar com um humano

    O Strands Agents SDK gerencia a complexidade do streaming bidirecional de voz. Toda a configuração do agente cabe em poucas linhas de código:

    from strands.experimental.bidi import BidiAgent
    from strands.experimental.bidi.models import BidiNovaSonicModel
    
    model = BidiNovaSonicModel(
        region="us-east-1",
        model_id="amazon.nova-2-sonic-v1:0",
        provider_config={
            "audio": {
                "input_sample_rate": 16000,
                "output_sample_rate": 16000,
                "voice": "tiffany",
            }
        },
        tools=tools,  # The seven healthcare tools listed below
    )
    
    agent = BidiAgent(
        model=model,
        tools=tools,
        system_prompt=system_prompt,
    )
    
    # In the WebSocket handler, connect inputs and outputs
    await agent.run(
        inputs=[receive_audio],
        outputs=[send_audio],
    )

    As sete ferramentas de saúde

    O agente de voz utiliza sete ferramentas para conduzir cada ligação. Cada ferramenta é implementada como uma função Python decorada com o @tool do Strands Agents SDK. O Nova 2 Sonic decide quando invocar cada ferramenta com base no que o paciente diz. Por exemplo, quando um paciente pede para reagendar, o modelo chama find_available_slots para consultar o DynamoDB, apresenta as opções por voz e então chama book_appointment_slot para finalizar a mudança.

    • authenticate_patient: Verifica a identidade usando nome, sobrenome e os quatro últimos dígitos do CPF/SSN. Consulta a tabela de Pacientes no DynamoDB via um Índice Secundário Global (GSI). Aplica limite de três tentativas por combinação de nome.
    • confirm_appointment: Confirma um agendamento existente, atualizando o status de “Agendado” ou “Reagendado” para “Confirmado” no DynamoDB, com verificações para evitar confirmações duplicadas.
    • cancel_appointment: Cancela um agendamento com motivo opcional, atualizando o status para “Cancelado” com nota com registro de data/hora.
    • find_available_slots: Consulta horários disponíveis para reagendamento, retornando até três opções para manter a conversa por voz concisa.
    • book_appointment_slot: Reserva um horário selecionado usando gravações condicionais no DynamoDB para evitar dupla reserva sob requisições concorrentes.
    • record_health_update: Captura informações de saúde pré-consulta, coletando condições médicas, alergias, acompanhante e preocupações específicas — uma pergunta por vez.
    • escalate_to_agent: Sinaliza a ligação para retorno humano, gerando um número de referência de seis dígitos e publicando uma mensagem no Amazon SNS com as informações do paciente.

    Esse design baseado em ferramentas permite trocar ou estender capacidades individualmente sem reescrever o restante do agente. Para adicionar uma nova funcionalidade (por exemplo, coletar informações de convênio), basta escrever uma nova função @tool e atualizar o system prompt do agente.

    Como o agente conduz uma ligação

    Quando o agente se conecta a um paciente, o BidiAgent gerencia a conversa completa em quatro fases:

    Autenticação

    O Nova 2 Sonic cumprimenta o paciente e solicita nome completo e os quatro últimos dígitos do número de identificação. Antes de verificar, o agente repete o que entendeu e pede confirmação — o que ajuda a capturar erros de reconhecimento de fala em nomes ou dígitos. Se a verificação falhar após três tentativas, o agente escala para um humano por segurança.

    Gerenciamento do agendamento

    Após a verificação, o Nova 2 Sonic apresenta os detalhes do próximo agendamento, incluindo nome do profissional, data e horário. O paciente escolhe confirmar, cancelar ou reagendar. Se optar por reagendar, o agente coleta preferências (manhã ou tarde, datas preferidas), consulta os horários disponíveis, apresenta até três opções e reserva o novo horário.

    Coleta de informações de saúde

    Para agendamentos confirmados ou reagendados, o agente coleta informações pré-consulta: condições médicas existentes, alergias, se haverá acompanhante e preocupações específicas para a consulta. Cada pergunta é feita individualmente para um fluxo de conversa natural.

    Escalonamento

    Em qualquer momento, se o paciente pedir para falar com um humano, o agente registra o motivo, gera um número de referência de seis dígitos e publica uma notificação via Amazon SNS para que a equipe retorne a ligação em até 24 horas.

    Implantando o agente

    O código-fonte completo está disponível no repositório GitHub. Os pré-requisitos para o deploy são:

    Passo 1: Clonar o repositório

    git clone https://github.com/aws-samples/sample-Nova-Sonic-AgentCore-Healthcare-Call-Center.git
    cd sample-Nova-Sonic-AgentCore-Healthcare-Call-Center

    Passo 2: Implantar a infraestrutura

    O stack do AWS CDK provisiona todos os recursos necessários: pools de usuário e identidade do Cognito, tabelas DynamoDB, um tópico Amazon SNS e o AgentCore Runtime com o agente em container.

    cd infrastructure
    python3 -m venv .venv
    source .venv/bin/activate
    pip install -r requirements.txt
    cdk deploy --require-approval never

    Ao final do deploy, anote os outputs do AWS CloudFormation: o ID do User Pool do Cognito, o Client ID, o Identity Pool ID e o ARN do AgentCore Runtime — esses valores são necessários para configurar o frontend.

    Passo 3: Criar um usuário de teste

    aws cognito-idp admin-create-user \
      --user-pool-id <UserPoolId> \
      --username testuser \
      --temporary-password TempPass123!
    
    aws cognito-idp admin-set-user-password \
      --user-pool-id <UserPoolId> \
      --username testuser \
      --password <YourSecurePassword> \
      --permanent

    Passo 4: Configurar e executar o frontend

    cd ../frontend
    npm install
    cp .env.example .env
    # Edit .env with your CDK output values
    npm run dev

    Abra http://localhost:5173 no navegador, faça login com o usuário de teste, escolha um paciente no menu e clique em “Start Call” para iniciar uma conversa por voz.

    Passo 5: Inserir dados de demonstração

    O stack do CDK já insere registros de pacientes de exemplo automaticamente durante o deploy. Se precisar reinserir ou personalizar os dados, execute:

    python3 scripts/seed_data.py

    Para testes, os pacientes pré-configurados são:

    • John Smith — últimos 4 dígitos: 1234
    • Jane Doe — últimos 4 dígitos: 5678
    • Michael Johnson — últimos 4 dígitos: 9012

    Exemplo de conversa

    O tutorial traz uma transcrição de uma interação completa de reagendamento, onde o agente autentica o paciente, encontra um novo horário, reserva e coleta informações de saúde pré-consulta. Veja o demo completo no YouTube.

    Agente: “Olá, aqui é Nova da Acme Healthcare. Estou ligando sobre sua próxima consulta. Para verificação, poderia me informar seu nome completo e os quatro últimos dígitos do seu CPF?”

    Paciente: “John Smith, 1234.”

    Agente: “Deixa eu confirmar: ouvi John Smith, um, dois, três, quatro. Está correto?”

    Paciente: “Sim, está certo.”

    Agente: “Obrigado pela verificação. Estou ligando sobre sua Consulta Anual com o Dr. Johnson agendada para 14 de junho às 16h30. Gostaria de confirmar esta consulta?”

    Paciente: “Na verdade, preciso reagendar.”

    Agente: “Fico feliz em ajudar. Você prefere manhã ou tarde?”

    Paciente: “Manhã é melhor.”

    Agente: “Encontrei estes horários matutinos com o Dr. Johnson: terça-feira, 1º de julho às 9h, ou quinta-feira, 3 de julho às 10h30. Qual funciona para você?”

    Paciente: “Terça às 9h.”

    Agente: “Reagendei sua consulta. Antes de finalizar, gostaria de coletar algumas informações para ajudar o Dr. Johnson a se preparar. Você tem alguma condição médica existente que devemos saber?”

    Paciente: “Tenho pressão alta.”

    Agente: “Obrigado. Você tem alguma alergia?”

    Paciente: “Sou alérgico à penicilina.”

    Agente: “Anotado. Alguma preocupação específica para esta consulta?”

    Paciente: “Tenho sentido dores no joelho.”

    Agente: “Documentei tudo para o Dr. Johnson. Sua consulta está confirmada para terça-feira, 1º de julho às 9h. Tenha um ótimo dia!”

    Suporte multilíngue e considerações importantes

    O Nova 2 Sonic detecta e muda para o idioma preferido do paciente no meio da conversa, sem necessidade de qualquer reconfiguração. Demos em espanhol e hindi estão disponíveis no repositório GitHub.

    É importante destacar que este projeto é uma implementação de referência para fins de demonstração. O Amazon Nova Sonic não foi projetado para fornecer opiniões ou conselhos, incluindo médicos, jurídicos ou financeiros, e não deve ser usado como substituto para julgamento clínico. Implantações em produção que lidam com Informações de Saúde Protegidas (PHI) exigem revisão de conformidade com HIPAA, um Acordo de Parceiro de Negócios (BAA) executado com a AWS e revisões de segurança e clínicas adequadas ao caso de uso.

    Limpeza dos recursos

    Para evitar cobranças contínuas, delete os recursos ao terminar os testes:

    cd infrastructure
    cdk destroy --force

    O comando cdk destroy pode não remover todos os grupos de log do Amazon CloudWatch. Verifique o console do CloudWatch por grupos de log remanescentes criados durante este deploy e delete-os manualmente.

    Conclusão

    A AWS demonstrou como é possível construir um agente de voz robusto para lembretes de consultas médicas combinando o Amazon Nova 2 Sonic com o Amazon Bedrock AgentCore. A arquitetura é serverless, usa ferramentas modulares e pode ser adaptada para outros setores que lidam com alto volume de ligações — como varejo ou hotelaria — simplesmente substituindo as ferramentas de saúde pela lógica do domínio desejado.

    Para quem quiser explorar a solução, o próximo passo é clonar o repositório e implantar o agente na própria conta AWS seguindo os passos descritos acima. O README do projeto cobre personalização, prontidão para produção e considerações de conformidade.

    Fonte

    Build a healthcare appointment agent with Amazon Nova 2 Sonic (https://aws.amazon.com/blogs/machine-learning/build-a-healthcare-appointment-agent-with-amazon-nova-2-sonic/)

  • BI com Inteligência Artificial usando Snowflake e Amazon QuickSight

    O problema que todo time de dados conhece bem

    Um dashboard mostra 42.000 visualizações ativas de filmes. Outro exibe 38.500. E o agente de chat cita um terceiro número completamente diferente. Times de dados perdem horas reconciliando métricas em vez de responder perguntas estratégicas — e a confiança na análise vai por água abaixo.

    Esse padrão é mais comum do que parece. A causa raiz costuma ser o que se chama de last-mile gap: a lógica de negócio fica dentro de cada aplicação individualmente, em vez de residir na camada de dados, onde todos os sistemas poderiam compartilhá-la.

    A AWS publicou um tutorial detalhado mostrando como resolver esse problema combinando as Semantic Views do Snowflake com o Amazon QuickSight. A ideia central é simples: centralizar as definições de negócio na camada de dados para que tanto sistemas de BI quanto de IA consultem as mesmas regras.

    O que é uma Semantic View no Snowflake

    Uma Semantic View é um objeto de schema nativo do Snowflake que anexa definições de negócio diretamente aos dados — tabelas, relacionamentos, métricas e dimensões. Qualquer aplicação que consulte essa view herda automaticamente as mesmas definições. O resultado prático: sistemas de BI e IA interpretam as informações de forma uniforme, o que aumenta a confiabilidade das respostas e reduz significativamente o risco de alucinações em modelos de linguagem.

    As Semantic Views podem ser usadas no Cortex Analyst e consultadas diretamente via SELECT. Elas também podem ser compartilhadas em listagens privadas do Snowflake. Por serem objetos nativos de schema, têm controles de acesso no nível do objeto — é possível conceder ou restringir permissões de uso e consulta da mesma forma que se faz com tabelas e views comuns. Para aprender a escrever Semantic SQL, a documentação oficial do Snowflake tem exemplos detalhados.

    Arquitetura da solução

    A integração funciona da seguinte forma: dados estruturados são ingeridos do Amazon Simple Storage Service (S3) para o Snowflake. Em cima desses dados, define-se uma Semantic View com SQL, adicionando relacionamentos, dimensões e métricas. A partir daí, tanto o Cortex Analyst (para consultas em linguagem natural) quanto o Amazon QuickSight (para dashboards interativos) consultam essa mesma camada semântica.

    O ponto-chave da arquitetura é que o modelo semântico sai das camadas individuais de BI ou IA e passa a viver na plataforma central de dados. Todas as ferramentas passam a usar os mesmos conceitos semânticos, eliminando divergências.

    Pré-requisitos para o tutorial

    Antes de começar, é necessário ter em mãos:

    • Conta Snowflake Enterprise na AWS. Quem não tiver pode criar uma conta trial do Snowflake selecionando a opção Enterprise na AWS.
    • Acesso com a role ACCOUNTADMIN no Snowflake — necessária para criar Semantic Views e conceder privilégios.
    • Conta na AWS. Quem não tiver pode criar uma conta AWS.
    • Alinhamento de região: ambas as contas devem estar em US West (Oregon) ou US East (N. Virginia). O Amazon QuickSight também está disponível em Asia Pacific (Sydney) e Europe (Ireland). Consulte a documentação do Amazon QuickSight para disponibilidade regional atualizada.
    • Familiaridade básica com SQL e Python.

    O tutorial leva entre 60 e 90 minutos para ser concluído do início ao fim. O custo estimado é inferior a US$ 10 combinando AWS e Snowflake.

    Passo a passo da integração

    Passo 1: Configurar o ambiente Snowflake e carregar os dados

    O tutorial usa o Snowsight, a interface web do Snowflake, para importar e executar um notebook pré-construído. O notebook cria automaticamente o warehouse de computação, o banco de dados e o schema, além de carregar os dados de avaliações de filmes — sem necessidade de executar SQL manualmente.

    O notebook SF_Quick_Quickstart.ipynb está disponível no repositório GitHub do projeto. Após importá-lo no Snowsight, basta executar todas as células em sequência. O notebook provisiona o warehouse WORKSHOPWH e carrega os dados no banco MOVIES. Ao final, devem aparecer três tabelas no schema MOVIES.PUBLIC: MOVIES, USERS e RATINGS.

    Se alguma célula falhar, vale verificar se a role ativa é ACCOUNTADMIN. Isso pode ser definido com o comando:

    USE ROLE ACCOUNTADMIN;

    Passo 2: Definir a Semantic View e exportar o DDL

    Após a execução bem-sucedida de todas as células, é necessário localizar a célula Get_SV_DDL no notebook. Ela executa o seguinte SQL para recuperar o DDL (Linguagem de Definição de Dados) da Semantic View:

    SELECT TO_VARCHAR(GET_DDL(
      'SEMANTIC_VIEW',
      'MOVIES.PUBLIC.MOVIE_ANALYTICS_SV'
    ));

    Após executar essa célula, é preciso baixar o resultado como CSV e salvar o arquivo como SF_DDL.csv. Esse arquivo será necessário no Passo 4 para gerar automaticamente o dataset no QuickSight. Sem ele, o script gerador não consegue interpretar o schema.

    Passo 3: Explorar os dados com o Cortex Analyst

    Com a Semantic View criada, já é possível consultar os dados em linguagem natural — sem escrever SQL. Essa etapa serve para verificar se a camada semântica está funcionando corretamente antes de conectar o QuickSight.

    No Snowsight, basta acessar a seção AI & ML e navegar até a Semantic View MOVIES_ANALYST_SV. Uma prática recomendada é adicionar verified queries — perguntas de exemplo com respostas confirmadas como corretas. Elas servem de referência para o Cortex Analyst ao responder perguntas formuladas de maneira similar, melhorando a precisão e reduzindo a latência das consultas.

    Exemplos de perguntas para testar:

    • “Show me the total rating values by movie title”
    • “List the top 10 most popular movies of all time”

    Para quem quiser consultar a Semantic View diretamente via SQL, a documentação do Snowflake traz exemplos de consultas em Semantic Views.

    Passo 4: Criar o dataset no Amazon QuickSight

    Com os dados semanticamente definidos no Snowflake, o próximo passo é conectá-los ao QuickSight. O tutorial oferece duas opções para isso:

    Opção 1 — Executar o pacote Python localmente: baixe a solução completa do repositório GitHub e siga as instruções do README.md para conectar ao Snowflake, buscar a definição da Semantic View, converter essa definição em schema do QuickSight e criar o dataset. Os scripts Python são interativos e guiam o usuário pelo processo.

    Opção 2 — Executar os scripts no AWS CloudShell: baixe o arquivo Solution_Package.zip do repositório GitHub, abra o console da AWS e acesse o AWS CloudShell. Faça o upload do arquivo pelo menu Actions → Upload file.

    Em seguida, execute os passos na seguinte ordem:

    Descompactar e entrar no diretório:

    unzip Solution_Package.zip
    cd Solution_Package

    Fazer o upload do arquivo SF_DDL.csv gerado no Passo 2, criar um secret na AWS para armazenar as credenciais do Snowflake:

    python create_secret.py

    E então executar o workflow interativo:

    python run_workflow.py

    O script guia o usuário pela seleção ou criação de uma fonte de dados Snowflake, configuração do dataset, parsing do SF_DDL.csv, criação do dataset com ingestão SPICE e monitoramento do progresso até a conclusão.

    Passo 5: Construir o dashboard no Amazon QuickSight

    Após a conclusão da ingestão, basta acessar o console do Amazon QuickSight, navegar até Datasets, selecionar o movie-analytics-dataset e escolher Create analysis.

    O QuickSight permite fazer perguntas em linguagem natural e gera visualizações automaticamente. Exemplos de perguntas para explorar:

    • “Show me the highest-rated movies” — gera um gráfico de barras com filmes por nota média
    • “What are the top 10 most-reviewed movies?” — exibe uma lista ranqueada por volume de avaliações
    • “How do ratings distribute across genres?” — produz uma análise por gênero
    • “Show me the trend of ratings over time” — cria um gráfico de linha com a atividade de avaliações ao longo do tempo
    • “Which users have submitted the most reviews?” — destaca os avaliadores mais ativos

    Como a Semantic View já define as métricas e dimensões centrais, é possível criar campos calculados no QuickSight que se constroem sobre essas definições governadas. Um exemplo prático: criar um campo rating_category com a fórmula:

    ifelse({user_rating} >= 4, 'High', {user_rating} >= 2.5, 'Medium', 'Low')

    Esse campo pode ser usado para segmentar visualizações — por exemplo, um gráfico de pizza mostrando a proporção de avaliações High, Medium e Low.

    Validando a consistência entre as ferramentas

    Uma etapa importante do tutorial é verificar se os números batem entre o Cortex Analyst e o QuickSight. Para isso, basta fazer a mesma pergunta nas duas ferramentas — por exemplo, “What is the average rating for the top 5 most-reviewed movies?” — e confirmar que os valores são idênticos. Se houver divergências, vale checar se há filtros adicionais ou regras de segurança em nível de linha aplicados em apenas uma das ferramentas, e se ambas estão usando a mesma lógica de agregação.

    Essa validação cruzada reforça a proposta central da solução: uma única camada semântica que entrega respostas consistentes independentemente da ferramenta que está fazendo a pergunta.

    Limpeza dos recursos

    Após o tutorial, recomenda-se remover os recursos criados para evitar custos desnecessários.

    No Snowflake:

    DROP DATABASE IF EXISTS ;
    
    -- Boa prática: suspender primeiro para aguardar queries em andamento
    ALTER WAREHOUSE IF EXISTS  SUSPEND;
    DROP WAREHOUSE IF EXISTS ;

    Na AWS: remover os secrets no AWS Secrets Manager, deletar os datasets e fontes de dados no QuickSight, e excluir análises e dashboards pelo console.

    Próximos passos sugeridos

    O tutorial apresenta uma base funcional que pode ser expandida de várias formas:

    • Ampliar a Semantic View: adicionar mais métricas, dimensões ou verified queries para cobrir novas perguntas de negócio.
    • Aplicar o padrão aos seus próprios dados: substituir o dataset de filmes pelos dados da sua organização no Amazon S3. O mesmo notebook e workflow de geração se aplicam a qualquer dataset tabular.
    • Compartilhar Semantic Views entre times: por serem objetos nativos do Snowflake com controles de acesso, as Semantic Views podem ser distribuídas para outras contas via Snowflake Data Sharing em listagens privadas.
    • Explorar recursos avançados do QuickSight: campos calculados, data stories e análises what-if para aprofundar os insights habilitados pela camada semântica.
    • Conhecer os padrões abertos: o Snowflake lidera a iniciativa Open Semantic Interchange (OSI), uma colaboração para criar um padrão vendor-agnostic para dados semânticos.

    Fonte

    AI-powered BI with Snowflake and Amazon Quick (https://aws.amazon.com/blogs/machine-learning/ai-powered-bi-with-snowflake-and-amazon-quick/)

  • Infraestrutura compartilhada, tenants isolados: multi-tenancy com Amazon Bedrock AgentCore

    O desafio do multi-tenancy em aplicações de IA

    Construir aplicações de IA para múltiplos clientes sobre a mesma infraestrutura é um dos desafios arquiteturais mais relevantes para quem desenvolve plataformas SaaS hoje. Sem os controles certos, os riscos são sérios: vazamento de dados entre clientes, qualidade de serviço inconsistente, custos impossíveis de rastrear por tenant e falta de visibilidade operacional.

    A AWS publicou o segundo artigo de uma série sobre como endereçar esses desafios usando o Amazon Bedrock AgentCore. O Parte 1 da série abordou as considerações de design para arquiteturas multi-tenant com AgentCore. Este segundo artigo vai além e mostra padrões concretos de implementação, com código e configurações reais.

    O exemplo central é um assistente de IA para saúde que atende múltiplas clínicas e hospitais. Mas os padrões apresentados se aplicam a qualquer plataforma SaaS, solução empresarial com múltiplas unidades de negócio ou serviço gerenciado para diferentes organizações clientes. O código de exemplo completo está disponível no repositório GitHub da AWS.

    Visão geral da solução

    A arquitetura proposta implementa uma hierarquia de três níveis: Tier → Tenant → Usuário. O isolamento é aplicado em cada camada — nos documentos da base de conhecimento, na memória conversacional, no acesso aos modelos e no rastreamento de custos.

    A estratégia de tiers é um padrão comum em SaaS: os tenants são agrupados em níveis de serviço distintos com base em suas necessidades, padrões de uso ou planos de preço. No exemplo de saúde, a solução define dois tiers:

    • Tier Básico: voltado para clínicas pequenas que precisam principalmente de busca e recuperação de documentos. Usa o modelo Mistral Ministral 3 8B Instruct, mantendo custos baixos para consultas simples.
    • Tier Premium: voltado para hospitais e centros de especialidade que precisam de análise clínica mais complexa. Usa o OpenAI GPT OSS 120B com capacidades avançadas de raciocínio, incluindo acesso a uma ferramenta de busca na web exclusiva deste tier.

    Dentro de cada tier, a solução adota o modelo de isolamento pool, onde os tenants compartilham a mesma infraestrutura e recursos computacionais. O isolamento entre eles é garantido por mecanismos lógicos: identificadores com escopo, políticas de acesso e particionamento de dados. Essa combinação de tiers com pool model permite equilibrar eficiência de custo com diferenciação de serviço.

    Arquitetura e componentes principais

    Os componentes da solução são:

    • Amazon Cognito: gerencia a autenticação dos usuários e armazena metadados do tenant (tier, clinic_id, role) como claims em Tokens Web JSON (JWT). Esses claims são propagados como contexto do tenant em toda a requisição.
    • Amazon API Gateway: roteia as requisições e aplica rate limiting por tier via usage plans.
    • AWS Lambda: extrai o contexto do tenant e invoca o agente AgentCore correspondente.
    • Componentes AgentCore: Runtime (execução do agente), Memory (estado da conversa), Identity (gerenciamento de identidade), Gateway (servidor de ferramentas) e Policy (limites de ação do agente).
    • Amazon Simple Storage Service (Amazon S3): armazena documentos clínicos em buckets separados por tier, com estrutura de prefixos hierárquicos para isolamento por tenant.
    • Amazon Bedrock Knowledge Bases: fornece busca semântica com filtragem por metadados para restringir consultas aos documentos do tenant solicitante.
    • Amazon Bedrock project: permite rastreamento de custos por tier via tags de alocação de custo.
    Figura 1: Arquitetura multi-tenant com isolamento hierárquico (Tier → Tenant → Usuário) — Imagem original — fonte: Aws

    Como o AgentCore endereça cada desafio de multi-tenancy

    AgentCore Runtime: isolamento computacional por tenant

    O AgentCore Runtime fornece o ambiente de execução dos agentes. Cada sessão de agente roda em uma micro-VM isolada, garantindo isolamento computacional por tenant. Instâncias separadas são mantidas por tier, cada uma configurada com os modelos e capacidades adequados ao seu nível de serviço. O ID do projeto Bedrock é carregado do SSM Parameter Store e passado na inicialização do modelo para garantir rastreamento de custos correto.

    # Agent configuration
    config = TIER_CONFIG.get(tier, TIER_CONFIG["basic"])
    model_id = config["default_model"]
    
    # Project ID is fetched from SSM
    project_id = get_ssm_parameter(config["project_ssm"])
    
    # Passed to OpenAIModel (premium tier) targeting the inference endpoint
    self.model = OpenAIModel(
        client_args={"base_url": mantle_base_url, "api_key": api_key, "project": project_id},
        model_id=model_id,
    )

    AgentCore Identity: autenticação unificada baseada em JWT

    O AgentCore Identity protege a arquitetura multi-tenant com um modelo de autenticação unificado baseado em JWT. O token de ID do Cognito valida o usuário tanto no Runtime quanto nas fronteiras do Gateway. Cada AgentCore Runtime é configurado com um autorizador JWT que valida os tokens do Cognito antes da execução do código do agente.

    O token carrega metadados do tenant como claims customizados, incluindo custom:tier (que direciona para o modelo, base de conhecimento e gateway corretos), custom:clinic_id (que é o ID do tenant e garante isolamento de dados) e custom:role (para controle de acesso baseado em papéis). A configuração do autorizador é aplicada durante o deploy do agente:

    AUTHORIZER_CONFIG='{"customJWTAuthorizer":{"discoveryUrl":"'$COGNITO_DISCOVERY_URL'","allowedAudience":["'$COGNITO_WEB_CLIENT_ID'"]}}'
    agentcore configure --entrypoint main.py \
        --name healthcare_basic \
        --authorizer-config "$AUTHORIZER_CONFIG" \
        --request-header-allowlist "Authorization"

    O Gateway também é configurado com autorização JWT usando a mesma URL de descoberta do Cognito. Quando o agente chama o gateway, ele encaminha o JWT original do usuário como Bearer token, junto com headers de contexto do tenant (X-Tier, X-Clinic-ID, X-S3-Prefix). A função Lambda de destino nunca recebe o JWT diretamente — ela lê apenas os headers de tenant confiáveis e assume uma role de Máquina de Distribuição de Tokens (TVM) com session tags derivadas desses headers.

    AgentCore Memory: isolamento de memória conversacional em duas camadas

    O histórico de conversas não pode vazar entre tenants nem entre usuários do mesmo tenant. A solução aplica isolamento de memória em duas camadas: escopo na aplicação e Controle de Acesso Baseado em Atributos (ABAC) com suporte em IAM.

    Na camada de aplicação, o AgentCore Memory usa uma estrutura de namespace hierárquico com um actor_id composto para organizar os dados de conversa por tenant:

    actor_id = f"{tier}-{clinic_id}-{user_id}"
    # Example: "basic-clinic-a-dr.smith@clinic-a.com"

    Os namespaces separam diferentes tipos de memória:

    clinic/{actor_id}/facts/{session_id}   # SEMANTIC --- clinical facts
    clinic/{actor_id}/preferences          # PREFERENCES -- user preferences

    Para reforçar o isolamento na camada de infraestrutura, a solução usa o padrão TVM com ABAC. Em tempo de execução, o agente assume uma role TVM com Tier, ClinicId e UserId como session tags, recebendo credenciais temporárias com escopo restrito ao namespace daquele tenant:

    sts = boto3.client("sts", region_name=region)
    response = sts.assume_role(
        RoleArn=tvm_role_arn,
        RoleSessionName=f"mem-{tier}-{clinic_id}-{user_id}",
        DurationSeconds=900,
        Tags=[
            {"Key": "Tier",     "Value": tier},
            {"Key": "ClinicId", "Value": clinic_id},
            {"Key": "UserId",   "Value": user_id},
        ],
        TransitiveTagKeys=["Tier", "ClinicId", "UserId"],
    )

    AgentCore Gateway: ferramentas dinâmicas com contexto de tenant

    O AgentCore Gateway transforma funções Lambda estáticas em ferramentas dinâmicas e conscientes do contexto, usando o Protocolo de Contexto de Modelo (MCP), um padrão open-source para conectar agentes de IA a ferramentas externas. Sem isso, seria necessário escrever código customizado para integrar APIs, gerenciar autenticação e propagação de contexto manualmente.

    A Lambda expõe duas ferramentas pelo Gateway: patient_context (dados demográficos e histórico médico do paciente) e clinic_config (configurações e informações de provedores da clínica). O agente inicializa o cliente MCP Gateway com headers com escopo de tenant, de modo que toda chamada de ferramenta carrega automaticamente o contexto do tenant. Mais detalhes sobre os headers estão disponíveis na documentação de headers do gateway.

    AgentCore Policy: controle de acesso declarativo com Cedar

    O AgentCore Policy aplica limites de ação específicos por tier nas ferramentas do gateway usando políticas de autorização Cedar. A solução cria um motor de políticas compartilhado, anexado aos gateways basic e premium no modo ENFORCE.

    Para o tier básico, uma política Cedar restringe o acesso à ferramenta patient_context ao horário comercial (8h–18h), avaliando o campo request_hour da entrada da ferramenta. Para o tier premium, a política permite acesso irrestrito 24/7. Ambos os tiers recebem permissão para a ferramenta clinic_config, que expõe apenas dados de configuração não sensíveis.

    # Cedar policy: basic tier --- restrict patient_context to business hours
    permit(
      principal is AgentCore::OAuthUser,
      action == AgentCore::Action::"HealthcareLambda-Basic___patient_context",
      resource == AgentCore::Gateway::"{gateway_arn}"
    )
    when {
      context.input has request_hour &&
      context.input.request_hour >= 8 &&
      context.input.request_hour < 18
    };
    
    # Cedar policy: premium tier --- 24/7 patient_context access
    permit(
      principal is AgentCore::OAuthUser,
      action == AgentCore::Action::"HealthcareLambda-Premium___patient_context",
      resource == AgentCore::Gateway::"{gateway_arn}"
    )
    when {
      context.input has patient_id
    };

    AgentCore Observability: rastreamento por tenant com OpenTelemetry

    A integração de observabilidade do AgentCore usa baggage do OpenTelemetry para propagar metadados do tenant por todo o ciclo de vida da requisição. O baggage do OpenTelemetry é um repositório de chave-valor que permite transportar dados adicionais junto ao contexto de rastreamento. A solução define os identificadores do tenant como baggage no ponto de entrada do Runtime, de modo que cada span e entrada de log carrega a atribuição do tenant:

    from opentelemetry import baggage, context
    
    # Set tenant context in OTel baggage (at AgentCore Runtime entrypoint)
    ctx = baggage.set_baggage("tier", tier)
    ctx = baggage.set_baggage("clinic_id", clinic_id, context=ctx)
    ctx = baggage.set_baggage("actor_id", actor_id, context=ctx)
    context.attach(ctx)

    Com isso, é possível usar o Amazon CloudWatch Logs Insights para rastrear o volume de requisições por clínica, combinado com os Projetos Bedrock para atribuição de custos por tier e logging estruturado de uso para rastreamento de tokens por clínica.

    Padrões de implementação multi-tenant

    Isolamento de dados via buckets S3 por tier

    A solução cria um bucket S3 separado por tier de serviço, com prefixos específicos por tenant dentro de cada bucket. Cada Knowledge Base de tier tem seu próprio bucket dedicado, fornecendo isolamento em nível de bucket entre tiers. Dentro de cada bucket, prefixos hierárquicos organizam os dados dos tenants:

    s3://healthcare-basic-kb-{suffix}/
    ├── basic-tier/
    │   ├── clinic-a/
    │   │   ├── appointment-notes/
    │   │   ├── lab-results/
    │   │   ├── patient-intake/
    │   │   └── prescriptions/
    │   ├── clinic-b/
    │   ├── clinic-c/
    │   └── clinic-d/
    
    s3://healthcare-premium-kb-{suffix}/
    ├── premium-tier/
    │   ├── hospital-a/
    │   │   ├── surgical-notes/
    │   │   ├── pathology-reports/
    │   │   └── imaging-studies/
    │   ├── hospital-b/
    │   ├── clinic-e/
    │   └── clinic-f/

    O prefixo S3 é construído a partir da identidade do tenant extraída dos claims JWT do Cognito. A ferramenta de recuperação de documentos aplica o isolamento através de filtro de metadados da Amazon Bedrock Knowledge Base no clinic_id:

    response = client.retrieve(
        knowledgeBaseId=kb_id,
        retrievalQuery={"text": query},
        retrievalConfiguration={
            "vectorSearchConfiguration": {
                "filter": {"equals": {"key": "clinic_id", "value": clinic_id}},
            }
        },
    )

    Atribuição de custos via Projetos Bedrock e logging estruturado

    A atribuição de custos opera em dois níveis: por tier através dos Projetos Bedrock, e por clínica através de logging estruturado de uso.

    Cada tier tem um Projeto Bedrock dedicado com tags de alocação de custo (CostCenter, Tier, Application). O ID do projeto é passado em cada requisição de inferência pelo endpoint Bedrock Mantle, de modo que todos os custos de invocação de modelos são automaticamente segmentados por tier no AWS Cost Explorer. Após ativar as tags de alocação de custo no AWS Billing (as tags podem levar até 24 horas para se propagar), é possível filtrar e agrupar os custos de inferência por CostCenter, Tier ou Application.

    Para granularidade por clínica, a solução registra o uso de tokens após cada invocação do agente como JSON estruturado com o contexto do tenant:

    def _log_usage(self, result) -> None:
        usage = result.metrics.accumulated_usage
        logger.info(json.dumps({
            "event": "inference_usage",
            "tier": self.tier,
            "clinic_id": self.clinic_id,
            "user_id": self.user_id,
            "model_id": self.model_id,
            "input_tokens": usage.get("inputTokens", 0),
            "output_tokens": usage.get("outputTokens", 0),
            "total_tokens": usage.get("totalTokens", 0),
        }))

    Esses logs chegam ao CloudWatch e podem ser consultados com Logs Insights para calcular o uso por clínica. Para estimar os custos, basta multiplicar as contagens de tokens pelo preço publicado por token de cada modelo.

    Rate limiting via API Gateway

    O rate limiting por tier é aplicado usando usage plans do API Gateway. A solução usa usage plans separados por tier:

    basic-tier-plan:
      throttle: {rate_limit: 2, burst_limit: 5}
      quota: {limit: 50, period: DAY}
    
    premium-tier-plan:
      throttle: {rate_limit: 10, burst_limit: 20}
      quota: {limit: 500, period: DAY}

    Conclusão

    O que a AWS demonstra neste artigo é que construir aplicações de IA multi-tenant seguras e escaláveis não exige lógica complexa de isolamento na camada de aplicação. Combinando serviços nativos como Cognito para identidade, prefixos S3 para isolamento de dados, API Gateway para rate limiting, Projetos Bedrock e logging estruturado para atribuição de custos, e o AgentCore para orquestração de IA, é possível entregar isolamento completo entre tenants com código customizado mínimo.

    Os padrões apresentados — hierarquia Tier → Tenant → Usuário, modelo pool com isolamento lógico, TVM com ABAC, políticas Cedar declarativas e observabilidade via OpenTelemetry — são aplicáveis a qualquer plataforma SaaS que utilize agentes de IA.

    Para explorar o código completo, acesse o repositório no GitHub ou consulte a documentação do Amazon Bedrock AgentCore. Para entender as considerações de design por trás desta arquitetura, confira também o artigo Building multi-tenant agents with Amazon Bedrock AgentCore.

    Fonte

    Shared infrastructure, isolated tenants: Pool model multi-tenancy with Amazon Bedrock AgentCore (https://aws.amazon.com/blogs/machine-learning/shared-infrastructure-isolated-tenants-pool-model-multi-tenancy-with-amazon-bedrock-agentcore/)

  • Amazon Bedrock AgentCore Memory agora suporta acesso entre contas

    O que foi anunciado

    A AWS anunciou uma nova capacidade para o Amazon Bedrock AgentCore Memory: o suporte a acesso entre contas, conhecido como cross-account access. Com essa novidade, passa a ser possível construir arquiteturas multi-account em que os recursos de memória e os agentes que os consomem estão em contas AWS diferentes.

    Como funciona o acesso entre contas

    A configuração do acesso entre contas é feita por meio de políticas baseadas em recursos (resource-based policies), que são anexadas diretamente ao recurso de memória. Essa abordagem é bastante comum no ecossistema AWS e permite um controle granular sobre quem pode acessar o quê.

    Uma vez configurado, os principais (principals) da conta consumidora ganham permissão para chamar as APIs do plano de dados de memória referenciando o ARN completo do recurso de memória. Com isso, esses principals conseguem realizar as seguintes operações:

    • Criar eventos
    • Escrever registros de memória
    • Recuperar registros
    • Executar buscas semânticas

    Destinos de entrega entre contas

    Além do acesso direto às APIs, o recurso também permite configurar destinos de entrega entre contas (cross-account delivery destinations). Isso significa que o recurso de memória pode entregar payloads e transmitir eventos para serviços que estão em outras contas AWS, incluindo:

    • Amazon S3 — buckets em contas distintas
    • Amazon SNS — tópicos em outras contas
    • Amazon Kinesis Data Streams — streams em contas separadas

    Essa flexibilidade é especialmente útil para organizações que adotam estratégias de múltiplas contas para separar ambientes, equipes ou domínios de negócio, e que precisam que os agentes de IA compartilhem contexto de memória de forma centralizada ou distribuída.

    Disponibilidade

    O suporte a cross-account access no Amazon Bedrock AgentCore Memory está disponível em todas as regiões AWS onde o Amazon Bedrock AgentCore Memory já é suportado. Não há necessidade de habilitar nada separadamente em termos de região — basta que o serviço base já esteja disponível no ambiente utilizado.

    Para começar a usar o recurso, a AWS disponibiliza o guia Acesso a memória entre contas no Amazon Bedrock AgentCore Developer Guide, com o passo a passo de configuração.

    Fonte

    Amazon Bedrock AgentCore Memory now supports cross-account access (https://aws.amazon.com/about-aws/whats-new/2026/06/agentcore-memory-cross-account-access)

  • Amazon CloudWatch Logs passa a suportar ingestão gerenciada de syslog

    O que mudou no Amazon CloudWatch Logs

    A AWS anunciou, em junho de 2026, uma novidade relevante para equipes que gerenciam infraestrutura em nuvem: o Amazon CloudWatch Logs agora suporta ingestão gerenciada de syslog. Isso significa que firewalls, roteadores, switches e servidores Linux podem enviar mensagens de log diretamente para o CloudWatch Logs — sem a necessidade de instalar ou manter qualquer agente.

    Como funciona a ingestão de syslog

    Com esse novo recurso, é possível configurar dispositivos de rede e servidores para encaminhar mensagens de syslog via TCP, TCP+TLS ou UDP para um endpoint de Nuvem Privada Virtual (VPC) na própria conta da AWS. A ausência de agentes simplifica bastante a operação, especialmente em ambientes distribuídos onde a implantação e manutenção de coletores de log costuma gerar overhead significativo.

    Formatos suportados e compatibilidade

    O CloudWatch Logs passou a ser compatível com três formatos amplamente utilizados na indústria:

    • RFC 5424 — padrão moderno de syslog
    • RFC 3164 — formato legado, ainda muito presente em equipamentos mais antigos
    • Cisco FTD/ASA — formato proprietário de appliances Cisco de segurança de rede

    Essa abrangência garante compatibilidade com uma ampla variedade de infraestruturas, o que é especialmente relevante para ambientes híbridos ou com equipamentos de diferentes fabricantes.

    Parsing automático e campos estruturados

    Um ponto de destaque é que o CloudWatch Logs realiza o parsing automático das mensagens de syslog recebidas, extraindo campos estruturados como facility, severity (severidade), hostname e application name (nome da aplicação). Isso elimina a necessidade de construir pipelines customizados de parsing — algo que historicamente consumia tempo e esforço das equipes de operações.

    Caso de uso: investigação de eventos de segurança

    Um exemplo prático mencionado pela AWS: equipes podem ingerir logs de firewalls de rede e, imediatamente, consultar esses dados por severidade ou hostname usando o Logs Analytics — seja para investigar eventos de segurança ou diagnosticar problemas de conectividade. A centralização desses logs em um único serviço facilita tanto a resposta a incidentes quanto a análise operacional do dia a dia.

    Disponibilidade

    O recurso já está disponível em todas as regiões comerciais da AWS, com exceção de Middle East (UAE), Middle East (Bahrain) e Israel (Tel Aviv). Para começar a utilizar, a AWS disponibiliza a documentação oficial do Amazon CloudWatch Logs.

    Fonte

    Amazon CloudWatch Logs supports managed syslog ingestion (https://aws.amazon.com/about-aws/whats-new/2026/06/amazon-cloudwatch-syslog-ingestion/)

  • Copiloto de Pesquisa de Proteínas com Amazon Bedrock AgentCore

    O gargalo que essa solução endereça

    Quem trabalha com pesquisa de proteínas conhece bem o problema: varrer manualmente milhares de sequências de peptídeos em busca de candidatos estruturalmente parecidos é lento, propenso a erros e exige especialização para interpretar os resultados. A AWS publicou um guia técnico mostrando como construir um copiloto conversacional que resolve exatamente isso — o pesquisador faz uma pergunta em linguagem natural e recebe resultados ranqueados com resumo científico, tudo em uma única interface.

    O que o agente é capaz de fazer

    A solução reúne três capacidades dentro de um único agente conversacional:

    • Interpretação de linguagem natural: extrai parâmetros estruturados de consultas como “Encontre 10 peptídeos similares ao peptídeo LPAIVREAI do vírus da dengue”.
    • Busca por similaridade vetorial: gera embeddings de proteínas com um modelo especializado e realiza busca por cosseno em um banco de dados vetorial.
    • Sumarização científica: produz resumos dos resultados com contexto biológico e sugestões para investigação adicional.

    A orquestração é feita pelo Strands Agents SDK, que coordena três ferramentas especializadas dentro de um único agente. O agente é hospedado no Amazon Bedrock AgentCore para servir em produção, e os embeddings de peptídeos ficam armazenados no Amazon Aurora PostgreSQL com a extensão pgvector.

    Arquitetura da solução

    Cinco componentes trabalham em conjunto para entregar a experiência conversacional:

    • Frontend Streamlit no AWS Fargate: fornece a interface de chat, envia consultas ao runtime do AgentCore e exibe os resultados em tabelas com opção de download.
    • Agente orquestrador no Bedrock AgentCore: um agente Strands rodando dentro de um runtime único do AgentCore, usando Anthropic Claude Sonnet 4.6 via Bedrock Converse API, com acesso a três ferramentas definidas pelo decorator @tool.
    • Ferramenta de parsing: um agente Strands dedicado (padrão LLM-as-parser) que extrai parâmetros estruturados — sequência, filtro de espécie, limite de resultados — a partir da consulta em linguagem natural.
    • Ferramenta de busca: gera embeddings via endpoint serverless do Amazon SageMaker AI rodando o modelo ESM-C 300M, e depois executa busca por similaridade de cosseno no Aurora PostgreSQL com pgvector.
    • Ferramenta de sumarização: outro agente Strands dedicado que analisa os resultados e produz um resumo científico conciso com sugestões de próximos passos.

    Esse design de runtime único com múltiplas ferramentas mantém a implantação simples sem abrir mão da separação clara de responsabilidades. O orquestrador decide quando e como acionar cada ferramenta com base na consulta recebida.

    Embeddings de proteínas com ESM-C 300M

    O coração da busca por similaridade é o ESM-C 300M, um modelo de linguagem de proteínas da EvolutionaryScale que produz embeddings de 960 dimensões capturando propriedades estruturais e funcionais de sequências de aminoácidos. Dois peptídeos com função biológica parecida geram embeddings próximos no espaço vetorial, viabilizando a busca por similaridade sem necessidade de alinhamento de sequências.

    O modelo é implantado como endpoint serverless do Amazon SageMaker AI, que escala para zero quando ocioso — sem custo entre invocações. Os pesos do modelo são empacotados diretamente no artefato de implantação para evitar download do HuggingFace no momento da inferência, o que é crítico para endpoints serverless onde a latência de cold start importa.

    O handler de inferência constrói a arquitetura do modelo e carrega os pesos pré-empacotados:

    from esm.models.esmc import ESMC
    from esm.tokenization import get_esmc_model_tokenizers
    
    def model_fn(model_dir):
        weights_path = os.path.join(model_dir, "weights", "esmc_300m.pt")
        model = ESMC(
            d_model=960,
            n_heads=15,
            n_layers=30,
            tokenizer=get_esmc_model_tokenizers(),
            use_flash_attn=False,
        )
        state_dict = torch.load(weights_path, map_location="cpu")
        model.load_state_dict(state_dict)
        model.eval()
        return model

    O predict_fn recebe uma sequência de proteína, a codifica e retorna o embedding com mean pooling:

    def predict_fn(input_data, model):
        sequence = input_data["sequence"]
        protein = ESMProtein(sequence=sequence)
        protein_tensor = model.encode(protein)
        logits_output = model.logits(
            protein_tensor,
            LogitsConfig(sequence=True, return_embeddings=True)
        )
        embeddings = logits_output.embeddings
        mean_embeddings = embeddings[:, 1:-1, :].mean(dim=1)
        return mean_embeddings[0].detach().cpu().tolist()

    O endpoint é configurado com 6144 MB de memória, concorrência máxima de 5 e usa o container de inferência CPU PyTorch 2.6.0.

    Busca vetorial com Aurora PostgreSQL e pgvector

    Os embeddings ficam armazenados no Amazon Aurora PostgreSQL-Compatible Edition Serverless v2 com a extensão pgvector. O schema é direto:

    CREATE TABLE peptides (
        id SERIAL PRIMARY KEY,
        sequence TEXT NOT NULL,
        embedding vector(960),
        properties JSONB,
        created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    );
    
    CREATE INDEX peptides_embedding_idx ON peptides
        USING ivfflat (embedding vector_cosine_ops)
        WITH (lists = 100);

    A coluna properties do tipo JSONB guarda metadados biológicos — espécie, organismo de origem, molécula de origem, posições de epítopo — permitindo combinar filtros de vetor e metadados na mesma query. Uma consulta como “Encontre peptídeos similares a LPAIVREAI do vírus da dengue” dispara tanto a busca por similaridade de cosseno quanto um filtro em properties->>'species'.

    O acesso ao banco ocorre via Amazon RDS Data API, o que significa que o runtime do agente não precisa de conectividade de rede direta com o banco — ele se comunica via HTTPS, simplificando os requisitos de rede para implantação no AgentCore.

    Construindo o agente com o Strands Agents SDK

    O Strands Agents SDK oferece uma abstração limpa para construir agentes que usam ferramentas. Cada ferramenta é uma função Python decorada com @tool, e o agente gera automaticamente as descrições das ferramentas para o modelo de linguagem a partir da docstring e dos type hints da função.

    As três ferramentas do agente

    A ferramenta de parsing delega para um agente Strands dedicado que atua como extrator de saída estruturada:

    from strands import Agent, tool
    from strands.models import BedrockModel
    
    parser_agent = Agent(
        model=BedrockModel(model_id="us.anthropic.claude-sonnet-4-6", region_name="us-east-1", streaming=False),
        system_prompt="""You are a peptide query parser. Extract structured search parameters from natural language queries. Return ONLY a valid JSON object."""
    )
    
    @tool
    def parse_peptide_query(query: str) -> str:
        """Parse a natural language peptide query into structured search parameters.
    
        Args:
            query: The user's natural language query about peptides.
    
        Returns:
            JSON string with extracted parameters like sequence, species, limit.
        """
        result = parser_agent(f"Parse this query: {query}")
        parsed = json.loads(str(result))
        return json.dumps(parsed)

    A ferramenta de busca combina geração de embeddings via SageMaker AI com busca por similaridade no pgvector:

    @tool
    def search_similar_peptides(sequence: str, species: str = "", limit: int = 20) -> str:
        """Search for peptides similar to the given sequence using ESM embeddings.
    
        Args:
            sequence: The peptide amino acid sequence (e.g., "LPAIVREAI").
            species: Optional species filter (e.g., "Dengue virus").
            limit: Maximum number of results to return.
    
        Returns:
            JSON string with list of similar peptides and their properties.
        """
        # Get embedding from SageMaker AI
        resp = sagemaker_client.invoke_endpoint(
            EndpointName=endpoint,
            ContentType="application/json",
            Body=json.dumps({"sequence": sequence}))
        embedding = json.loads(resp["Body"].read().decode())["embedding"]
    
        # Vector similarity search with optional metadata filter
        sql = "SELECT sequence, properties, "
        sql += "(embedding <=> :query_embedding::vector) AS cosine_distance "
        sql += "FROM peptides"
        if species:
            sql += " WHERE properties->>'species' = :species"
        sql += " ORDER BY cosine_distance LIMIT :limit"
    
        results = run_sql(sql, params)
        return json.dumps({"results": peptides, "count": len(peptides)})

    A ferramenta de sumarização usa outro agente Strands dedicado para análise científica:

    summarizer_agent = Agent(
        model=BedrockModel(model_id="us.anthropic.claude-sonnet-4-6", region_name="us-east-1", streaming=False),
        system_prompt="""You are a peptide research expert providing concise, high-level summaries. Analyze search results and provide a brief, insightful summary focusing on key findings and ideas for further investigation."""
    )
    
    @tool
    def summarize_results(original_query: str, search_results_json: str) -> str:
        """Summarize peptide search results with scientific insights.
    
        Args:
            original_query: The original user query.
            search_results_json: JSON string of search results.
    
        Returns:
            A concise scientific summary of the search results.
        """
        results = json.loads(search_results_json)
        summary = summarizer_agent(f"Original query: {original_query}"
                                   f"Results: {results}")
        return str(summary)

    O agente orquestrador

    O orquestrador amarra tudo. Ele recebe a consulta do usuário e decide quais ferramentas acionar e em que ordem:

    SYSTEM_PROMPT = """You are a peptide research assistant. You have three tools:
    1. parse_peptide_query - Parse a natural language query into structured parameters
    2. search_similar_peptides - Search for similar peptides using ESM embeddings
    3. summarize_results - Summarize search results with scientific insights
    
    For every user query, follow this workflow:
    1. First, use parse_peptide_query to extract the sequence and parameters
    2. Then, use search_similar_peptides with the extracted sequence
    3. Finally, use summarize_results to provide insights
    
    Always complete the three steps."""
    
    strands_agent = Agent(
        model=BedrockModel(model_id="us.anthropic.claude-sonnet-4-6", region_name="us-east-1", streaming=False),
        tools=[parse_peptide_query, search_similar_peptides, summarize_results],
        system_prompt=SYSTEM_PROMPT
    )

    Vale notar o padrão “agents-as-tools” aqui: o parser e o sumarizador são eles próprios agentes Strands, mas ficam embrulhados em decorators @tool e expostos ao orquestrador como ferramentas chamáveis. O orquestrador não sabe nem precisa saber que essas ferramentas usam modelos de linguagem internamente — ele as chama como funções normais.

    Implantação no Amazon Bedrock AgentCore

    O Amazon Bedrock AgentCore fornece um runtime gerenciado para hospedar agentes de IA. O código do agente roda em um ambiente containerizado construído e implantado via AWS CodeBuild — sem necessidade de Docker local.

    O runtime espera uma função de entrypoint que recebe um payload e um contexto:

    from bedrock_agentcore.runtime import BedrockAgentCoreApp
    
    app = BedrockAgentCoreApp()
    
    @app.entrypoint
    def invoke(payload, context):
        query = payload.get("query") or payload.get("prompt")
        result = strands_agent(query)
        return {
            "status": "success",
            "original_query": query,
            "parsed_query": _tool_outputs.get("parsed_query", {}),
            "search_results": _tool_outputs.get("search_results", []),
            "summary": _tool_outputs.get("summary", str(result)),
            "session_id": context.session_id
        }
    
    if __name__ == '__main__':
        app.run()

    A infraestrutura completa é definida como código via AWS CloudFormation. A stack de VPC cria sub-redes privadas com NAT gateways e VPC endpoints para Amazon Bedrock, RDS Data API e AWS Secrets Manager. O cluster Aurora PostgreSQL Serverless v2 é configurado com escalonamento automático de 0,5 a 4 ACUs (1–8 GB de RAM), e um recurso customizado com AWS Lambda inicializa a extensão pgvector e cria a tabela de peptídeos durante a criação da stack:

    DBCluster:
      Type: AWS::RDS::DBCluster
      Properties:
        Engine: aurora-postgresql
        EnableHttpEndpoint: true  # Amazon RDS Data API
        ServerlessV2ScalingConfiguration:
          MinCapacity: 0.5
          MaxCapacity: 4

    Ordem de implantação

    A solução deve ser implantada nesta sequência:

    • VPC e rede: sub-redes privadas com NAT gateways e VPC endpoints para os serviços necessários.
    • Banco de dados Aurora PostgreSQL: cluster Serverless v2 com pgvector habilitado e tabela de peptídeos inicializada.
    • Endpoint do SageMaker AI: endpoint serverless rodando ESM-C 300M com 6144 MB de memória e concorrência máxima de 5.
    • Dados de peptídeos: o dataset de epítopos virais do IEDB é carregado no banco gerando embeddings para cada sequência via endpoint do SageMaker AI.
    • Runtime do AgentCore e interface Streamlit: o agente Strands é implantado no runtime do Bedrock AgentCore via AWS CodeBuild, e o frontend Streamlit é implantado no AWS Fargate.

    O que considerar antes de ir para produção

    • Latência de cold start: o endpoint serverless do SageMaker AI leva 2–3 minutos na primeira invocação após um período ocioso enquanto o container inicializa e carrega os pesos. Invocações subsequentes dentro da janela de keep-alive completam em segundos. Para cargas sensíveis à latência, um endpoint provisionado é mais adequado.
    • Escolha do modelo de embedding: o ESM-C 300M foi escolhido pelo equilíbrio entre qualidade de embedding e velocidade de inferência em CPU. Para maior precisão em tarefas de similaridade estrutural, os modelos ESM-C 600M ou ESM2 oferecem dimensões maiores ao custo de mais memória e latência.
    • Escalonamento do dataset: a carga inicial usa 1.000 peptídeos amostrados do IEDB. Para datasets maiores em produção, considere carregamento em batch, aumento proporcional do parâmetro lists do índice IVFFlat e escalonamento dos ACUs do Aurora. A RDS Data API tem limite de resposta de 1 MB, então queries com grandes conjuntos de resultados podem precisar de paginação.
    • Custo: os componentes serverless (endpoint do SageMaker AI, Aurora Serverless v2, runtime do AgentCore) escalam para próximo de zero quando ociosos. Os principais custos durante uso ativo são inferência de LLM no Bedrock — três chamadas por consulta: parser, orquestrador e sumarizador — e invocações do endpoint do SageMaker AI.

    O que essa arquitetura entrega na prática

    O que antes exigia consultar manualmente bancos de dados de sequências, executar ferramentas de alinhamento e interpretar resultados em múltiplas aplicações — um processo que pode levar horas por busca — é reduzido a uma única consulta em linguagem natural que retorna resultados ranqueados e sumarizados em menos de um minuto (ou 2–3 minutos no cold start).

    O padrão também generaliza além da pesquisa de peptídeos. Qualquer domínio onde seja necessário buscar sobre embeddings especializados, filtrar por metadados estruturados e sintetizar resultados — genômica, design de fármacos, ciência de materiais — pode se beneficiar dessa combinação de modelos de embedding específicos de domínio com orquestração por LLM.

    Pré-requisitos para reproduzir a solução

    • Uma conta AWS com acesso aos modelos de fundação do Amazon Bedrock (Anthropic Claude Sonnet 4.6).
    • Python 3.12 ou superior.
    • A AWS CLI configurada com as credenciais apropriadas.
    • Permissões IAM para Amazon Bedrock, Amazon SageMaker AI, Amazon Aurora, Amazon ECS e AWS CodeBuild.
    • O pacote bedrock-agentcore-starter-toolkit instalado (pip install bedrock-agentcore-starter-toolkit).
    • O dataset de epítopos virais do IEDB.

    O tempo estimado de implantação é de 30–45 minutos. Consulte as páginas de preços da AWS para Bedrock, SageMaker AI, Aurora Serverless v2 e AWS Fargate para estimativas de custo.

    Limpeza dos recursos

    Para evitar cobranças contínuas, exclua os recursos na ordem inversa à implantação:

    • Interface Streamlit — exclua a stack do AWS Fargate via console do AWS CloudFormation ou AWS CLI.
    • Endpoint do SageMaker AI — exclua o endpoint, a configuração do endpoint e o modelo.
    • Banco de dados — exclua o dataset IEDB e depois a stack do Aurora PostgreSQL via CloudFormation.
    • VPC — exclua a stack de VPC via CloudFormation.
    • Runtime do AgentCore — exclua o runtime via console do Amazon Bedrock AgentCore.

    Referências

    Vita R et al. The Immune Epitope Database (IEDB): 2024 update. Nucleic Acids Res. 2025 Jan 6;53(D1):D436-D443. doi: 10.1093/nar/gkae1092. PMID: 39558162; PMCID: PMC11701597.

    ESM Team. “ESM Cambrian: Revealing the mysteries of proteins with unsupervised learning.” EvolutionaryScale, 2024. https://evolutionaryscale.ai/blog/esm-cambrian

    Fonte

    Build a protein research copilot with Amazon Bedrock AgentCore (https://aws.amazon.com/blogs/machine-learning/build-a-protein-research-copilot-with-amazon-bedrock-agentcore/)