Notícias
Jade: Framework Java para sistemas baseados em agentes
TemaTec 231
Vanderson Botêlho da Silva é bacharel em Ciência da Computação pela Universidade Federal de Campina Grande (UFCG) e mestre em Informática Aplicada pela Pontifícia Universidade Católica do Paraná (PUC-PR). Atualmente é doutorando em Informática Aplicada, na linha de pesquisa de Agentes Inteligentes pela PUC-PR e chefe da Divisão de Arquitetura de Software e Tecnologia do Serpro.
A complexidade das aplicações em termos de número de funcionalidades, infraestruturas e alto volume de dados, requer abordagem de desenvolvimento flexível e distribuída, na medida que os sistemas devem ser capazes de adaptarem-se dinamicamente às modificações de estrutura e ambiente. Os sistemas multiagente são fortes candidatos à construção de arquiteturas com esses pré-requisitos.
O Jade (Java Agent Development) é um framework desenvolvido em Java que oferece um conjunto de ferramentas gráficas e APIs para construção de sistemas baseados em agentes de software. O framework provê uma arquitetura distribuída compatível com as especificações da Foundation for Intelligent Physical Agents (FIPA), um conjunto de padrões internacionais mantidos pela IEEE. A figura abaixo ilustra os principais elementos da sua arquitetura.
Instalação
O download da ferramenta pode ser feito no site: http://jade.tilab.com. Para reproduzir os exemplos apresentados neste artigo, deve-se importar a biblioteca jade.jar necessária para o desenvolvimento em qualquer IDE Java.

Criação de Containers
O trecho de código a seguir demonstra como iniciar plataformas a partir de uma simples classe Java.
public class MeuSMA {
public static void main(String[] args) {
String[] parametros = {
"-gui",
"-local-host",
"127.0.0.1"
};
jade.Boot.main(parametros);
}
}
A classe jade.Boot é responsável por iniciar a plataforma a partir de um conjunto de parâmetros. O resultado dessa chamada é exibido na tela de configuração do Jade.

Os agentes são identificados pela plataforma a partir da regra de formação: <nomedoagente>@<dispositivo>:<porta>/<plataforma>. É possível inicializar vários containers de forma distribuída. A ligação entre os containers é realizada por meio de parâmetros informados na inicialização dos containers secundários, conforme apresentado:
public class MeuSMA {
public static void main(String[] args) {
String[] parametros = {
"-gui",
"-local-host",
"127.0.0.1"};
jade.Boot.main(parametros);
String[] novoContainer = {
"-local-host", "127.0.0.1",
"-container", "-container-name",
"Meu-Container"};
jade.Boot.main(novoContainer);
}
}
Nesse exemplo, os parâmetros do novoContainer criam um container secundário, identificado pelo nome “Meu-Container”. A figura a seguir apresenta graficamente a nova formação da plataforma Jade após nosso exemplo.

Os agentes especiais do Jade (ams, df e rma) hospedam-se no container principal da plataforma, e não há restrições para que outros agentes criados pelo sistema se hospedem ou se movam livremente entre qualquer container.
Criação de Agentes
Agora trataremos a construção dos agentes nos containers Jade e como inicializá-los. O trecho de código a seguir apresenta dois exemplos de classes de agentes:
public class AgenteComprador extends Agent {
}
public class AgenteVendedor extends Agent {
}
Suas classes de agente devem estender a classe jade.core.Agent. Com poucas linhas de código, é possível iniciar seus agentes. O trecho de código abaixo demonstra como criar um agente “comprador” no container principal e um agente “vendedor” no container secundário:
public class MeuSMA {
public static void main(String[] args) {
String[] parametros = {
"-gui", "-local-host", "127.0.0.1",
"comprador:AgenteComprador()",};
jade.Boot.main(parametros);
String[] novoContainer = {
"-local-host", "127.0.0.1", "-container",
"-container-name", "Meu-Container",
"vendedor:AgenteVendedor()"};
jade.Boot.main(novoContainer);
}
}
A figura a seguir apresenta os dois agentes criados em seus respectivos containers.

Comportamentos
O Jade provê um conjunto de classes para composição de comportamentos dos agentes: simples (SimpleBehaviour), paralelos (ParallelBehaviour), cíclicos (CyclicBehaviour), entre outras dezenas de comportamentos. Todo comportamento possui dois métodos: action() para especificar a ação do comportamento e o done() para informar se o comportamento foi concluído. O trecho a seguir exemplifica a criação de um comportamento que será executado dez vezes:
public class MeuAgente extends Agent {
protected void setup() {
addBehaviour( new SimpleBehaviour() {
int count = 1;
public boolean done() {
return (count == 11);
}
public void action() {
System.out.println(count++);
}
});
}
}
Os comportamentos podem ser incluídos ou removidos dinamicamente a qualquer momento. Isso permite a mutação do agente com ampla flexibilidade de programação.
Comunicação
De acordo com a especificação FIPA, o serviço de transporte de mensagens é um dos mais importantes para uma plataforma de agentes. No Jade, todas as mensagens trocadas pelos agentes seguem a estrutura de mensagem da especificação SC00061G (FIPA, 2014).
(REQUEST :sender ( agent-identifier :name rma@127.0.0.1:1099/JADE :addresses (sequence http://serpro-0000000:7778/acc )) :receiver (set ( agent-identifier :name vendedor@127.0.0.1:1099/JADE ) ) :content "Ola" )
Nesse exemplo, a mensagem representa uma solicitação (REQUEST); as informações sobre o emissor da mensagem estão no atributo sender e as informações do destinatário no atributo receiver, o conteúdo da mensagem é posto pelo atributo content. O Jade oferece a classe ACLMessage para construção de mensagens de forma programática. O trecho de código a seguir demostra como dois agentes podem se comunicar.
public class AgenteComprador extends Agent {
public void setup() {
System.out.println("Olá, sou o agente " + getLocalName());
addBehaviour(new OneShotBehaviour() {
@Override
public void action() {
ACLMessage msgRx = new ACLMessage(ACLMessage.REQUEST);
msgRx.addReceiver(new AID("vendedor", false));
msgRx.setContent("Olá, quero comprar uma TV");
send(msgRx);
}
});
addBehaviour(new CyclicBehaviour() {
public void action() {
ACLMessage msgRx = receive();
if (msgRx != null) {
System.out.println(msgRx);
} else {
block();
}
}
});
}
}
O agente comprador possui dois comportamentos: solicitar ao agente vendedor a compra e receber a resposta do vendedor de forma cíclica.
public class AgenteVendedor extends Agent {
public void setup() {
System.out.println("Olá, sou o agente " + getLocalName());
addBehaviour(new CyclicBehaviour() {
public void action() {
ACLMessage msgRx = receive();
if (msgRx != null) {
System.out.println(msgRx);
ACLMessage msgTx = msgRx.createReply();
msgTx.setPerformative(ACLMessage.REFUSE);
msgTx.setContent("Não temos seu produto no estoque");
send(msgTx);
} else {
block();
}
}
});
}
}
O agente vendedor possui um comportamento para receber requisições vindas de agentes compradores. Nesse exemplo, o vendedor recusará o pedido, hipoteticamente, por não possuir o item solicitado. A saída no terminal será:
Olá, sou o agente vendedor Olá, sou o agente comprador (REQUEST :sender ( agent-identifier :name comprador@127.0.0.1:1099/JADE :addresses (sequence http://serpro-1551251:7778/acc )) :receiver (set ( agent-identifier :name vendedor@127.0.0.1:1099/JADE ) ) :content "Olá, quero comprar uma TV" ) (REFUSE :sender ( agent-identifier :name vendedor@127.0.0.1:1099/JADE :addresses (sequence http://serpro-1551251:7778/acc )) :receiver (set ( agent-identifier :name comprador@127.0.0.1:1099/JADE :addresses (sequence http://serpro-1551251:7778/acc )) ) :content "Não temos seu produto no estoque" :reply-with comprador@127.0.0.1:1099/JADE1407613837881 )
Referências
- BELLIFEMINE, Fabio Luigi; CAIRE, Giovanni; GREENWOOD, Dominic. Developing multi-agent systems with JADE. John Wiley & Sons, 2007.
- FIPA, Standard Status Specifications, 2002. Disponível em: <http://www.fipa.org/repository/standardspecs.html>. Acesso em 10 ago. 2014.
Autor:
Vanderson Botêlho da Silva é bacharel em Ciência da Computação pela Universidade Federal de Campina Grande (UFCG) e mestre em Informática Aplicada pela Pontifícia Universidade Católica do Paraná (PUC-PR). Atualmente é doutorando em Informática Aplicada, na linha de pesquisa de Agentes Inteligentes pela PUC-PR e chefe da Divisão de Arquitetura de Software e Tecnologia do Serpro. Possui experiência na área de Engenharia de Software, com ênfase em gestão de projetos, testes de desempenho, desenvolvimento orientado a comportamento e computação distribuída.



