SMA et Python

Document Actions

Par Cedric le 04/12/2009 10:22

Petite initiation aux systèmes multi-agent avec Python.

Catégories : messagerie,reseau
Modules python : python-dnspython,python-dns,python-psyco
Version Python : 2.6

Introduction

Ce tutoriel est un petit aperçu du framework de développement de systèmes multi-agent SPADE.

Vous pouvez utiliser le module python-dns ou python-dnspython, au choix. Le module Psyco est optionnel.

Les systèmes multi-agent

Un système multi-agent (SMA) est un système composé d'un ensemble d'agents, situés dans un certain environnement et interagissant selon certaines relations. Un agent est une entité caractérisée par le fait qu'elle est, au moins partiellement, autonome. Ce peut-être un processus, un robot, un être humain, etc. On retrouve souvent les SMA dans le domaine de l'IA notamment de l'intelligence collective.

FIPA

Afin de prévenir la prolifération des systèmes d'agents incompatibles et d'assurer l'interopérabilité de ses normes avec d'autres technologies, la FIPA (Foundation for Intelligent Physical Agents) a été formé. Le plus utilisé des standards de la FIPA est un standard de langage de communication, ACL (Agent Communication Language). Avec ce langage les agents communiquent en s'envoyant des messages où en effectuant des modifications dans leur environnement.
La FIPA définit un modèle pour une plate-forme d'agent et une langue de communication. Pour être conforme aux normes de la FIPA il faut au moins avoir:

  • un chanel de communication (ACC, Agent Communication Channel). Mécanisme permettant aux agents (et à la plate-forme) de communiquer;
  • un système de gestion d'agent (AMS, Agent Management System). Une manière pour les agents de s'inscrire dans la plate-forme et d'être joignable via le DF (Directory Facilitator). Le DF est une sorte de service de pages blanches (et jaunes en fait);
  • le DF (Directory Facilitator), est donc une sorte d'annuaire où les agents s'inscrivent au moment du déploiement. Grâce au DF on peut retrouver un agent sur un réseau simplement grâce à sa fonction;
  • le support du langage de communication ACL. Il peut être représenté dans une syntaxe ressemblant à Lisp ou à du XML.

Les agents sont rattachés à des conteneurs éparpillés sur le réseau. Un conteneur peut héberger plusieurs agents. Le conteneur principal en revanche est le seul à disposer du DF et de l'AMS.
Supposons que C1 le conteneur principal héberge A1, A2, A3 et que C2 (sur un autre réseau) héberge A4. A1 va par exemple pouvoir utiliser le DF afin de trouver le conteneur de A4. De même A4 peut consulter le DF, même s'il n'est pas sur la plate-forme principale.


Principaux frameworks de développement d'infrastrustructure multi-agent

Python


Java


Évidemment il y en a d'autres.
J'ai eu l'occasion d'utiliser SPADE et JADE (malheureusement bien plus ce dernier).


Introduction à SPADE

SPADE est une plate-forme de développement d'infrastructure basée sur la paradigme des système multi-agent. SPADE est basé sur le protocole XMPP/Jabber et est écrit en Python. SPADE est conforme aux normes FIPA/ACL et de ce fait un agent Python peut très bien communiquer avec un agent C++ ou Java.

Un agent est donc une entité pouvent prendre des décisions toute seule ou en groupe. À chaque agent on attribue une tâche (Behavior) qui est en fait une sorte de thread. On pourrait par exemple imaginer un agent ayant une bahavior pour envoyer des ordres à d'autres agents, ainsi qu'un behavior afin de récupérer les résultats.
On distinque différents types de behavior:
  • cycliques et périodiques pour les tâches répétitives;
  • One-Shot et Time-Out pour effectuer des tâches occasionnelles;
  • à états (terminal), pour des comportements plus complexes;
  • orienté événement. Répond à certains événements reçus par l'agent.

Lorsque un agent A1 envoie un message à A2, A1 doit dire quel behavior devra intercepter le message. En effet, chaque behavior d'un agent a sa propre liste d'attente (boîte aux lettres). Cependant l'envoie de messages est réalisé par l'agent lui même (et pas le behavior). C'est pour cette raison qu'on verra que la méthode d'envoie s'utilise de cette manière: self.myAgent.send(ACLmessage). Il faut passer par l'attribut myAgent de la classe.


Avantages


  • un des gros aventages et de ne pas avoir à se soucier des adresses et ports d'écoutes;
  • le deuxième est la facilité à créer des comportements sans se soucier des threads;
  • il est facile d'envoyer des chaînes de caractères dans de l'ACL et de récupérer ces chaînes. On peut aussi envoyer des données sérialisées, du XML, etc.;
  • le déploiement des agents et le référencement dans le DF est automatique. Lorsque l'agent disparait il est retiré du DF.

Cette solution est donc parfaite pour les système distribués.

Petit exemple avec un client envoyant un message à un serveur


Le code (avec les commentaires) devrait se comprendre assez aisément.

Le serveur

import spade

class Server(spade.Agent.Agent):
    def _setup(self):
        print "Server starting . . ."
        # Add the "Receive" as the default behaviour
        rb = self.Receive()
        self.setDefaultBehaviour(rb)

    def tearDown(self):
        self.stop()

    class Receive(spade.Behaviour.Behaviour):
        """
        This behaviour is in charge of waiting for
        messages.
        """

        def _onStart(self):
            print "Listening for client..."

        def _process(self):
            self.msg = None
            # Blocking receive for 10 seconds
            self.msg = self._receive(True, 10)

            # Check wether the message arrived
            if self.msg:
                print "I got a message!"
                print "The message is", self.msg.getContent()
            else:
                print "I waited but got no message"

        def onEnd(self):
            print "Server closed."

if __name__ == "__main__":
    a = Server("agent_server@192.168.1.5", "secret")
    a.start()
Ici on peut facilement ajouter des behaviors avec de nouvelles classes. On pourrait avoir un behavior spécialement pour les messages de services.


Le client


import spade

class Client(spade.Agent.Agent):
    def _setup(self):
        print "Client starting . . ."
        b = self.Send()
        self.addBehaviour(b, None)

    def tearDown(self):
        self.stop()

    class Send(spade.Behaviour.OneShotBehaviour):
        """
        This behaviour is in charge of sending a
        message to the receiver.
        """

        def _process(self):
            # First, form the receiver AID
            receiver = spade.AID.aid(name="agent_server@192.168.1.5",
                                     addresses=["xmpp://agent_server@192.168.1.5"])

            # Second, build the message
            self.msg = spade.ACLMessage.ACLMessage()  # Instantiate the message
            self.msg.setPerformative("inform")        # Set the "inform" FIPA performative
            self.msg.setOntology("myOntology")        # Set the ontology of the message content
            self.msg.setLanguage("English")           # Set the language of the message content
            self.msg.addReceiver(receiver)            # Add the message receiver
            self.msg.setContent("Hello World")        # Set the message content
            # Third, send the message with the "send" method of the agent
            self.myAgent.send(self.msg)
            # myAgent is an attribute that can be used in any behaviour.
            # It is a reference to the agent that holds the behaviour and
            # thus it can be used as a shortcut to access any method or
            # attribute the agent object has.

if __name__ == "__main__":
    a = Client("agent_client@192.168.1.5", "secret")
    a.start()
Ici le receiver sera aussi la pate-forme principale (192.168.1.5). Le client est a l'adresse 192.168.1.4. Le serveur peut maintenant répondre. Il peut même envoyer un message destiné uniquement aux agents responsables d'une fonction donnée.

Le client implémente un comportement One-Shot. Le message sera donc envoyé une seule fois. Tandis que le serveur va boucler.

On voit qu'on peut facilement réaliser une petite messagerie instantanée XMPP de cette manière.


Éxecution

On lance la plate-forme SPADE:
cedric@debian:~/spade$ python configure.py 192.168.1.5 # main platform
cedric@debian:~/spade$ python runspade.py
Using Psyco optimizing compiler
SPADE  2.0-RC3  <garanda@dsic.upv.es> - http://spade.gti-ia.dsic.upv.es/
...WebAdmin serving at port 8008
.. [done]
Maintenant on peut consulter le DF avec le navigateur.

Le serveur:
cedric@debian:~/spade$ python server.py
Using Psyco optimizing compiler
Server starting . . .

Agent: agent_server@192.168.1.5 registered correctly (inform)
I waited but got no message
I waited but got no message
I waited but got no message
I waited but got no message
I got a message!
The message is Hello World

Et le client:
[cedric@localhost spade] python client.py
Using Psyco optimizing compiler
Client starting . . .

Agent: agent_client@192.168.1.5 registered correctly (inform)

Voilà ce n'était qu'une petite démonstration de SPADE et des SMA. Vous trouverez d'autres exemples sympa et un peu plus évolués dans le manuel de SPADE ainsi que dans les exemples des sources. Notamment des exemples pour enregistrer des agents auprès du DF et envoyer des requêtes à ce dernier.

Questions

Posté par Shonen le 24/01/2011 16:26
Bonjour,
j'ai installé et lancé SPADE et quand je lance le navigateur j'ai 2 erreurs dans les onglets services (name is not defined) et organization (file not found).

j'ai juste suivi la procédure d'installation standard : c'est à dire un environnement python installé sur mac OS, j'ai téléchargé spade, dezip et lancer avec le terminal. (j'ai aussi installé dnspython).

J'ai la version de python 2.7.

Je ne trouve pas de documentation complète sur l'installation de spade (même sur le manuel spade il y a juste 2 commandes).

et avec idle (même si le site de spade s'affiche avec quelques erreurs cités plus haut) je ne peux pas faire d' import spade dans IDLE.

J'ai oublié une étape? je n'ai rien compris au fonctionnement de Spade (possible)? ou puis-je trouver une documentation complète (que ça soit en anglais, espagnol ou italien m'importe peu).

Cordialement
Python.org : Le site officiel du langage Python.
Zope.org : Le site web officiel de Zope.
Daily Python-URL : Actus de l'univers Python.
Tribute to Zyons : Zyons notre ami et membre fondateur de l'Afpy, nous quittait en 2005.