Chapter 4. Developing with the ADK

Table of Contents

4.1. About this chapter
4.2. Agent aspects
4.2.1. Identity
4.2.2. Addressing Agents
4.2.3. Security Information
4.3. Behavior
4.4. Memory
4.5. Life Cycle
4.6. Communication
4.6.1. Messages
4.6.2. FIPA
4.6.3. Language
4.7. DNA Files
4.8. Agent Persistence

4.1. About this chapter

This chapter provides information on some concepts involved with agent development. As seen from Chapter 2, The ADK Environment, we know that agents:

  • Have an identity.

  • Behave in a certain way.

  • Have a memory.

  • Have a life cycle.

In this chapter, the identity aspect of an agent is discussed in more detail. Furthermore, an overview of some important elements of agent development, such as agent communication, agent DNA files and persistence is given.

4.2. Agent aspects

This section discusses identity, behavior, memory and life cycle.

4.2.1. Identity

Each agent has a unique identity, known as its ID reference. This is necessary in order to be able to distinguish between agents. This ID reference is given to an agent when it is created, and stays with it for its whole lifetime. For example, this identity is used to determine what the agent is permitted to do and to store the agent in the persistency facility. The AgentID is a purely internal matter that need not concern the agent developer or the agent itself.

For the benefit of the user, an agent also has an (easier) nickname. This nickname is mainly intended for communication between humans and agents. Unlike ID references, agent nicknames are not guaranteed to be unique. Nicknames are set using the Agent class's setName method.

4.2.2. Addressing Agents

Agents also have a unique address. This address is used when sending messages to and from agents. From ADK 3.0 onwards, addresses are Uniform Resource Identifiers as defined in the URI Specification and are encapsulated in the AddressURI class.. AddressURI's conform to the following syntax:

Syntax of addresses
[1]Address::= LocationAddress | AddressURI  
[2]LocationAddress::= Scheme , "://" , Habitat  
[3]AddressURI::= LocationAddress , , , [ ]  
[4]Scheme::= "agent"  
[5]Habitat::= { , "." } * , , [ "." ]  

The habitat part of an address is the name of the addressed habitat. A habitat's name must have at least its last part starting with a letter. This is done in order to maintain compatibility with DNS. Habitat names are therefore treated case-insensitive as well.

The agent part of an address is corresponding with the agent's registration on the destination habitat. The agent part is treated case-sensitive. This part is considered to be hierarchical. The current implementation uses JNDI for the agent registration.

4.2.2.1. Examples addresses

A few examples of well-formed addresses. The first is a location address, the others form addresses of agents. The last is used for an agent named Léon.

Example 4.1. Some well-formed addresses

agent://myhabitat

agent://agentserver/tryllian/system-agents/transporter

agent://agentserver/user/Application/Worker-4?all

agent://info-1.people.company/personnel/France/L%E9on

4.2.2.2. Habitat names

A habitat name is set by the habitat on startup. This can be set in various ways. If no name is set, the ARE will use the habitat ID.

4.2.2.2.1. Conventions

It is strongly recommended; that a habitat administrator uses a Fully Qualified Domain Name as the habitat's name. For running multiple habitats on one computer system, one can use CNAMEs, in coordination with the network administrator. (This is, in fact, essential when using the HTTP Messenger Plugin.)

It is furthermore recommended; that network administrators use an appropriate hierarchy in habitat naming. An hierarchy according to the well-known Domain Name System (DNS) is recommended;, where the nodes come first, followed by their group, etc... Other (future) features may use such an hierarchy for optimization.

Example 4.2. Habitat naming convention

node.cluster.department.realm.world

4.2.2.3. Agent registration

The agent part of an address is handled by the habitat referred to in the address (the habitat in the habitat part of the address). How an agent has to register itself within this habitat is left to that habitat.

Example 4.3. Address with agent hierarchy

agent://habitat/universe/set/instance

Note

The current implementation uses JNDI for agent registration. See ???.

The ADK supports the use of JNDI (Java Naming and Directory Interface). For a detailed discussion on how the ADK provides JNDI facilities to agents running inside a Habitat, refer to the ARE Technical Specifications document found in the docs directory of the ADK installation. In many cases, the Directory wrapper provided by the AFC will make using JDNI directly unnecessary.

4.2.3. Security Information

An agent also carries a certificate defining its security clearance. Depending on its security clearance, an agent may be allowed or prohibited to perform various operations, such as downloading a file, cloning itself or entering a habitat The certificate protects the agent from unwanted harassment by other agents. Certificates are further described in Chapter 12, Security which also explains the philosophy underlying Tryllian's security framework.

4.3. Behavior

The behavior of an agent is governed by the sense-reason-act loop introduced in Chapter 2, The ADK Environment. In the sense phase, the agent gathers information, in the reason phase, it analyzes this information and in the act phase it modifies its behavior based on its findings. More information on the task model, which is used to define the reasoning phase, is given in Chapter 7, The Agent Task Model.

4.4. Memory

Agents are able to store useful information in memory, for example, when it receives information from other agents or from its environment. This information is the basis for its behavior, but can also be the goal of an agent's life. If an agent finds an answer, it could return to its owner, or evaluate the answer to see if it is good enough.

4.5. Life Cycle

Agents are created, live and eventually die. Creating an agent is either done at startup or by a different agent. As soon as an agent is created, it can roam the agent world and interact with other agents, as well as its environment. During its lifespan, it can move to other habitats or remain where it is. When an agent has served its purpose, it can terminate, in which case it will disappear from the agent world. Thanks to persistence, described in Section 4.8, “Agent Persistence”, the lifetime of an agent is not directly dependend on that of the habitat.

4.6. Communication

The agent world allows agents to send messages to each other or to system agents. For complex interactions, a common set of messages is needed that can be understood and have been agreed upon by the different parties involved. This is called a language.

4.6.1. Messages

In the agent world, all communication is eventually done by means of messages. Essentially, messages are objects that can be sent to agents, thus establishing communication. The basic message only informs the recipient of a certain fact. The sender does not expect the receiver to answer it.

A more complex message is sent when an agent asks the habitat agent to give it a list of all the names of agents present in the habitat. Upon receiving the message, the habitat agent answers with a list of names. This shows the forming of a dialog by sending a query message. More types of messages exist for different purposes, as we shall see in the later chapter on agent communication.

From a programmer's point of view, there are two kinds of messages: messages that you can receive (IncomingMessages) and messages that you can send (OutgoingMessages).

Messenger plugins take care of sending messages between agents on different habitats, wrapping the message into JMS or JXTA messages or HTTP requests depending upon the protocol used.

For more details regarding messages, refer to the ARE Specifications document and the chapters on agent communication.

4.6.2. FIPA

In order to let agents communicate, they have to use the same type of messages, or else they are unable to understand one another. Agents communicate in the Tryllian agent world by using the languages based on the FIPA Agent Communication Language, an international standard for agent communication.

4.6.3. Language

For more complex communication, sending a simple message is not sufficient. Suppose we want an agent to trade on our behalf and to allow it to pay for a purchased item if it is within an acceptable price range. In order to make this possible, we have to find an agent which has something to sell, can understand our price request and if a deal is made, send the information the buying agent needs to pay the right amount of money to the owner. But what if the buying agent's owner lives in Europe and the selling agent's owner lives in America? Then perhaps this is not the ideal transaction. Perhaps it is a better idea to first ask the agent where his creator is located or what type of payment is accepted.

The above dialog can be made easier by designing an agent language. The language is carried by the messages, but the structure is separated from them. By designing a language for specialized tasks and letting the agents use it, you prevent agents from not understanding each other. At the beginning of a conversation between agents, both parties exchange information about the languages they understand. If both agents understand a certain language, they can use it to communicate more effectively. If they do not have a language in common, they cannot communicate.

4.7. DNA Files

Agents are packaged into DNA files. A DNA file contains:

  • One or more jar files containing the code of your agent.

  • Zero or more jar files containing libraries or resources used by your agent.

  • An agent descriptor specifying:

    • The name of your agent's main class.

    • Version information.

    • A list of all jar files used by the agent.

  • A signature over these files; this is used for authentication and integrity checks.

If your agent moves to another habitat, only the files that need to be updated will be transferred through the network. If your agent or a similar agent has already moved to the remote habitat only the state of the agent is transferred. To create a DNA file you can use the ANT task provided with the ADK, the command-line DNAComposer tool or the DeployTool.

4.8. Agent Persistence

Like any program, process or operating system, the runtime environment of an agent, the habitat, can go down. To prevent the agents from accidentally getting killed in the process, the ADK provides persistence. The ARE allows agents to save their current state in a database before the habitat goes down. When the habitat comes back up, the agents will be restored in the state retrieved from the database. This saving and restoring of individual agents is known as agent persistence. Saving and restoring other state information of the habitat, such as the JNDI tables, is transparently provided by the ARE. (Note that automatic persistence on habitat shutdown only happens when shutting down the habitat gracefully using the habitat service manager and the habitat shutdown protocol; killall -9 java on GNU/Linux will result in lost data. Agents can also request a checkpoint during runtime whenever needed.)

When an agent is restored from the database, the last saved state is used. Each individual agent considers exactly which state changes are worth saving. The ADK currently provides two options for an agent to make sure its persisted state is sufficiently current.

The first one is the ability for an agent to checkpoint itself. The standard AFC task tryllian.afc.task.standard.CheckpointTask will force your agent to be checkpointed: a snapshot is taken of the current state and then stored in a database. As an added feature, the ARE automatically checkpoints agents with every move.

The second way is the ability for an agent to suspend itself. The standard AFC task tryllian.afc.task.standard.SuspendTask will force your agent to be suspended. In this case, the agent's state is stored in the database just like checkpointing, but afterwards the agent is removed from the collection of active agents in the habitat. Suspension gives idle agents a chance to relieve the system of their load. A suspended agent will remain in suspended state until a message arrives for it. When this happens, the agent will be transparently restored into the habitat, without experiencing more than the 'blackout' of some time having suddenly passed.

For an agent to use persistence, certain requirements must be met: the habitat must be connected to a database and the agent must be capable of persistence. As of version 2.0 of the ADK, persistence is pre-configured to use hsqldb for its database, and agents are persistent by default, so no configuration is necessary unless you need to use an enterprise ready database like Oracle. Details on setting up a different database for persistence are found in the Quickstart Guide.

By default, persistence uses (de)serialization of the agents' entire object hierarchy. Agents that want control over the way their state is saved to or restored from the persistent database can do so by implementing the interface tryllian.are.StateSerializable.Agent persistence is optional. If it makes more sense for your agent to simply disappear when the habitat goes down and comes up again, this is most easily achieved by implementing the tagging interface tryllian.are.TransientAgent.