The KQML Language

Previous: KQML and Intelligent Information Integration Up: KQML as an Agent Communication Language Next: KQML Software Architectures

The KQML Language

Communication takes place on several levels. The content of the message is only a part of the communication. Being able to locate and engage the attention of someone you want to communicate with is a part of the process. Packaging your message in a way which makes your purpose in communicating clear is another.

When using KQML, a software agent transmits content messages, composed in a language of its own choice, wrapped inside of a KQML message. The content message can be expressed in any representation language and written in either ASCII strings or one of many binary notations (e.g. network independent XDR representations). All KQML implementations ignore the content portion of the message except to the extent that they need to recognize where it begins and ends.

The syntax of KQML is based on a balanced parenthesis list. The initial element of the list is the performative and the remaining elements are the performative's arguments as keyword/value pairs. Because the language is relatively simple, the actual syntax is not significant and can be changed if necessary in the future. The syntax reveals the roots of the initial implementations, which were done in Common Lisp, but has turned out to be quite flexible.

KQML is expected to be supported by an software substrate which makes it possible for agents to locate one another in a distributed environment. Most current implementations come with custom environments of this type; these are commonly based on helper programs called routers or facilitators. These environments are not a specified part of KQML. They are not standardized and most of the current KQML environments will evolve to use some of the emerging commercial frameworks, such as OMG's CORBA or Microsoft's OLE2, as they become more widely used.

The KQML language supports these implementations by allowing the KQML messages to carry information which is useful to them, such as the names and addresses of the sending and receiving agents, a unique message identifier, and notations by any intervening agents. There are also optional features of the KQML language which contain descriptions of the content: its language, the ontology it assumes, and some type of more general description, such as a descriptor naming a topic within the ontology. These optional features make it possible for the supporting environments to analyze, route and deliver messages based on their content, even though the content itself is inaccessible.

The forms of these parts of the KQML message may vary, depending on the transport mechanism used to carry the KQML messages. In implementations which use TCP streams as the transport mechanism, they appear as fields in the body of the message. In an earlier version of KQML, these fields were kept in reserved locations, in an outer wrapper of the message, to emphasize the difference from other fields. In other transport mechanisms the syntax and content of these message may be different. For example, in the E-mail implementation of KQML, these fields are embedded in KQML mail headers.

The set of performatives forms the core of the language. It determines the kinds of interactions one can have with a KQML-speaking agent. The primary function of the performatives is to identify the protocol to be used to deliver the message and to supply a speech act which the sender attaches to the content. The performative signifies that the content is an assertion, a query, a command, or any other mutually agreed upon speech act. It also describes how the sender would like any reply to be delivered, that is, what protocol will be followed.

Conceptually, a KQML message consists of a performative, its associated arguments which include the real content of the message, and a set of optional arguments transport which describe the content and perhaps the sender and receiver. For example, a message representing a query about the price of a share of IBM stock might be encoded as:


  (ask-one 
    :content (PRICE IBM ?price)
    :receiver stock-server
    :language LPROLOG
    :ontology NYSE-TICKS)

In this message, the KQML performative is ask-one, the content is (price ibm ?price), the ontology assumed by the query is identified by the token nyse-ticks, the receiver of the message is to be a server identified as stock-server and the query is written in a language called LPROLOG. A similar query could be conveyed using standard Prolog as the content language in a form that requests the set of all answers as:


  (ask-all
    :content "price(IBM, [?price, ?time])"
    :receiver stock-server
    :language standard_prolog
    :ontology NYSE-TICKS)

The first message asks for a single reply; the second asks for a set as a reply. If we had posed a query which had a large number of replies, would could ask that they each be sent separately, instead of as a single large collection by changing the performative. (To save space, we will no longer repeat fields which are the same as in the above examples.)


  (stream-all 
    ;;?VL is a large set of symbols
    :content (PRICE ?VL ?price))
The stream-all performative asks that a set of answers be turned into a set of replies. To exert control of this set of reply messages we can wrap another performative around the preceding message.


  (standby
     :content (stream-all 
                 :content (PRICE ?VL ?price)))

The standby performative expects a KQML language content and it requests that the agent receiving the request take the stream of messages and hold them and release them one at a time, each time the sending agent transmits a message with the next performative. The exchange of next/reply messages can continue until the stream is depleted or until the sending agent sends either a discard message (i.e. discard all remaining replies) or a rest message (i.e. send all of the remaining replies now). This combination is so useful that it can be abbreviated:


  (generate
      :content (PRICE ?VL ?price)))

A different set of answers to the same query can be obtained (from a suitable server) with the query:


  (subscribe
     :content (stream-all 
                :content (PRICE IBM ?price)))

This performative requests all future changes to the answer to the query, i.e. it is a stream of messages which are generated as the trading price of IBM stock changes. An abbreviation for subscribe/stream combination is known a monitor.


  (monitor
      :content (PRICE IBM ?price)))

Though there is a predefined set of reserved performatives, it is neither a minimal required set nor a closed one. A KQML agent may choose to handle only a few (perhaps one or two) performatives. The set is extensible; a community of agents may choose to use additional performatives if they agree on their interpretation and the protocol associated with each. However, an implementation that chooses to implement one of the reserved performatives must implement it in the standard way.

Some of the reserved performatives are shown in Figure . In addition to standard communication performatives such as ask, tell, deny, delete, and more protocol oriented performatives such as subscribe, KQML contains performatives related to the non-protocol aspects of pragmatics, such as advertise - which allows an agent to announce what kinds of asynchronous messages it is willing to handle; and recruit - which can be used to find suitable agents for particular types of messages. For example, the server in the above example might have earlier announced:


   (advertise
       :ontology NYSE-TICKS
       :language LPROLOG
       :content (monitor
                   :content (PRICE ?x ?y)))
Which is roughly equivalent to announcing that it is a stock ticker and inviting monitor requests concerning stock prices. This advertise message is what justifies the subscriber's sending the monitor message.

finin@cmsc