⭐ AMCP Best Practices

Production-ready patterns and recommendations

πŸ€– Agent Design Principles

βœ… Single Responsibility

Each agent should have a single, well-defined responsibility.

βœ… Good

// Focused on weather data processing only
public class WeatherProcessorAgent extends Agent {
    public void processWeatherData(WeatherData data) {
        // Process weather data
    }
}

❌ Avoid

// Too many responsibilities
public class WeatherAgent extends Agent {
    public void processWeatherData() { }
    public void sendNotifications() { }
    public void manageUsers() { }
    public void generateReports() { }
}

βœ… Stateless Design

Design agents to be stateless when possible for better scalability.

@Agent("order-processor")
public class OrderProcessorAgent extends Agent {
    
    // Avoid instance variables for state
    // Use event payload or external storage instead
    
    @EventHandler
    public void processOrder(Event event) {
        OrderData order = event.getPayload(OrderData.class);
        
        // Process order without storing state
        ProcessedOrder result = processOrderData(order);
        
        // Publish result
        publish(Event.builder()
            .topic("order.processed")
            .payload(result)
            .build());
    }
}

πŸ“‘ Event Design Patterns

Topic Naming Convention

Use hierarchical, descriptive topic names

// Good topic naming
weather.data.raw.london
order.created.ecommerce
user.profile.updated

// Avoid generic names
data
event
message

Event Versioning

Include version information for backward compatibility

Event event = Event.builder()
    .topic("order.created.v2")
    .payload(orderData)
    .metadata("version", "2.0")
    .build();

Correlation IDs

Use correlation IDs to track related events

Event response = Event.builder()
    .topic("order.processed")
    .payload(result)
    .correlationId(originalEvent.getCorrelationId())
    .build();

⚑ Performance Optimization

πŸ”„ Batch Processing

Process events in batches when possible to improve throughput.

@EventHandler
@BatchSize(100)
@BatchTimeout(5000) // 5 seconds
public void processBatchedEvents(List<Event> events) {
    // Process events in batch
    List<ProcessedData> results = events.stream()
        .map(this::processEvent)
        .collect(Collectors.toList());
    
    // Publish batch results
    publishBatch(results);
}

🧡 Async Processing

Use asynchronous processing for non-blocking operations.

@EventHandler
public void handleEvent(Event event) {
    // Quick validation
    if (!isValidEvent(event)) {
        return;
    }
    
    // Async processing
    CompletableFuture.supplyAsync(() -> {
        return heavyProcessing(event);
    }).thenAccept(result -> {
        publishResult(result);
    });
}

πŸ’Ύ Caching Strategy

Implement intelligent caching for frequently accessed data.

@Agent("data-service")
public class DataServiceAgent extends Agent {
    
    private final Cache<String, Data> cache = CacheBuilder.newBuilder()
        .maximumSize(10000)
        .expireAfterWrite(10, TimeUnit.MINUTES)
        .build();
    
    @EventHandler
    public void handleDataRequest(Event event) {
        String key = event.getPayload(String.class);
        
        Data data = cache.get(key, () -> {
            return expensiveDataLookup(key);
        });
        
        publishData(data);
    }
}

πŸ”’ Security Best Practices

πŸ” Authentication

Always authenticate agents before allowing mesh participation.

@Agent("secure-agent")
@RequireAuthentication
public class SecureAgent extends Agent {
    
    @Override
    public void onActivation() {
        // Agent automatically authenticated before activation
        subscribe("secure.data.*");
    }
}

πŸ›‘οΈ Input Validation

Validate all incoming event data to prevent injection attacks.

@EventHandler
public void handleUserInput(Event event) {
    UserInput input = event.getPayload(UserInput.class);
    
    // Validate input
    if (!inputValidator.isValid(input)) {
        publishError("Invalid input received");
        return;
    }
    
    // Sanitize input
    UserInput sanitized = inputSanitizer.sanitize(input);
    
    processInput(sanitized);
}

πŸ”‘ Topic Permissions

Implement topic-level access control.

@Agent("financial-agent")
@TopicPermissions({
    @Permission(topic = "financial.data.*", access = READ_WRITE),
    @Permission(topic = "public.data.*", access = READ_ONLY)
})
public class FinancialAgent extends Agent {
    // Agent can only access permitted topics
}

πŸ“Š Monitoring & Observability

πŸ“ˆ Metrics Collection

Collect key performance metrics for monitoring.

@Agent("monitored-agent")
public class MonitoredAgent extends Agent {
    
    private final MeterRegistry meterRegistry;
    private final Counter eventCounter;
    private final Timer processingTimer;
    
    @EventHandler
    public void handleEvent(Event event) {
        Timer.Sample sample = Timer.start(meterRegistry);
        
        try {
            processEvent(event);
            eventCounter.increment("success");
        } catch (Exception e) {
            eventCounter.increment("error");
            throw e;
        } finally {
            sample.stop(processingTimer);
        }
    }
}

πŸ“ Structured Logging

Use structured logging for better observability.

@EventHandler
public void processOrder(Event event) {
    String orderId = event.getMetadata("orderId");
    
    log.info("Processing order", 
        kv("orderId", orderId),
        kv("agentId", getAgentId()),
        kv("timestamp", Instant.now()));
    
    try {
        // Process order
        log.info("Order processed successfully", 
            kv("orderId", orderId));
    } catch (Exception e) {
        log.error("Order processing failed", 
            kv("orderId", orderId),
            kv("error", e.getMessage()));
    }
}

🚨 Health Checks

Implement comprehensive health checks.

@Agent("health-monitored-agent")
public class HealthMonitoredAgent extends Agent implements HealthIndicator {
    
    @Override
    public Health health() {
        return Health.up()
            .withDetail("activeConnections", getActiveConnections())
            .withDetail("lastEventTime", getLastEventTime())
            .withDetail("errorRate", getErrorRate())
            .build();
    }
    
    @Scheduled(fixedRate = 30000) // Every 30 seconds
    public void publishHealthStatus() {
        Health health = health();
        
        publish(Event.builder()
            .topic("agent.health." + getAgentId())
            .payload(health)
            .build());
    }
}

πŸš€ Deployment Best Practices

🐳 Containerization

Use Docker for consistent deployments across environments.

# Dockerfile
FROM openjdk:17-jre-slim

COPY target/my-agent-1.0.jar /app/agent.jar

EXPOSE 8080

HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD curl -f http://localhost:8080/health || exit 1

ENTRYPOINT ["java", "-jar", "/app/agent.jar"]

☸️ Kubernetes Deployment

Use Kubernetes for orchestration and scaling.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: weather-agent
spec:
  replicas: 3
  selector:
    matchLabels:
      app: weather-agent
  template:
    metadata:
      labels:
        app: weather-agent
    spec:
      containers:
      - name: weather-agent
        image: amcp/weather-agent:1.5.0
        ports:
        - containerPort: 8080
        env:
        - name: AMCP_BROKER_URL
          value: "kafka:9092"
        resources:
          requests:
            memory: "512Mi"
            cpu: "250m"
          limits:
            memory: "1Gi"
            cpu: "500m"
        livenessProbe:
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 30
          periodSeconds: 10

πŸ”„ Blue-Green Deployment

Implement zero-downtime deployments.

# Blue-Green deployment strategy
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: weather-agent-rollout
spec:
  replicas: 5
  strategy:
    blueGreen:
      activeService: weather-agent-active
      previewService: weather-agent-preview
      autoPromotionEnabled: false
      scaleDownDelaySeconds: 30
      prePromotionAnalysis:
        templates:
        - templateName: success-rate
        args:
        - name: service-name
          value: weather-agent-preview
  selector:
    matchLabels:
      app: weather-agent
  template:
    metadata:
      labels:
        app: weather-agent
    spec:
      containers:
      - name: weather-agent
        image: amcp/weather-agent:1.5.0