What you’ll build
This programming tutorial illustrates the programming of message oriented interaction between autonomous agents. You will develop a simple market place where an agent who wants to buy some product or service, announces its requirements, other agents bid, and the winner is then chosen.
In a market place, different interaction processes (interaction protocols
) can be followed by the agents.
Here we will consider a simple auction protocol and its implementation based on message exchanges:
-
An auctioneer broadcasts a message with the requirements he/she would like to be satisfied
-
Participants send him/her back messages with the prices
-
The auctioneer broadcasts to the participants the winner of the auction process
What you’ll need
-
Your favorite text editor or IDE
-
JDK 1.8 or later
-
A JaCaMo platform installed and configured
-
To have already followed some introductory tutorials as JaCaMo Hello World Tutorial
-
Get the whole code of this tutorial: Download ZIP
STEP 1. Simple Market Place
-
Get the whole code of this step: Download ZIP
Learned features
In this step, you will learn:
|
Understand
The very first implementation of the market has 5 agents:
-
bob
(auctioneer): this agent is interested in buying a flight ticket from Paris to Athens. -
francois
,alice
,maria
, andgiacomo
(participants): each agent manages a travel agency, that is to say that they can sell flight tickets from somewhere to somewhere else at a certain price.Each time the participant gets an event corresponding to the reception of an auction for a
service
from an agent, it sends back a bid to this agent with a random price. This agent will only respond to auctions for services. Each service has a simple description.
Practice
Implement this system as follows:
1. Create a new JaCaMo project called auction_ag
with the following project file content:
1mas auction_ag {
2
3 agent bob: auctioneer.asl
4
5 agent alice : participant.asl
6 agent maria : participant.asl
7 agent francois: participant.asl
8 agent giacomo : participant.asl
9
10 asl-path: src/agt
11 src/agt/inc
12}
2. The agent code for the participant agents is composed of a simple plan.
By this plan each time the participant gets an event corresponding to
the creation of an auction belief for a service
, it sends back a bid
with a random price (you can improve as you want this strategy)
Notice that service
(after +auction
) is not a
variable, so this agent will only respond to auctions for services.
The variable D
is bound to the description of the service.
Variable A
is bound to the source of the perception (bob
in our case).
The message has the format bib( <service description>, <price>)
.
1+auction(service, D)[source(A)] <-
2 .send(A,tell,bid(D, math.random * 100 + 10)).
3
4{ include("$jacamoJar/templates/common-cartago.asl") }
5{ include("$jacamoJar/templates/common-moise.asl") }
3. The agent code for the auctioneer bob
is composed of two plans.
-
The first plan achieves the initial goal
start
by broadcasting an auction announcement. The message content has the formauction(<type>, <description>)
. -
Bids are sent to
bob
bytell
messages (see code of participants) and thus are represented as beliefs in his mind. Each belief addition produces an event like+bid(<service>,<price>)
that is handled by the second plan. If the agent has already received 4 bids for this service, the winner is announced.To be able to handle all the bids that have been received you can use the internal actions
.findall
, as well as the function for getting the length of a list.length
. To get the minimal value of a list you can use.min
internal action. All these functions are described in Jason API.
1!start. // initial goal
2
3+!start <- .broadcast(tell, auction(service, flight_ticket(paris,athens,"15/12/2015"))).
4
5// Here comes the plan for handling received bids and checking for new winner
6
7
8{ include("$jacamoJar/templates/common-cartago.asl") }
9{ include("$jacamoJar/templates/common-moise.asl") }
Using the mind inspector after the execution shows the beliefs and sources of beliefs (notice the annotation source
of the
beliefs):
4. The execution of the application will look like the following screen:
STEP 2. Improving the auctioneer
-
Get the whole code of this step: Download ZIP
Learned features
In this step, you will learn:
|
Understand
We modify the auctioneer
agent so that it can launch two auctions concurrently.
Notice that plans in bob
and participants are triggered by events
(+bid
, +auction
) and executed concurrently: participants can
produce bids and auctioneer can receive bids concurrently.
In the current version, the auctioneer bob
waits for exactly 4 bids! It is far from a good design choice:
(i) the number of participants may be unknown and (ii) some of them may not respond.
We will change the program auctioneer.asl
so that a decision is taken after 10 seconds, regardless of the number of bids.
Practice
-
Create a new JaCaMo project in which you copy what you did in the previous step (you can also create it from the downloaded code of this step)
-
Modify the plan for the goal
start
so that its execution triggers two auctions in parallel -
Refactor the program
auctioneer.asl
so that a decision is taken after 10 seconds, regardless of the number of bids, we can use the internal action.at
. This internal action.at
can be used to produce a goal after some time. For example,.at("now + 10 seconds", { +!decide } )
will create a new goaldecide
after 10 seconds.
STEP 3. Improving the participant
-
Get the whole code of this step: Download ZIP
Learned features
In this step, you will learn: |
Understand
-
In this step we change the code of participants so that they use
broadcast
to announce their bids (like an auction room where everyone can listen to the bids done by participants). -
Participant agents can now listen the bids done by other participants.
-
We change the code of a participant agent (e.g.
giacomo
) so that as soon as it listens a bid from another agent for a service, it bids for the same service with a better price (i.e. lower price).
Practice
-
Create a new JaCaMo project in which you copy what you did in the previous step (you can also create it from the downloaded code of this step)
-
Refactor the
participant.asl
agent code so that instead of using a.send
each agent broadcasts its bid (.broadcast
) -
Create a
repeater.asl
agent program having reactive plan that creates a new bid from eachbid
heared from the other agents. -
Question: Based on the number of running auction a and participants p, how many messages are sent in the broadcast version developed in these exercises?
Solution: available here.
STEP 4. Introducing agents on the market place
-
Get the whole code of this step: Download ZIP
Learned features
In this step, you will learn:
|
Understand
-
In the current system,
bob
starts the auction without checking that there are at least some agents in the market place. -
We will solve this problem by adding some "introduction" step before starting the auctions:
-
the
auctioneer
agent introduces itself by announcing to the other agents that it playsinitiator
-
the
participant
agents answer by announcing that they playparticipant
in the market
-
-
As soon as the
auctioneer
agent knows that at least two agents are in the market place, it launches the auctions -
In this step, we will use also the Jade Platform as the agent communication platform so that we can use it in a distributed setting. We will also test and use the
Sniffer
service of the Jade platform to see and inspect the messages that are exchanged in the system among the agents.
Practice
-
Create a new JaCaMo project in which you copy what you did in the previous step (you can also create it from the downloaded code of this step)
-
Refactor the code of
auctioneer.asl
,participant.asl
andrepeater.asl
to integrate these changes -
Change the code of
auction_ag.jcm
so that to introducejade()
in theplatform
section of this file -
Simply adding
platform: jade()
at the end of the project file (auction_ag.jcm
) will launch the use of the jade platform (See here for hints on the use of the `.jcm`file). Test and use the Sniffer agent of the Jade platform to see and inspect the messages that are exchanged in the system.
Hint: see the JADE Tutorial.
STEP 5. Auctioning through artifacts
-
Get the whole code of this step: Download ZIP
Learned features
In this step, you will learn:
|
Understand
-
Instead of using message exchanges among the agents, in this part of the tutorial we instrument the agents' environment with artifacts that will help the coordination required for the market place auction protocol.
-
The speech acts used in the direct messages exchanged between the agents are replaced by interaction through perception and action on artifacts
-
Instead of implementing the auction protocol within the agents' code as done in the previous part, we will externalise and encapsulate the coordination mechanism within an auction artifact shared between the agents.
-
Thanks to the abstractions provided in JaCaMo we can also situate this artifact in a workspace, duplicate it, and control its access.
-
Each auction is managed by one artifact instance where:
-
The auctioneer starts the auction setting the service description,
-
The participants perceive the service and likely do their bids,
-
After some time, the auctioneer stops the auction and the winner is defined.
-
-
Thus, the auction artifact has the following observable properties:
-
the service description,
-
the current best bid,
-
the current winner (shown only when the auction has finished),
-
whether the auction is running or not,
-
-
and the following operations:
-
start,
-
stop, and
-
bid.
-
Practice
-
Create a new JaCaMo project
-
Create a new artifact, called
AuctionArtifact
with the following initial code:
package auction_env;
import jason.asSyntax.Atom;
import cartago.*;
public class AuctionArtifact extends Artifact {
String currentWinner = "no_winner";
@OPERATION public void init() {
// observable properties
defineObsProperty("running", false);
defineObsProperty("task", "no_task");
defineObsProperty("best_bid", Double.MAX_VALUE);
defineObsProperty("winner", new Atom(currentWinner)); // Atom is a Jason type
}
@OPERATION public void start(String task) {
if (getObsProperty("running").booleanValue())
failed("The protocol is already running and so you cannot start it!");
getObsProperty("task").updateValue(task);
getObsProperty("running").updateValue(true);
}
@OPERATION public void stop() {
if (! getObsProperty("running").booleanValue())
failed("The protocol is not running, why to stop it?!");
getObsProperty("running").updateValue(false);
getObsProperty("winner").updateValue(new Atom(currentWinner));
}
@OPERATION public void bid(double bidValue) {
// this is where you have to act
System.out.println("Operation not yet implemented / Come back later for "+getObsProperty("task").stringValue());
}
}
-
In the project file, create a
market
workspace and the same agents as before, joining this workspace -
Refactor the code of the
auctioneer.asl
so that the agent instead of sending messages for launching an auction, creates an auction artifact for each service to auction on and acts on the auction artifact with the proper operations -
Refactor the code of the
participant.asl
so that the corresponding agents focus on the auction artifacts created by the auctioneer and bid the proper price on the corresponding artifact -
What are the pros and cons of this solution wrt the direct exchange of messages?