Author: Make.com Service User

  • Como o Amazon Bedrock detecta phishing gerado por IA

    O phishing mudou — e os filtros antigos não acompanharam

    Engenharia social por e-mail é uma das táticas mais antigas e persistentes no mundo da segurança cibernética. Mas o que mudou radicalmente nos últimos anos é a qualidade dos ataques. Graças à Inteligência Artificial Generativa (IA Generativa), criminosos conseguem criar milhares de mensagens únicas, com gramática impecável, contexto adequado e detalhes personalizados sobre a vítima — tudo de forma automatizada.

    Pense no cenário clássico de detecção de phishing: erros de português, saudações genéricas, logotipos tortos, domínios estranhos. Essas eram as pistas que os filtros tradicionais aprenderam a capturar. O problema é que a IA generativa eliminou exatamente esses erros. Hoje, um e-mail de phishing sofisticado pode ser a mensagem mais bem escrita da sua caixa de entrada.

    Além disso, os atacantes modernos usam técnicas de Inteligência de Fontes Abertas (OSINT — Open Source Intelligence) para mapear hierarquias organizacionais, relações entre funcionários e padrões de comunicação a partir de redes profissionais, sites corporativos e rastros digitais públicos. Com esse mapeamento, é possível gerar mensagens que se adaptam em tempo real conforme a vítima responde.

    A pergunta que a AWS se propôs a responder é: como usar a mesma tecnologia de IA para detectar esses ataques antes que causem dano?

    Amazon Bedrock como camada de defesa comportamental

    O Amazon Bedrock é um serviço gerenciado que disponibiliza Modelos de Fundação (FMs — Foundation Models) de diversas empresas de IA por meio de uma API unificada. A proposta da AWS, detalhada em um artigo técnico recente, é usar esses modelos como uma camada adicional de análise sobre a infraestrutura de segurança de e-mail já existente.

    O ponto central da abordagem é a mudança de paradigma: em vez de filtrar mensagens pelo que elas parecem (erros gramaticais, formatação suspeita), o Bedrock analisa o que elas sabem e pedem — ou seja, o comportamento implícito na mensagem comparado ao histórico do remetente.

    Para isso, a solução é estruturada como um pipeline de análise em múltiplos estágios, onde cada e-mail passa por autenticação, análise comportamental e pontuação de risco antes de chegar à caixa de entrada do usuário.

    As duas capacidades centrais do Bedrock nessa solução

    A AWS descreve duas capacidades integradas que sustentam a defesa contra phishing com IA:

    • Modelos de Fundação pré-treinados: oferecem compreensão sofisticada de linguagem natural, capazes de detectar manipulação sutil, anomalias contextuais e padrões de personificação que sistemas baseados em regras simplesmente não conseguem capturar.
    • Amazon Bedrock Guardrails: camada de governança configurável que define os limites de operação dos modelos. Ela filtra tanto os prompts de entrada quanto as saídas geradas, impedindo que informações sensíveis sejam expostas durante a análise e garantindo que o sistema opere dentro das políticas de IA responsável da organização.

    Um ponto importante sobre os Guardrails: a configuração exige calibração cuidadosa. Restrições excessivamente rígidas podem impedir que o modelo analise conteúdo suspeito que legitimamente precisa ser avaliado — como um e-mail que contém linguagem ofensiva justamente para tentar burlar filtros.

    Como o pipeline funciona na prática

    O fluxo de análise é dividido em cinco etapas principais:

    Etapa 1 — Guardrails de entrada e pré-processamento

    Antes de qualquer análise de IA, o e-mail passa pelos Guardrails do Bedrock, que verificam o conteúdo e sinalizam o que deve ir para revisão manual. Informações de Identificação Pessoal (PII — Personally Identifiable Information) descobertas durante a análise podem ser automaticamente redigidas, evitando que o modelo gere respostas que exponham dados confidenciais.

    Etapa 2 — Construção do prompt com contexto

    Após passar pela triagem inicial, o sistema constrói um prompt de análise combinando o conteúdo do e-mail com três elementos de contexto: o padrão de comunicação histórico do remetente, o contexto organizacional e exemplos conhecidos de phishing armazenados nas Amazon Bedrock Knowledge Bases. Dessa forma, o modelo não avalia a mensagem de forma isolada — ele compara com um quadro completo de referências.

    Etapa 3 — Análise pelo modelo de fundação com Guardrails ativos

    O modelo processa o e-mail usando o prompt construído, enquanto os Guardrails mantêm a análise dentro dos limites definidos. O modelo consegue examinar conteúdo suspeito com profundidade sem gerar saídas que exponham informações sensíveis no processo.

    Etapa 4 — Pontuação de risco multifatorial

    A partir da análise, o pipeline gera três pontuações independentes: anomalias de conteúdo, desvios comportamentais e alinhamento contextual. Essas três pontuações são combinadas em uma média ponderada que resulta em um score único de 0 a 100. Os limiares definidos no artigo são: abaixo de 30 é seguro, entre 30 e 70 é suspeito, e acima de 70 é perigoso.

    Etapa 5 — Classificação e roteamento automatizado

    Com base no score final, o e-mail é roteado automaticamente: mensagens seguras chegam normalmente à caixa de entrada, mensagens suspeitas vão para quarentena para revisão da equipe de segurança, e mensagens perigosas são bloqueadas com alerta imediato para o time responsável.

    O rastreador de comportamento do remetente

    Um componente-chave da solução é o que a AWS chama de sender baseline tracker — um perfil dinâmico de cada remetente que registra como aquela pessoa normalmente escreve: vocabulário, formalidade, tipos de solicitação e com quem costuma se comunicar.

    Imagine um cenário concreto: um fornecedor que sempre manda e-mails curtos sobre notas fiscais de repente envia uma mensagem formal pedindo urgentemente a alteração de dados bancários. O pipeline detecta esse desvio comportamental e sinaliza para a equipe de segurança revisar — mesmo que a mensagem seja gramaticalmente perfeita e pareça legítima à primeira vista.

    Esse é exatamente o tipo de ataque que os filtros tradicionais não conseguem pegar. E é exatamente o que o exemplo técnico do artigo original ilustra:

    {
      "risk_score": 78,
      "risk_level": "DANGEROUS",
      "key_findings": [
        "Domain mismatch: 'example-website.com' vs 'example.com'",
        "First-ever payment change request from this sender",
        "Phone number doesn't match vendor records"
      ]
    }

    No exemplo, o modelo flagrou uma tentativa de personificação de fornecedor com score 78 (perigoso). Os três achados principais foram: incompatibilidade de domínio entre o endereço real e o usado no e-mail, uma solicitação de mudança de dados bancários que nunca havia ocorrido antes com aquele remetente, e um número de telefone que não bate com os registros do fornecedor.

    O ciclo contínuo de aprendizado

    O que diferencia essa abordagem de sistemas estáticos de detecção é o loop de feedback contínuo. A cada ciclo, o sistema fica mais preciso:

    Imagem original — fonte: Aws
    • Analisar (Analyze): o modelo avalia os e-mails recebidos usando prompts dinâmicos construídos com base em inteligência acumulada e no contexto do remetente.
    • Pontuar (Score): um score de 0 a 100 é atribuído, e mensagens suspeitas são colocadas em quarentena para revisão.
    • Revisar (Review): a equipe de segurança classifica as mensagens sinalizadas como phishing confirmado ou falso positivo.
    • Aprender (Learn): essas classificações alimentam o sistema, atualizando a biblioteca de exemplos, os perfis comportamentais dos remetentes e o catálogo de padrões emergentes.
    • Aprimorar (Enhance): os novos exemplos e padrões confirmados são incorporados aos prompts de análise, melhorando a precisão nas próximas rodadas.

    Nos ciclos iniciais, a equipe de segurança precisará dedicar mais tempo classificando mensagens sinalizadas — é o período em que o sistema está construindo seu entendimento de base. Com o tempo, à medida que a biblioteca de exemplos e os perfis de remetentes crescem, o modelo se torna progressivamente mais preciso, e a atenção da equipe se desloca do ruído para as ameaças genuínas.

    Engenharia de prompt dinâmica e few-shot learning

    Dois conceitos técnicos importantes sustentam a melhoria contínua do sistema. O primeiro é a engenharia de prompt dinâmica: as instruções enviadas ao modelo são refinadas iterativamente com base nos resultados reais, incorporando o feedback da equipe de segurança diretamente nos prompts de análise.

    O segundo é o few-shot learning: exemplos verificados de phishing e mensagens legítimas são catalogados e usados como demonstrações de referência nos prompts futuros. Quando um novo e-mail chega, o modelo não parte do zero — ele consulta exemplos reais e previamente validados que seguem padrões similares para embasar sua avaliação.

    O que isso significa para equipes de segurança

    A proposta da AWS não é substituir a infraestrutura de segurança existente nem o julgamento humano. Os protocolos de autenticação de e-mail — Estrutura de Política de Remetente (SPF — Sender Policy Framework), Correio Identificado por Chaves de Domínio (DKIM — DomainKeys Identified Mail) e Conformidade, Relatório e Autenticação de Mensagem Baseada em Domínio (DMARC — Domain-based Message Authentication, Reporting and Conformance) — continuam sendo a primeira linha de defesa. O Bedrock atua como uma camada analítica adicional, rodando em paralelo à infraestrutura existente.

    A mensagem central do artigo é direta: a IA tornou o phishing mais difícil de detectar. A mesma tecnologia, aplicada defensivamente, pode torná-lo mais difícil de ter sucesso. Para equipes que queiram explorar essa abordagem, a AWS indica o console do Amazon Bedrock como ponto de partida para configurar os Guardrails e construir o pipeline de detecção.

    Fonte

    How Amazon Bedrock catches AI-generated phishing (https://aws.amazon.com/blogs/machine-learning/how-amazon-bedrock-catches-ai-generated-phishing/)

  • Filtragem estruturada de memória com metadados no AgentCore Memory

    O problema: busca semântica não é suficiente sozinha

    Imagine um agente de suporte ao cliente que recebe a consulta “problemas de cobrança” e devolve uma mistura de tickets técnicos, conversas de vendas com reclamações de recibo e disputas de faturamento — tudo junto. Esse é o limite da busca por similaridade semântica quando agentes acumulam semanas de histórico de interações: o sistema encontra tudo que é semanticamente próximo, mas não consegue filtrar pelo que realmente importa, como tipo de problema, status ou período de tempo.

    O Amazon Bedrock AgentCore Memory é um serviço gerenciado de memória que dá aos agentes de IA a capacidade de lembrar e recuperar informações entre conversas. Ele organiza os registros de memória em namespaces que definem escopos isolados — como clients/client-123 — garantindo que os dados de cada entidade fiquem separados. Para entender mais sobre organização de namespaces, a AWS publicou o post Organizando a memória de agentes em escala: padrões de design de namespace no AgentCore Memory.

    À medida que as memórias crescem, sinais relevantes se perdem em resultados semanticamente similares, mas contextualmente irrelevantes. O isolamento por namespace sozinho não resolve isso. A filtragem por metadados fecha essa lacuna: é possível aplicar filtros baseados em atributos de negócio — como prioridade, departamento ou intervalo de tempo — antes que a busca semântica seja executada.

    Em avaliações realizadas com um conjunto de 151 perguntas baseado em um benchmark de memória de longo prazo (no estilo LoCoMo, com múltiplas sessões de conversa), a precisão geral nas respostas subiu de 40% para 64% com a filtragem por metadados habilitada. Para perguntas que dependem de fronteiras contextuais — como buscas por período de tempo, filtragem por prioridade ou escopo por departamento — o ganho foi ainda maior: de 16% para 69%.

    Imagem original — fonte: Aws

    Como namespaces e metadados se complementam

    O AgentCore Memory usa namespaces para organizar e isolar memórias ao longo das fronteiras das entidades primárias. O namespace define quem é o dono dos dados — por exemplo, patients/patient-456. Já os metadados lidam com o sub-agrupamento dentro dessas fronteiras: a categoria, o status de resolução, a data, a prioridade e as tags.

    Em ambientes multi-tenant, o padrão fica claro: os namespaces já fornecem separação completa de dados entre tenants. Dentro do namespace de cada tenant, os agentes ainda precisam filtrar por tipo de ticket antes de buscar padrões de resolução. Os namespaces respondem ao quem; os metadados respondem ao o quê, quando e quão urgente.

    Como os metadados funcionam no AgentCore Memory

    Os metadados operam tanto na memória de curto prazo quanto na de longo prazo, seguindo um ciclo de vida em três fases: configuração, ingestão e recuperação.

    Imagem original — fonte: Aws

    Na memória de curto prazo, é possível anexar pares de chave-valor baseados em strings aos eventos, marcando interações com informações contextuais que não fazem parte da conversa em si, mas são críticas para recuperação posterior. Essas tags são carregadas para a memória de longo prazo durante a extração e consolidação, onde se tornam dimensões filtráveis.

    Fase 1: Configuração

    Ao criar um recurso de memória, é necessário declarar quais chaves de metadados serão indexadas para filtragem e recuperação rápida. As chaves indexadas são armazenadas em um formato otimizado para filtragem de consultas, enquanto as chaves não indexadas ficam armazenadas junto aos registros de memória apenas para fins informativos. O exemplo a seguir cria um recurso de memória de suporte ao cliente com configuração de metadados:

    response = agentcore_client.create_memory(
        name="CustomerSupportMemory",
        eventExpiryDuration=30,
        indexedKeys=[
            {"key": "priority", "type": "STRING"},
            {"key": "agent_type", "type": "STRING"},
            {"key": "channel", "type": "STRING"},
            {"key": "ticket_id", "type": "STRING"}
        ],
        memoryStrategies=[{
            "semanticMemoryStrategy": {
                "name": "SupportSemanticStrategy",
                "description": "Captures support interaction details",
                "namespaces": ["support/{actorId}"],
                "memoryRecordSchema": {
                    "metadataSchema": [
                        {
                            "key": "priority",
                            "type": "STRING",
                            "extractionType": "STRICTLY_CONSISTENT",
                            "extractionConfig": {
                                "llmExtractionConfig": {
                                    "definition": "Issue priority level based on customer impact.",
                                    "llmExtractionInstruction": "LATEST_VALUE",
                                    "validation": {
                                        "stringValidation": {
                                            "allowedValues": ["critical", "high", "medium", "low"]
                                        }
                                    }
                                }
                            }
                        },
                        {
                            "key": "agent_type",
                            "type": "STRING",
                            "extractionType": "STRICTLY_CONSISTENT",
                            "extractionConfig": {
                                "llmExtractionConfig": {
                                    "definition": "Support agent classification.",
                                    "llmExtractionInstruction": "Prefer the most specialized agent type. Hierarchy: specialist > tier3 > tier2 > tier1 > bot."
                                }
                            }
                        },
                        {
                            "key": "sentiment",
                            "type": "STRING",
                            "extractionType": "STRICTLY_CONSISTENT",
                            "extractionConfig": {
                                "llmExtractionConfig": {
                                    "definition": "Customer sentiment during the interaction.",
                                    "llmExtractionInstruction": "Classify the overall customer sentiment based on tone and language used.",
                                    "validation": {
                                        "stringValidation": {
                                            "allowedValues": ["positive", "neutral", "negative", "frustrated"]
                                        }
                                    }
                                }
                            }
                        }
                    ]
                }
            }
        }]
    )

    Cada entrada do schema tem um campo definition, que descreve o que o campo representa, e um llmExtractionInstruction, que fornece orientação adicional de extração e comportamento de resolução de conflitos ao Modelo de Linguagem de Grande Escala (LLM). A operação embutida LATEST_VALUE fornece resolução baseada em recência, enquanto instruções personalizadas em linguagem natural tratam lógicas específicas do domínio. O campo opcional validation restringe os valores extraídos — como allowedValues para STRING, maxItems para STRINGLIST, ou mínimo-máximo para NUMBER.

    Um ponto importante: ticket_id é declarado como chave indexada no nível da memória, mas não está incluído no memoryRecordSchema da estratégia. Isso significa que essa chave não será populada nos registros de memória extraídos. Somente chaves definidas no schema da estratégia aparecem nos registros após a extração. Para mais detalhes sobre as restrições de configuração, consulte a documentação do AgentCore Memory.

    Imagem original — fonte: Aws

    Além das chaves configuradas, a filtragem temporal está disponível por meio dos campos x-amz-agentcore-memory-createdAt e x-amz-agentcore-memory-updatedAt, gerados automaticamente pelo sistema, que suportam os operadores BEFORE e AFTER sem exigir que você declare chaves de data/hora indexadas.

    Extração determinística com STRICTLY_CONSISTENT

    Algumas chaves de metadados são classificadores organizacionais — como department, compliance_level ou interaction_type — cujos valores a aplicação já conhece no momento da criação do evento. Para esses casos, a extração via LLM introduz variabilidade indesejada: a mesma conversa pode gerar "eng" em um registro e "Engineering" em outro.

    O AgentCore Memory resolve isso com o tipo de extração STRICTLY_CONSISTENT. Quando uma chave é configurada dessa forma, o valor fornecido no evento é propagado sem alteração através da extração e consolidação — o LLM não é consultado para essa chave. Além disso, eventos com os mesmos valores determinísticos são sempre extraídos juntos e isolados de eventos com valores diferentes, eliminando ambiguidade. A consolidação respeita a mesma separação: um registro com department: "billing" não será mesclado com um de department: "engineering", por mais similar que seja o conteúdo.

    Esse mecanismo é ideal para isolamento de conformidade (registros HIPAA não se misturam com registros padrão), roteamento organizacional e qualquer cenário em que o valor seja conhecido no momento do evento e precise ser preservado exatamente nos registros resultantes. O AgentCore Memory suporta até três chaves STRICTLY_CONSISTENT por estratégia, e cada uma consome um dos dez slots de chaves indexadas do recurso de memória — chaves indexadas não podem ser removidas depois de adicionadas.

    Fase 2: Ingestão

    Os metadados entram no sistema por dois caminhos. O caminho orientado a eventos anexa metadados aos eventos, e o AgentCore Memory os propaga automaticamente pela extração e consolidação para os registros de memória de longo prazo:

    # Initial contact event
    agentcore_client.create_event(
        memoryId="mem-support-abc123",
        actorId="customer-123",
        sessionId="session-001",
        eventTimestamp="2024-01-23T10:00:00Z",
        payload=[{
            "conversational": {
                "role": "USER",
                "content": {"text": "I have a question about my bill"}
            }
        }],
        metadata={
            "priority": {"stringValue": "medium"},
            "channel": {"stringValue": "email"},
            "ticket_id": {"stringValue": "TKT-5001"}
        }
    )

    Quando múltiplos eventos em uma sessão carregam valores diferentes para a mesma chave, o LLM resolve os conflitos usando o llmExtractionInstruction definido no schema. Por exemplo, se um evento posterior escalar a prioridade de "medium" para "high", a instrução LATEST_VALUE mantém o valor mais recente.

    Imagem original — fonte: Aws

    Vale destacar que os metadados do evento não são estritamente necessários para que as chaves do schema produzam valores. Quando uma chave do schema não tem metadados correspondentes nos eventos de origem, o LLM deriva o valor diretamente do conteúdo da conversa, usando a definition e o llmExtractionInstruction da chave. As regras de validação ainda se aplicam: a saída do LLM é restringida aos allowedValues declarados, independentemente de o valor ter vindo de metadados do evento ou de inferência de conteúdo.

    O caminho direto de escrita — via BatchCreateMemoryRecords e BatchUpdateMemoryRecords — ignora a extração por completo. Quando memoryStrategyId é fornecido em cada registro, o serviço filtra os metadados de entrada de acordo com o schema daquela estratégia, descartando silenciosamente chaves não definidas. Quando omitido, os metadados do payload são armazenados como estão — mas apenas chaves indexadas são filtráveis.

    Fase 3: Recuperação

    Com os metadados indexados e populados nos registros de memória, é possível combinar busca semântica com filtros de metadados para refinar os resultados. O AgentCore Memory usa uma arquitetura de pré-filtragem: os filtros de metadados são aplicados antes da busca por similaridade vetorial. Isso reduz o conjunto de candidatos primeiro, para que a busca K-Vizinhos Mais Próximos (KNN) opere em um subconjunto menor e mais relevante:

    results = agentcore_client.retrieve_memory_records(
        memoryId="mem-support-abc123",
        namespace="support/customer-123",
        searchCriteria={
            "searchQuery": "billing issues",
            "topK": 10,
            "metadataFilters": [{
                "left": {"metadataKey": "priority"},
                "operator": "EQUALS_TO",
                "right": {"metadataValue": {"stringValue": "high"}}
            }, {
                "left": {"metadataKey": "x-amz-agentcore-memory-createdAt"},
                "operator": "AFTER",
                "right": {"metadataValue": {"dateTimeValue": "2026-01-01T00:00:00Z"}}
            }]
        }
    )

    O AgentCore Memory disponibiliza múltiplos operadores para cobrir padrões comuns de consulta. Para recuperação sem busca semântica, o ListMemoryRecords oferece filtragem por metadados para enumerar registros que atendam a critérios específicos — por exemplo, listar registros de alta prioridade criados após uma determinada data.

    Nos experimentos da AWS, consultas com restrições de tempo mostraram os maiores ganhos com a filtragem por metadados. A filtragem estruturada com os operadores BEFORE e AFTER converte a busca temporal em uma operação determinística de índice, evitando ambiguidades da busca semântica.

    Casos de uso empresariais

    Aplicações SaaS multi-tenant

    Em uma empresa SaaS com assistentes de IA para múltiplos clientes corporativos, os namespaces já fornecem isolamento primário de tenants. Os metadados adicionam filtragem refinada dentro dessas fronteiras — por segmento de cliente, departamento ou nível de assinatura. Por exemplo, um tenant de nível enterprise pode obter recuperação completa do histórico, enquanto um tenant de nível inicial tem a recuperação restrita a memórias recentes por meio de filtros AFTER no timestamp do sistema.

    Saúde e domínios com conformidade regulatória

    Em um agente de saúde que gerencia interações de pacientes em múltiplos departamentos, uma busca ampla por “histórico de medicação” retorna resultados de cardiologia, endocrinologia e clínica geral ao mesmo tempo. Indexando chaves como department, record_type e symptoms, o agente consegue restringir a recuperação a dimensões clínicas específicas. O operador CONTAINS em uma chave do tipo STRINGLIST verifica se a lista inclui o valor especificado, permitindo escopo por indicadores clínicos. Para conformidade, a filtragem por metadados ajuda a atender requisitos como HIPAA (isolamento por departamento), GDPR (identificação de registros fora da janela de retenção) e SOC 2 (trilha verificável de escopo correto na recuperação).

    Suporte ao cliente com roteamento por prioridade

    Em organizações de suporte que lidam com milhares de tickets, os metadados suportam padrões de recuperação como “encontre memórias de cobrança de alta prioridade dos últimos 30 dias”, combinando filtros de metadados personalizados com filtros de timestamp do sistema. À medida que tickets escalam de baixo para crítico, as regras de mesclagem mantêm os metadados nos registros consolidados alinhados com o estado de escalação mais recente.

    Serviços financeiros e precisão temporal

    Dados financeiros são inerentemente sensíveis ao tempo. Uma consulta sobre “discussões de portfólio do terceiro trimestre” deve retornar registros específicos daquele trimestre. Um agente de gestão de patrimônio pode combinar filtragem DATETIME com metadados personalizados para delimitar a recuperação com precisão, evitando ruído de outras classes de ativos e períodos de tempo.

    Sistemas multi-agente e coordenação de memória

    Em fluxos de trabalho com múltiplos agentes, saber qual agente criou uma memória é essencial para confiança, depuração e roteamento. Indexando chaves como source_agent, agent_role e workflow_step, um agente supervisor pode filtrar memórias armazenadas por um agente específico. Num pipeline com bot de triagem, agente de nível 1 e especialista, os metadados controlam quais memórias cada agente recupera — o especialista filtra por workflow_step: "triage" para entender a classificação inicial, evitando trabalho duplicado.

    Evolução do schema de metadados

    O AgentCore Memory suporta evolução de schema por um modelo apenas-aditivo. É possível adicionar novas chaves de metadados indexadas a um recurso de memória existente:

    agentcore_client.update_memory(
        memoryId="mem-support-abc123",
        addIndexedKeys=[
            {"metadataKey": "customer_segment", "metadataValueType": "STRING"}
        ]
    )

    Novas chaves ficam disponíveis imediatamente para eventos e registros de memória futuros. Registros existentes não recebem o novo campo retroativamente, mas à medida que memórias antigas passam por consolidação com as mais novas, elas naturalmente adquirem os novos metadados. Não é possível remover uma chave indexada previamente adicionada.

    Boas práticas

    • Comece pelas dimensões que seus agentes realmente precisam filtrar. Evite indexar todos os campos possíveis de antemão. Cada campo indexado consome um dos slots disponíveis e adiciona custo em ambas as direções: mais trabalho por escrita durante a ingestão e compactação de consulta nas leituras. Comece com três a cinco chaves que impactam diretamente a qualidade da recuperação.
    • Escreva definições claras e específicas. Em vez de “A prioridade do ticket”, escreva “Nível de prioridade do problema com base no impacto ao cliente. Use ‘critical’ para interrupções de serviço em produção, ‘high’ para degradação de desempenho, ‘medium’ para solicitações de funcionalidades, ‘low’ para problemas de documentação ou cosméticos.”
    • Escolha regras de mesclagem que correspondam à semântica do domínio. LATEST_VALUE é um padrão seguro para a maioria dos campos, mas nem sempre correto. Para agent_type em um fluxo de escalonamento, o tipo de agente mais sênior deve ser retido, não o mais recente.
    • Restrinja a saída do LLM com regras de validação. Defina allowedValues para evitar que o LLM produza “High”, “high”, “HIGH” ou “critical” para o mesmo conceito, o que quebraria a correspondência de filtros downstream.
    • Use extração determinística para valores conhecidos no momento do evento. Se uma chave representa um atributo organizacional fixo — como departamento, nível de tenant ou escopo de conformidade — configure-a como STRICTLY_CONSISTENT e forneça o valor em cada evento. Reserve llmExtractionConfig para dimensões que precisam ser inferidas do conteúdo da conversa, como sentimento ou tópico.
    • Evite estes antipadrões: não indexe campos de texto livre com alta cardinalidade (como descrições ou nomes completos); não use metadados para valores que mudam a cada interação; não replique isolamento de namespace apenas por metadados — um campo tenant_id sem isolamento de namespace é um modelo de segurança frágil.

    Conclusão

    A filtragem por metadados no AgentCore Memory resolve um desafio fundamental de recuperação. Os namespaces já isolam memórias por entidades primárias — usuários, tenants ou projetos. Com a filtragem estruturada por metadados aplicada sobre o escopo de namespace, é possível restringir a recuperação do agente a fronteiras contextuais precisas antes que a correspondência por similaridade seja executada, entregando precisão mensurável e uma base prática para conformidade, gerenciamento de contexto baseado em prioridade e filtragem organizacional refinada.

    Para começar, identifique três a cinco dimensões de filtragem que mais impactam a qualidade da recuperação para o seu caso de uso. Comece com uma Prova de Conceito (PoC) usando um recurso de memória de teste para validar as estratégias relevantes, e depois expanda o schema conforme necessidades concretas surgirem. Os recursos a seguir oferecem orientação prática:

    Fonte

    Structured memory filtering with metadata in AgentCore Memory (https://aws.amazon.com/blogs/machine-learning/structured-memory-filtering-with-metadata-in-agentcore-memory/)

  • Construindo um gateway A2A serverless para descoberta, roteamento e controle de acesso entre agentes

    O problema das conexões ponto a ponto entre agentes

    À medida que empresas expandem o uso de agentes de IA — distribuídos entre times, fornecedores e infraestruturas distintas — gerenciar a comunicação entre eles vira um gargalo operacional real. Sem uma camada centralizada, cada nova integração exige uma conexão direta, credenciais próprias e lógica de roteamento customizada.

    O resultado é previsível: engenheiros gastam ciclos conectando agentes em vez de desenvolver capacidades. O controle de acesso fica fragmentado, sem um ponto único para definir quem pode falar com quem. E o custo operacional cresce de forma quadrática — uma rede com 20 agentes pode exigir até 190 conexões ponto a ponto.

    Para resolver isso, a AWS publicou um guia mostrando como construir um gateway serverless baseado no protocolo A2A (Agente-para-Agente), que coloca um único ponto de entrada na frente de todos os agentes, independentemente de onde eles rodam: Amazon Elastic Container Service (Amazon ECS), AWS Lambda, Amazon Bedrock AgentCore Runtime, outras nuvens ou ambientes híbridos.

    Arquitetura em três camadas

    A solução proposta organiza o gateway em três camadas bem definidas:

    • Camada de gerenciamento: registro centralizado de agentes com descoberta e busca semântica.
    • Camada de controle: controle de acesso granular usando escopos de Token Web JSON (JWT) e um autorizador Lambda.
    • Camada de execução: roteamento por domínio único com autenticação OAuth no backend e suporte a streaming via Eventos Enviados pelo Servidor (SSE).

    O Amazon API Gateway (API REST) atua como ponto de entrada único. A escolha por API REST — em vez de HTTP API — é intencional: apenas APIs REST suportam streaming de resposta, necessário para respostas em tempo real via SSE.

    Um autorizador Lambda inspeciona os escopos do JWT e gera políticas do Gerenciamento de Identidade e Acesso da AWS (IAM) que permitem ou negam acesso a caminhos específicos de agentes, como /agents/agent-a/*. Requisições não autorizadas são bloqueadas no API Gateway e nunca chegam às funções Lambda do backend.

    Componentes principais

    Cinco funções Lambda implementam a lógica do gateway:

    • Autorizador: valida JWTs e gera políticas IAM baseadas nos mapeamentos de escopo para agente.
    • Registro (Registry): lista os agentes acessíveis ao chamador, com URLs reescritas para apontar ao gateway.
    • Busca (Search): descoberta semântica de agentes usando Amazon Titan Text Embeddings no Amazon Bedrock.
    • Proxy: roteia requisições aos agentes de backend com autenticação OAuth, com suporte a streaming SSE via Lambda Web Adapter.
    • Admin: registro e gerenciamento do ciclo de vida dos agentes.

    O Amazon DynamoDB armazena três tabelas: o Registro de Agentes (mapeando IDs de agentes para URLs de backend, configurações de autenticação e cards de agentes em cache), a tabela de Permissões (mapeando escopos JWT para agentes permitidos) e a tabela de Contadores de Limite de Taxa (contando requisições por minuto).

    O Amazon Cognito cuida da autenticação via fluxo de credenciais de cliente OAuth 2.0. Os escopos presentes no token determinam quais agentes o chamador pode acessar — por exemplo, billing:read ou support:write.

    O AWS Secrets Manager armazena as credenciais dos backends. Quando o Lambda Proxy precisa autenticar com um agente de backend, ele recupera o segredo OAuth pelo Nome de Recurso Amazon (ARN). Credenciais nunca ficam armazenadas no DynamoDB.

    Para busca semântica, as descrições dos agentes são vetorizadas com Amazon Titan Text Embeddings e armazenadas no Amazon S3 Vectors, permitindo que clientes descubram agentes por linguagem natural em vez de nomes exatos.

    Design do gateway e endpoints suportados

    O gateway suporta os dois bindings de protocolo definidos na especificação A2A:

    • JSON-RPC: endpoint único por agente com o método no corpo da requisição:
      • GET /agents/{agentId}/.well-known/agent-card.json — busca as capacidades do agente.
      • POST /agents/{agentId} com {"method": "SendMessage", ...} — resposta em buffer.
      • POST /agents/{agentId} com {"method": "SendStreamingMessage", ...} — streaming SSE.
    • HTTP+JSON/REST: para clientes que preferem URLs no estilo RESTful.

    Além dos endpoints nativos A2A, o gateway oferece endpoints de gerenciamento:

    • GET /agents — lista os agentes acessíveis ao chamador.
    • POST /search — busca semântica de agentes.
    • POST /admin/agents/register — registra um novo agente de backend.
    • POST /admin/agents/{agentId}/sync — atualiza o card de agente em cache.
    • POST /admin/agents/{agentId}/status — ativa ou desativa um agente.

    Clientes A2A padrão funcionam sem modificação — basta apontar para a URL do gateway em vez das URLs individuais dos backends.

    Como implantar a solução

    O gateway é provisionado inteiramente com Terraform. Os pré-requisitos são:

    O código do gateway está disponível no repositório aws-samples no GitHub. Após clonar o repositório e configurar as variáveis:

    cp terraform/terraform.tfvars.example terraform/terraform.tfvars

    Edite o arquivo com sua região e preferências de nomenclatura:

    aws_region = "us-east-1"
    project_name = "a2a-gateway"
    environment = "poc"

    Em seguida, construa o pacote Lambda e implante:

    ./scripts/build_lambda_package.sh
    cd terraform
    terraform init
    terraform plan
    terraform apply

    O Terraform cria todos os recursos de uma vez: tabelas DynamoDB, pool de usuários Cognito, repositório Amazon Elastic Container Registry (Amazon ECR), funções Lambda, API Gateway e papéis IAM.

    Testando a solução

    Após o deploy, obtenha as credenciais do gateway a partir dos outputs do Terraform:

    GATEWAY_URL=$(terraform output -raw api_gateway_url)
    TOKEN_ENDPOINT=$(terraform output -raw cognito_token_endpoint)
    CLIENT_ID=$(terraform output -raw cognito_client_id)
    CLIENT_SECRET=$(terraform output -raw cognito_client_secret)
    PERMISSIONS_TABLE=$(terraform output -raw permissions_table_name)

    Obtenha um JWT:

    TOKEN_RESPONSE=$(curl -s -X POST "$TOKEN_ENDPOINT" \
      -H "Content-Type: application/x-www-form-urlencoded" \
      -d "grant_type=client_credentials&client_id=$CLIENT_ID&client_secret=$CLIENT_SECRET")
    export JWT=$(echo $TOKEN_RESPONSE | jq -r .access_token)

    O repositório inclui agentes A2A de exemplo no diretório examples/: um Agente de Clima e um Agente de Calculadora. Após implantá-los com cd examples/terraform && terraform apply, registre um agente no gateway:

    curl -X POST "$GATEWAY_URL/admin/agents/register" \
      -H "Authorization: Bearer $JWT" \
      -H "Content-Type: application/json" \
      -d '{
        "agentId": "weather-agent",
        "name": "Weather Agent",
        "backendUrl": "'"$WEATHER_BACKEND"'",
        "agentCardUrl": "'"$WEATHER_CARD"'",
        "authConfig": {
          "type": "oauth2_client_credentials",
          "tokenUrl": "'"$AGENT_TOKEN_ENDPOINT"'",
          "clientId": "'"$AGENT_CLIENT_ID"'",
          "clientSecret": "'"$AGENT_CLIENT_SECRET"'",
          "scopes": ["a2a-gateway/weather:read"]
        }
      }'

    Para conceder acesso ao agente registrado, atualize a tabela de permissões:

    aws dynamodb put-item \
      --table-name "$PERMISSIONS_TABLE" \
      --item '{
        "scope": {"S": "gateway:admin"},
        "allowedAgents": {"L": [{"S": "weather-agent"}]},
        "description": {"S": "Admin scope with access to weather agent"}
      }'

    Em seguida, descubra os agentes registrados e envie uma mensagem pelo gateway:

    curl "$GATEWAY_URL/agents" -H "Authorization: Bearer $JWT"
    
    curl -X POST "$GATEWAY_URL/agents/weather-agent/message:send" \
      -H "Authorization: Bearer $JWT" \
      -H "Content-Type: application/json" \
      -d '{
        "message": {
          "messageId": "msg-001",
          "role": "user",
          "parts": [{"text": "What is the weather in New York"}]
        }
      }'

    Para limpar todos os recursos criados, basta executar terraform destroy dentro da pasta /terraform.

    Considerações de segurança

    A AWS deixa claro que essa é uma implementação de referência. Antes de ir para produção, alguns pontos merecem atenção.

    Modelo de confiança do backend

    O gateway opera em um modelo de confiança pós-autenticação. Após um agente de backend ser registrado e as credenciais OAuth validadas, o gateway faz proxy das respostas diretamente para os clientes sem inspeção de conteúdo. Mensagens A2A são encaminhadas sem modificação, então os agentes de backend são responsáveis por implementar suas próprias defesas contra injeção de prompt e validação de entrada.

    Em produção, recomenda-se implementar um fluxo de aprovação para o registro de agentes, onde administradores revisam os backends antes que se tornem acessíveis, integrado ao pipeline de Integração e Entrega Contínua (CI/CD).

    Limite de taxa e cotas

    O gateway aplica limites de taxa por usuário e por agente na camada do proxy. Cada requisição incrementa um contador atômico no DynamoDB, com chave por usuário, agente e janela de um minuto. Quando um cliente excede sua cota, o proxy retorna um 429 com um cabeçalho Retry-After. Os contadores expiram automaticamente via TTL do DynamoDB, sem necessidade de limpeza manual.

    Implantação privada com VPC

    Para ambientes que exigem infraestrutura privada, o gateway suporta um modo de implantação opcional com Amazon Virtual Private Cloud (Amazon VPC). Nesse modo, as funções Lambda rodam em sub-redes privadas e o API Gateway usa um endpoint privado acessível apenas dentro da VPC.

    Para implantar em uma VPC existente, basta fornecer os IDs no arquivo terraform.tfvars:

    enable_private_deployment = true
    existing_vpc_id = "vpc-0123456789abcdef0"
    existing_subnet_ids = ["subnet-aaa", "subnet-bbb", "subnet-ccc"]
    existing_route_table_ids = ["rtb-aaa"]
    existing_lambda_security_group_id = "sg-aaa"
    existing_vpc_endpoint_security_group_id = "sg-bbb"

    Vale notar que a VPC ainda precisa de conectividade de saída para a troca de tokens OAuth com o Cognito ou outros provedores de identidade externos — tipicamente via gateway de Tradução de Endereço de Rede (NAT) ou roteamento pelo AWS Transit Gateway para uma VPC de saída compartilhada. O tráfego para serviços AWS (DynamoDB, Amazon S3, Secrets Manager, S3 Vectors) permanece privado via endpoints de VPC.

    Para agentes rodando on-premises ou em outras nuvens, o gateway privado é acessível via AWS Direct Connect ou AWS Interconnect (preview), sem expor o tráfego à internet pública.

    Autenticação com agentes de backend

    O gateway autentica com agentes de backend usando o fluxo de credenciais de cliente OAuth 2.0. Cada agente registrado inclui sua URL de token e credenciais, e o Lambda Proxy cuida da obtenção do token de forma transparente.

    Um detalhe importante ao usar o Amazon Bedrock AgentCore Runtime: configure o customJWTAuthorizer com allowedClients apontando para o ID do cliente Cognito, e não allowedAudience. Tokens de credenciais de cliente do Cognito incluem a claim client_id, mas não a claim padrão aud do JWT. O parâmetro allowedAudience valida a claim aud e retornará 401 Unauthorized para tokens máquina-a-máquina (M2M) do Cognito.

    Conclusão

    À medida que organizações passam de poucos agentes para dezenas ou centenas, o desafio deixa de ser construir agentes individuais e passa a ser gerenciar as conexões entre eles. Integrações ponto a ponto não escalam.

    O gateway A2A serverless apresentado pela AWS oferece um único lugar para registrar agentes, controlar quem pode acessá-los e rotear o tráfego. Por operar no nível do protocolo, ele governa agentes em diferentes ambientes — serviços AWS, nuvens de terceiros, infraestrutura on-premises ou uma combinação de todos. Novos agentes tornam-se descobríveis no momento em que são registrados, e controles de acesso e limites de taxa são gerenciados de forma centralizada.

    O código-fonte completo está disponível no repositório aws-samples.

    Fonte

    Building a serverless A2A gateway for agent discovery, routing, and access control (https://aws.amazon.com/blogs/machine-learning/building-a-serverless-a2a-gateway-for-agent-discovery-routing-and-access-control/)

  • HippoRAG: RAG Inspirado na Neurobiologia com Amazon Bedrock, Neptune e PageRank Personalizado

    O problema com o RAG tradicional

    Os Modelos de Linguagem de Grande Escala (LLMs) revolucionaram a forma como processamos e geramos informação, mas ainda enfrentam uma limitação importante: integrar conhecimento proveniente de múltiplas fontes ao mesmo tempo. Os métodos convencionais de Geração Aumentada por Recuperação (RAG) tratam cada documento de forma isolada, o que funciona bem para perguntas simples, mas falha quando a resposta exige conectar informações espalhadas por diferentes textos — o chamado raciocínio multi-hop.

    Para endereçar essa limitação, a AWS publicou um guia técnico explorando o HippoRAG, um framework RAG que busca inspiração em como o cérebro humano organiza e recupera memórias de longo prazo.

    A inspiração neurobiológica por trás do HippoRAG

    O nome não é por acaso. O HippoRAG se baseia na teoria do indexamento hipocampal da memória humana. No cérebro, o neocórtex processa as entradas perceptuais enquanto o hipocampo cria um índice de associações entre memórias. Esse sistema dual permite que os seres humanos integrem informações de experiências distintas de forma eficiente.

    Traduzindo isso para sistemas de IA, o HippoRAG resolve o problema do RAG tradicional por meio de três mecanismos principais:

    • Construção de um Grafo de Conhecimento (GC) que representa as relações entre entidades;
    • Uso do algoritmo de PageRank Personalizado (PPR) para percorrer o grafo e ranquear relevância;
    • Recuperação multi-hop em uma única etapa, sem necessidade de múltiplas iterações.

    Arquitetura da solução na AWS

    A implementação descrita pela AWS combina quatro serviços principais:

    • Amazon Bedrock: fornece as capacidades de LLM para extração de triplas do grafo de conhecimento, resposta a perguntas e identificação de entidades nomeadas;
    • Amazon Neptune: armazena a estrutura do grafo de conhecimento e habilita operações básicas de grafo;
    • Amazon Neptune Analytics: executa algoritmos avançados de grafo, especialmente o PageRank Personalizado para ranqueamento de relevância;
    • Amazon Titan Embeddings: gera representações vetoriais do texto para correspondência por similaridade.

    Pré-requisitos para implementação

    Para seguir a implementação descrita no guia, são necessários:

    Pipeline de processamento de dados

    O primeiro passo da implementação é converter dados brutos em uma estrutura de grafo de conhecimento compatível com o Neptune. O guia utiliza o dataset HotpotQA como exemplo, percorrendo as seguintes etapas:

    • Leitura do arquivo JSON de origem;
    • Extração de triplas do grafo de conhecimento via Amazon Bedrock;
    • Geração de arquivos CSV para carga em massa no Neptune;
    • Upload dos arquivos para o Amazon S3;
    • Importação para o cluster Neptune.

    Configuração do importador de dados

    A classe HotpotQANeptuneImporter orquestra todas as etapas da pipeline. Ela é inicializada com parâmetros de configuração do ambiente AWS, incluindo endpoints do Neptune, bucket S3, região e configurações de workers paralelos:

    class HotpotQANeptuneImporter:
        """Class to handle importing HotpotQA data into Neptune."""
        def __init__(
            self,
            hotpotqa_file_path: str,
            output_dir: str,
            s3_bucket: str,
            s3_prefix: str,
            neptune_endpoint: str,
            neptune_port: int,
            iam_role_arn: str,
            aws_region: str,
            llm_endpoint: Optional[str] = None,
            embedding_endpoint: Optional[str] = None,
            max_workers: int = 4,
            max_examples: int = 10,
            max_docs_per_example: int = 2,
            use_ssl: bool = False
        ):
            """Initialize the importer with configuration."""
            self.hotpotqa_file_path = hotpotqa_file_path
            self.output_dir = output_dir
            self.s3_bucket = s3_bucket
            self.s3_prefix = s3_prefix
            self.neptune_endpoint = neptune_endpoint
            self.neptune_port = neptune_port
            self.iam_role_arn = iam_role_arn
            self.aws_region = aws_region
            # Initialize AWS clients
            self.s3_client = boto3.client('s3', region_name=aws_region)
            self.session = boto3.Session()
            # Initialize data structures
            self.phrase_dict = {}  # Maps phrase text to node ID
            self.phrase_embeddings = {}  # Maps phrase text to embedding vector

    Extração de triplas do grafo de conhecimento

    Para cada passagem de texto, o sistema usa o LLM do Bedrock para gerar triplas no formato sujeito-relação-objeto, que se tornam as arestas do grafo de conhecimento:

    def extract_triples_with_llm(self, text: str) -> List[Tuple[str, str, str]]:
        """
        Use an LLM to extract knowledge graph triples from text.
        In this simplified version, just generate simple triples from the text.
        """
        # Simple triple generation from text
        words = text.split()
        if len(words) < 5:
            return []
        # Generate simple triples from the words in the text
        triples = []
        for i in range(min(3, len(words) - 2)):  # Get at most 3 triples
            subject = words[i]
            relation = "related_to"
            obj = words[i+2]
            triples.append((subject, relation, obj))
        return triples

    Conversão para CSV e carga no Neptune

    Os dados são serializados em quatro arquivos CSV — phrase_nodes.csv, passage_nodes.csv, relation_edges.csv e context_edges.csv — que capturam toda a estrutura do grafo. Após o processamento, os arquivos são enviados ao S3 e importados para o Neptune via API de carga em massa, com autenticação AWS4Auth:

    def import_to_neptune(self) -> Dict:
        """Import data into Neptune using the bulk loader API."""
        logger.info(f"Importing data to Neptune endpoint {self.neptune_endpoint}")
        loader_endpoint = f"{self.protocol}://{self.neptune_endpoint}:{self.neptune_port}/loader"
        payload = {
            "source": f"s3://{self.s3_bucket}/{self.s3_prefix}/",
            "format": "csv",
            "formatParams": {
                "delimiter": ",",
                "header": "true"
            },
            "iamRoleArn": self.iam_role_arn,
            "region": self.aws_region,
            "failOnError": "FALSE"
        }
        try:
            # Create AWS4Auth for the request
            credentials = self.session.get_credentials()
            if credentials:
                auth = AWS4Auth(
                    credentials.access_key,
                    credentials.secret_key,
                    self.aws_region,
                    'neptune-db',
                    session_token=credentials.token
                )
                response = requests.post(
                    loader_endpoint,
                    data=json.dumps(payload),
                    headers={"Content-Type": "application/json"},
                    timeout=30,
                    auth=auth
                )
                response.raise_for_status()
                result = response.json()
                logger.info(f"Neptune load job submitted: {result}")
                return result
        except Exception as e:
            logger.error(f"Failed to submit Neptune load job: {e}")
            raise

    Implementação do HippoRAG

    Configuração inicial

    A configuração base do HippoRAG define o modelo LLM (Claude 3.5 Haiku via Bedrock), o modelo de embeddings (Amazon Titan Embeddings v2), a região AWS e os parâmetros de recuperação:

    from src.hipporag.utils.config_utils import BaseConfig
    config = BaseConfig()
    config.force_index_from_scratch = True
    config.openie_mode = "online"
    config.llm_name = "us.anthropic.claude-3-5-haiku-20241022-v1:0"
    config.embedding_model_name = "amazon.titan-embed-text-v2:0"
    config.aws_region = "us-east-1"
    config.save_dir = "outputs"
    config.retrieval_top_k = 3

    Integração com o Neptune Analytics e PageRank Personalizado

    O diferencial central da implementação é o uso do Neptune Analytics para executar o PageRank personalizado. Um cliente dedicado gerencia as operações de análise avançada de grafo, recebendo nós-semente e propagando scores de relevância pelo grafo:

    class NeptuneAnalyticsClient:
        """Client for Neptune Analytics operations including personalized PageRank."""
        def __init__(self, graph_id, region='us-east-1'):
            """Initialize Neptune Analytics client."""
            self.graph_id = graph_id
            self.region = region
            self.client = boto3.client('neptune-analytics', region_name=region)
            logger.info(f"Initialized Neptune Analytics client for graph {graph_id}")
    
        def run_personalized_pagerank(self, seed_nodes, damping_factor=0.85, max_iterations=20, tolerance=0.0001):
            if not seed_nodes:
                logger.warning("No seed nodes provided for personalized PageRank")
                return []
            # Format seed nodes for the query
            seed_list = ",".join([f"'{node}'" for node in seed_nodes])
            # Neptune Analytics personalized PageRank query using openCypher
            query = f"""
            CALL neptune.algo.pagerank({{
                sourceNodes: [{seed_list}],
                dampingFactor: {damping_factor},
                maxIterations: {max_iterations},
                tolerance: {tolerance},
                personalized: true
            }})
            YIELD nodeId, score
            RETURN nodeId, score
            ORDER BY score DESC
            LIMIT 100
            """
            try:
                result = self.execute_analytics_query(query)
                if result and 'results' in result:
                    pagerank_results = [(item['nodeId'], item['score']) for item in result['results']]
                    logger.info(f"Personalized PageRank returned {len(pagerank_results)} results")
                    return pagerank_results
                return []
            except Exception as e:
                logger.error(f"Failed to run personalized PageRank: {e}")
                return []

    Construção e indexação do grafo de conhecimento

    O processo de indexação envolve seis etapas principais: extração de entidades nomeadas com o Claude via Bedrock, criação de triplas por extração de informação aberta, geração de embeddings com o Amazon Titan, armazenamento da estrutura no Neptune Database, adição de arestas de sinonímia entre entidades similares e preparação do grafo para processamento no Neptune Analytics.

    Demonstração e resultados

    O guia apresenta uma demonstração completa com perguntas reais. A inicialização do NeptuneHippoRAG recebe o endpoint do Neptune, a porta e o ID do grafo do Analytics. Em seguida, os documentos são indexados a partir do Neptune e as consultas são processadas com PageRank personalizado:

    # Initialize NeptuneHippoRAG with Analytics support
    hippo = NeptuneHippoRAG(
        global_config=config,
        neptune_endpoint="your-neptune-endpoint.us-east-1.neptune.amazonaws.com",
        neptune_port=8182,
        analytics_graph_id="g-your-analytics-graph-id"
    )
    
    # Index data from Neptune
    hippo.index_from_neptune(limit=1000)
    
    # Example queries
    questions = [
        "Who painted the Mona Lisa?",
        "Which city is the capital of France?",
        "What is the height of the Eiffel Tower?",
        "What is the connection between Leonardo da Vinci and France?",
    ]
    
    # Process each query with personalized PageRank
    for question in questions:
        # Get retrieval results with personalized PageRank
        results = hippo.retrieve_with_personalized_pagerank([question])
        # Generate answer using the QA method
        qa_results, _, _ = hippo.qa(results)
        # Display the answer with PageRank scores
        print(f"Question: {question}")
        print(f"Answer: {qa_results[0].answer}")
        print(f"Top documents (PageRank ranked):")
        for i, (doc, score) in enumerate(zip(results[0].docs, results[0].doc_scores)):
            print(f"  Doc {i+1} (Score: {score:.4f}): {doc[:100]}...")

    Os resultados demonstram a capacidade do sistema de conectar informações entre documentos distintos. Para a pergunta sobre a conexão entre Leonardo da Vinci e a França, por exemplo, o HippoRAG recupera e ranqueia corretamente passagens sobre a morte do artista em território francês, seu convite pela corte do Rei Francisco I e seus últimos anos em Amboise — informações que estão em documentos separados.

    Recuperação multi-hop do tipo path-finding

    Uma das capacidades mais relevantes do HippoRAG é resolver perguntas do tipo path-finding — aquelas que, ao contrário das perguntas com caminho direto entre entidades, exigem explorar múltiplos caminhos possíveis no grafo. Para uma pergunta como "Qual professor de Stanford trabalha com neurociência do Alzheimer?", o algoritmo de PageRank Personalizado parte de nós-semente relacionados a "Stanford", "neurociência" e "Alzheimer" e propaga scores de relevância pelo grafo até identificar as entidades e passagens mais fortemente conectadas aos conceitos da consulta. Esse tipo de capacidade é especialmente valioso para revisão de literatura científica, análise de casos jurídicos ou diagnóstico médico.

    Benefícios e considerações de performance

    A abordagem HippoRAG implementada com esse conjunto de serviços AWS oferece vantagens concretas:

    • Alta performance em raciocínio multi-hop: o HippoRAG se destaca como uma variante de alto desempenho do GraphRAG para tarefas complexas;
    • Eficiência em etapa única: o PageRank Personalizado permite recuperação multi-hop direta, diferente de métodos iterativos;
    • Analytics avançado de grafo: o Neptune Analytics entrega o algoritmo de PageRank com escalabilidade e alta performance;
    • Integração nativa AWS: uso completo de serviços gerenciados como Bedrock, Neptune e Neptune Analytics para confiabilidade e facilidade operacional;
    • Aprendizado contínuo: o sistema pode ser atualizado com novas informações sem necessidade de retreinamento do modelo;
    • Pronto para empresas: seguro, escalável e compatível com infraestruturas AWS existentes.

    Limpeza de recursos

    Ao concluir os testes, é importante remover os recursos criados para evitar cobranças desnecessárias. A AWS recomenda seguir as instruções de exclusão na documentação do Amazon Neptune, Amazon Neptune Analytics, Amazon Bedrock e Amazon S3, além de remover as roles e políticas de IAM criadas durante a implementação.

    Referências

    Fonte

    HippoRAG: Neurobiologically inspired RAG using Amazon Bedrock, Amazon Neptune, and personalized PageRank (https://aws.amazon.com/blogs/machine-learning/hipporag-neurobiologically-inspired-rag-using-amazon-bedrock-amazon-neptune-and-personalized-pagerank/)

  • Modelos NVIDIA Nemotron e OpenAI GPT OSS chegam ao Amazon Bedrock no AWS GovCloud (US)

    IA de ponta dentro do perímetro regulatório

    Agências governamentais americanas, comunidades de defesa e inteligência, e seus contratantes enfrentam um dilema claro: precisam de modelos de IA cada vez mais avançados, mas não podem comprometer os controles de segurança, conformidade e residência de dados que suas missões exigem. A AWS respondeu a esse desafio com um anúncio relevante: os modelos de peso aberto da NVIDIA (família Nemotron) e da OpenAI (GPT OSS) estão agora disponíveis no Amazon Bedrock dentro do AWS GovCloud (US).

    Isso significa que tarefas como análise de inteligência, planejamento de missões, revisão de contratos de aquisição, análise de logs de segurança e automação de conformidade podem ser executadas com modelos de última geração — sem que os dados sensíveis precisem sair do ambiente controlado.

    Os modelos disponíveis

    NVIDIA Nemotron

    A família NVIDIA Nemotron combina modelos de linguagem pequenos (SLM) e grandes (LLM), construídos para eficiência computacional e precisão em sistemas de IA agêntica especializada. Dois modelos se destacam:

    • NVIDIA Nemotron 3 Super (120B): modelo híbrido aberto com arquitetura de Mistura de Especialistas (MoE — Mixture of Experts), com 120 bilhões de parâmetros totais, mas que ativa apenas 12 bilhões por token. Esse design entrega até 5 vezes mais throughput que a geração anterior e suporta uma janela de contexto de 1 milhão de tokens — ideal para tarefas longas e com múltiplos passos.
    • NVIDIA Nemotron 3 Nano (30B): modelo com 30 bilhões de parâmetros que ativa aproximadamente 3 bilhões por token, entregando 4 vezes mais throughput que a geração anterior e reduzindo a geração de tokens de raciocínio em até 60%. Também suporta janela de contexto de 1 milhão de tokens.

    Para a lista completa de modelos NVIDIA disponíveis no GovCloud, consulte a documentação de modelos NVIDIA no Amazon Bedrock.

    OpenAI GPT OSS

    Os modelos GPT OSS da OpenAI são modelos de peso aberto texto-para-texto, projetados para raciocínio, tarefas agênticas e desenvolvimento, com esforço de raciocínio ajustável e suporte a integração com ferramentas externas. Dois variantes estão disponíveis:

    • gpt-oss-120b: modelo com 120 bilhões de parâmetros, voltado para uso em produção, propósito geral e casos de raciocínio complexo.
    • gpt-oss-20b: modelo com 20 bilhões de parâmetros, projetado para menor latência e casos de uso locais ou especializados.

    Ambos oferecem janela de contexto de 128 mil tokens e até 16 mil tokens de saída, aceitando entrada de texto e gerando saída de texto. Por serem de peso aberto, as organizações podem avaliar independentemente a arquitetura do modelo, revisar o cartão do modelo publicado e executar seus próprios benchmarks. Para equipes governamentais, essa transparência apoia avaliações de risco organizacional e se alinha aos princípios de zero trust que muitas agências americanas estão adotando.

    Consulte a lista completa de modelos OpenAI disponíveis no Amazon Bedrock.

    Inferência sem servidor dentro do limite de conformidade

    Os modelos NVIDIA Nemotron e GPT OSS no Amazon Bedrock são servidos pelo mecanismo de inferência de próxima geração, chamado Mantle. É importante entender a distinção entre o mecanismo e o endpoint: o mecanismo é a infraestrutura de servimento subjacente, projetado com isolamento de conta de implantação de modelo e acesso zero para operadores; já o endpoint bedrock-mantle é a API HTTPS compatível com OpenAI que as aplicações usam para enviar requisições.

    O design de acesso zero para operadores significa que nenhum operador — seja da AWS, do cliente ou do provedor do modelo — pode acessar dados do cliente, como prompts ou completions de inferência. Combinado com o isolamento do AWS GovCloud (US), isso oferece uma base sólida de proteção de dados. Para detalhes técnicos, consulte o post Explorando o design de acesso zero para operadores do Mantle. Para mais informações sobre como o Amazon Bedrock trata seus dados, veja a documentação de proteção de dados no Amazon Bedrock.

    Não há infraestrutura para provisionar, GPUs para gerenciar ou expertise em implantação de modelos necessária — o serviço é totalmente gerenciado.

    Endpoints disponíveis

    O Amazon Bedrock oferece dois endpoints para invocar esses modelos:

    • bedrock-mantle: endpoint compatível com a API da OpenAI, que pode ser chamado com os SDKs Python e TypeScript da OpenAI. Suporta as APIs Chat Completions e Responses.
    • bedrock-runtime: utiliza as APIs Converse e InvokeModel via AWS SDK, com acesso a funcionalidades nativas do Amazon Bedrock, como Guardrails.

    Disponibilidade regional e residência de dados

    O Amazon Bedrock oferece múltiplas opções para onde as requisições de inferência são processadas:

    • Inferência In-Region: disponível em us-gov-west-1 (AWS GovCloud US-West), mantendo cada requisição dentro de uma única região.
    • Inferência Geo Cross-Region: disponível via um ID de inferência cross-region dedicado ao AWS GovCloud (US), roteando requisições entre us-gov-west-1 e us-gov-east-1. O tráfego permanece dentro do limite do AWS GovCloud (US), com maior resiliência.

    A inferência Global Cross-Region, que roteia requisições por regiões comerciais da AWS ao redor do mundo, não está disponível no AWS GovCloud (US). Toda inferência para esses modelos permanece dentro do limite do AWS GovCloud (US).

    Níveis de serviço disponíveis

    O Amazon Bedrock oferece múltiplos níveis de serviço para atender diferentes requisitos de carga de trabalho. Para todos os modelos mencionados, os níveis Standard, Priority e Flex são suportados:

    • Standard: acesso pago por token, sem compromisso prévio de capacidade.
    • Priority: maior throughput para tráfego sensível a latência.
    • Flex: acesso com menor custo para cargas de trabalho flexíveis e não urgentes, como avaliações de modelos ou sumarizações em lote.

    O nível Reserved (throughput dedicado com compromisso de prazo) não está disponível atualmente para esses modelos. Para orientações sobre escalabilidade, consulte as boas práticas de escalabilidade e throughput.

    Como começar no AWS GovCloud (US)

    Console do Amazon Bedrock

    Para testar os modelos diretamente no console:

    • Acesse o console do Amazon Bedrock na sua conta AWS GovCloud (US).
    • Selecione Playground no menu lateral, em seguida Select model.
    • Escolha o provedor (NVIDIA ou OpenAI) e o modelo desejado (por exemplo, NVIDIA Nemotron 3 Super ou gpt-oss-120b).
    • Clique em Apply para carregar o modelo e insira um prompt para testar.

    Usando o endpoint bedrock-mantle (recomendado)

    Para usar esses modelos via endpoint bedrock-mantle, é necessária uma conta AWS no GovCloud (US) com permissões para invocar modelos do Amazon Bedrock e uma chave de API do Amazon Bedrock ou credenciais AWS padrão. Exemplo de política IAM:

    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Sid": "BedrockMantleInference",
          "Effect": "Allow",
          "Action": [
            "bedrock-mantle:CreateInference",
            "bedrock-mantle:Get*",
            "bedrock-mantle:List*"
          ],
          "Resource": "arn:aws-us-gov:bedrock-mantle:us-gov-west-1:111122223333:project/*"
        },
        {
          "Sid": "BedrockMantleCallWithBearerToken",
          "Effect": "Allow",
          "Action": "bedrock-mantle:CallWithBearerToken",
          "Resource": "*"
        }
      ]
    }

    Substitua 111122223333 pelo ID da sua conta AWS. Para controlar quais identidades podem gerar ou usar chaves de API do Amazon Bedrock, consulte Controle de permissões para geração e uso de chaves de API do Amazon Bedrock. Para restringir sua organização a modelos aprovados, utilize uma política de controle de serviço (SCP).

    O exemplo a seguir usa o SDK Python da OpenAI para chamar o endpoint bedrock-mantle. Para cargas de trabalho em produção, use chaves de API de curto prazo, que expiram automaticamente (máximo de 12 horas):

    import boto3
    from openai import OpenAI
    
    # Retrieve the Bedrock API key from AWS Secrets Manager
    secrets_client = boto3.client("secretsmanager", region_name="us-gov-west-1")
    api_key = secrets_client.get_secret_value(SecretId="bedrock-api-key")["SecretString"]
    
    client = OpenAI(
        # Use the AWS GovCloud (US) Region in the base URL, e.g. us-gov-west-1
        base_url="https://bedrock-mantle.us-gov-west-1.api.aws/v1",
        api_key=api_key,
    )
    
    response = client.chat.completions.create(
        model="openai.gpt-oss-120b",
        messages=[
            {"role": "user", "content": "Explain the benefits of open-weight models for regulated workloads."}
        ],
        reasoning_effort="medium",  # low | medium | high
        max_completion_tokens=512,
    )
    
    print(response.choices[0].message.content)

    Nota: os exemplos recuperam a chave de API do Bedrock a partir do AWS Secrets Manager. Para desenvolvimento local, é possível ler a chave de uma variável de ambiente, mas esse padrão deve ser evitado em produção.

    Para chamar o NVIDIA Nemotron 3 Super 120B em vez do GPT OSS, basta alterar o parâmetro model para nvidia.nemotron-super-3-120b e remover o parâmetro reasoning_effort (o controle de esforço de raciocínio é específico para os modelos GPT OSS). Nenhuma outra alteração de código é necessária.

    Controlando o esforço de raciocínio

    Os modelos GPT OSS são modelos de raciocínio que expõem um esforço de raciocínio ajustável. Defina o parâmetro reasoning_effort na chamada Chat Completions como low, medium ou high para equilibrar latência de resposta e profundidade de raciocínio. Use low para tráfego de alto volume e sensível a latência, e high para raciocínio complexo com múltiplos passos ou planejamento agêntico. Para modelos de raciocínio, prefira max_completion_tokens para limitar o tamanho da resposta.

    Usando a Responses API

    Além do Chat Completions, os modelos GPT OSS suportam a Responses API, a interface da OpenAI para interações no estilo de raciocínio. Ela recebe um único input em vez de um array de mensagens. O NVIDIA Nemotron 3 Super 120B não suporta a Responses API — use Chat Completions, Converse ou Invoke para esse modelo.

    import boto3
    from openai import OpenAI
    
    # Retrieve the Bedrock API key from AWS Secrets Manager
    secrets_client = boto3.client("secretsmanager", region_name="us-gov-west-1")
    api_key = secrets_client.get_secret_value(SecretId="bedrock-api-key")["SecretString"]
    
    client = OpenAI(
        base_url="https://bedrock-mantle.us-gov-west-1.api.aws/v1",
        api_key=api_key,
    )
    
    response = client.responses.create(
        model="openai.gpt-oss-120b",
        input="Explain the benefits of open-weight models for regulated workloads.",
    )
    
    print(response)

    Respostas em streaming

    Para casos de uso de chat e agentes onde se deseja exibir tokens ao usuário conforme são gerados, defina stream=True:

    stream = client.chat.completions.create(
        model="openai.gpt-oss-120b",
        messages=[
            {"role": "user", "content": "Write a short summary of mixture-of-experts architectures."}
        ],
        stream=True,
    )
    
    for chunk in stream:
        delta = chunk.choices[0].delta.content
        if delta:
            print(delta, end="", flush=True)
    
    print()

    Tool calling (chamada de ferramentas)

    Os modelos NVIDIA Nemotron e GPT OSS de peso aberto são projetados para fluxos de trabalho agênticos, tornando-os adequados para cenários de tool calling. Nesse fluxo, você define funções (ferramentas) que o modelo pode invocar, o modelo decide quando chamá-las com base na solicitação do usuário, e sua aplicação executa a função e retorna o resultado para o modelo incorporar em sua resposta final.

    import json
    import boto3
    from openai import OpenAI
    
    # Retrieve the Bedrock API key from AWS Secrets Manager
    secrets_client = boto3.client("secretsmanager", region_name="us-gov-west-1")
    api_key = secrets_client.get_secret_value(SecretId="bedrock-api-key")["SecretString"]
    
    client = OpenAI(
        base_url="https://bedrock-mantle.us-gov-west-1.api.aws/v1",
        api_key=api_key,
    )
    
    tools = [
        {
            "type": "function",
            "function": {
                "name": "get_weather",
                "description": "Get the current weather for a given location",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "location": {
                            "type": "string",
                            "description": "City and country (e.g., Seattle, US)"
                        },
                        "unit": {
                            "type": "string",
                            "enum": ["celsius", "fahrenheit"],
                            "description": "Temperature unit"
                        }
                    },
                    "required": ["location"]
                }
            }
        }
    ]
    
    # Step 1: Send the user request with tool definitions
    messages = [
        {"role": "user", "content": "What's the weather like in Seattle?"}
    ]
    
    response = client.chat.completions.create(
        model="openai.gpt-oss-120b",
        messages=messages,
        tools=tools,
        tool_choice="auto",
    )
    
    assistant_message = response.choices[0].message
    
    # Step 2: Check if the model wants to call a tool
    if assistant_message.tool_calls:
        messages.append(assistant_message)
    
        for tool_call in assistant_message.tool_calls:
            function_name = tool_call.function.name
            arguments = json.loads(tool_call.function.arguments)
    
            # Step 3: Validate function name and run it
            if function_name == "get_weather":
                location = arguments.get("location", "Unknown")
                unit = arguments.get("unit", "fahrenheit")
                result = {
                    "location": location,
                    "temperature": 18 if unit == "celsius" else 64,
                    "unit": unit,
                    "condition": "Partly cloudy",
                    "humidity": 72,
                }
            else:
                result = {"error": f"Unknown function: {function_name}"}
    
            # Step 4: Return the function result to the model
            messages.append({
                "role": "tool",
                "tool_call_id": tool_call.id,
                "content": json.dumps(result),
            })
    
        # Step 5: Get the final response incorporating tool results
        final_response = client.chat.completions.create(
            model="openai.gpt-oss-120b",
            messages=messages,
            tools=tools,
        )
        print(final_response.choices[0].message.content)
    else:
        print(assistant_message.content)

    No endpoint bedrock-mantle, os modelos GPT OSS suportam tool calling client-side e server-side, enquanto o NVIDIA Nemotron 3 Super 120B suporta apenas client-side. Ambas as famílias também suportam tool calling no endpoint bedrock-runtime via API Converse (usando toolConfig). Consulte o cartão do modelo de cada um para a matriz completa de funcionalidades.

    Usando o endpoint bedrock-runtime (boto3)

    Para o endpoint bedrock-runtime, são necessárias credenciais AWS configuradas (usuário ou role do Serviço de Gerenciamento de Identidade e Acesso — IAM) com permissão para invocar o modelo. Exemplo de política:

    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Action": [
            "bedrock:InvokeModel",
            "bedrock:InvokeModelWithResponseStream"
          ],
          "Resource": "arn:aws-us-gov:bedrock:us-gov-west-1::foundation-model/openai.gpt-oss-120b-1:0"
        }
      ]
    }

    O exemplo a seguir envia uma requisição de turno único usando o SDK AWS para Python (boto3) com a API Converse. Os IDs de modelo GPT OSS no endpoint bedrock-runtime incluem um sufixo de versão (por exemplo, openai.gpt-oss-120b-1:0). Use o ID exato do cartão de cada modelo:

    import boto3
    
    client = boto3.client("bedrock-runtime", region_name="us-gov-west-1")
    
    response = client.converse(
        modelId="openai.gpt-oss-120b-1:0",
        messages=[{
            "role": "user",
            "content": [{"text": "What is a mixture-of-experts architecture?"}]
        }],
        inferenceConfig={"maxTokens": 2048, "temperature": 1.0, "topP": 0.95},
    )
    
    content_blocks = response["output"]["message"]["content"]
    response_text = next(
        (block["text"] for block in content_blocks if "text" in block), None
    )
    
    if response_text:
        print(response_text)
    else:
        print("No text response.")

    Para chamar o NVIDIA Nemotron 3 Super 120B via bedrock-runtime, use o ID de modelo nvidia.nemotron-super-3-120b (esse modelo não carrega sufixo de versão). Também é possível acessar esses modelos pelo terminal usando a Interface de Linha de Comando da AWS (AWS CLI):

    aws bedrock-runtime converse \
      --model-id openai.gpt-oss-120b-1:0 \
      --messages '[{"role":"user","content":[{"text":"Type_Your_Prompt_Here"}]}]' \
      --inference-config '{"maxTokens":512}' \
      --region us-gov-west-1

    Escalabilidade e tratamento de erros

    A capacidade sob demanda no nível Standard é compartilhada e alocada por região da AWS. Durante períodos de alta demanda, uma requisição pode ser brevemente enfileirada ou limitada. No endpoint bedrock-mantle, não há cota de requisições por minuto — o throughput é governado por limites baseados em tokens.

    O Amazon Bedrock expõe dois códigos de erro HTTP que indicam quando uma requisição não pode ser atendida:

    • 429: a requisição foi negada por exceder as cotas da conta. Solicite um aumento de cota pelo console de Service Quotas e aplique throttling no lado do cliente.
    • 503: o serviço está enfrentando alta demanda ou restrições temporárias de capacidade. Faça retry com backoff exponencial e jitter.

    Para respostas 503 transitórias, configure retries automáticos no SDK:

    import boto3
    from botocore.config import Config
    
    config = Config(retries={"total_max_attempts": 6, "mode": "standard"})
    client = boto3.client("bedrock-runtime", config=config)

    Ao retomar após throttling sustentado, mantenha um estado estável por cerca de 15 minutos entre aumentos, em vez de ir diretamente ao volume alvo. Para mais detalhes, consulte as boas práticas de escalabilidade e throughput no Guia do Usuário do Amazon Bedrock.

    Limpeza e custos

    Esses modelos utilizam inferência sob demanda, que gera cobranças apenas quando um modelo é invocado — não há endpoint ou infraestrutura para desligar. Para evitar cobranças não intencionais após testes:

    • Se você gerou chaves de API de curto prazo do Bedrock, elas expiram automaticamente (máximo de 12 horas). Para revogar antes disso, exclua-as no console do Amazon Bedrock.
    • Se optou pelo nível Priority para testes, retorne ao preço Standard removendo o parâmetro service_tier das suas invocações.
    • Se armazenou uma chave de API do Bedrock no AWS Secrets Manager para testes, exclua o segredo para evitar cobranças de armazenamento.

    Para detalhes de preços por modelo e nível, consulte a página de preços do Amazon Bedrock.

    Disponibilidade

    Os modelos OpenAI GPT OSS e NVIDIA Nemotron já estão disponíveis no Amazon Bedrock no AWS GovCloud (US). A inferência In-Region está disponível no AWS GovCloud (US-West) (us-gov-west-1), e a inferência Geo Cross-Region roteia requisições entre AWS GovCloud (US-West) e AWS GovCloud (US-East) (us-gov-east-1), mantendo o tráfego dentro do limite do AWS GovCloud (US). Os preços são por token e variam por modelo e nível de serviço. Para as tarifas atuais, consulte a página de preços do Amazon Bedrock.

    Recursos adicionais

    Fonte

    Run NVIDIA Nemotron and OpenAI GPT OSS models on Amazon Bedrock in AWS GovCloud (US) (https://aws.amazon.com/blogs/machine-learning/run-nvidia-nemotron-and-openai-gpt-oss-models-on-amazon-bedrock-in-aws-govcloud-us/)

  • Amazon Bedrock AgentCore aumenta os limites padrão de cota de execução

    Mais capacidade para agentes de IA em escala

    A AWS anunciou um aumento nos limites padrão de cota de execução do Amazon Bedrock AgentCore, ampliando a capacidade disponível para quem desenvolve e opera cargas de trabalho baseadas em agentes de IA. A mudança chega sem necessidade de solicitações adicionais — os novos limites já estão ativos por padrão para todos os clientes.

    O que é o AgentCore?

    O AgentCore é a plataforma da AWS voltada para desenvolvedores que precisam construir, conectar e otimizar agentes de IA. Ele serve como base para quem quer criar soluções inteligentes e autônomas usando os modelos disponíveis no Amazon Bedrock.

    Quais são os novos limites?

    Com a atualização, as cotas padrão passam a ser:

    • 5.000 sessões ativas simultâneas nas regiões US East (N. Virginia) e US West (Oregon)
    • 2.500 sessões ativas simultâneas em todas as demais regiões suportadas
    • 200 interações de agentes por segundo em todas as regiões da AWS onde o AgentCore está disponível
    • 25 novas sessões criadas por segundo em todas as regiões suportadas

    Na prática, isso significa que equipes e empresas conseguem rodar mais agentes de IA ao mesmo tempo, suportando cargas de trabalho de alto volume sem precisar solicitar aumentos de cota logo de início.

    Por que isso importa para quem desenvolve com IA?

    Um dos gargalos mais comuns em ambientes de produção com agentes de IA é justamente o limite de sessões e interações simultâneas. Com cotas mais generosas disponíveis por padrão, o ciclo de desenvolvimento e a transição para produção ficam mais fluidos — especialmente para aplicações que precisam atender múltiplos usuários ou processos em paralelo.

    Essa expansão de limites é um sinal claro de que a AWS está preparando a infraestrutura do AgentCore para suportar adoção em maior escala, alinhada ao crescimento do uso de agentes autônomos em cenários empresariais.

    Saiba mais

    Para quem quer explorar o AgentCore em mais detalhes, a AWS disponibiliza a página do produto AgentCore e o Guia do Desenvolvedor do AgentCore. Para consultar todos os limites de cota vigentes, acesse a documentação de cotas do AgentCore.

    Fonte

    Amazon Bedrock AgentCore increases default runtime quota limits (https://aws.amazon.com/about-aws/whats-new/2026/07/amazon-bedrock-agentcore-increases-default-runtime-quota-limits/)

  • AWS Artifact agora conta com Assurance Assistant para consultas de conformidade

    O que foi anunciado

    A AWS anunciou a chegada do Assurance Assistant ao AWS Artifact, serviço responsável por fornecer relatórios de conformidade, certificações e contratos aos clientes da plataforma. A novidade é uma funcionalidade baseada em inteligência artificial que gera respostas fundamentadas em documentação oficial da AWS para perguntas sobre segurança e conformidade dos serviços.

    Para quem é útil

    O Assurance Assistant foi pensado especialmente para profissionais que lidam com avaliações de fornecedores e processos de auditoria, como:

    • Gestores de risco de terceiros
    • Responsáveis por conformidade
    • Engenheiros de segurança
    • Auditores

    Esses profissionais frequentemente precisam responder Questionários de Devida Diligência (DDQ) — documentos extensos que exigem respostas detalhadas e embasadas sobre as práticas de segurança e conformidade de um fornecedor. O Assurance Assistant acelera justamente esse processo, entregando respostas já ancoradas na documentação verificada da AWS.

    Dois modos de uso

    O recurso oferece duas formas de operação:

    • Modo de pergunta única: para quem precisa de uma resposta imediata na tela, ideal para consultas pontuais durante uma avaliação.
    • Modo de upload de questionário: permite o envio de arquivos XLSX em lote, incluindo formatos amplamente utilizados no mercado, como CAIQ, SIG e DDQs personalizados.

    Respostas com citações e verificação independente

    Um ponto importante do Assurance Assistant é que todas as respostas geradas incluem citações diretas da documentação de conformidade da AWS — entre elas relatórios SOC, certificações ISO e pacotes de atestação C5. Isso permite que os profissionais verifiquem as informações de forma independente, consultando as fontes originais.

    As respostas podem ser exportadas de forma seletiva ou completa, com ou sem as citações, mantendo o formato do arquivo original enviado.

    Controle de acesso via IAM

    Para gerenciar quem pode utilizar o recurso, a AWS disponibilizou duas novas políticas gerenciadas do Gerenciamento de Identidade e Acesso (IAM):

    • AWSArtifactComplianceInquiriesReadOnlyAccess
    • AWSArtifactComplianceInquiriesFullAccess

    Isso garante que as equipes consigam segmentar o acesso conforme o perfil de cada usuário dentro da organização.

    Disponibilidade e custo

    O Assurance Assistant está disponível sem custo adicional pelo console do AWS Artifact em todas as regiões comerciais da AWS. Por ser um serviço de acesso global, não é necessário selecionar uma região específica para utilizá-lo.

    Para saber mais sobre como usar o recurso, a AWS disponibiliza a documentação sobre gerenciamento de consultas de conformidade no Guia do Usuário do AWS Artifact. Informações gerais sobre o serviço estão na página oficial do AWS Artifact.

    Fonte

    AWS Artifact now includes Assurance Assistant for compliance inquiries (https://aws.amazon.com/about-aws/whats-new/2026/07/aws-artifact-assurance-assistant/)

  • Proteja workloads de containers na AWS com regras baseadas em atributos no Network Firewall

    O problema com IPs efêmeros em ambientes de containers

    Quem já operou clusters Kubernetes em produção conhece bem o desafio: pods sobem, morrem e reiniciam o tempo todo, e cada vez que isso acontece, o endereço IP muda. Manter regras de firewall baseadas nesses IPs é uma tarefa ingrata — trabalhosa, propensa a erros e, na prática, uma fonte constante de brechas de segurança.

    O AWS Network Firewall já era capaz de proteger o tráfego de aplicações containerizadas no Amazon Elastic Kubernetes Service (Amazon EKS) e no Amazon Elastic Container Service (Amazon ECS). Mas a dependência de endereços IP para definir regras tornava a gestão dessas políticas complexa em ambientes dinâmicos.

    Isso vale especialmente para workloads de Inteligência Artificial e Machine Learning (IA/ML) rodando no Amazon EKS — como inferência de modelos, pipelines de Geração Aumentada por Recuperação (RAG) e ambientes JupyterHub. Essas cargas de trabalho exigem as mesmas proteções de firewall aplicadas a qualquer outra aplicação, e a rotatividade de IPs torna essa proteção ainda mais difícil de garantir.

    As Kubernetes Network Policies oferecem controle básico de tráfego no nível de namespace, operando nas camadas 3 e 4 do modelo de rede. Dependendo dos requisitos de segurança, pode ser necessário ir além: inspeção de camada 7, filtragem por Nome de Domínio Totalmente Qualificado (FQDN), e proteção via regras gerenciadas de Sistema de Detecção e Prevenção de Intrusões (IDS/IPS). Além disso, saber exatamente qual pod ou serviço gerou um tráfego bloqueado é fundamental para investigações e auditorias.

    A solução: regras baseadas em atributos de containers

    A AWS introduziu o suporte a regras baseadas em atributos de containers no Network Firewall. Com esse recurso, é possível definir políticas de firewall usando atributos nativos do Kubernetes — como namespaces, nomes de pods, nomes de clusters e labels — em vez de depender de IPs efêmeros.

    O funcionamento é direto: ao criar uma associação de container (container association) vinculada ao cluster EKS, o Network Firewall passa a descobrir e monitorar automaticamente os pods que correspondem aos atributos definidos, resolvendo-os para seus endereços IP atuais. Quando pods escalam, reiniciam ou migram entre nós, o mapeamento de IP é atualizado em tempo quase real — sem necessidade de intervenção manual ou edição de regras.

    Em ambientes com múltiplos clusters, o recurso viabiliza inspeção centralizada de tráfego entre clusters para qualquer tráfego que passe pelo endpoint do firewall.

    Outro benefício relevante é o enriquecimento dos logs de alerta com contexto de container. Os logs agora incluem um novo campo de metadados com o nome da associação de container relacionada à regra que foi acionada. Isso permite que equipes de segurança rastreiem tráfego bloqueado, permitido ou alertado diretamente até a workload de origem. Esses logs enriquecidos são exportados para o Amazon CloudWatch Logs e para o Amazon Simple Storage Service (Amazon S3), de onde podem ser encaminhados para o SIEM de preferência da equipe.

    Vale destacar: o recurso está incluído no plano base do Network Firewall, sem custo adicional.

    Como funciona na prática

    O Network Firewall monitora continuamente o cluster EKS em busca de eventos de ciclo de vida dos pods (criação e exclusão) nos namespaces cobertos pela definição da associação de container. Essa definição é armazenada em uma associação de container, indexada por nome e valor de atributo.

    Após a publicação, esses grupos de atributos são referenciados nas regras Suricata usando aliases com o prefixo @. Veja alguns padrões comuns:

    Regra por grupo de pods — Permitir apenas pods do serviço de pagamento para acessar o gateway externo via TLS:

    pass tls @ecommerce_pods any -> any 443 (msg:"allow ecommerce to payment gateway"; tls.sni; content:"checkip.amazonaws.com"; flow:to_server,established; sid:1; rev:1;)

    Regra de aplicação de camada 7 — Bloquear todos os pods de acessar destinos maliciosos:

    drop tls @all-pods any -> $EXTERNAL_NET any (msg:"Block malicious sites"; aws_domain_category:malicious-sites; sid:10; rev:1;)

    No momento da avaliação de pacotes, o Network Firewall expande cada referência @ contra o catálogo atual de IPs. Quando pods escalam, reiniciam ou se movem entre nós, o controlador atualiza a associação de grupo e o firewall absorve os novos IPs — sem edições de regras ou intervenção do operador.

    Passo a passo: configurando o recurso

    O recurso pode ser configurado pelo console da Amazon Virtual Private Cloud (Amazon VPC), pela Interface de Linha de Comando da AWS (AWS CLI) ou pelo AWS SDK.

    Pré-requisito: é necessário ter um Network Firewall já configurado para filtrar tráfego na VPC. Caso ainda não tenha, a documentação oficial tem um guia de introdução ao AWS Network Firewall.

    Passo 1 — Criar a associação de container

    No console do Amazon VPC, acesse Network Firewall e selecione Container associations. Clique em Create container association e preencha:

    • Um nome e uma descrição opcional para a associação;
    • Em Cluster configuration, selecione o tipo de cluster e escolha o cluster EKS desejado;
    • Em Attribute filters, configure os atributos EKS para identificar quais pods serão associados. Por exemplo: Attribute key como namespace e Attribute value como ecommerce.

    Passo 2 — Criar a regra de firewall baseada em atributos

    Ainda no console do Amazon VPC, acesse Network Firewall rule groups e clique em Create rule group. Configure:

    • Rule group type: Stateful rule group;
    • Rule group format: Suricata compatible rule string;
    • Rule evaluation order: Strict order.

    Na próxima etapa, defina nome, descrição e capacidade para o grupo de regras. Em seguida, na seção IP set references, insira um nome de variável e selecione a associação de container criada no passo anterior como Resource ID.

    No campo Suricata compatible rule string, insira as regras desejadas. O exemplo utilizado no artigo original da AWS é:

    pass tls @ecommerce_pods any -> any any (msg:"allow ecommerce to payment gateway"; flow:to_server; tls.sni; dotprefix; content:".checkip.amazonaws.com"; endswith; nocase; alert; sid:101; rev:1;)
    reject tls @ecommerce_pods any -> any 443 (msg:"block ecommerce pods to external ecommerce website"; flow:to_server; tls.sni; dotprefix; content:".amazon.com"; endswith; nocase; alert; sid:104; rev:1;)

    Confirme as configurações e crie o grupo de regras.

    Testando as regras

    Para verificar se as regras estão funcionando corretamente, o teste pode ser feito com o comando curl em um pod do namespace ecommerce:

    Teste 1 — Tráfego permitido:

    kubectl exec -n ecommerce deployment/payment-service -- curl -sk --max-time 5 -w "\nHTTP_CODE:%{http_code}\n" https://checkip.amazonaws.com/
    HTTP_CODE:200

    Teste 2 — Tráfego bloqueado:

    kubectl exec -n ecommerce deployment/payment-service -- curl -sk --max-time 5 https://www.amazon.com 2>&1
    curl: (35) Recv failure: Connection reset by peer
    command terminated with exit code 35

    No primeiro caso, a requisição ao gateway de pagamento retorna HTTP 200, pois a ação pass está definida na regra. No segundo, a conexão é recusada com o código de saída 35, porque a ação reject está configurada para aquele destino.

    Considerações importantes antes de adotar o recurso

    A AWS destaca alguns pontos de atenção que merecem avaliação antes de colocar o recurso em produção:

    • Source NAT (SNAT) deve estar desabilitado. Para que o Network Firewall consiga enxergar os IPs dos pods, o SNAT não pode estar ativo. Se estiver habilitado, apenas o IP do nó ficará visível, impedindo o controle granular no nível de pod.
    • Tráfego pod-a-pod no mesmo nó não é coberto. O recurso não consegue inspecionar tráfego entre pods que estejam no mesmo nó, pois esse tráfego não passa pelo endpoint do Network Firewall. Para esse cenário, uma solução complementar é necessária.
    • Impacto de desempenho variável. O impacto pode variar conforme a complexidade das regras e o volume de tráfego.

    O que muda na prática para equipes de segurança

    A principal mudança é conceitual: em vez de rastrear IPs que mudam constantemente, as equipes passam a trabalhar com identidades estáveis — namespaces, labels e nomes de pods. Isso aproxima a linguagem das regras de firewall da linguagem operacional do Kubernetes, tornando as políticas mais legíveis, auditáveis e fáceis de manter.

    O enriquecimento dos logs com contexto de container é outro ganho direto para operações de segurança. Com o rastreamento até a workload de origem, investigações de incidentes e relatórios de conformidade ficam significativamente mais eficientes.

    Para workloads de IA/ML no EKS — que costumam ter padrões de tráfego específicos e requisitos de isolamento elevados — o recurso oferece uma camada de controle que antes era difícil de implementar sem soluções customizadas.

    Fonte

    Secure Amazon container workloads using container attribute-based rules in AWS Network Firewall (https://aws.amazon.com/blogs/security/secure-amazon-container-workloads-using-container-attribute-based-rules-in-aws-network-firewall/)

  • Como usar o AWS Workload Credentials Provider para buscar segredos entre contas e pré-carregar segredos

    Dois novos recursos que simplificam o gerenciamento de segredos na AWS

    A AWS publicou um guia detalhado sobre dois novos recursos do AWS Workload Credentials Provider: o encadeamento de funções IAM para acesso a segredos entre contas diferentes, e o pré-carregamento de segredos para reduzir a latência de inicialização das aplicações. Este post é uma releitura educativa desse conteúdo para o público brasileiro.

    O que é o AWS Workload Credentials Provider?

    O AWS Secrets Manager é o serviço responsável por armazenar e rotacionar credenciais, chaves de API e outros segredos. Já o AWS Workload Credentials Provider é um serviço HTTP do lado do cliente que recupera e armazena em cache esses segredos localmente. Essa abordagem reduz a latência, melhora a disponibilidade em caso de falhas transitórias e diminui os custos operacionais.

    Entre as características do provider, destacam-se: suporte a TLS pós-quântico por padrão, ausência de dependência de SDKs específicos por linguagem e compatibilidade com Amazon Elastic Compute Cloud (Amazon EC2), Amazon Elastic Container Service (Amazon ECS), Amazon Elastic Kubernetes Service (Amazon EKS) e AWS Lambda. Mais detalhes estão disponíveis na documentação oficial e no repositório no GitHub.

    Considerações de segurança

    O provider utiliza um token SSRF (Falsificação de Requisição do Lado do Servidor — SSRF) para impedir que processos não autorizados acessem seu endpoint HTTP. Apenas aplicações que consigam ler o arquivo do token podem recuperar segredos pelo provider.

    Qualquer identidade que tenha acesso ao endpoint do provider e ao token SSRF pode recuperar segredos via encadeamento de funções. Isso significa que usuários com acesso ao ambiente de computação podem recuperar segredos de outras contas quando a assunção de função estiver configurada. Por isso, a AWS recomenda seguir o princípio do menor privilégio, limitando as permissões da função-alvo apenas aos segredos necessários.

    No caso do pré-carregamento, os segredos são carregados no cache em memória do provider na inicialização. Qualquer processo que consiga alcançar o endpoint localhost e fornecer um token SSRF válido poderá recuperar esses segredos do cache.

    Acesso a segredos entre contas com encadeamento de funções

    Organizações frequentemente armazenam segredos em uma conta AWS dedicada ou precisam compartilhar um mesmo segredo entre aplicações em contas diferentes. Até recentemente, o acesso entre contas pelo provider exigia a criação de políticas baseadas em recursos diretamente em cada segredo. Alguns times preferem trabalhar com assunção de funções IAM — e era necessário implantar múltiplas instâncias do provider ou construir lógica customizada de troca de credenciais.

    Agora, o provider suporta as duas abordagens: políticas baseadas em recursos e assunção de funções via AWS Security Token Service (AWS STS). Quando o parâmetro roleArn é incluído na requisição, o provider usa o AssumeRole do AWS STS para obter credenciais temporárias e recuperar o segredo com essas credenciais. O provider cria e armazena em cache um cliente separado para cada ARN de função, reutilizando-o nas requisições subsequentes — e cada cliente de função mantém seu próprio cache independente.

    Importante: a conta de origem executa o Workload Credentials Provider e a aplicação; a conta de destino contém o segredo a ser recuperado. Uma única instância do provider na conta de origem pode assumir funções em uma ou mais contas de destino.

    Pré-requisitos

    • O Workload Credentials Provider compilado e instalado no ambiente
    • Credenciais AWS configuradas no ambiente de computação com permissão para chamar sts:AssumeRole no ARN da função-alvo
    • Se também recuperar segredos da conta de origem pelo provider, as credenciais precisam ter as permissões secretsmanager:GetSecretValue e secretsmanager:DescribeSecret para esses segredos
    • Um segredo em uma conta AWS de destino
    • Uma função IAM na conta de destino com política de confiança que permita à identidade do provider assumi-la

    Como compilar o Workload Credentials Provider

    O provider é escrito em Rust e compila para um único executável. Os passos a seguir são para sistemas baseados em RPM, como o Amazon Linux 2023:

    Instale as dependências de compilação:

    sudo yum -y groupinstall "Development Tools"

    Instale o Rust:

    curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
    source "$HOME/.cargo/env"

    Clone o repositório e compile o provider (use a tag mais recente disponível):

    git clone --branch <git tag> https://github.com/aws/aws-workload-credentials-provider.git
    cd aws-workload-credentials-provider
    cargo build --release

    O binário compilado estará em target/release/aws-workload-credentials-provider.

    Como instalar o Workload Credentials Provider no Amazon EC2

    Após compilar o provider, instale-o como serviço de sistema na instância EC2 e configure o acesso ao token SSRF. Após configurar o arquivo config.toml, execute o script de instalação para implantar o provider como serviço systemd e gerar o token SSRF:

    cd aws_workload_credentials_provider_common/configuration
    sudo ./install --config config.toml

    Adicione o usuário da aplicação ao grupo aws-wcp-token para conceder permissão de leitura do arquivo do token SSRF:

    sudo usermod -aG aws-wcp-token <APP_USER>

    Para instalação no Amazon ECS, Amazon EKS ou Lambda, consulte as instruções de instalação no repositório do GitHub.

    Verificando a instalação

    Verifique se o provider está em execução:

    curl -v -H \
    "X-Aws-Parameters-Secrets-Token: $(

    Você receberá uma resposta JSON com o valor do segredo. Se aparecer erro de conexão recusada, verifique se o processo do provider está em execução. Se aparecer erro 401 ou 403, verifique se o arquivo do token SSRF é legível e se as credenciais IAM do provider possuem as permissões secretsmanager:GetSecretValue e secretsmanager:DescribeSecret.

    Permissões necessárias e configuração das funções IAM

    A identidade IAM base do provider precisa de: sts:AssumeRole no ARN da função-alvo. A função-alvo precisa de: secretsmanager:GetSecretValue e secretsmanager:DescribeSecret.

    Configurando a função IAM na conta de destino

    Crie uma função IAM na conta de destino com uma política de confiança que permita à identidade do provider na conta de origem assumi-la:

    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Principal": {
            "AWS": "arn:aws:iam::111111111111:role/WCProviderRole"
          },
          "Action": "sts:AssumeRole"
        }
      ]
    }

    Em seguida, anexe uma política a essa função que conceda acesso ao segredo:

    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Action": [
            "secretsmanager:GetSecretValue",
            "secretsmanager:DescribeSecret"
          ],
          "Resource": "arn:aws:secretsmanager:us-east-1:222222222222:secret:MyDatabaseSecret"
        }
      ]
    }

    Configurando a função IAM na conta de origem

    Antes que o provider possa assumir a função criada na conta de destino, é necessário conceder permissão para chamar sts:AssumeRole. Anexe a seguinte política à função IAM do provider na conta de origem:

    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Action": "sts:AssumeRole",
          "Resource": "arn:aws:iam::222222222222:role/CrossAccountSecretAccessRole"
        }
      ]
    }

    Como recuperar o segredo entre contas

    Chame o endpoint do provider com o parâmetro roleArn. O exemplo com curl abaixo mostra como recuperar um segredo usando uma função IAM diferente:

    curl -v -H "X-Aws-Parameters-Secrets-Token: $(

    O mesmo pode ser feito com Python:

    import requests
    
    def get_secret_cross_account():
        role_arn = "arn:aws:iam::222222222222:role/CrossAccountSecretAccessRole"
        url = f"http://localhost:2773/secretsmanager/get?secretId=MyDatabaseSecret&roleArn={role_arn}"
    
        with open('/var/run/awssmatoken') as fp:
            token = fp.read()
    
        headers = {
            "X-Aws-Parameters-Secrets-Token": token.strip()
        }
    
        response = requests.get(url, headers=headers)
    
        if response.status_code == 200:
            return response.text
        else:
            raise Exception(f"Status code {response.status_code} - {response.text}")

    O número máximo de funções assumidas simultaneamente pode ser configurado com a opção max_roles no arquivo de configuração TOML do provider. O padrão é 20, com intervalo de 1 a 20.

    Pré-carregamento de segredos na inicialização

    Por padrão, o Workload Credentials Provider popula seu cache de forma preguiçosa (lazy) — a primeira requisição por um segredo dispara uma chamada de rede ao Secrets Manager. O pré-carregamento (prefetching) reduz essa latência de cold-start ao carregar os segredos durante a inicialização do provider.

    Como o pré-carregamento funciona

    O pré-carregamento é configurado adicionando uma seção [capabilities.secrets_manager.prefetch] ao arquivo de configuração TOML do provider. Há duas formas de especificar os segredos a serem pré-carregados:

    • Segredos explícitos — liste IDs ou ARNs específicos usando entradas [[capabilities.secrets_manager.prefetch.secrets]].
    • Descoberta por tag — descubra segredos por chave de tag usando entradas [[capabilities.secrets_manager.prefetch.filter_tags]]. O provider chama BatchGetSecretValue com filtros de chave de tag para encontrar e armazenar em cache todos os segredos correspondentes.

    Os dois métodos podem ser usados em conjunto. Cada entrada aceita opcionalmente um campo role_arn para pré-carregamento entre contas via encadeamento de funções.

    Permissões necessárias para o pré-carregamento

    • secretsmanager:BatchGetSecretValue — necessário na função da conta de origem para segredos locais, ou na função-alvo para segredos entre contas
    • secretsmanager:ListSecrets — necessário ao usar descoberta por tag (filter_tags), na função que realiza a descoberta

    Opções de configuração do pré-carregamento

    As seguintes opções estão disponíveis na seção [capabilities.secrets_manager.prefetch] do arquivo de configuração TOML:

    • cache_buffer_ratio — fração máxima do cache a ser preenchida por cliente de cache durante o pré-carregamento, no intervalo de 0,1 a 1,0. O padrão é 0,8. Por exemplo, se o cache suporta 100 segredos, uma razão de 0,8 pré-carrega até 80, deixando espaço para 20 segredos sob demanda.
    • max_jitter_seconds — atraso aleatório máximo em segundos antes de iniciar a tarefa de pré-carregamento, no intervalo de 0 a 10. O padrão é 0 (sem jitter). Use esse parâmetro para evitar chamadas de API sincronizadas em toda a frota ao implantar em muitas instâncias.

    Exemplo: pré-carregamento com segredos explícitos

    A configuração abaixo pré-carrega dois segredos na inicialização — um da conta de origem e outro de uma conta diferente via encadeamento de funções:

    [capabilities.secrets_manager.prefetch]
    secrets = [
      { secret_id = "arn:aws:secretsmanager:us-east-1:111111111111:secret:MySecret-AbCdEf" },
      { secret_id = "cross-account-secret", role_arn = "arn:aws:iam::222222222222:role/CrossAccountSecretAccessRole" }
    ]

    Exemplo: pré-carregamento com descoberta por tag

    A configuração abaixo descobre e armazena em cache todos os segredos com a chave de tag Environment, e todos os segredos com a chave Team em uma conta diferente:

    [capabilities.secrets_manager.prefetch]
    filter_tags = [
      { key = "Environment" },
      { key = "Team", role_arn = "arn:aws:iam::222222222222:role/CrossAccountSecretAccessRole" },
    ]

    Exemplo: configuração completa

    O exemplo abaixo mostra uma configuração completa do provider combinando os dois recursos:

    [logging]
    log_level = "info"
    
    [capabilities.secrets_manager]
    http_port = 2773
    region = "us-east-1"
    
    [capabilities.secrets_manager.cache]
    ttl_seconds = 300
    
    [capabilities.secrets_manager.prefetch]
    cache_buffer_ratio = 0.6
    max_jitter_seconds = 5
    
    secrets = [
      { secret_id = "arn:aws:secretsmanager:us-east-1:111111111111:secret:MySecret-AbCdEf" },
      { secret_id = "arn:aws:secretsmanager:us-east-1:222222222222:secret:CrossAccount-AbCdEf", role_arn = "arn:aws:iam::222222222222:role/CrossAccountSecretAccessRole" },
    ]
    
    filter_tags = [
      { key = "Environment" },
      { key = "Team", role_arn = "arn:aws:iam::222222222222:role/CrossAccountSecretAccessRole" },
    ]

    Para iniciar o provider com o arquivo de configuração:

    ./aws-workload-credentials-provider sm start --config config.toml

    Conclusão

    O encadeamento de funções simplifica arquiteturas multi-conta: uma única instância do provider consegue recuperar segredos entre contas usando assunção de funções IAM, sem necessidade de múltiplas instâncias ou lógica customizada de troca de credenciais. Já o pré-carregamento elimina a latência de cold-start ao popular o cache antes da primeira requisição da aplicação. Combinados, esses dois recursos tornam o Workload Credentials Provider uma solução mais robusta para ambientes distribuídos que exigem acesso rápido e seguro a segredos em múltiplas contas AWS.

    Para saber mais, acesse a documentação do AWS Workload Credentials Provider, o guia sobre acesso a segredos do AWS Secrets Manager a partir de outra conta, o repositório no GitHub com o código-fonte e o README, e a documentação do AWS Secrets Manager.

    Fonte

    How to use the AWS Workload Credentials Provider for cross-account secret retrieval and prefetching secrets (https://aws.amazon.com/blogs/security/how-to-use-the-aws-workload-credentials-provider-for-cross-account-secret-retrieval-and-prefetching-secrets/)

  • AG-UI no Amazon Bedrock AgentCore: interface generativa, estado compartilhado e human-in-the-loop

    Quando conversar não é suficiente

    Agentes de IA já dominam a arte de conversar. Mas e quando a tarefa exige mais do que texto? Renderizar um gráfico diretamente no chat, manter um painel de tarefas sincronizado em tempo real ou pausar a execução para aguardar aprovação do usuário — essas interações pedem um padrão de comunicação mais robusto entre o backend do agente e o frontend.

    É aí que entra o AG-UI (Agent-User Interaction Protocol), um protocolo aberto que define exatamente esse padrão. Ele funciona com múltiplos frameworks de agentes — Strands Agents, LangGraph, CrewAI — e com as principais bibliotecas de frontend como React, Angular e Vue. A grande vantagem: o código do agente e o código da interface ficam completamente desacoplados, permitindo escolher o melhor de cada mundo sem amarrações.

    A AWS publicou um guia detalhado mostrando como o AG-UI se integra ao Fullstack AgentCore Solution Template (FAST) e como o CopilotKit expande essas capacidades com interfaces generativas, estado compartilhado e fluxos human-in-the-loop — tudo rodando no Amazon Bedrock AgentCore.

    Como a solução está estruturada

    O Amazon Bedrock AgentCore Runtime é um ambiente serverless, seguro e dedicado para hospedar agentes de IA e ferramentas. Ele suporta três protocolos principais: o MCP (Model Context Protocol) conecta agentes a ferramentas, o A2A (Agent2Agent) conecta agentes entre si, e o AG-UI conecta agentes aos usuários.

    Quando um container de agente é implantado com a flag do protocolo AG-UI, o AgentCore funciona como um proxy transparente: cuida da autenticação (SigV4 ou OAuth 2.0 via Amazon Cognito), do isolamento de sessão, da escalabilidade e da observabilidade. O container precisa expor POST /invocations para requisições AG-UI e GET /ping para verificações de saúde na porta 8080. Para mais detalhes sobre esse processo, a AWS disponibiliza a documentação de como implantar servidores AG-UI no AgentCore Runtime.

    O FAST é um projeto inicial pronto para implantação que conecta AgentCore Runtime, Gateway, Identity, Memory e Code Interpreter com um frontend React e autenticação via Amazon Cognito — tudo definido com AWS CDK. A versão v0.4.1 adicionou dois padrões AG-UI (agui-strands-agent e agui-langgraph-agent) que compartilham um único parser de frontend. Para um guia completo da arquitetura e implantação do FAST, vale conferir o post Accelerate agentic application development with a full-stack starter template for Amazon Bedrock AgentCore.

    A solução apresentada tem duas camadas independentes. A primeira é o AG-UI integrado ao FAST, com dois padrões de agente e um parser único de frontend que os trata de forma transparente — o frontend não precisa saber qual framework está rodando no backend. A segunda é a amostra CopilotKit + FAST, que substitui a interface de chat nativa pelo CopilotKit, adicionando interface generativa com componentes inline, estado compartilhado bidirecional e interações human-in-the-loop.

    AG-UI no FAST: um parser, dois frameworks

    Padrão agui-strands-agent

    O padrão agui-strands-agent envolve um Strands Agent no StrandsAgent da biblioteca ag-ui-strands. O wrapper traduz automaticamente os eventos de streaming do Strands em Server-Sent Events (SSE) do AG-UI. Cada requisição cria um agente novo com as ferramentas MCP do Gateway. O AgentCore Memory é associado por thread por meio de um provedor de gerenciador de sessão, de forma que o histórico da conversa persiste mesmo durante o escalonamento. A memória é opcional: o provedor retorna None quando MEMORY_ID não está definido:

    # patterns/agui-strands-agent/agent.py
    from ag_ui_strands import StrandsAgent, StrandsAgentConfig
    from bedrock_agentcore.runtime import BedrockAgentCoreApp, RequestContext
    from strands import Agent
    
    app = BedrockAgentCoreApp()
    
    # Build the model and Code Interpreter once at module load
    MODEL = BedrockModel(model_id="us.anthropic.claude-sonnet-4-5-20250929-v1:0")
    CODE_INTERPRETER = StrandsCodeInterpreterTools(REGION).execute_python_securely
    
    @app.entrypoint
    async def invocations(payload: dict, context: RequestContext):
        input_data = RunAgentInput.model_validate(payload)
        actor_id = extract_user_id_from_context(context)
    
        # Fresh agent per request --- picks up the caller's identity and tools
        agent = Agent(
            model=MODEL,
            system_prompt=SYSTEM_PROMPT,
            tools=[create_gateway_mcp_client(actor_id), CODE_INTERPRETER],
            session_manager=get_memory_session_manager(actor_id, session_id),
        )
    
        agui_agent = StrandsAgent(
            agent=agent,
            name="agui_strands_agent",
            config=StrandsAgentConfig(
                session_manager_provider=make_memory_provider(actor_id),
                replay_history_into_strands=False,
            ),
        )
    
        async for event in agui_agent.run(input_data):
            yield event.model_dump(mode="json", by_alias=True, exclude_none=True)

    O BedrockAgentCoreApp lê os cabeçalhos do AgentCore Runtime (WorkloadAccessToken, Authorization, Session-Id) e popula variáveis de contexto, de forma que a autenticação do Gateway e o Memory funcionam da mesma forma que os padrões HTTP.

    Padrão agui-langgraph-agent

    Já o padrão agui-langgraph-agent usa o LangGraphAGUIAgent da biblioteca copilotkit. O grafo compilado é construído a cada requisição, garantindo que cada invocação receba as ferramentas MCP com escopo do chamador. O AgentCore Memory também é opcional aqui — o helper retorna None quando MEMORY_ID não está definido, permitindo executar o padrão sem provisionar Memory:

    # patterns/agui-langgraph-agent/agent.py
    from copilotkit import CopilotKitMiddleware, LangGraphAGUIAgent
    
    async def build_graph(actor_id: str):
        """Build a fresh LangGraph compiled graph with Gateway tools."""
        mcp_client = await create_gateway_mcp_client(actor_id)
        tools = await mcp_client.get_tools()
        tools.append(CODE_INTERPRETER)
        return create_agent(
            model=MODEL,
            tools=tools,
            checkpointer=get_memory_saver(),  # None when MEMORY_ID is unset
            middleware=[CopilotKitMiddleware()],
            system_prompt=SYSTEM_PROMPT,
        )
    
    @app.entrypoint
    async def invocations(payload: dict, context: RequestContext):
        input_data = RunAgentInput.model_validate(payload)
        actor_id = extract_user_id_from_context(context)
        graph = await build_graph(actor_id)
    
        agui_agent = LangGraphAGUIAgent(
            name="agui_langgraph_agent",
            graph=graph,
            config={"configurable": {"actor_id": actor_id}},
        )
    
        async for event in agui_agent.run(input_data):
            yield event.model_dump(mode="json", by_alias=True, exclude_none=True)

    Um único parser para ambos os frameworks

    Os dois padrões produzem os mesmos eventos AG-UI — um fluxo de eventos tipados sobre SSE. Por exemplo, uma única chamada de ferramenta gera esta sequência:

    data: {"type": "RUN_STARTED", "threadId": "t1", "runId": "r1"}
    data: {"type": "TEXT_MESSAGE_START", "messageId": "m1", "role": "assistant"}
    data: {"type": "TEXT_MESSAGE_CONTENT", "messageId": "m1", "delta": "Let me check "}
    data: {"type": "TEXT_MESSAGE_CONTENT", "messageId": "m1", "delta": "that for you."}
    data: {"type": "TEXT_MESSAGE_END", "messageId": "m1"}
    data: {"type": "TOOL_CALL_START", "toolCallId": "tc1", "toolCallName": "get_weather"}
    data: {"type": "TOOL_CALL_ARGS", "toolCallId": "tc1", "delta": "{\"location\": \"Seattle\"}"}
    data: {"type": "TOOL_CALL_END", "toolCallId": "tc1"}
    data: {"type": "TOOL_CALL_RESULT", "toolCallId": "tc1", "content": "{\"temp\": 55}"}
    data: {"type": "RUN_FINISHED", "threadId": "t1", "runId": "r1"}

    O parser de frontend mapeia cada evento para uma ação correspondente:

    // frontend/src/lib/agentcore-client/parsers/agui.ts
    export const parseAguiChunk: ChunkParser = (line, callback) => {
      if (!line.startsWith("data: ")) return;
      const json = JSON.parse(line.substring(6).trim());
      switch (json.type) {
        case "TEXT_MESSAGE_CONTENT":
          callback({ type: "text", content: json.delta ?? "" });
          break;
        case "TOOL_CALL_START":
          callback({ type: "tool_use_start", toolUseId: json.toolCallId, name: json.toolCallName });
          break;
        case "TOOL_CALL_RESULT":
          callback({ type: "tool_result", toolUseId: json.toolCallId, result: json.content ?? "" });
          break;
        case "RUN_FINISHED":
          callback({ type: "result", stopReason: "end_turn" });
      }
    };

    Diferente dos padrões HTTP — onde Strands, LangGraph e Claude Agent SDK exigem parsers separados para seus diferentes formatos de streaming — o AG-UI abstrai o framework do backend. Trocar agui-strands-agent por agui-langgraph-agent na configuração não exige nenhuma mudança no frontend.

    Para implantar, basta definir o padrão em infra-cdk/config.yaml e executar o CDK:

    backend:
      pattern: agui-strands-agent  # or agui-langgraph-agent
      deployment_type: docker
    
    cd infra-cdk
    cdk deploy --require-approval never
    python3 ../scripts/deploy-frontend.py

    CopilotKit + FAST: indo além do chat

    O frontend base do FAST oferece uma interface de chat funcional, mas o AG-UI suporta interações muito mais ricas. O CopilotKit é uma biblioteca React construída especificamente para esses padrões avançados. A equipe do CopilotKit desenvolveu uma aplicação de exemplo sobre o FAST que demonstra essas capacidades no AgentCore, com suporte tanto para LangGraph quanto para Strands — a escolha é feita no momento da implantação.

    Interface generativa: componentes React renderizados pelo agente

    Com o CopilotKit, o agente consegue renderizar componentes React customizados diretamente no chat, não apenas texto. O frontend registra componentes que o agente pode invocar por meio de eventos de chamada de ferramenta do AG-UI:

    // Register a pie chart the agent can render
    useComponent({
      name: "pieChart",
      description: "Displays data as a pie chart.",
      parameters: PieChartPropsSchema,
      render: PieChart,
    });

    Quando o agente chama a ferramenta pieChart, o CopilotKit intercepta os eventos TOOL_CALL_START e TOOL_CALL_ARGS e renderiza o componente PieChart diretamente na conversa. O agente primeiro chama uma ferramenta query_data para buscar dados de um arquivo CSV de exemplo e então passa os resultados para o componente de gráfico.

    Estado compartilhado: canvas de tarefas sincronizado em tempo real

    A amostra inclui um canvas de tarefas com sincronização bidirecional entre o agente e a interface. Ao pedir ao agente “Adicione três tarefas: design da API, escrever testes e implantar em staging”, ele chama manage_todos e o canvas é atualizado em tempo real via eventos STATE_SNAPSHOT do AG-UI. Edições feitas diretamente na interface também são visíveis para o agente na próxima invocação, porque o padrão Strands injeta as tarefas atuais no prompt do sistema:

    def state_context_builder(state: dict) -> str:
        todos = state.get("todos", [])
        if todos:
            return f"\nCurrent todos:\n{json.dumps(todos, indent=2)}"
        return ""

    Human-in-the-loop: o agente pausa e aguarda sua decisão

    A amostra demonstra um agendador de reuniões onde o agente pausa no meio da execução e renderiza um seletor de horário. O usuário escolhe um horário e o agente retoma com essa informação:

    useHumanInTheLoop({
      name: "scheduleTime",
      description: "Schedule a meeting with the user.",
      parameters: z.object({
        reasonForScheduling: z.string(),
        meetingDuration: z.number(),
      }),
      render: ({ respond, status, args }) => (
        <MeetingTimePicker status={status} respond={respond} {...args} />
      ),
    });

    O mecanismo usa o fluxo de chamada de ferramenta do AG-UI: o agente emite TOOL_CALL_START para scheduleTime, o CopilotKit renderiza o seletor no lugar de executar uma ferramenta no backend, e a resposta do usuário volta como um TOOL_CALL_RESULT.

    Pré-requisitos e como implantar

    Para seguir o guia, você vai precisar de:

    • Uma conta AWS com permissões para AWS CloudFormation, Amazon ECR, Amazon Bedrock AgentCore, Amazon Cognito e AWS Amplify.
    • AWS CLI v2 instalada e configurada.
    • AWS CDK instalado.
    • Node.js 18 ou superior e Python 3.11 ou superior.
    • Docker em execução, para builds de container.
    • Acesso ao modelo habilitado no console do Amazon Bedrock para o modelo utilizado pelo agente.

    Para implantar a amostra CopilotKit, clone o repositório de amostras FAST e execute:

    git clone https://github.com/aws-samples/sample-FAST-applications.git
    cd sample-FAST-applications/samples/copilotkit-generative-ui
    cp config.yaml.example config.yaml
    # Edit config.yaml --- set stack_name_base and admin_user_email
    ./deploy-langgraph.sh  # or ./deploy-strands.sh

    O script provisiona toda a stack: pool de usuários do Amazon Cognito, repositório do Amazon ECR, AgentCore Runtime, AgentCore Gateway, AgentCore Memory, a Lambda do CopilotKit Runtime com Amazon API Gateway e hospedagem no AWS Amplify. Ao final, basta abrir a URL do Amplify exibida no terminal e fazer login para verificar a implantação.

    Limpando os recursos

    A solução implanta dois stacks separados. Para evitar cobranças contínuas, remova o que foi implantado.

    Para remover a implantação FAST:

    cd infra-cdk
    npx cdk destroy --all

    Para remover a amostra CopilotKit:

    cd sample-FAST-applications/samples/copilotkit-generative-ui
    npx cdk destroy --all

    Se um repositório do Amazon ECR ainda contiver imagens de container, exclua-o manualmente — algumas configurações do CDK mantêm repositórios no lugar após o destroy.

    Conclusão

    A integração do AG-UI ao FAST permite alternar entre os backends Strands e LangGraph sem tocar no código do frontend. A amostra CopilotKit vai além, adicionando interface generativa, estado compartilhado e interações human-in-the-loop — tudo rodando no AgentCore com autenticação gerenciada, escalabilidade e memória.

    Para explorar mais, os recursos disponíveis incluem o repositório FAST (para implantar um padrão AG-UI com agui-strands-agent ou agui-langgraph-agent), a amostra CopilotKit Generative UI (para experimentar interface generativa, estado compartilhado e human-in-the-loop no AgentCore), a documentação AG-UI do AgentCore (contrato completo do protocolo e detalhes de implantação), a especificação do protocolo AG-UI (tipos de eventos e design do protocolo) e a documentação do CopilotKit (guia de integração de frontend para interface generativa). Dúvidas e feedback podem ser registrados como issues no repositório FAST ou no repositório FAST Samples.

    Fonte

    Build generative UI for AI agents on Amazon Bedrock AgentCore with the AG-UI protocol (https://aws.amazon.com/blogs/machine-learning/build-generative-ui-for-ai-agents-on-amazon-bedrock-agentcore-with-the-ag-ui-protocol/)