Chapter 2

Agent Communication Protocols

弘益人間 (홍익인간) · Benefit All Humanity

Effective communication is the foundation of collaboration. Just as human societies thrive through shared language and understanding, multi-agent systems achieve collective goals through standardized communication protocols that enable agents to coordinate, negotiate, and cooperate for the benefit of all.

The Importance of Agent Communication

Communication is the cornerstone of multi-agent systems. Without effective communication mechanisms, agents cannot coordinate their actions, share information, or collaborate to solve complex problems. Agent communication languages (ACLs) provide the standardized syntax and semantics necessary for agents to understand each other.

Key Insight: Agent communication is not just about data exchange—it's about sharing intentions, beliefs, and commitments that enable coordinated action toward common goals.

Unlike traditional inter-process communication, agent communication protocols must handle:

FIPA-ACL: The Foundation for Intelligent Physical Agents

FIPA-ACL (Foundation for Intelligent Physical Agents - Agent Communication Language) is the most widely adopted standard for agent communication. Developed by FIPA in the late 1990s, it provides a comprehensive framework for agent interaction.

FIPA Message Structure

Every FIPA-ACL message consists of multiple parameters that define the communication act:

// FIPA-ACL Message Structure
interface FIPAMessage {
    performative: string;      // Type of communicative act
    sender: AgentIdentifier;   // Sender agent ID
    receiver: AgentIdentifier[]; // One or more receivers
    content: any;              // Message content
    language: string;          // Content language (e.g., 'fipa-sl')
    ontology: string;          // Domain ontology
    protocol: string;          // Interaction protocol
    conversationId: string;    // Conversation identifier
    replyWith: string;         // Reply identifier
    inReplyTo: string;         // Reference to previous message
    replyBy: Date;             // Deadline for reply
}

// Example FIPA-ACL message
const message: FIPAMessage = {
    performative: 'request',
    sender: { name: 'buyer-agent-001', address: 'http://mas.example.com/buyer001' },
    receiver: [{ name: 'seller-agent-042', address: 'http://mas.example.com/seller042' }],
    content: {
        action: 'provide-quote',
        item: 'laptop',
        quantity: 5,
        maxPrice: 1000
    },
    language: 'fipa-sl',
    ontology: 'ecommerce-ontology',
    protocol: 'fipa-request',
    conversationId: 'conv-12345',
    replyWith: 'req-67890',
    replyBy: new Date('2025-12-26T10:00:00Z')
};

// 弘益人間: Clear communication for mutual benefit

FIPA Performatives

FIPA-ACL defines 22 standard performatives (communicative acts). The most commonly used include:

Performative Purpose Example Use
INFORM Share information "Temperature is 25°C"
REQUEST Ask agent to perform action "Please send status report"
QUERY-IF Ask if proposition is true "Is task completed?"
PROPOSE Make a proposal "I can deliver for $50"
ACCEPT-PROPOSAL Accept a proposal "I accept your offer"
REJECT-PROPOSAL Reject a proposal "Price too high"
AGREE Agree to perform action "I will complete by 5pm"
REFUSE Refuse to perform action "Cannot complete request"
FAILURE Report action failure "Task failed due to error"
CFP Call for proposals "Need quotes for delivery"
class FIPAAgent {
    constructor(id) {
        this.id = id;
        this.messageHandler = new Map();
        this.setupHandlers();
    }

    setupHandlers() {
        // Handle different performatives
        this.messageHandler.set('inform', this.handleInform.bind(this));
        this.messageHandler.set('request', this.handleRequest.bind(this));
        this.messageHandler.set('query-if', this.handleQuery.bind(this));
        this.messageHandler.set('propose', this.handlePropose.bind(this));
        this.messageHandler.set('cfp', this.handleCFP.bind(this));
    }

    async sendInform(receiver, content) {
        return this.sendMessage({
            performative: 'inform',
            sender: this.id,
            receiver: [receiver],
            content: content,
            language: 'fipa-sl'
        });
    }

    async sendRequest(receiver, action) {
        return this.sendMessage({
            performative: 'request',
            sender: this.id,
            receiver: [receiver],
            content: { action: action },
            protocol: 'fipa-request',
            conversationId: this.generateConversationId()
        });
    }

    handleInform(message) {
        console.log(`Received information: ${JSON.stringify(message.content)}`);
        this.updateBeliefs(message.content);
    }

    async handleRequest(message) {
        const canDo = await this.canPerformAction(message.content.action);

        if (canDo) {
            await this.sendMessage({
                performative: 'agree',
                sender: this.id,
                receiver: [message.sender],
                inReplyTo: message.replyWith,
                content: { action: message.content.action }
            });

            const result = await this.performAction(message.content.action);

            await this.sendMessage({
                performative: result.success ? 'inform' : 'failure',
                sender: this.id,
                receiver: [message.sender],
                content: result
            });
        } else {
            await this.sendMessage({
                performative: 'refuse',
                sender: this.id,
                receiver: [message.sender],
                inReplyTo: message.replyWith,
                content: { reason: 'Cannot perform requested action' }
            });
        }
    }

    async handleCFP(message) {
        // Call for proposals - evaluate and respond with proposal
        const proposal = await this.generateProposal(message.content);

        if (proposal) {
            await this.sendMessage({
                performative: 'propose',
                sender: this.id,
                receiver: [message.sender],
                inReplyTo: message.replyWith,
                content: proposal
            });
        }
    }
}

// 弘益人間: Agents communicate to coordinate for collective benefit

KQML: Knowledge Query and Manipulation Language

KQML (Knowledge Query and Manipulation Language) predates FIPA-ACL and focuses on knowledge sharing between agents. While less common today, it influenced the development of FIPA-ACL.

KQML Performatives

KQML defines performatives focused on knowledge operations:

// KQML message example
class KQMLMessage {
    constructor(performative, sender, receiver, content) {
        this.performative = performative;
        this.sender = sender;
        this.receiver = receiver;
        this.content = content;
        this.language = 'KIF'; // Knowledge Interchange Format
        this.ontology = null;
    }

    toString() {
        return `(${this.performative}
            :sender ${this.sender}
            :receiver ${this.receiver}
            :language ${this.language}
            :content "${this.content}")`;
    }
}

// Example: Ask if temperature exceeds threshold
const askIfMsg = new KQMLMessage(
    'ask-if',
    'monitor-agent',
    'sensor-agent-01',
    '(> temperature 30)'
);

// Example: Tell current temperature
const tellMsg = new KQMLMessage(
    'tell',
    'sensor-agent-01',
    'monitor-agent',
    '(= temperature 25)'
);

Message Transport and Protocols

Agent communication requires reliable message transport mechanisms. The WIA-AI-016 standard supports multiple transport protocols:

HTTP/HTTPS

RESTful HTTP APIs provide a simple, widely-supported transport mechanism for agent messages. Agents expose endpoints for receiving messages and use HTTP POST to send messages.

// HTTP-based agent message transport
class HTTPAgentTransport {
    constructor(agentId, port) {
        this.agentId = agentId;
        this.port = port;
        this.endpoint = `http://localhost:${port}/messages`;
    }

    // Send message via HTTP POST
    async send(message) {
        const response = await fetch(this.endpoint, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify(message)
        });

        return response.json();
    }

    // Receive messages via HTTP server
    startServer(messageHandler) {
        const express = require('express');
        const app = express();

        app.use(express.json());

        app.post('/messages', async (req, res) => {
            const message = req.body;
            const response = await messageHandler(message);
            res.json(response);
        });

        app.listen(this.port, () => {
            console.log(`Agent ${this.agentId} listening on port ${this.port}`);
        });
    }
}

// 弘益人間: Open communication channels for all agents

WebSocket

WebSocket provides bidirectional, full-duplex communication ideal for real-time agent interactions. It reduces latency and overhead compared to HTTP polling.

// WebSocket agent communication
class WebSocketAgentTransport {
    constructor(agentId, url) {
        this.agentId = agentId;
        this.ws = new WebSocket(url);
        this.messageQueue = [];
        this.handlers = new Map();

        this.ws.onopen = () => {
            console.log(`Agent ${agentId} connected`);
            this.flushQueue();
        };

        this.ws.onmessage = (event) => {
            const message = JSON.parse(event.data);
            this.handleMessage(message);
        };
    }

    send(message) {
        if (this.ws.readyState === WebSocket.OPEN) {
            this.ws.send(JSON.stringify(message));
        } else {
            this.messageQueue.push(message);
        }
    }

    flushQueue() {
        while (this.messageQueue.length > 0) {
            const message = this.messageQueue.shift();
            this.send(message);
        }
    }

    onMessage(performative, handler) {
        this.handlers.set(performative, handler);
    }

    handleMessage(message) {
        const handler = this.handlers.get(message.performative);
        if (handler) {
            handler(message);
        }
    }
}

Message Queue Systems

For large-scale systems, message queue systems like RabbitMQ, Apache Kafka, or MQTT provide reliable, scalable message delivery with features like guaranteed delivery, message persistence, and pub/sub patterns.

Conversation Protocols

Many agent interactions require multiple message exchanges following structured patterns called conversation protocols or interaction protocols.

Request Protocol

The FIPA Request protocol defines a simple interaction where one agent requests another to perform an action:

  1. Initiator sends REQUEST
  2. Participant responds with AGREE or REFUSE
  3. If agreed, participant later sends INFORM (success) or FAILURE

Contract Net Protocol

The Contract Net Protocol enables task allocation through bidding:

  1. Manager sends CFP (Call for Proposals) to potential contractors
  2. Contractors respond with PROPOSE or REFUSE
  3. Manager evaluates proposals and sends ACCEPT-PROPOSAL to winner(s)
  4. Manager sends REJECT-PROPOSAL to others
  5. Accepted contractors perform task and report results
// Contract Net Protocol implementation
class ContractNetManager {
    async allocateTask(task, contractors) {
        // Step 1: Send CFP to all contractors
        const cfp = {
            performative: 'cfp',
            content: {
                task: task,
                deadline: Date.now() + 3600000, // 1 hour
                requirements: task.requirements
            },
            conversationId: this.generateConversationId(),
            replyBy: new Date(Date.now() + 300000) // 5 min for proposals
        };

        const proposals = await this.broadcast(contractors, cfp);

        // Step 2: Evaluate proposals
        const bestProposal = this.evaluateProposals(
            proposals.filter(p => p.performative === 'propose')
        );

        if (!bestProposal) {
            console.log('No suitable proposals received');
            return null;
        }

        // Step 3: Accept best proposal
        await this.send(bestProposal.sender, {
            performative: 'accept-proposal',
            inReplyTo: bestProposal.replyWith,
            conversationId: cfp.conversationId
        });

        // Step 4: Reject other proposals
        for (const proposal of proposals) {
            if (proposal.sender !== bestProposal.sender &&
                proposal.performative === 'propose') {
                await this.send(proposal.sender, {
                    performative: 'reject-proposal',
                    inReplyTo: proposal.replyWith,
                    conversationId: cfp.conversationId
                });
            }
        }

        // Step 5: Wait for task completion
        return this.waitForCompletion(bestProposal.sender, cfp.conversationId);
    }

    evaluateProposals(proposals) {
        return proposals.reduce((best, current) => {
            if (!best) return current;

            const currentScore = this.scoreProposal(current);
            const bestScore = this.scoreProposal(best);

            return currentScore > bestScore ? current : best;
        }, null);
    }

    scoreProposal(proposal) {
        const content = proposal.content;
        let score = 0;

        // Lower cost is better
        score += (1000 - content.cost) / 10;

        // Earlier delivery is better
        const timeScore = (content.deliveryTime - Date.now()) / 3600000;
        score += Math.max(0, 100 - timeScore);

        // Higher quality is better
        score += content.quality * 10;

        return score;
    }
}

// 弘益人間: Fair task allocation benefiting all participants

Auction Protocols

Various auction mechanisms can be implemented as conversation protocols:

Ontologies and Shared Understanding

For agents to truly understand each other, they must share a common ontology—a formal specification of concepts, relationships, and constraints in a domain.

// Simple ontology definition
const eCommerceOntology = {
    concepts: {
        Product: {
            properties: ['name', 'price', 'category', 'manufacturer'],
            relationships: ['hasReview', 'inCategory']
        },
        Order: {
            properties: ['orderId', 'totalAmount', 'status', 'timestamp'],
            relationships: ['containsProduct', 'placedBy', 'deliveredTo']
        },
        Customer: {
            properties: ['customerId', 'name', 'email', 'address'],
            relationships: ['placed', 'reviewed']
        }
    },

    relationships: {
        hasReview: { domain: 'Product', range: 'Review' },
        inCategory: { domain: 'Product', range: 'Category' },
        containsProduct: { domain: 'Order', range: 'Product' },
        placedBy: { domain: 'Order', range: 'Customer' }
    }
};

// Using ontology for semantic understanding
class SemanticAgent {
    constructor(ontology) {
        this.ontology = ontology;
    }

    validateMessage(message) {
        const concept = message.content.concept;

        if (!this.ontology.concepts[concept]) {
            throw new Error(`Unknown concept: ${concept}`);
        }

        const requiredProps = this.ontology.concepts[concept].properties;
        const providedProps = Object.keys(message.content.data);

        return requiredProps.every(prop => providedProps.includes(prop));
    }

    interpretMessage(message) {
        if (!this.validateMessage(message)) {
            return null;
        }

        return {
            concept: message.content.concept,
            data: message.content.data,
            semantics: this.ontology.concepts[message.content.concept]
        };
    }
}

Security in Agent Communication

Secure communication is critical in multi-agent systems, especially in open environments where malicious agents may exist.

Authentication

Agents must verify the identity of communication partners using digital certificates, API keys, or token-based authentication.

Encryption

Message content should be encrypted to prevent eavesdropping. TLS/SSL for HTTP and encryption layers for message queues provide transport security.

Message Integrity

Digital signatures ensure messages haven't been tampered with during transmission.

// Secure agent communication
class SecureAgent {
    constructor(agentId, privateKey, publicKey) {
        this.agentId = agentId;
        this.privateKey = privateKey;
        this.publicKey = publicKey;
        this.trustedAgents = new Map();
    }

    signMessage(message) {
        const crypto = require('crypto');
        const sign = crypto.createSign('SHA256');
        sign.update(JSON.stringify(message));
        const signature = sign.sign(this.privateKey, 'hex');

        return {
            ...message,
            signature: signature,
            senderPublicKey: this.publicKey
        };
    }

    verifyMessage(message) {
        const crypto = require('crypto');
        const verify = crypto.createVerify('SHA256');

        const { signature, senderPublicKey, ...content } = message;
        verify.update(JSON.stringify(content));

        return verify.verify(senderPublicKey, signature, 'hex');
    }

    encryptMessage(message, recipientPublicKey) {
        const crypto = require('crypto');
        const encrypted = crypto.publicEncrypt(
            recipientPublicKey,
            Buffer.from(JSON.stringify(message))
        );

        return {
            encrypted: encrypted.toString('hex'),
            sender: this.agentId
        };
    }

    decryptMessage(encryptedMessage) {
        const crypto = require('crypto');
        const decrypted = crypto.privateDecrypt(
            this.privateKey,
            Buffer.from(encryptedMessage.encrypted, 'hex')
        );

        return JSON.parse(decrypted.toString());
    }
}

// 弘益人間: Secure communication protecting all participants

Performance Optimization

Efficient communication is essential for scalable multi-agent systems:

Chapter Summary

Review Questions

  1. What are the key components of a FIPA-ACL message structure?
  2. Explain the difference between INFORM and REQUEST performatives.
  3. How does the Contract Net Protocol work? Describe each step.
  4. Why are ontologies important for agent communication?
  5. What are the advantages of WebSocket over HTTP for agent communication?
  6. Describe three security measures that should be implemented in multi-agent communication.
  7. How does KQML differ from FIPA-ACL in its approach to agent communication?
  8. What is a conversation protocol and why is it needed?
  9. List three performance optimization techniques for agent communication.
  10. How do standardized communication protocols support the 弘익人間 principle?