{"id":659761,"date":"2025-11-18T02:00:57","date_gmt":"2025-11-18T01:00:57","guid":{"rendered":"https:\/\/blog.jetbrains.com\/?post_type=ai&#038;p=659761"},"modified":"2025-11-18T02:01:00","modified_gmt":"2025-11-18T01:01:00","slug":"koog-a2a-desenvolvimento-de-agentes-de-ia-conectados-no-kotlin","status":"publish","type":"ai","link":"https:\/\/blog.jetbrains.com\/pt-br\/ai\/2025\/11\/koog-a2a-desenvolvimento-de-agentes-de-ia-conectados-no-kotlin\/","title":{"rendered":"Koog \u00d7 A2A: desenvolvimento de agentes de IA conectados no Kotlin"},"content":{"rendered":"<p>Se voc\u00ea j\u00e1 tiver tentado desenvolver um sistema de v\u00e1rios agentes de IA, provavelmente encontrou <em>este problema<\/em>. Ele come\u00e7a bastante simples: voc\u00ea tem um agente escrevendo postagens de blog, outro revisando essas postagens e talvez um terceiro sugerindo ou gerando imagens. Todos eles, isoladamente, s\u00e3o eficazes. Mas faz\u00ea-los trabalharem juntos? \u00c9 aqui que as coisas podem come\u00e7ar a dar errado.<\/p>\n<p>Cada agente fala sua pr\u00f3pria &#8220;l\u00edngua&#8221;: um usa uma interface de API diferente, outro tem seu pr\u00f3prio formato de mensagens e cada um pode ter requisitos espec\u00edficos de autentica\u00e7\u00e3o. Faz\u00ea-los se comunicarem significa escrever c\u00f3digo espec\u00edfico de integra\u00e7\u00e3o para cada conex\u00e3o. Em vez de se concentrar em tornar os seus agentes mais inteligentes, r\u00e1pidos ou \u00fateis, voc\u00ea fica ocupado com a cria\u00e7\u00e3o de conex\u00f5es entre eles.<\/p>\n<h2 class=\"wp-block-heading\">O que faz o A2A: a camada de comunica\u00e7\u00e3o entre agentes<\/h2>\n<p><strong>\u00c9 aqui que entra o <a href=\"https:\/\/a2a-protocol.org\/latest\/\" target=\"_blank\" rel=\"noopener\">protocolo Agent2Agent (A2A)<\/a>.<\/strong><\/p>\n<p>Com o A2A, os seus agentes podem se comunicar diretamente atrav\u00e9s de um protocolo padronizado, que funciona como um tradutor universal para o seu ecossistema de IA. O agente que escreve os seus blogs passa conte\u00fado de forma transparente para o seu revisor, que aciona o seu gerador de imagens, enquanto o revisor retorna corre\u00e7\u00f5es e o gerador de imagens solicita esclarecimentos sobre o estilo. Tudo isso \u00e9 orquestrado atrav\u00e9s de uma camada unificada de comunica\u00e7\u00e3o.<\/p>\n<p>Em vez de gerenciar dezenas de conex\u00f5es ponto a ponto, o A2A fornece:<\/p>\n<ul>\n<li><strong>Conectividade plug-and-play<\/strong>: Os agentes descobrem uns aos outros e se conectam automaticamente.<\/li>\n<li><strong>Mensagens padronizadas<\/strong>: Um formato unificado, um protocolo claro e nenhuma dor de cabe\u00e7a com tradu\u00e7\u00f5es.<\/li>\n<li><strong>Orquestra\u00e7\u00e3o incorporada<\/strong>: Defina os fluxos de trabalho uma \u00fanica vez e deixe o A2A cuidar da coordena\u00e7\u00e3o.<\/li>\n<li><strong>Escalabilidade sem complexidade<\/strong>: Adicione ou reutilize agentes sem reescrever as conex\u00f5es j\u00e1 existentes.<\/li>\n<\/ul>\n<p>O resultado? Voc\u00ea ocupa o seu tempo melhorando os recursos dos seus agentes e n\u00e3o depurando as conversas entre eles. E o melhor \u00e9 que voc\u00ea pode implementar os seus agentes na linguagem ou framework que preferir. Para usu\u00e1rios da JVM, o Koog \u00e9 uma das melhores escolhas e na vers\u00e3o 0.5.0, ele se integra de forma transparente com o ecossistema do A2A.<\/p>\n<h2 class=\"wp-block-heading\">O que faz o Koog: o mecanismo de orquestra\u00e7\u00e3o interna<\/h2>\n<p>O Koog \u00e9 um framework baseado em Kotlin para desenvolver agentes de IA visando JVM, Android, iOS, WebAssembly e aplicativos de navegador. Ele \u00e9 excelente para:<\/p>\n<ul>\n<li><strong>Gerenciar fluxos de trabalho complexos<\/strong>: Projete estrat\u00e9gias baseadas em grafos, com suporte a loops, branches, fallbacks e execu\u00e7\u00e3o de branches paralelos.<\/li>\n<li><strong>Componentes prontos para usar<\/strong>: Desfrute dos n\u00f3s incorporados ao Koog para chamar LLMs e ferramentas externas, resumir o hist\u00f3rico de mensagens e executar estrat\u00e9gias inteiras.<\/li>\n<li><strong>Orquestra\u00e7\u00e3o de ferramentas<\/strong>: Transforme qualquer fun\u00e7\u00e3o no seu c\u00f3digo em uma ferramenta que o seu agente de IA pode utilizar, sequencialmente ou at\u00e9 em paralelo.<\/li>\n<li><strong>Integra\u00e7\u00e3o nativa com MCP<\/strong>: Conecte-se de forma transparente a qualquer servidor de MCP, usando o Kotlin MCP SDK.<\/li>\n<li><strong>Suporte a mem\u00f3ria e armazenamento<\/strong>: Suporte a mem\u00f3ria de agentes e fluxos de trabalho de RAG (Retrieval-Augmented Generation), com gerenciamento eficiente de contextos.<\/li>\n<li><strong>Toler\u00e2ncia a falhas<\/strong>: Novas tentativas, cria\u00e7\u00e3o de checkpoints, mecanismos de recupera\u00e7\u00e3o e persist\u00eancia de estados, tudo isso incorporado para garantir uma execu\u00e7\u00e3o confi\u00e1vel.<\/li>\n<li><strong>Observabilidade<\/strong>: Tratamento completo de eventos de agentes, grava\u00e7\u00e3o de logs e suporte a OpenTelemetry, incorporando integra\u00e7\u00f5es com o Langfuse e o W&amp;B Weave.<\/li>\n<\/ul>\n<p>Em resumo, o Koog \u00e9 excelente para desenvolver agentes de IA confi\u00e1veis.<\/p>\n<h2 class=\"wp-block-heading\">Por que combinar o Koog com o A2A<\/h2>\n<p>O Koog e o A2A trabalham em camadas diferentes da pilha de agentes de IA. Quando usados juntos, eles se complementam e preenchem as lacunas.<\/p>\n<p><strong>O Koog j\u00e1 cuida das partes mais dif\u00edceis<\/strong> da orquestra\u00e7\u00e3o de IA necess\u00e1ria para o uso corporativo no mundo real.<\/p>\n<p><strong>O A2A junta a pe\u00e7a que faltava:<\/strong> ele possibilita que os agentes do Koog se comuniquem com quaisquer outros agentes compat\u00edveis com A2A no seu ecossistema. Em vez de criarem integra\u00e7\u00f5es espec\u00edficas para cada servi\u00e7o externo, os seus fluxos de trabalho de IA no Koog podem descobrir e usar outros agentes automaticamente.<\/p>\n<p><strong>O resultado \u00e9 uma combina\u00e7\u00e3o perfeita:<\/strong> os fluxos de trabalho avan\u00e7ados do Koog tornam-se tarefas do A2A, que qualquer agente pode solicitar, enquanto os agentes do Koog aproveitam todo o poder do ecossistema do A2A. E como o Koog \u00e9 executado no back-end, no pr\u00f3prio dispositivo e em ambientes de navegador, voc\u00ea pode entregar IA interconectada de forma mais ampla e eficaz do que nunca.<\/p>\n<p>Como isso \u00e9 poss\u00edvel? Vamos ver!<\/p>\n<h2 class=\"wp-block-heading\">O protocolo A2A<\/h2>\n<p>O protocolo A2A define os componentes essenciais para a comunica\u00e7\u00e3o entre agentes:<\/p>\n<ul>\n<li><strong>Descoberta de agentes<\/strong> atrav\u00e9s de fichas de agentes padronizadas (documentos em JSON que descrevem capacidades).<\/li>\n<li><strong>Formatos de mensagens<\/strong> para solicita\u00e7\u00f5es e respostas, com esquemas consistentes.<\/li>\n<li>Gerenciamento do <strong>ciclo de vida das tarefas<\/strong>, com estados claros: solicitada \u2192 em processamento \u2192 conclu\u00edda\/falhada.<\/li>\n<li><strong>Camadas de transporte<\/strong>, como JSON-RPC, gRPC e REST.<\/li>\n<li><strong>Esquemas de seguran\u00e7a<\/strong> usando OAuth2-padr\u00e3o, chaves de API e tokens de JWT.<\/li>\n<li><strong>Tratamento de erros<\/strong> com c\u00f3digos de erro padronizados.<\/li>\n<\/ul>\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"1008\" height=\"752\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/image-50.png\" alt=\"\" class=\"wp-image-645498\" \/><\/figure>\n<h3 class=\"wp-block-heading\">Fichas de agentes: cart\u00f5es de visita digitais<\/h3>\n<p>Cada agente no ecossistema do A2A publica suas capacidades atrav\u00e9s de uma &#8220;ficha de agente&#8221; \u2014 um arquivo padr\u00e3o JSON, hospedado em alguma URL, como <em>\/.conhecida\/ficha-de-agente.json<\/em>, no dom\u00ednio do agente. A ficha de agente funciona como um cart\u00e3o de visita digital, possibilitando que outros agentes descubram os servi\u00e7os que ele fornece.<\/p>\n<p>Tipicamente, uma ficha de agente cont\u00e9m:<\/p>\n<ul>\n<li><strong>Informa\u00e7\u00f5es b\u00e1sicas<\/strong>, tais como o nome do agente, a descri\u00e7\u00e3o e a vers\u00e3o.<\/li>\n<li><strong>Habilidades<\/strong>: O que o agente pode fazer (por exemplo, redigir documentos, revisar textos, analisar dados ou gerar imagens).<\/li>\n<li><strong>Endpoints<\/strong>: Como se comunicar com o agente.\u00a0<\/li>\n<li><strong>Outras informa\u00e7\u00f5es opcionais<\/strong>: Capacidades habilitadas, autentica\u00e7\u00e3o e outras.<\/li>\n<\/ul>\n<p>Esse mecanismo de descoberta elimina a necessidade de trabalho manual de integra\u00e7\u00e3o. Quando um agente precisa de uma habilidade espec\u00edfica, simplesmente verifica a ficha do agente relevante para compreender como interagir com aquele servi\u00e7o.<\/p>\n<p>No Koog, as fichas de agentes s\u00e3o definidas usando classes de dados do Kotlin:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"kotlin\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">val agentCard = AgentCard(\n    name = \"Redator de blogs\",\n    description = \"Agente de IA que cria postagens e artigos de alta qualidade para blogs\",\n    url = \"https:\/\/api.blog-writer.com\/a2a\/v1\",\n    version = \"1.0.0\",\n    capabilities = AgentCapabilities(streaming = true),\n    defaultInputModes = listOf(\"text\/plain\"),\n    defaultOutputModes = listOf(\"text\/markdown\"),\n    skills = listOf(\n        AgentSkill(\n            id = \"redator-de-postagens\",\n            name = \"Reda\u00e7\u00e3o de postagens de blog\",\n            description = \"Gere postagens envolventes de blog sobre qualquer assunto\",\n            tags = listOf(\"writing\", \"content\", \"blog\"),\n            examples = listOf(\"Escreva uma postagem sobre tend\u00eancias em IA\")\n        )\n    )\n)<\/pre>\n<h3 class=\"wp-block-heading\">Mensagens universais: um \u00fanico padr\u00e3o simples<\/h3>\n<p>O A2A usa um formato de mensagens \u00fanico e padronizado para toda a comunica\u00e7\u00e3o entre agentes. Essa simplicidade \u00e9 poderosa: em vez de aprenderem dezenas de APIs diferentes, os agentes s\u00f3 precisam compreender um \u00fanico padr\u00e3o de comunica\u00e7\u00e3o.<\/p>\n<p>Todas as intera\u00e7\u00f5es seguem o mesmo fluxo:<\/p>\n<ol>\n<li><strong>Enviar uma mensagem<\/strong> com a solicita\u00e7\u00e3o de uma tarefa e os par\u00e2metros.<\/li>\n<li><strong>Receber<\/strong> resultados imediatos ou uma tarefa para acompanhar.<\/li>\n<li><strong>Obter atualiza\u00e7\u00f5es<\/strong> atrav\u00e9s de canais em tempo real, no caso de opera\u00e7\u00f5es mais longas.<\/li>\n<\/ol>\n<p>Esta abordagem universal significa que para adicionar novas capacidades de agentes, n\u00e3o \u00e9 preciso mudar o protocolo de comunica\u00e7\u00e3o. Quer voc\u00ea esteja solicitando que um agente resuma um texto ou gere um relat\u00f3rio complexo, a estrutura da mensagem continua consistente.<\/p>\n<p>No Koog, criar e enviar uma mensagem \u00e9 simples e direto, usando objetos e protocolos j\u00e1 implementados:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"kotlin\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">val message = Message(\n    role = Role.User,\n    parts = listOf(\n        TextPart(\"Escreva uma postagem de blog sobre o futuro dos agentes de IA\")\n    ),\n    contextId = \"blog-project-456\"\n)\n\nval request = Request(\n    data = MessageSendParams(\n        message = message,\n        configuration = MessageConfiguration(\n            blocking = false, \/\/ Obter primeira resposta\n            historyLength = 5 \/\/ Incluir contexto\n        )\n    )\n)\n\nval response = client.sendMessage(request)<\/pre>\n<p>O formato das mensagens tem suporte a conte\u00fado formatado, atrav\u00e9s de diferentes tipos <em>Part<\/em>, incluindo TextPart para conte\u00fado em texto simples, FilePart para arquivos anexados e DataPart para dados estruturados em JSON.<\/p>\n<p>Essa estrutura unificada significa que os agentes do Koog podem se comunicar com qualquer agente compat\u00edvel com A2A, seja para processamento de textos, an\u00e1lise de arquivos ou transforma\u00e7\u00f5es complexas de dados.<\/p>\n<h3 class=\"wp-block-heading\">Ciclo de vida das tarefas: fluxos de trabalho inteligentes<\/h3>\n<p>O A2A gerencia diferentes tipos de tarefas de forma inteligente, com base na complexidade e na dura\u00e7\u00e3o:<\/p>\n<p><strong>Mensagens imediatas<\/strong>: Opera\u00e7\u00f5es simples, como formata\u00e7\u00e3o de textos ou c\u00e1lculos r\u00e1pidos, que retornam resultados diretamente na resposta da IA. N\u00e3o \u00e9 necess\u00e1rio aguard\u00e1-las, nem acompanh\u00e1-las.<\/p>\n<p><strong>Tarefas de execu\u00e7\u00e3o longa<\/strong>: Opera\u00e7\u00f5es complexas, como an\u00e1lise de documentos ou fluxos de trabalho com v\u00e1rias etapas. Essas opera\u00e7\u00f5es s\u00e3o agendadas e retornam uma tarefa. O agente solicitante pode ent\u00e3o monitorar o andamento e coletar os resultados da tarefa, quando ela estiver conclu\u00edda.<\/p>\n<p><strong>Atualiza\u00e7\u00f5es em tempo real<\/strong>: No caso de opera\u00e7\u00f5es muito demoradas, eventos enviados pelo servidor (SSE) fornecem atualiza\u00e7\u00f5es do andamento em tempo real. Isso mant\u00e9m os agentes informados, sem precisar de polling constante.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"kotlin\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">class BlogWriterExecutor : AgentExecutor {\n    override suspend fun execute(\n        context: RequestContext,\n        eventProcessor: SessionEventProcessor\n    ) {\n        val task = Task(\n            contextId = context.contextId,\n            status = TaskStatus(\n                state = TaskState.Submitted,\n                message = Message(\n                    role = Role.Agent,\n                    parts = listOf(TextPart(\"Solicita\u00e7\u00e3o para redigir um blog recebida\")),\n                    contextId = context.contextId,\n    \t\t\ttaskId = context.taskId,\n                )\n            )\n        )\n\n        eventProcessor.sendTaskEvent(task)\n\t ...\n    }\n}\n<\/pre>\n<h3 class=\"wp-block-heading\">Seguran\u00e7a incorporada: apenas padr\u00f5es do setor<\/h3>\n<p>O A2A n\u00e3o reinventa a seguran\u00e7a. Em vez disso, ele usa padr\u00f5es comprovados e amplamente adotados, como OAuth2, chaves de API e HTTPS-padr\u00e3o.<\/p>\n<p>Esta abordagem significa que os desenvolvedores n\u00e3o precisam aprender novos esquemas de autentica\u00e7\u00e3o. Se voc\u00ea compreende a seguran\u00e7a moderna de APIs de Web, j\u00e1 compreende a seguran\u00e7a do A2A. O sistema herda todas as ferramentas, melhores pr\u00e1ticas e auditorias de seguran\u00e7a que v\u00eam junto com esses padr\u00f5es consagrados.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"json\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\"securitySchemes\": {\n   \"google\": {\n       \"openIdConnectUrl\": \"https:\/\/accounts.google.com\/.well-known\/openid-configuration\",\n       \"type\": \"openIdConnect\"\n   }\n}\n<\/pre>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"kotlin\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">class AuthorizedA2AServer(\n    agentExecutor: AgentExecutor,\n    agentCard: AgentCard,\n    agentCardExtended: AgentCard? = null,\n    taskStorage: TaskStorage = InMemoryTaskStorage(),\n    messageStorage: MessageStorage = InMemoryMessageStorage(),\n    private val authService: AuthService, \/\/ Servi\u00e7o respons\u00e1vel pela autentica\u00e7\u00e3o\n) : A2AServer(\n    agentExecutor = agentExecutor,\n    agentCard = agentCard,\n    agentCardExtended = agentCardExtended,\n    taskStorage = taskStorage,\n    messageStorage = messageStorage,\n) {\n\n    private suspend fun authenticateAndAuthorize(\n        ctx: ServerCallContext,\n        requiredPermission: String\n    ): AuthenticatedUser {\n        val token = ctx.headers[\"Authorization\"]?.firstOrNull()\n            ?: throw A2AInvalidParamsException(\"Token de autoriza\u00e7\u00e3o faltando\")\n\n        val user = authService.authenticate(token)\n            ?: throw A2AInvalidParamsException(\"Token de autoriza\u00e7\u00e3o inv\u00e1lido\")\n\n        if (requiredPermission !in user.permissions) {\n            throw A2AUnsupportedOperationException(\"Permiss\u00f5es insuficientes\")\n        }\n\n        return user\n    }\n\n   override suspend fun onSendMessage(\n        request: Request,\n        ctx: ServerCallContext\n    ): Response {\n        val user = authenticateAndAuthorize(ctx, requiredPermission = \"send_message\")\n\n        \/\/ Passagem de dados do usu\u00e1rio ao executor do agente atrav\u00e9s do estado do contexto\n        val enrichedCtx = ctx.copy(\n            state = ctx.state + (AuthStateKeys.USER to user)\n        )\n\n        \/\/ Delega\u00e7\u00e3o \u00e0 implementa\u00e7\u00e3o de n\u00edvel superior com conte\u00fado formatado\n        return super.onSendMessage(request, enrichedCtx)\n    }\n\n   \/\/ o resto dos m\u00e9todos incorporadoa do A2A \n   \/\/ ...\n}<\/pre>\n<h2 class=\"wp-block-heading\">Como integrar os agentes do Koog com o A2A<\/h2>\n<p>O framework Koog j\u00e1 tem incorporados tanto o cliente quanto o servidor de A2A. Isto significa que os agentes do Koog podem se comunicar com outros agentes compat\u00edveis com A2A e, ao mesmo tempo, tamb\u00e9m se tornam pass\u00edveis de serem descobertos pelo mundo exterior. Veja um exemplo simples, demonstrando como voc\u00ea pode implementar isso.<\/p>\n<h3 class=\"wp-block-heading\">Como incorporar agentes do Koog a servidores de A2A<\/h3>\n<p>Primeiro, defina uma estrat\u00e9gia para o agente. O Koog oferece conversores convenientes (<em>toKoogMessage<\/em>, <em>toA2AMessage<\/em>), que fazem transforma\u00e7\u00f5es transparentes entre os formatos de mensagens do Koog e do A2A, eliminando a necessidade de serializa\u00e7\u00e3o manual. N\u00f3s especializados, como <em>nodeA2ASendMessage<\/em>, cuidam desse processo de troca de mensagens, tornando os fluxos de trabalho de comunica\u00e7\u00e3o simples e diretos de implementar:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"kotlin\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">fun blogpostWritingStrategy() = strategy(\"blogpost-writer-strategy\") {\n    val blogpostRequest by node { input -&gt;\n        val userMessage = input.toKoogMessage().content\n\n        llm.writeSession {\n            user {\n                +\"Escreva uma postagem de blog com base na solicita\u00e7\u00e3o do usu\u00e1rio\"\n                +xml {\n                    tag(\"user_request\") {\n                        +userMessage\n                    }\n                }\n            }\n\n            requestLLM().toA2AMessage()\n        }\n    }\n\n    val sendMessage by nodeA2ARespondMessage()\n\n    nodeStart then blogpostRequest then sendMessage then nodeFinish\n}<\/pre>\n<p>Depois, defina o pr\u00f3prio agente. Depois que voc\u00ea instalar o recurso <em>A2AServer<\/em>, o seu agente se tornar\u00e1 pass\u00edvel de ser descoberto e ficar\u00e1 acess\u00edvel a outros no ecossistema, possibilitando a cria\u00e7\u00e3o de redes sofisticadas, onde agentes especializados colaboram uns com os outros de forma transparente.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"kotlin\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">fun createBlogpostWritingAgent(\n    requestContext: RequestContext,\n    eventProcessor: SessionEventProcessor\n): AIAgent {\n     \/\/ Obten\u00e7\u00e3o das mensagens j\u00e1 existentes para o contexto da comunica\u00e7\u00e3o atual\n     val messageHistory = requestContext.messageStorage.getAll().map { it.toKoogMessage() }\n\n     val agentConfig = AIAgentConfig(\n        prompt = prompt(\"blogpost\") {\n            system(\"Voc\u00ea \u00e9 um agente para escrever postagens de blog\")\n\n            messages(messageHistory)\n        },\n        model = GoogleModels.Gemini2_5Flash,\n        maxAgentIterations = 5\n    )\n\n    return agent = AIAgent(\n        promptExecutor = MultiLLMPromptExecutor(\n            LLMProvider.Google to GoogleLLMClient(System.getenv(\"GOOGLE_API_KEY\")),\n        ),\n        strategy = blogpostWritingStrategy(),\n        agentConfig = agentConfig\n    ) {\n        install(A2AAgentServer) {\n            this.context = requestContext\n            this.eventProcessor = eventProcessor\n        }\n\n        handleEvents {\n            onAgentFinished { ctx -&gt;\n                \/\/ Atualiza\u00e7\u00e3o do contexto da comunica\u00e7\u00e3o atual com a resposta do agente\n                val resultMessge = ctx.result as A2AMessage\n                requestContext.messageStorage.save(resultMessge)\n            }\n        }\n    }\n}<\/pre>\n<p>Em terceiro lugar, precisamos incorporar o agente ao executor e depois definir um servidor.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"kotlin\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">class BlogpostAgentExecutor : AgentExecutor {\n    override suspend fun execute(\n        context: RequestContext,\n        eventProcessor: SessionEventProcessor\n    ) {\n        createBlogpostWritingAgent(context, eventProcessor)\n            .run(context.params.message)\n    }\n}\n\nval a2aServer = A2AServer(\n    agentExecutor = BlogpostAgentExecutor(),\n    agentCard = agentCard,\n)<\/pre>\n<p>A etapa final \u00e9 definir um transporte do servidor e executar o servidor.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"kotlin\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">val transport = HttpJSONRPCServerTransport(\n    requestHandler = a2aServer\n)\n\ntransport.start(\n    engineFactory = Netty,\n    port = 8080,\n    path = \"\/a2a\",\n    wait = true,\n    agentCard = agentCard,\n    agentCardPath = A2AConsts.AGENT_CARD_WELL_KNOWN_PATH\n)<\/pre>\n<p>Agora o seu agente est\u00e1 pronto para atender a solicita\u00e7\u00f5es!\u00a0<\/p>\n<h3 class=\"wp-block-heading\">Como invocar outros agentes compat\u00edveis com A2A a partir de um agente do Koog<\/h3>\n<p>Primeiramente, voc\u00ea precisa configurar um cliente de A2A e conect\u00e1-lo, para ele buscar uma ficha de agente.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"kotlin\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">val agentUrl = \"https:\/\/example.com\"\n\nval cardResolver = UrlAgentCardResolver(\n    baseUrl = agentUrl,\n    path = A2AConsts.AGENT_CARD_WELL_KNOWN_PATH,\n)\n\nval transport = HttpJSONRPCClientTransport(\n    url = agentUrl,\n)\n\nval a2aClient = A2AClient(\n    transport = transport,\n    agentCardResolver = cardResolver\n)\n\n\/\/ Inicializa\u00e7\u00e3o do cliente e busca da ficha\na2aClient.connect()<\/pre>\n<p>Depois, voc\u00ea pode usar <em>nodeA2ASendMessage<\/em> ou <em>nodeA2ASendMessageStreaming<\/em> na sua estrat\u00e9gia, para invocar esses clientes e receber uma mensagem ou resposta a uma tarefa.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"kotlin\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">val agentId = \"agent_id\"\nval agent = AIAgent(\n    promptExecutor = MultiLLMPromptExecutor(\n        LLMProvider.Google to GoogleLLMClient(System.getenv(\"GOOGLE_API_KEY\")),\n    ),\n    strategy = strategy(\"a2a\") {\n        val nodePrepareRequest by node&lt;String, A2AClientRequest&gt; { input -&gt;\n            A2AClientRequest(\n                agentId = agentId,\n                callContext = ClientCallContext.Default,\n                params = MessageSendParams(\n                    message = A2AMessage(\n                        messageId = Uuid.random().toString(),\n                        role = Role.User,\n                        parts = listOf(\n                            TextPart(input)\n                        )\n                    )\n                )\n            )\n        }\n        val nodeA2A by nodeA2AClientSendMessage(agentId)\n        \n        val nodeProcessResponse by node {\n            \/\/ Process event\n            when (it) {\n                is A2AMessage -&gt; it.parts\n                    .filterIsInstance()\n                    .joinToString(separator = \"n\") { it.text }\n                \n                is Task -&gt; it.artifacts\n                    .orEmpty()\n                    .flatMap { it.parts }\n                    .filterIsInstance()\n                    .joinToString(separator = \"n\") { it.text }\n            }\n        }\n\n        nodeStart then nodePrepareRequest then nodeA2A then nodeProcessResponse then nodeFinish\n\n    },\n    agentConfig = agentConfig\n) {\n   install(A2AAgentClient) {\n        this.a2aClients = mapOf(agentId to client)\n    }\n}\n\nagent.run(\"Escreva uma postagem de blog sobre a integra\u00e7\u00e3o do A2A com o Koog\")<\/pre>\n<h2 class=\"wp-block-heading\">Pr\u00f3ximos passos<\/h2>\n<p>Para se aprofundar mais no Koog e no A2A, confira estes materiais \u00fateis:<\/p>\n<p><a href=\"https:\/\/docs.koog.ai\/\" target=\"_blank\" rel=\"noopener\">Documenta\u00e7\u00e3o do Koog<\/a><\/p>\n<p><a href=\"https:\/\/a2a-protocol.org\/latest\/specification\/\" target=\"_blank\" rel=\"noopener\">Especifica\u00e7\u00e3o do A2A<\/a><\/p>\n<p><a href=\"https:\/\/github.com\/JetBrains\/koog\/tree\/develop\/examples\/simple-examples\/src\/main\/kotlin\/ai\/koog\/agents\/example\/a2a\" data-type=\"link\" data-id=\"https:\/\/github.com\/JetBrains\/koog\/tree\/develop\/examples\/simple-examples\/src\/main\/kotlin\/ai\/koog\/agents\/example\/a2a\" target=\"_blank\" rel=\"noopener\">Exemplos de A2A com Koog<\/a><\/p>\n\n\n<p><em>Artigo original em ingl\u00eas por:<\/em><\/p>\n\n\n    <div class=\"about-author \">\n        <div class=\"about-author__box\">\n            <div class=\"row\">\n                <div class=\"about-author__box-img\">\n                    <img decoding=\"async\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/10\/T0288D531-UL11E3JG5-1870329d7bae-512.png\" width=\"200\" height=\"200\" alt=\"Andrey Bragin\" loading=\"lazy\"  class=\"avatar avatar-200 wp-user-avatar wp-user-avatar-200 photo avatar-default\">\n                <\/div>\n                <div class=\"about-author__box-text\">\n                                            <h4>Andrey Bragin<\/h4>\n                                                        <\/div>\n            <\/div>\n        <\/div>\n    <\/div>\n","protected":false},"author":1086,"featured_media":659764,"comment_status":"closed","ping_status":"closed","template":"","categories":[89,907],"tags":[6847,8724],"cross-post-tag":[6355],"acf":[],"_links":{"self":[{"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/ai\/659761"}],"collection":[{"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/ai"}],"about":[{"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/types\/ai"}],"author":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/users\/1086"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/comments?post=659761"}],"version-history":[{"count":2,"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/ai\/659761\/revisions"}],"predecessor-version":[{"id":659776,"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/ai\/659761\/revisions\/659776"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/media\/659764"}],"wp:attachment":[{"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/media?parent=659761"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/categories?post=659761"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/tags?post=659761"},{"taxonomy":"cross-post-tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/cross-post-tag?post=659761"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}