DEV Community

vishalmysore
vishalmysore

Posted on

Insurance Domain Agentic Mesh in Java: From Underwriting Rules to Claims Automation

An AI Agentic Mesh is a cutting-edge distributed architecture pattern where multiple specialized AI agents collaborate autonomously to solve complex, domain-specific problems. Unlike traditional monolithic systems, an agentic mesh enables agents to:

  • Operate independently with specific domain expertise
  • Communicate seamlessly using standardized protocols (MCP, A2A)
  • Scale horizontally by adding new specialized agents
  • Maintain loose coupling while ensuring high cohesion
  • Self-organize to handle complex workflows
  • Transform legacy code into intelligent, collaborative agents

Code for article is here
https://github.com/vishalmysore/insuranceagenticmesh

Why Transform Your Java Code into Agentic Mesh?

The insurance industry presents unique challenges that make it an ideal candidate for demonstrating agentic mesh architecture:

  • Complex workflows spanning policy management, claims, underwriting, and customer service
  • Domain expertise that can be encapsulated in specialized agents
  • Existing Java codebases that can be easily converted to agents
  • Modular architecture enabling incremental migration from monolithic systems
  • AI-powered decision making without completely rewriting your applications

Understanding the Insurance Agentic Mesh {#insurance-mesh}

System Overview

This Insurance Agentic Mesh implementation showcases a cutting-edge distributed system built with Java, demonstrating how to transform traditional service-oriented code into four specialized AI agents:

┌─────────────────────────────────────────────────────────────┐
│                    Insurance Mesh Client                     │
│                  (AgentCatalog + AgenticMesh)               │
└────────────────────┬────────────────────────────────────────┘
                     │
        ┌────────────┼────────────┬────────────┐
        │            │            │            │
        ▼            ▼            ▼            ▼
    ┌───────┐  ┌────────┐  ┌──────────┐  ┌──────────┐
    │Policy │  │Claims  │  │Under-    │  │Customer  │
    │Mgmt   │  │Process │  │writing   │  │Service   │
    │:7871  │  │:7872   │  │:7873     │  │:7874     │
    └───────┘  └────────┘  └──────────┘  └──────────┘
Enter fullscreen mode Exit fullscreen mode

Agent Responsibilities

1. Policy Management Agent (Port 7871)

Domain: Complete policy lifecycle management

Key Capabilities:

  • Policy creation, renewal, and cancellation
  • Premium calculation with multi-factor analysis
  • Policy details retrieval and updates
  • Customer policy portfolio management
@Agent(groupName = "policyManagementOperations")
@Service
public class PolicyManagementService {

    @Action(description = "Create a new insurance policy")
    public String createPolicy(String policyType, String customerName, 
                               double coverageAmount) {
        String policyNumber = "POL-" + (System.currentTimeMillis() % 100000);
        return String.format("Policy created successfully!\n" +
               "Policy Number: %s\n" +
               "Policy Type: %s\n" +
               "Customer: %s\n" +
               "Coverage Amount: $%.2f\n" +
               "Status: ACTIVE", 
               policyNumber, policyType, customerName, coverageAmount);
    }

    @Action(description = "Calculate premium for a policy")
    public String calculatePremium(String policyType, int age, 
                                   double coverageAmount, String riskCategory) {
        double basePremium = coverageAmount * 0.0025;
        double ageFactor = age > 50 ? 1.5 : 1.0;
        double riskFactor = riskCategory.equalsIgnoreCase("HIGH") ? 2.0 : 
                           riskCategory.equalsIgnoreCase("MEDIUM") ? 1.3 : 1.0;
        double totalPremium = basePremium * ageFactor * riskFactor;

        return String.format("Annual Premium: $%.2f\nMonthly: $%.2f", 
                           totalPremium, totalPremium / 12);
    }
}
Enter fullscreen mode Exit fullscreen mode

2. Claims Processing Agent (Port 7872)

Domain: End-to-end claims management

Key Capabilities:

  • Claim submission and validation
  • Status tracking and updates
  • Approval/denial workflows
  • Payment processing
  • Documentation management
@Agent(groupName = "claimsProcessingOperations")
@Service
public class ClaimsProcessingService {

    @Action(description = "Submit a new insurance claim")
    public String submitClaim(String policyNumber, String claimType, 
                             double claimAmount, String description) {
        String claimNumber = "CLM-" + (System.currentTimeMillis() % 100000);
        return String.format("Claim submitted successfully!\n" +
               "Claim Number: %s\n" +
               "Status: PENDING REVIEW\n" +
               "Expected Processing: 5-7 business days", claimNumber);
    }

    @Action(description = "Calculate claim payout amount")
    public String calculateClaimPayout(String claimNumber, double claimAmount, 
                                       double deductible, double coveragePercentage) {
        double payoutAmount = (claimAmount - deductible) * (coveragePercentage / 100.0);
        return String.format("Final Payout Amount: $%.2f", Math.max(0, payoutAmount));
    }
}
Enter fullscreen mode Exit fullscreen mode

3. Underwriting Agent (Port 7873)

Domain: Risk assessment and pricing

Key Capabilities:

  • Multi-factor risk analysis
  • Premium rate calculation
  • Eligibility evaluation
  • Risk report generation
  • Application approval/denial
@Agent(groupName = "underwritingOperations")
@Service
public class UnderwritingService {

    @Action(description = "Assess risk for an insurance application")
    public String assessRisk(String applicantName, int age, 
                            String healthStatus, String occupation, boolean smoker) {
        int riskScore = 50;

        // Multi-factor risk calculation
        if (age > 60) riskScore += 30;
        else if (age > 45) riskScore += 15;

        if (healthStatus.equalsIgnoreCase("EXCELLENT")) riskScore -= 20;
        else if (healthStatus.equalsIgnoreCase("POOR")) riskScore += 30;

        if (smoker) riskScore += 25;

        String riskCategory = riskScore < 40 ? "LOW" : 
                             riskScore < 70 ? "MEDIUM" : "HIGH";

        return String.format("Risk Score: %d/100\nCategory: %s", 
                           riskScore, riskCategory);
    }
}
Enter fullscreen mode Exit fullscreen mode

4. Customer Service Agent (Port 7874)

Domain: Customer support and account management

Key Capabilities:

  • Account information retrieval
  • Customer inquiry handling
  • Appointment scheduling
  • Document generation
  • Payment processing
@Agent(groupName = "customerServiceOperations")
@Service
public class CustomerServiceService {

    @Action(description = "Handle customer inquiry")
    public String handleInquiry(String customerId, String inquiryType, 
                                String question) {
        String response;
        switch (inquiryType.toLowerCase()) {
            case "policy":
                response = "Your policy information retrieved. " +
                          "You have 3 active policies.";
                break;
            case "claim":
                response = "Please provide your claim number for status.";
                break;
            default:
                response = "A representative will respond within 24 hours.";
        }
        return String.format("Ticket: TKT-%d\nResponse: %s", 
                           System.currentTimeMillis() % 100000, response);
    }
}
Enter fullscreen mode Exit fullscreen mode

Core Components and Architecture {#architecture}

Technology Stack

<dependencies>
    <!-- Spring Boot for REST APIs -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <version>3.2.4</version>
    </dependency>

    <!-- A2A Java Library - Core Agentic Mesh -->
    <dependency>
        <groupId>io.github.vishalmysore</groupId>
        <artifactId>a2ajava</artifactId>
        <version>1.0.7</version>
    </dependency>

    <!-- Tools4AI - Agent Action Framework -->
    <dependency>
        <groupId>io.github.vishalmysore</groupId>
        <artifactId>tools4ai</artifactId>
        <version>1.1.9.7</version>
    </dependency>

    <!-- Tools4AI Annotations -->
    <dependency>
        <groupId>io.github.vishalmysore</groupId>
        <artifactId>tools4ai-annotations</artifactId>
        <version>0.0.2</version>
    </dependency>
</dependencies>
Enter fullscreen mode Exit fullscreen mode

Configuration Architecture

Each agent server uses Spring profiles for isolation:

application-policymanagement.properties:

server.port=7871
spring.application.name=policy-management-server
Enter fullscreen mode Exit fullscreen mode

tools4ai_policymanagement.properties:

agent.provider=openai
gemini.modelName=gemini-2.0-flash-001
anthropic.modelName=claude-3-haiku-20240307
openAiModelName=nvidia/nemotron-nano-12b-v2-vl
Enter fullscreen mode Exit fullscreen mode

Server Bootstrap

Each agent runs as an independent Spring Boot application:

@SpringBootApplication
public class PolicyManagementServer {
    public static void main(String[] args) {
        System.setProperty("spring.profiles.active", "policymanagement");
        SpringApplication.run(PolicyManagementServer.class, args);
    }
}
Enter fullscreen mode Exit fullscreen mode

A2A Java Library: AgentCatalog and AgenticMesh {#a2a-library}

Understanding AgentCatalog

AgentCatalog is the foundational component of the A2A Java library that enables agent discovery and communication. It acts as a registry and coordinator for all agents in the mesh.

Key Features:

  • Agent Registration: Dynamic addition of agent endpoints
  • Query Routing: Intelligent routing of queries to appropriate agents
  • Load Balancing: Distribution of requests across agents
  • Fault Tolerance: Handling agent failures gracefully
  • Protocol Support: MCP (Model Context Protocol) and A2A (Agent-to-Agent)

Basic Usage:

import io.github.vishalmysore.mesh.AgentCatalog;

public class BasicAgentCatalogExample {
    public static void main(String[] args) {
        // Create AgentCatalog instance
        AgentCatalog catalog = new AgentCatalog();

        // Register agents by endpoint URL
        catalog.addAgent("http://localhost:7871/"); // Policy Management
        catalog.addAgent("http://localhost:7872/"); // Claims Processing
        catalog.addAgent("http://localhost:7873/"); // Underwriting
        catalog.addAgent("http://localhost:7874/"); // Customer Service

        // Execute queries - catalog routes to appropriate agent
        String result = catalog.processQuery(
            "Create a life insurance policy for John Doe with $500,000 coverage"
        ).getTextResult();

        System.out.println(result);
    }
}
Enter fullscreen mode Exit fullscreen mode

Advanced AgentCatalog Features:

public class AdvancedAgentCatalogExample {
    public void demonstrateAdvancedFeatures() {
        AgentCatalog catalog = new AgentCatalog();

        // Add agents with metadata
        catalog.addAgent("http://localhost:7871/");
        catalog.addAgent("http://localhost:7872/");

        // Multi-agent query - catalog determines which agents to use
        String complexResult = catalog.processQuery(
            "For customer CUST-12345, check active policies, " +
            "assess risk for additional coverage, and show pending claims"
        ).getTextResult();

        // The catalog automatically:
        // 1. Parses the complex query
        // 2. Identifies required agents (Policy, Underwriting, Claims)
        // 3. Routes sub-queries to appropriate agents
        // 4. Aggregates responses
        // 5. Returns unified result

        System.out.println(complexResult);
    }
}
Enter fullscreen mode Exit fullscreen mode

Understanding AgenticMesh

AgenticMesh builds on top of AgentCatalog to provide advanced orchestration capabilities, including pipeline processing, parallel execution, and complex workflow management.

Key Features:

  • Pipeline Processing: Sequential agent execution with context passing
  • Parallel Execution: Concurrent agent invocation for performance
  • Workflow Orchestration: Complex multi-step processes
  • Context Management: Shared state across agent interactions
  • Error Handling: Comprehensive error recovery mechanisms

Basic Usage:

import io.github.vishalmysore.mesh.AgentCatalog;
import io.github.vishalmysore.mesh.AgenticMesh;

public class BasicAgenticMeshExample {
    public static void main(String[] args) {
        // Initialize catalog and mesh
        AgentCatalog catalog = new AgentCatalog();
        catalog.addAgent("http://localhost:7871/");
        catalog.addAgent("http://localhost:7872/");
        catalog.addAgent("http://localhost:7873/");
        catalog.addAgent("http://localhost:7874/");

        AgenticMesh mesh = new AgenticMesh(catalog);

        // Pipeline execution - agents execute in sequence
        String pipelineResult = mesh.pipeLineMesh(
            "Create policy for John Doe, assess risk, calculate premium"
        ).getTextResult();

        System.out.println(pipelineResult);
    }
}
Enter fullscreen mode Exit fullscreen mode

Complete Client Implementation Example

Here's the full implementation from the Insurance Mesh project:

package org.example.insuranceclient;

import io.github.vishalmysore.mesh.AgentCatalog;
import io.github.vishalmysore.mesh.AgenticMesh;
import lombok.extern.java.Log;

@Log
public class InsuranceMeshClient {
    public static void main(String[] args) {
        log.info("Initializing Insurance Agentic Mesh...");

        // Step 1: Create AgentCatalog
        AgentCatalog agentCatalog = new AgentCatalog();

        // Step 2: Register all insurance domain agents
        agentCatalog.addAgent("http://localhost:7871/"); // Policy Management
        agentCatalog.addAgent("http://localhost:7872/"); // Claims Processing
        agentCatalog.addAgent("http://localhost:7873/"); // Underwriting
        agentCatalog.addAgent("http://localhost:7874/"); // Customer Service

        log.info("Insurance Mesh initialized with 4 specialized agents");

        // Step 3: Execute individual queries via AgentCatalog
        System.out.println("\n=== AgentCatalog Examples ===\n");

        // Query 1: Customer information
        String customerInfo = agentCatalog.processQuery(
            "Get customer account information for customer ID CUST-12345"
        ).getTextResult();
        System.out.println("Customer Information:\n" + customerInfo);

        // Query 2: Risk assessment
        String riskAssessment = agentCatalog.processQuery(
            "Assess risk for John Doe, 42 years old, good health, " +
            "software engineer, non-smoker"
        ).getTextResult();
        System.out.println("\nRisk Assessment:\n" + riskAssessment);

        // Query 3: Policy creation
        String policyResult = agentCatalog.processQuery(
            "Create a life insurance policy for John Doe with $500,000 coverage"
        ).getTextResult();
        System.out.println("\nPolicy Creation:\n" + policyResult);

        // Query 4: Claim submission
        String claimResult = agentCatalog.processQuery(
            "Submit a medical claim for policy POL-12345, " +
            "claim amount $5000, for emergency surgery"
        ).getTextResult();
        System.out.println("\nClaim Submission:\n" + claimResult);

        // Query 5: Complex cross-domain query
        String complexQuery = agentCatalog.processQuery(
            "For customer CUST-12345, check their active policies, " +
            "assess if they need additional coverage, and show any pending claims"
        ).getTextResult();
        System.out.println("\nComplex Query Result:\n" + complexQuery);

        // Step 4: Create AgenticMesh for pipeline processing
        AgenticMesh agenticMesh = new AgenticMesh(agentCatalog);

        System.out.println("\n=== AgenticMesh Pipeline Examples ===\n");

        // Pipeline query - sequential execution with context passing
        String pipelineResult = agenticMesh.pipeLineMesh(
            "For customer CUST-12345, check their active policies, " +
            "assess if they need additional coverage, and show any pending claims"
        ).getTextResult();
        System.out.println("\nPipeline Result:\n" + pipelineResult);

        log.info("Insurance Mesh demo completed");
    }
}
Enter fullscreen mode Exit fullscreen mode

AgentCatalog vs AgenticMesh: When to Use What

Feature AgentCatalog AgenticMesh
Use Case Simple queries, agent discovery Complex workflows, pipelines
Execution Model Intelligent routing Sequential/parallel orchestration
Context Sharing Limited Full context passing
Performance Faster for single queries Optimized for multi-step
Complexity Low Medium to High

Use AgentCatalog when:

  • Making single agent calls
  • Simple query routing needed
  • Low latency requirements
  • Independent operations

Use AgenticMesh when:

  • Multi-step workflows required
  • Context must be passed between agents
  • Complex orchestration needed
  • Pipeline processing required

Converting Existing Java Code to Agentic Architecture {#implementation}

Transforming a Traditional Service into an Agent

The beauty of the A2A Java library is that it allows you to convert your existing Java services into intelligent agents with minimal code changes. Let's see how to transform traditional code into agentic architecture.

Before: Traditional Java Service

package org.example.myservice;

import org.springframework.stereotype.Service;

@Service
public class TraditionalPolicyService {

    // Traditional service method
    public PolicyResponse createPolicy(String customerName, 
                                      String policyType, 
                                      double coverage) {
        // Your existing business logic
        Policy policy = new Policy();
        policy.setCustomerName(customerName);
        policy.setPolicyType(policyType);
        policy.setCoverage(coverage);
        policy.setStatus("ACTIVE");

        return new PolicyResponse(policy);
    }

    public double calculatePremium(Policy policy, int age) {
        // Your existing calculation logic
        double basePremium = policy.getCoverage() * 0.0025;
        double ageFactor = age > 50 ? 1.5 : 1.0;
        return basePremium * ageFactor;
    }
}
Enter fullscreen mode Exit fullscreen mode

After: Agentic Service (Just Add Annotations!)

package org.example.myservice;

import com.t4a.annotations.Action;
import com.t4a.annotations.Agent;
import org.springframework.stereotype.Service;

// Add @Agent annotation - that's it!
@Agent(groupName = "policyOperations")
@Service
public class AgenticPolicyService {

    // Add @Action annotation to expose as agent capability
    @Action(description = "Create a new insurance policy for a customer")
    public String createPolicy(String customerName, 
                              String policyType, 
                              double coverage) {
        // Keep your existing business logic!
        Policy policy = new Policy();
        policy.setCustomerName(customerName);
        policy.setPolicyType(policyType);
        policy.setCoverage(coverage);
        policy.setStatus("ACTIVE");

        // Return as String for agent communication
        return String.format("Policy created: %s for %s with coverage $%.2f",
                           policy.getId(), customerName, coverage);
    }

    @Action(description = "Calculate insurance premium based on coverage and age")
    public String calculatePremium(double coverage, int age) {
        // Your existing calculation logic unchanged!
        double basePremium = coverage * 0.0025;
        double ageFactor = age > 50 ? 1.5 : 1.0;
        double premium = basePremium * ageFactor;

        return String.format("Premium calculated: $%.2f/year", premium);
    }
}
Enter fullscreen mode Exit fullscreen mode

Key Changes:

  1. Add @Agent annotation to your service class
  2. Add @Action annotations to methods you want to expose
  3. Convert return types to String for agent communication
  4. Your business logic remains unchanged!

Building Your First Agent Server from Scratch

Step 1: Create the Service with @agent and @Action

package org.example.myservice;

import com.t4a.annotations.Action;
import com.t4a.annotations.Agent;
import org.springframework.stereotype.Service;

@Agent(groupName = "myServiceOperations")
@Service
public class MyService {

    @Action(description = "Process customer request")
    public String processRequest(String customerId, String requestType) {
        // Your business logic here
        return "Request processed for customer: " + customerId;
    }

    @Action(description = "Calculate quote")
    public String calculateQuote(String productType, double amount) {
        double quote = amount * 1.15; // Example calculation
        return String.format("Quote for %s: $%.2f", productType, quote);
    }
}
Enter fullscreen mode Exit fullscreen mode

Step 2: Create the Server Bootstrap

package org.example.myservice;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class MyServiceServer {
    public static void main(String[] args) {
        System.setProperty("spring.profiles.active", "myservice");
        SpringApplication.run(MyServiceServer.class, args);
    }
}
Enter fullscreen mode Exit fullscreen mode

Step 3: Configure Server Properties

application-myservice.properties:

server.port=7875
spring.application.name=my-service-server
logging.level.com.t4a=DEBUG
Enter fullscreen mode Exit fullscreen mode

tools4ai_myservice.properties:

agent.provider=openai
openAiKey=${OPENAI_API_KEY}
openAiModelName=gpt-4
Enter fullscreen mode Exit fullscreen mode

Step 4: Build and Run

# Build the project
mvn clean package

# Run your server
java -cp target/classes org.example.myservice.MyServiceServer
Enter fullscreen mode Exit fullscreen mode

Step 5: Test with curl

# Discover available tools
curl -H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"tools/list","params":{},"id":1}' \
http://localhost:7875/

# Call an action
curl -H "Content-Type: application/json" \
-d '{
    "jsonrpc": "2.0",
    "method": "tools/call",
    "params": {
        "name": "processRequest",
        "arguments": {
            "provideAllValuesInPlainEnglish": "{\"customerId\":\"CUST-123\",\"requestType\":\"quote\"}"
        }
    },
    "id": 2
}' \
http://localhost:7875/
Enter fullscreen mode Exit fullscreen mode

Integrating Your Agent into the Mesh

public class ExtendedInsuranceMesh {
    public static void main(String[] args) {
        AgentCatalog catalog = new AgentCatalog();

        // Add existing agents
        catalog.addAgent("http://localhost:7871/"); // Policy
        catalog.addAgent("http://localhost:7872/"); // Claims
        catalog.addAgent("http://localhost:7873/"); // Underwriting
        catalog.addAgent("http://localhost:7874/"); // Customer Service

        // Add your new agent
        catalog.addAgent("http://localhost:7875/"); // Your Service

        // Now your agent is part of the mesh
        String result = catalog.processQuery(
            "Process quote request for customer CUST-123 using my service"
        ).getTextResult();

        System.out.println(result);
    }
}
Enter fullscreen mode Exit fullscreen mode

Advanced Agentic Mesh Concepts {#advanced-concepts}

1. Hierarchical Agent Organization

Create specialized sub-meshes for complex domains:

public class HierarchicalMeshExample {
    public void createHierarchicalMesh() {
        // Life Insurance Sub-Mesh
        AgentCatalog lifeInsuranceMesh = new AgentCatalog();
        lifeInsuranceMesh.addAgent("http://localhost:7881/"); // Life Policy
        lifeInsuranceMesh.addAgent("http://localhost:7882/"); // Life Claims
        lifeInsuranceMesh.addAgent("http://localhost:7883/"); // Life Underwriting

        // Auto Insurance Sub-Mesh
        AgentCatalog autoInsuranceMesh = new AgentCatalog();
        autoInsuranceMesh.addAgent("http://localhost:7891/"); // Auto Policy
        autoInsuranceMesh.addAgent("http://localhost:7892/"); // Auto Claims
        autoInsuranceMesh.addAgent("http://localhost:7893/"); // Auto Underwriting

        // Master Mesh coordinating sub-meshes
        AgentCatalog masterMesh = new AgentCatalog();
        // Add coordination logic here
    }
}
Enter fullscreen mode Exit fullscreen mode

2. Dynamic Agent Discovery

Implement service discovery for dynamic mesh composition:

public class DynamicMeshExample {
    private AgentCatalog catalog;
    private Set<String> registeredAgents = new HashSet<>();

    public void registerAgentDynamically(String agentUrl, String agentType) {
        if (!registeredAgents.contains(agentUrl)) {
            catalog.addAgent(agentUrl);
            registeredAgents.add(agentUrl);
            System.out.println("Registered new agent: " + agentType + 
                             " at " + agentUrl);
        }
    }

    public void discoverAndRegisterAgents() {
        // Integration with service discovery (Consul, Eureka, etc.)
        List<ServiceInstance> instances = discoveryClient.getInstances("insurance-agent");
        for (ServiceInstance instance : instances) {
            registerAgentDynamically(instance.getUri().toString(), 
                                   instance.getMetadata().get("agentType"));
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

3. Context-Aware Agent Selection

Implement intelligent agent selection based on query context:

public class ContextAwareRoutingExample {
    private AgentCatalog catalog;

    public String processContextAwareQuery(String query, Map<String, Object> context) {
        // Analyze query intent
        String intent = analyzeIntent(query);

        // Select agents based on context
        if (context.containsKey("policyType") && 
            context.get("policyType").equals("life")) {
            // Route to life insurance specific agents
            return catalog.processQuery(query + " [LIFE_INSURANCE_CONTEXT]")
                         .getTextResult();
        } else if (context.containsKey("urgency") && 
                  (Boolean) context.get("urgency")) {
            // Route to high-priority agents
            return catalog.processQuery(query + " [URGENT]")
                         .getTextResult();
        }

        return catalog.processQuery(query).getTextResult();
    }

    private String analyzeIntent(String query) {
        // NLP-based intent classification
        return "CREATE_POLICY"; // Simplified example
    }
}
Enter fullscreen mode Exit fullscreen mode

4. Agent Collaboration Patterns

Pattern 1: Sequential Pipeline

public class SequentialPipelinePattern {
    public void executeSequentialWorkflow(AgenticMesh mesh) {
        // Each step depends on previous step's output
        String result = mesh.pipeLineMesh(
            "Step 1: Assess risk for applicant → " +
            "Step 2: Calculate premium based on risk → " +
            "Step 3: Create policy with calculated premium → " +
            "Step 4: Send confirmation to customer"
        ).getTextResult();
    }
}
Enter fullscreen mode Exit fullscreen mode

Pattern 2: Parallel Scatter-Gather

public class ParallelScatterGatherPattern {
    public void executeParallelWorkflow(AgentCatalog catalog) {
        // Execute multiple independent queries in parallel
        ExecutorService executor = Executors.newFixedThreadPool(4);

        List<Future<String>> futures = Arrays.asList(
            executor.submit(() -> catalog.processQuery(
                "Check customer credit score").getTextResult()),
            executor.submit(() -> catalog.processQuery(
                "Verify customer identity").getTextResult()),
            executor.submit(() -> catalog.processQuery(
                "Check existing policies").getTextResult()),
            executor.submit(() -> catalog.processQuery(
                "Assess risk profile").getTextResult())
        );

        // Gather results
        futures.forEach(future -> {
            try {
                String result = future.get();
                System.out.println("Result: " + result);
            } catch (Exception e) {
                e.printStackTrace();
            }
        });

        executor.shutdown();
    }
}
Enter fullscreen mode Exit fullscreen mode

Pattern 3: Conditional Routing

public class ConditionalRoutingPattern {
    public String executeConditionalWorkflow(AgentCatalog catalog, 
                                            String customerId) {
        // Step 1: Get customer tier
        String tierResult = catalog.processQuery(
            "Get customer tier for " + customerId
        ).getTextResult();

        // Step 2: Route based on tier
        if (tierResult.contains("PREMIUM")) {
            return catalog.processQuery(
                "Process premium customer request with priority handling"
            ).getTextResult();
        } else if (tierResult.contains("GOLD")) {
            return catalog.processQuery(
                "Process gold customer request with standard handling"
            ).getTextResult();
        } else {
            return catalog.processQuery(
                "Process standard customer request"
            ).getTextResult();
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

5. Error Handling and Resilience

public class ResilientMeshExample {
    private AgentCatalog catalog;
    private static final int MAX_RETRIES = 3;
    private static final long RETRY_DELAY_MS = 1000;

    public String executeWithRetry(String query) {
        int attempts = 0;
        Exception lastException = null;

        while (attempts < MAX_RETRIES) {
            try {
                return catalog.processQuery(query).getTextResult();
            } catch (Exception e) {
                lastException = e;
                attempts++;
                System.err.println("Attempt " + attempts + " failed: " + 
                                 e.getMessage());

                if (attempts < MAX_RETRIES) {
                    try {
                        Thread.sleep(RETRY_DELAY_MS * attempts);
                    } catch (InterruptedException ie) {
                        Thread.currentThread().interrupt();
                        break;
                    }
                }
            }
        }

        throw new RuntimeException("Failed after " + MAX_RETRIES + 
                                 " attempts", lastException);
    }

    public String executeWithFallback(String query, String fallbackQuery) {
        try {
            return catalog.processQuery(query).getTextResult();
        } catch (Exception e) {
            System.err.println("Primary query failed, using fallback: " + 
                             e.getMessage());
            return catalog.processQuery(fallbackQuery).getTextResult();
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

6. Performance Monitoring and Metrics

public class MonitoredMeshExample {
    private AgentCatalog catalog;
    private Map<String, AgentMetrics> metricsMap = new ConcurrentHashMap<>();

    public String executeWithMonitoring(String query) {
        long startTime = System.currentTimeMillis();
        String result = null;
        boolean success = false;

        try {
            result = catalog.processQuery(query).getTextResult();
            success = true;
            return result;
        } catch (Exception e) {
            throw e;
        } finally {
            long duration = System.currentTimeMillis() - startTime;
            recordMetrics(query, duration, success);
        }
    }

    private void recordMetrics(String query, long duration, boolean success) {
        String agentType = extractAgentType(query);
        AgentMetrics metrics = metricsMap.computeIfAbsent(
            agentType, k -> new AgentMetrics()
        );

        metrics.incrementTotalCalls();
        metrics.addDuration(duration);
        if (success) {
            metrics.incrementSuccessCount();
        } else {
            metrics.incrementFailureCount();
        }
    }

    public void printMetrics() {
        metricsMap.forEach((agent, metrics) -> {
            System.out.println("\nAgent: " + agent);
            System.out.println("Total Calls: " + metrics.getTotalCalls());
            System.out.println("Success Rate: " + metrics.getSuccessRate() + "%");
            System.out.println("Avg Duration: " + metrics.getAverageDuration() + "ms");
        });
    }

    private String extractAgentType(String query) {
        // Logic to determine which agent type handled the query
        return "POLICY_MANAGEMENT"; // Simplified
    }
}

class AgentMetrics {
    private AtomicLong totalCalls = new AtomicLong(0);
    private AtomicLong successCount = new AtomicLong(0);
    private AtomicLong failureCount = new AtomicLong(0);
    private List<Long> durations = Collections.synchronizedList(new ArrayList<>());

    public void incrementTotalCalls() { totalCalls.incrementAndGet(); }
    public void incrementSuccessCount() { successCount.incrementAndGet(); }
    public void incrementFailureCount() { failureCount.incrementAndGet(); }
    public void addDuration(long duration) { durations.add(duration); }

    public long getTotalCalls() { return totalCalls.get(); }
    public double getSuccessRate() {
        return (successCount.get() * 100.0) / totalCalls.get();
    }
    public double getAverageDuration() {
        return durations.stream().mapToLong(Long::longValue).average().orElse(0.0);
    }
}
Enter fullscreen mode Exit fullscreen mode

Real-World Use Cases {#use-cases}

Use Case 1: New Customer Onboarding

public class CustomerOnboardingWorkflow {
    private AgenticMesh mesh;

    public String onboardNewCustomer(CustomerApplication application) {
        StringBuilder workflow = new StringBuilder();

        // Step 1: Create customer account
        workflow.append("Create customer account for ")
                .append(application.getName())
                .append(" with email ")
                .append(application.getEmail());

        // Step 2: Assess risk
        workflow.append(" → Assess risk: age ")
                .append(application.getAge())
                .append(", health ")
                .append(application.getHealthStatus());

        // Step 3: Calculate premium
        workflow.append(" → Calculate premium for ")
                .append(application.getPolicyType())
                .append(" coverage $")
                .append(application.getCoverageAmount());

        // Step 4: Create policy
        workflow.append(" → Create policy if approved");

        // Step 5: Send welcome package
        workflow.append(" → Generate welcome documents and send");

        return mesh.pipeLineMesh(workflow.toString()).getTextResult();
    }
}
Enter fullscreen mode Exit fullscreen mode

Use Case 2: Claims Processing with Fraud Detection

public class ClaimsProcessingWorkflow {
    private AgentCatalog catalog;

    public String processClaimWithFraudCheck(ClaimSubmission claim) {
        // Step 1: Validate policy
        String policyValidation = catalog.processQuery(
            "Verify policy " + claim.getPolicyNumber() + " is active and valid"
        ).getTextResult();

        if (!policyValidation.contains("ACTIVE")) {
            return "Claim denied: Policy not active";
        }

        // Step 2: Check claim history
        String claimHistory = catalog.processQuery(
            "Get claim history for policy " + claim.getPolicyNumber()
        ).getTextResult();

        // Step 3: Fraud detection analysis
        boolean suspiciousClaim = detectFraud(claim, claimHistory);

        if (suspiciousClaim) {
            // Route to manual review
            return catalog.processQuery(
                "Flag claim " + claim.getClaimNumber() + 
                " for manual fraud investigation"
            ).getTextResult();
        }

        // Step 4: Calculate payout
        String payout = catalog.processQuery(
            "Calculate claim payout for " + claim.getClaimNumber() +
            " amount " + claim.getClaimAmount()
        ).getTextResult();

        // Step 5: Approve and process payment
        return catalog.processQuery(
            "Approve and process payment for claim " + claim.getClaimNumber()
        ).getTextResult();
    }

    private boolean detectFraud(ClaimSubmission claim, String history) {
        // Fraud detection logic
        return claim.getClaimAmount() > 10000 && 
               history.contains("multiple recent claims");
    }
}
Enter fullscreen mode Exit fullscreen mode

Use Case 3: Policy Renewal with Upsell

public class PolicyRenewalWorkflow {
    private AgenticMesh mesh;

    public String processRenewalWithUpsell(String policyNumber) {
        String workflow = String.format(
            "Get policy details for %s → " +
            "Assess if customer needs additional coverage → " +
            "Calculate renewal premium with any applicable discounts → " +
            "Generate personalized upsell recommendations → " +
            "Send renewal notice with recommendations → " +
            "Process renewal if customer accepts",
            policyNumber
        );

        return mesh.pipeLineMesh(workflow).getTextResult();
    }
}
Enter fullscreen mode Exit fullscreen mode

Use Case 4: Multi-Policy Quote Comparison

public class QuoteComparisonWorkflow {
    private AgentCatalog catalog;
    private ExecutorService executor = Executors.newFixedThreadPool(3);

    public ComparisonResult compareMultiplePolicies(CustomerProfile customer) {
        // Request quotes in parallel
        Future<String> lifeFuture = executor.submit(() ->
            catalog.processQuery(
                "Calculate life insurance premium for " + customer.describe()
            ).getTextResult()
        );

        Future<String> autoFuture = executor.submit(() ->
            catalog.processQuery(
                "Calculate auto insurance premium for " + customer.describe()
            ).getTextResult()
        );

        Future<String> homeFuture = executor.submit(() ->
            catalog.processQuery(
                "Calculate home insurance premium for " + customer.describe()
            ).getTextResult()
        );

        try {
            ComparisonResult result = new ComparisonResult();
            result.setLifeQuote(lifeFuture.get());
            result.setAutoQuote(autoFuture.get());
            result.setHomeQuote(homeFuture.get());
            result.calculateBundleDiscount();
            return result;
        } catch (Exception e) {
            throw new RuntimeException("Quote comparison failed", e);
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Performance and Scalability {#performance}

Horizontal Scaling Strategies

1. Agent Replication

public class ReplicatedAgentMesh {
    private AgentCatalog catalog;

    public void setupReplicatedAgents() {
        // Add multiple instances of same agent for load distribution
        catalog.addAgent("http://policy-server-1:7871/");
        catalog.addAgent("http://policy-server-2:7871/");
        catalog.addAgent("http://policy-server-3:7871/");

        catalog.addAgent("http://claims-server-1:7872/");
        catalog.addAgent("http://claims-server-2:7872/");

        // Catalog automatically distributes load across replicas
    }
}
Enter fullscreen mode Exit fullscreen mode

2. Regional Distribution

public class GeographicallyDistributedMesh {
    private Map<String, AgentCatalog> regionalCatalogs = new HashMap<>();

    public void setupRegionalMeshes() {
        // US East Region
        AgentCatalog usEast = new AgentCatalog();
        usEast.addAgent("http://us-east-policy:7871/");
        usEast.addAgent("http://us-east-claims:7872/");
        regionalCatalogs.put("US_EAST", usEast);

        // US West Region
        AgentCatalog usWest = new AgentCatalog();
        usWest.addAgent("http://us-west-policy:7871/");
        usWest.addAgent("http://us-west-claims:7872/");
        regionalCatalogs.put("US_WEST", usWest);

        // Europe Region
        AgentCatalog europe = new AgentCatalog();
        europe.addAgent("http://eu-policy:7871/");
        europe.addAgent("http://eu-claims:7872/");
        regionalCatalogs.put("EUROPE", europe);
    }

    public String routeByRegion(String query, String customerRegion) {
        AgentCatalog catalog = regionalCatalogs.get(customerRegion);
        return catalog.processQuery(query).getTextResult();
    }
}
Enter fullscreen mode Exit fullscreen mode

Performance Optimization Techniques

1. Query Caching

public class CachedMeshExample {
    private AgentCatalog catalog;
    private Cache<String, String> queryCache = CacheBuilder.newBuilder()
        .maximumSize(1000)
        .expireAfterWrite(10, TimeUnit.MINUTES)
        .build();

    public String executeWithCache(String query) {
        try {
            return queryCache.get(query, () -> 
                catalog.processQuery(query).getTextResult()
            );
        } catch (ExecutionException e) {
            throw new RuntimeException("Query execution failed", e);
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

2. Connection Pooling

public class ConnectionPooledMesh {
    private AgentCatalog catalog;
    private ExecutorService executorService;

    public void setupConnectionPool() {
        // Configure HTTP client with connection pooling
        int maxConnections = 200;
        int maxConnectionsPerRoute = 50;

        executorService = Executors.newFixedThreadPool(
            Runtime.getRuntime().availableProcessors() * 2
        );

        // Configure agent catalog with pooled connections
        // Implementation depends on underlying HTTP client
    }
}
Enter fullscreen mode Exit fullscreen mode

3. Asynchronous Processing

public class AsyncMeshExample {
    private AgentCatalog catalog;

    public CompletableFuture<String> executeAsync(String query) {
        return CompletableFuture.supplyAsync(() ->
            catalog.processQuery(query).getTextResult()
        );
    }

    public void executeBatchAsync(List<String> queries) {
        List<CompletableFuture<String>> futures = queries.stream()
            .map(this::executeAsync)
            .collect(Collectors.toList());

        CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
            .thenAccept(v -> {
                futures.forEach(future -> {
                    try {
                        System.out.println("Result: " + future.get());
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                });
            });
    }
}
Enter fullscreen mode Exit fullscreen mode

Monitoring and Observability

Distributed Tracing Integration

public class TracedMeshExample {
    private AgentCatalog catalog;

    public String executeWithTracing(String query, String traceId) {
        Span span = tracer.buildSpan("mesh-query")
            .withTag("query", query)
            .withTag("trace.id", traceId)
            .start();

        try {
            long startTime = System.currentTimeMillis();
            String result = catalog.processQuery(query).getTextResult();
            long duration = System.currentTimeMillis() - startTime;

            span.setTag("duration.ms", duration);
            span.setTag("success", true);

            return result;
        } catch (Exception e) {
            span.setTag("error", true);
            span.setTag("error.message", e.getMessage());
            throw e;
        } finally {
            span.finish();
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Security and Compliance {#security}

Authentication and Authorization

public class SecureMeshExample {
    private AgentCatalog catalog;

    public String executeWithAuth(String query, String apiKey, 
                                  String userRole) {
        // Validate API key
        if (!isValidApiKey(apiKey)) {
            throw new SecurityException("Invalid API key");
        }

        // Check authorization
        if (!isAuthorized(userRole, extractOperation(query))) {
            throw new SecurityException("Unauthorized operation");
        }

        // Add security context to query
        Map<String, String> securityContext = new HashMap<>();
        securityContext.put("user_role", userRole);
        securityContext.put("api_key_hash", hashApiKey(apiKey));

        return catalog.processQuery(
            query + " [SECURITY_CONTEXT: " + securityContext + "]"
        ).getTextResult();
    }

    private boolean isValidApiKey(String apiKey) {
        // Validate against secure storage
        return true; // Simplified
    }

    private boolean isAuthorized(String role, String operation) {
        // Role-based access control
        Map<String, Set<String>> permissions = Map.of(
            "ADMIN", Set.of("CREATE", "READ", "UPDATE", "DELETE"),
            "AGENT", Set.of("READ", "UPDATE"),
            "CUSTOMER", Set.of("READ")
        );
        return permissions.getOrDefault(role, Set.of())
                         .contains(operation);
    }

    private String extractOperation(String query) {
        if (query.toLowerCase().contains("create")) return "CREATE";
        if (query.toLowerCase().contains("update")) return "UPDATE";
        if (query.toLowerCase().contains("delete")) return "DELETE";
        return "READ";
    }

    private String hashApiKey(String apiKey) {
        // Hash for logging purposes
        return String.valueOf(apiKey.hashCode());
    }
}
Enter fullscreen mode Exit fullscreen mode

Data Encryption

public class EncryptedMeshExample {
    private AgentCatalog catalog;
    private Cipher cipher;

    public String executeWithEncryption(String query, 
                                       SecretKey encryptionKey) {
        try {
            // Encrypt sensitive data in query
            String encryptedQuery = encryptQuery(query, encryptionKey);

            // Execute with encrypted data
            String encryptedResult = catalog.processQuery(encryptedQuery)
                                           .getTextResult();

            // Decrypt result
            return decryptResult(encryptedResult, encryptionKey);
        } catch (Exception e) {
            throw new RuntimeException("Encryption error", e);
        }
    }

    private String encryptQuery(String query, SecretKey key) 
        throws Exception {
        cipher.init(Cipher.ENCRYPT_MODE, key);
        byte[] encrypted = cipher.doFinal(query.getBytes());
        return Base64.getEncoder().encodeToString(encrypted);
    }

    private String decryptResult(String encrypted, SecretKey key) 
        throws Exception {
        cipher.init(Cipher.DECRYPT_MODE, key);
        byte[] decrypted = cipher.doFinal(
            Base64.getDecoder().decode(encrypted)
        );
        return new String(decrypted);
    }
}
Enter fullscreen mode Exit fullscreen mode

Audit Logging

public class AuditedMeshExample {
    private AgentCatalog catalog;
    private AuditLogger auditLogger;

    public String executeWithAudit(String query, String userId, 
                                   String sessionId) {
        AuditEvent event = new AuditEvent();
        event.setTimestamp(Instant.now());
        event.setUserId(userId);
        event.setSessionId(sessionId);
        event.setQuery(sanitizeForLog(query));
        event.setAction("MESH_QUERY");

        try {
            String result = catalog.processQuery(query).getTextResult();
            event.setStatus("SUCCESS");
            event.setResultSummary(summarizeResult(result));
            return result;
        } catch (Exception e) {
            event.setStatus("FAILURE");
            event.setErrorMessage(e.getMessage());
            throw e;
        } finally {
            auditLogger.log(event);
        }
    }

    private String sanitizeForLog(String query) {
        // Remove sensitive data before logging
        return query.replaceAll("ssn=\\d{9}", "ssn=XXX-XX-XXXX")
                   .replaceAll("account=\\d+", "account=XXXXX");
    }

    private String summarizeResult(String result) {
        return result.length() > 200 ? 
               result.substring(0, 200) + "..." : result;
    }
}
Enter fullscreen mode Exit fullscreen mode

Compliance Features

public class CompliantMeshExample {
    private AgentCatalog catalog;

    public String executeWithCompliance(String query, 
                                       ComplianceContext context) {
        // GDPR compliance - check data processing consent
        if (context.getRegulation().equals("GDPR")) {
            if (!hasDataProcessingConsent(context.getCustomerId())) {
                throw new ComplianceException(
                    "No data processing consent for customer"
                );
            }
        }

        // HIPAA compliance - check PHI access authorization
        if (context.getDataType().equals("PHI")) {
            if (!isAuthorizedForPHI(context.getUserId())) {
                throw new ComplianceException(
                    "Not authorized to access PHI"
                );
            }
        }

        // Execute with compliance tracking
        String result = catalog.processQuery(query).getTextResult();

        // Log for compliance audit trail
        logComplianceEvent(context, query, result);

        return result;
    }

    private boolean hasDataProcessingConsent(String customerId) {
        // Check consent database
        return true; // Simplified
    }

    private boolean isAuthorizedForPHI(String userId) {
        // Check authorization database
        return true; // Simplified
    }

    private void logComplianceEvent(ComplianceContext context, 
                                   String query, String result) {
        // Log to immutable audit trail
        ComplianceLog log = new ComplianceLog();
        log.setTimestamp(Instant.now());
        log.setRegulation(context.getRegulation());
        log.setUserId(context.getUserId());
        log.setCustomerId(context.getCustomerId());
        log.setAction(extractAction(query));
        log.setDataAccessed(extractDataTypes(result));
        // Persist log
    }

    private String extractAction(String query) {
        // Extract action type for compliance tracking
        return "DATA_ACCESS"; // Simplified
    }

    private List<String> extractDataTypes(String result) {
        // Classify data types accessed
        return List.of("PERSONAL_INFO", "FINANCIAL_INFO");
    }
}
Enter fullscreen mode Exit fullscreen mode

Best Practices and Design Patterns {#best-practices}

1. Agent Design Principles

Single Responsibility Principle

// GOOD: Agent focused on single domain
@Agent(groupName = "policyOperations")
public class PolicyAgent {
    @Action(description = "Create policy")
    public String createPolicy(...) { }

    @Action(description = "Update policy")
    public String updatePolicy(...) { }
}

// AVOID: Agent with mixed responsibilities
@Agent(groupName = "everythingOperations")
public class GodAgent {
    public String createPolicy(...) { }
    public String processClaim(...) { }
    public String assessRisk(...) { }
    public String handleCustomerService(...) { }
}
Enter fullscreen mode Exit fullscreen mode

Clear Action Definitions

// GOOD: Clear, descriptive actions
@Action(description = "Calculate life insurance premium based on age, " +
                     "health status, coverage amount, and risk factors")
public String calculateLifeInsurancePremium(
    int applicantAge,
    String healthStatus,
    double coverageAmount,
    String riskCategory
) { }

// AVOID: Vague action descriptions
@Action(description = "Do calculation")
public String calculate(Object... params) { }
Enter fullscreen mode Exit fullscreen mode

2. Error Handling Patterns

public class RobustMeshClient {
    private AgentCatalog catalog;

    public Result executeRobust(String query) {
        Result result = new Result();

        try {
            // Validate input
            validateQuery(query);

            // Execute with timeout
            String response = executeWithTimeout(query, 30, TimeUnit.SECONDS);

            result.setSuccess(true);
            result.setData(response);

        } catch (ValidationException e) {
            result.setSuccess(false);
            result.setErrorType("VALIDATION_ERROR");
            result.setErrorMessage(e.getMessage());

        } catch (TimeoutException e) {
            result.setSuccess(false);
            result.setErrorType("TIMEOUT");
            result.setErrorMessage("Query execution timed out");

        } catch (AgentUnavailableException e) {
            result.setSuccess(false);
            result.setErrorType("AGENT_UNAVAILABLE");
            result.setErrorMessage("Required agent is not available");
            // Implement retry logic or fallback

        } catch (Exception e) {
            result.setSuccess(false);
            result.setErrorType("UNKNOWN_ERROR");
            result.setErrorMessage(e.getMessage());
            // Log for investigation
        }

        return result;
    }

    private void validateQuery(String query) throws ValidationException {
        if (query == null || query.trim().isEmpty()) {
            throw new ValidationException("Query cannot be empty");
        }
        if (query.length() > 10000) {
            throw new ValidationException("Query too long");
        }
    }

    private String executeWithTimeout(String query, long timeout, 
                                     TimeUnit unit) 
        throws TimeoutException {
        ExecutorService executor = Executors.newSingleThreadExecutor();
        Future<String> future = executor.submit(() ->
            catalog.processQuery(query).getTextResult()
        );

        try {
            return future.get(timeout, unit);
        } catch (TimeoutException e) {
            future.cancel(true);
            throw e;
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            executor.shutdown();
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Top comments (0)