Communication Between Agents › Message Formats: Speaking a Common Language

Michael BrenndoerferJuly 27, 20254 min read
AI Agent HandbookAll chapters
Part 10 of 15Multi-Agent Systems - Teamwork Among AIs
Chapter 28Communication Between Agents › Message Formats: Speaking a Common Language
Reading section 3 of 11 · Message Formats: Speaking a Common Language · 4 minSection 3 of 11 · 4 min

Book contents

Section 3 of 11 · 4 min read

Communication Between Agents › Message Formats: Speaking a Common LanguageOne section · Sections in this chapter3 / 11 ↓

The first step to better communication is establishing a shared format. Just as humans might agree to communicate via email with specific subject lines and structure, agents benefit from standardized message formats.

Natural Language Messages

The simplest approach is natural language. Agent A sends a message like "I found that Bitcoin is currently trading at $45,000 with high volatility." Agent B reads this and responds accordingly.

Advantages:

  • Flexible and expressive
  • Easy to understand when debugging
  • Works well with language models' strengths

Disadvantages:

  • Ambiguous (what does "high volatility" mean exactly?)
  • Hard to parse programmatically
  • Prone to misinterpretation

Natural language works well for high-level coordination where precision isn't critical. For example, a coordinator agent might tell worker agents: "Focus on the Q4 data" or "Prioritize accuracy over speed."

Structured Data Messages

For precise information exchange, structured formats like JSON work better:

In[4]:
Code
## Agent A sends structured data
message = {
    "from": "research_agent",
    "to": "analysis_agent",
    "timestamp": "2025-11-10T14:30:00Z",
    "message_type": "research_findings",
    "data": {
        "topic": "Bitcoin price",
        "current_price": 45000,
        "currency": "USD",
        "volatility": 0.15,
        "confidence": 0.92
    }
}

Now Agent B knows exactly what it's receiving. The price is a number, not a string. The volatility is quantified. The confidence score indicates how reliable this information is. The timestamp shows when the data was collected.

Let's rebuild our example with structured communication:

In[5]:
Code
## Using Claude Sonnet 4.5 with structured message passing
from anthropic import Anthropic
import json
from datetime import datetime

client = Anthropic(api_key=os.getenv("ANTHROPIC_API_KEY"))

class AgentMessage:
    """
    Standard message format for agent communication.
    """
    def __init__(self, sender, recipient, message_type, data):
        self.sender = sender
        self.recipient = recipient
        self.message_type = message_type
        self.data = data
        self.timestamp = datetime.utcnow().isoformat()
    
    def to_json(self):
        return json.dumps({
            "from": self.sender,
            "to": self.recipient,
            "type": self.message_type,
            "timestamp": self.timestamp,
            "data": self.data
        }, indent=2)
    
    @staticmethod
    def from_json(json_str):
        obj = json.loads(json_str)
        msg = AgentMessage(
            obj["from"],
            obj["to"],
            obj["type"],
            obj["data"]
        )
        msg.timestamp = obj["timestamp"]
        return msg

def extract_json(text):
    """
    Extract JSON from text that might include markdown code blocks.
    """
    import re
    # Build the pattern for code fences dynamically to avoid backtick issues
    fence = chr(96) * 3  # Three backticks
    pattern = fence + r'(?:json)?\s*\n?([\s\S]*?)\n?' + fence
    code_block_match = re.search(pattern, text)
    if code_block_match:
        return code_block_match.group(1).strip()
    # Otherwise, try to find JSON object directly
    json_match = re.search(r'\{[\s\S]*\}', text)
    if json_match:
        return json_match.group(0)
    return text.strip()

def research_agent_v2(query):
    """
    Research agent that returns structured messages.
    """
    system_prompt = """You are a research specialist.
    Return findings as a valid JSON object with these exact fields:
    - topic: what you researched
    - findings: key information discovered (as a string or simple list)
    - sources: where the information came from (as a string or list)
    - confidence: 0-1 score of how confident you are
    
    Return ONLY the JSON object, no other text or markdown."""
    
    response = client.messages.create(
        model="claude-sonnet-4-5",
        max_tokens=512,
        system=system_prompt,
        messages=[{"role": "user", "content": query}]
    )
    
    # Parse the research findings (extract JSON from potential markdown)
    raw_text = response.content[0].text
    json_text = extract_json(raw_text)
    try:
        findings = json.loads(json_text)
    except json.JSONDecodeError:
        # Fallback: create a simple findings object from the raw text
        findings = {
            "topic": query,
            "findings": raw_text[:500],
            "sources": ["LLM response"],
            "confidence": 0.7
        }
    
    # Wrap in a standard message
    message = AgentMessage(
        sender="research_agent",
        recipient="analysis_agent",
        message_type="research_complete",
        data=findings
    )
    
    return message

def analysis_agent_v2(message):
    """
    Analysis agent that expects structured messages.
    """
    # Verify message type
    if message.message_type != "research_complete":
        return AgentMessage(
            sender="analysis_agent",
            recipient=message.sender,
            message_type="error",
            data={"error": f"Expected 'research_complete', got '{message.message_type}'"}
        )
    
    system_prompt = """You are an analysis specialist.
    You receive research findings as JSON and provide recommendations.
    Return your analysis as a valid JSON object with:
    - recommendation: your main recommendation (as a string)
    - reasoning: why you recommend this (as a string)
    - confidence: 0-1 score of confidence
    
    Return ONLY the JSON object, no other text or markdown."""
    
    # Extract research data
    research_data = json.dumps(message.data)
    
    response = client.messages.create(
        model="claude-sonnet-4-5",
        max_tokens=512,
        system=system_prompt,
        messages=[{"role": "user", "content": f"Analyze: {research_data}"}]
    )
    
    # Parse the analysis (extract JSON from potential markdown)
    raw_text = response.content[0].text
    json_text = extract_json(raw_text)
    try:
        analysis = json.loads(json_text)
    except json.JSONDecodeError:
        # Fallback: create a simple analysis object from the raw text
        analysis = {
            "recommendation": raw_text[:300],
            "reasoning": "Based on the research findings",
            "confidence": 0.7
        }
    
    # Return structured response
    return AgentMessage(
        sender="analysis_agent",
        recipient="research_agent",
        message_type="analysis_complete",
        data=analysis
    )

## Example usage
print("=== Structured Agent Communication ===\n")

## Research agent does its work
research_msg = research_agent_v2("Research the benefits of renewable energy")
print(f"Research Agent sent:\n{research_msg.to_json()}\n")

## Analysis agent receives and processes
analysis_msg = analysis_agent_v2(research_msg)
print(f"Analysis Agent sent:\n{analysis_msg.to_json()}")
Out[5]:
Console
=== Structured Agent Communication ===
Research Agent sent:
{
  "from": "research_agent",
  "to": "analysis_agent",
  "type": "research_complete",
  "timestamp": "2025-12-07T12:03:02.665175",
  "data": {
    "topic": "Benefits of renewable energy",
    "findings": [
      "Environmental benefits: Renewable energy sources produce little to no greenhouse gas emissions or air pollutants during operation, helping combat climate change and reduce air pollution-related health issues",
      "Energy independence: Reduces reliance on imported fossil fuels and enhances national energy security by utilizing domestic resources like sun, wind, and water",
      "Economic advantages: Creates jobs in manufacturing, installation, and maintenance sectors; solar and wind are now cost-competitive with or cheaper than fossil fuels in many regions",
      "Sustainability: Renewable sources are inexhaustible on human timescales, unlike finite fossil fuel reserves",
      "Price stability: Operating costs are more predictable as fuel costs are eliminated; insulates consumers from volatile fossil fuel price fluctuations",
      "Health benefits: Reduces respiratory diseases, cardiovascular problems, and premature deaths associated with fossil fuel pollution",
      "Grid resilience: Distributed renewable energy systems can improve grid reliability and reduce transmission losses",
      "Water conservation: Most renewable technologies use significantly less water than conventional thermal power plants"
    ],
    "sources": [
      "International Energy Agency (IEA) reports on renewable energy",
      "U.S. Department of Energy and Environmental Protection Agency studies",
      "International Renewable Energy Agency (IRENA) publications",
      "Academic research from environmental science journals",
      "National Renewable Energy Laboratory (NREL) data",
      "World Health Organization studies on air quality and health"
    ],
    "confidence": 0.95
  }
}
Analysis Agent sent:
{
  "from": "analysis_agent",
  "to": "research_agent",
  "type": "analysis_complete",
  "timestamp": "2025-12-07T12:03:10.502700",
  "data": {
    "recommendation": "Accelerate investment and policy support for renewable energy transition across all sectors, prioritizing solar and wind deployment while developing grid infrastructure and energy storage solutions to maximize environmental, economic, and health benefits",
    "reasoning": "The research demonstrates overwhelming evidence across multiple dimensions: (1) Environmental - significant reduction in greenhouse gases and air pollution; (2) Economic - cost competitiveness achieved, job creation potential, and price stability advantages; (3) Health - measurable reduction in pollution-related diseases and mortality; (4) Strategic - enhanced energy security and independence from volatile fossil fuel markets; (5) Sustainability - inexhaustible resources ensuring long-term viability. The high confidence score (0.95) and credible sources (IEA, IRENA, NREL, WHO) validate these findings. The convergence of economic viability with environmental necessity creates a rare policy alignment where financial and ecological interests coincide, making this an optimal time for aggressive renewable energy expansion",
    "confidence": 0.92
  }
}

This structured approach gives us several benefits:

Type Safety: The message_type field lets agents verify they're receiving the expected kind of message.

Traceability: Timestamps and sender/recipient fields create an audit trail of communication.

Error Handling: Agents can send error messages in the same format, making it easy to handle failures.

Extensibility: You can add new message types without breaking existing communication patterns.