← Back to DevBytes

AI Agent Maintenance Contracts: Recurring Revenue Streams

What Are AI Agent Maintenance Contracts?

AI agent maintenance contracts are ongoing service agreements between developers and clients that ensure deployed AI agents remain functional, secure, and performant over time. Unlike traditional software licensing models where a client purchases a perpetual license, maintenance contracts create a recurring revenue stream where clients pay regularly — monthly, quarterly, or annually — for continuous support, updates, monitoring, and optimization of their AI agent deployments.

An AI agent — whether it's a customer support bot, a code review assistant, a data pipeline orchestrator, or an autonomous trading agent — doesn't simply "run forever" after deployment. Models drift, APIs change, security vulnerabilities emerge, business logic evolves, and underlying data distributions shift. A maintenance contract formalizes the ongoing relationship required to keep these agents healthy.

Key components typically covered in such contracts include:

Why Recurring Revenue Matters for AI Agent Developers

Recurring revenue transforms a project-based freelance business or product studio into a sustainable, predictable operation. For developers building AI agents, the benefits are substantial:

How to Structure AI Agent Maintenance Contracts

Tiered Support Models

A well-designed tier structure allows you to serve different client segments while maximizing revenue from high-value accounts. Here's a proven three-tier framework:

# Example Tier Configuration (JSON structure for contract management system)

{
  "tiers": {
    "essential": {
      "monthly_price": 499,
      "included_hours": 5,
      "response_time_sla": "48h",
      "resolution_sla": "5 business days",
      "monitoring": "basic_health_checks",
      "retraining": "quarterly",
      "support_channels": ["email"],
      "max_agents_covered": 3,
      "additional_agent_cost": 149
    },
    "professional": {
      "monthly_price": 1499,
      "included_hours": 15,
      "response_time_sla": "8h",
      "resolution_sla": "48h",
      "monitoring": "full_telemetry_with_alerts",
      "retraining": "monthly",
      "support_channels": ["email", "slack", "phone_emergency"],
      "max_agents_covered": 10,
      "additional_agent_cost": 129,
      "includes": ["quarterly_business_review", "cost_optimization_report"]
    },
    "enterprise": {
      "monthly_price": 4999,
      "included_hours": 40,
      "response_time_sla": "1h",
      "resolution_sla": "4h",
      "monitoring": "full_telemetry_with_predictive_alerts",
      "retraining": "continuous_adaptive",
      "support_channels": ["email", "slack", "phone_emergency", "dedicated_dsm"],
      "max_agents_covered": 50,
      "additional_agent_cost": 99,
      "includes": ["monthly_strategy_session", "custom_sla_negotiation", 
                   "on_premise_support", "compliance_reporting"]
    }
  }
}

Pricing Strategies

Several pricing models work well for AI agent maintenance contracts. The right choice depends on your agent's value proposition and the client's usage pattern:

# Hybrid pricing calculator example

class MaintenancePricingCalculator:
    def __init__(self, base_fee: float, included_requests: int, 
                 overage_rate_per_1000: float, retraining_surcharge: float = 0):
        self.base_fee = base_fee
        self.included_requests = included_requests
        self.overage_rate = overage_rate_per_1000
        self.retraining_surcharge = retraining_surcharge

    def calculate_monthly(self, total_requests: int, 
                          retraining_triggered: bool = False) -> dict:
        overage = max(0, total_requests - self.included_requests)
        overage_cost = (overage / 1000) * self.overage_rate
        
        subtotal = self.base_fee + overage_cost
        retraining_fee = self.retraining_surcharge if retraining_triggered else 0
        
        return {
            "base_fee": self.base_fee,
            "overage_requests": overage,
            "overage_cost": round(overage_cost, 2),
            "retraining_fee": retraining_fee,
            "total": round(subtotal + retraining_fee, 2),
            "effective_rate_per_request": round(
                (subtotal + retraining_fee) / max(total_requests, 1), 4
            )
        }

# Usage example
calculator = MaintenancePricingCalculator(
    base_fee=999.00,
    included_requests=100000,
    overage_rate_per_1000=5.50,
    retraining_surcharge=250.00
)

invoice = calculator.calculate_monthly(
    total_requests=142000,
    retraining_triggered=True
)

print(invoice)
# Output: {
#   'base_fee': 999.0,
#   'overage_requests': 42000,
#   'overage_cost': 231.0,
#   'retraining_fee': 250.0,
#   'total': 1480.0,
#   'effective_rate_per_request': 0.0104
# }

Contract Lifecycle Management

A robust maintenance contract system must handle the entire lifecycle — from initial agreement through renewal, upsell, and (when necessary) graceful offboarding:

# Contract lifecycle state machine

from enum import Enum
from datetime import datetime, timedelta
from typing import Optional

class ContractState(Enum):
    DRAFT = "draft"
    PENDING_APPROVAL = "pending_approval"
    ACTIVE = "active"
    GRACE_PERIOD = "grace_period"
    SUSPENDED = "suspended"
    RENEWAL_NEGOTIATION = "renewal_negotiation"
    EXPIRED = "expired"
    TERMINATED = "terminated"

class MaintenanceContract:
    def __init__(self, contract_id: str, client_name: str, tier: str,
                 monthly_fee: float, start_date: datetime, duration_months: int):
        self.contract_id = contract_id
        self.client_name = client_name
        self.tier = tier
        self.monthly_fee = monthly_fee
        self.start_date = start_date
        self.end_date = start_date + timedelta(days=30 * duration_months)
        self.state = ContractState.DRAFT
        self.auto_renew = False
        self.renewal_reminders_sent = []
        self.payment_history = []
        self.modifications_log = []

    def activate(self) -> bool:
        if self.state in (ContractState.DRAFT, ContractState.PENDING_APPROVAL):
            self.state = ContractState.ACTIVE
            self.modifications_log.append({
                "timestamp": datetime.now().isoformat(),
                "action": "activate",
                "previous_state": "draft"
            })
            return True
        return False

    def enter_grace_period(self) -> None:
        self.state = ContractState.GRACE_PERIOD
        self.modifications_log.append({
            "timestamp": datetime.now().isoformat(),
            "action": "grace_period_entered",
            "reason": "payment_overdue"
        })

    def process_renewal(self, new_duration_months: int, 
                        adjusted_fee: Optional[float] = None) -> None:
        if self.state == ContractState.GRACE_PERIOD:
            self.state = ContractState.RENEWAL_NEGOTIATION
        
        new_fee = adjusted_fee or self.monthly_fee
        self.monthly_fee = new_fee
        self.start_date = self.end_date
        self.end_date = self.start_date + timedelta(days=30 * new_duration_months)
        self.state = ContractState.ACTIVE
        self.renewal_reminders_sent = []
        self.modifications_log.append({
            "timestamp": datetime.now().isoformat(),
            "action": "renewal",
            "new_fee": new_fee,
            "new_end_date": self.end_date.isoformat()
        })

    def check_renewal_window(self) -> dict:
        """Returns renewal status and recommended actions"""
        days_remaining = (self.end_date - datetime.now()).days
        
        if days_remaining < 0:
            return {"status": "expired", "action": "enter_grace_period"}
        elif days_remaining <= 30 and len(self.renewal_reminders_sent) == 0:
            return {"status": "renewal_window", "action": "send_first_reminder"}
        elif days_remaining <= 14 and len(self.renewal_reminders_sent) == 1:
            return {"status": "urgent_renewal", "action": "send_second_reminder"}
        elif days_remaining <= 7 and len(self.renewal_reminders_sent) <= 2:
            return {"status": "critical_renewal", "action": "schedule_client_call"}
        else:
            return {"status": "active_stable", "action": "no_action_needed"}

Implementation: Building a Maintenance Contract System

Contract Data Model and Database Schema

A production-ready maintenance contract system requires careful schema design. Here's a PostgreSQL schema that supports multi-tenant, multi-tier contract management with full audit trails:

-- Core schema for AI Agent Maintenance Contract System

CREATE TABLE clients (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    company_name VARCHAR(255) NOT NULL,
    contact_email VARCHAR(255) NOT NULL,
    billing_email VARCHAR(255),
    stripe_customer_id VARCHAR(100) UNIQUE,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

CREATE TABLE ai_agents (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    client_id UUID NOT NULL REFERENCES clients(id) ON DELETE CASCADE,
    agent_name VARCHAR(255) NOT NULL,
    agent_type VARCHAR(100) NOT NULL, -- e.g., 'chatbot', 'code_review', 'data_pipeline'
    deployment_environment VARCHAR(100),
    model_provider VARCHAR(100),
    model_version VARCHAR(50),
    average_daily_requests INTEGER DEFAULT 0,
    last_health_check TIMESTAMP WITH TIME ZONE,
    status VARCHAR(50) DEFAULT 'active',
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    UNIQUE(client_id, agent_name)
);

CREATE TABLE maintenance_tiers (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tier_name VARCHAR(100) NOT NULL UNIQUE,
    monthly_base_fee DECIMAL(10,2) NOT NULL,
    included_support_hours INTEGER NOT NULL,
    included_retraining_events INTEGER DEFAULT 0,
    sla_response_hours INTEGER NOT NULL,
    sla_resolution_hours INTEGER NOT NULL,
    max_agents_included INTEGER NOT NULL,
    additional_agent_fee DECIMAL(10,2) NOT NULL,
    overage_hourly_rate DECIMAL(10,2) NOT NULL,
    features JSONB DEFAULT '{}',
    is_active BOOLEAN DEFAULT true
);

CREATE TABLE contracts (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    contract_number VARCHAR(50) NOT NULL UNIQUE,
    client_id UUID NOT NULL REFERENCES clients(id),
    tier_id UUID NOT NULL REFERENCES maintenance_tiers(id),
    status VARCHAR(50) NOT NULL DEFAULT 'draft',
    -- 'draft', 'active', 'grace_period', 'suspended', 'renewed', 'expired', 'terminated'
    start_date DATE NOT NULL,
    end_date DATE NOT NULL,
    auto_renew BOOLEAN DEFAULT false,
    renewal_reminder_count INTEGER DEFAULT 0,
    last_renewal_action TIMESTAMP WITH TIME ZONE,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

CREATE TABLE contract_agents (
    contract_id UUID NOT NULL REFERENCES contracts(id) ON DELETE CASCADE,
    agent_id UUID NOT NULL REFERENCES ai_agents(id) ON DELETE CASCADE,
    added_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    PRIMARY KEY (contract_id, agent_id)
);

CREATE TABLE invoices (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    contract_id UUID NOT NULL REFERENCES contracts(id),
    invoice_number VARCHAR(50) NOT NULL UNIQUE,
    period_start DATE NOT NULL,
    period_end DATE NOT NULL,
    base_amount DECIMAL(10,2) NOT NULL,
    overage_hours DECIMAL(10,2) DEFAULT 0,
    overage_amount DECIMAL(10,2) DEFAULT 0,
    additional_agents_fee DECIMAL(10,2) DEFAULT 0,
    retraining_events_fee DECIMAL(10,2) DEFAULT 0,
    total_amount DECIMAL(10,2) NOT NULL,
    status VARCHAR(50) DEFAULT 'pending',
    -- 'pending', 'sent', 'paid', 'overdue', 'void'
    stripe_invoice_id VARCHAR(100),
    due_date DATE NOT NULL,
    paid_at TIMESTAMP WITH TIME ZONE,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

CREATE TABLE sla_incidents (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    contract_id UUID NOT NULL REFERENCES contracts(id),
    agent_id UUID REFERENCES ai_agents(id),
    incident_type VARCHAR(100) NOT NULL,
    severity VARCHAR(20) NOT NULL, -- 'critical', 'high', 'medium', 'low'
    detected_at TIMESTAMP WITH TIME ZONE NOT NULL,
    acknowledged_at TIMESTAMP WITH TIME ZONE,
    resolved_at TIMESTAMP WITH TIME ZONE,
    sla_target_hours INTEGER,
    actual_resolution_hours DECIMAL(8,2),
    sla_breached BOOLEAN DEFAULT false,
    postmortem_document_url VARCHAR(500),
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- Index for performance
CREATE INDEX idx_contracts_status ON contracts(status);
CREATE INDEX idx_invoices_status_due ON invoices(status, due_date);
CREATE INDEX idx_sla_incidents_contract ON sla_incidents(contract_id, detected_at);
CREATE INDEX idx_ai_agents_client_status ON ai_agents(client_id, status);

Automated Billing Engine

The billing engine is the financial heart of your maintenance contract system. It must handle recurring invoice generation, proration, usage calculation, and integration with payment processors:

# Automated billing engine with Stripe integration

import stripe
from datetime import datetime, date, timedelta
from decimal import Decimal
from typing import List, Optional

stripe.api_key = "sk_live_..."

class MaintenanceBillingEngine:
    def __init__(self, db_connection):
        self.db = db_connection
        self.today = date.today()

    def generate_monthly_invoices(self) -> dict:
        """Batch generate invoices for all active contracts"""
        active_contracts = self.db.query(
            """SELECT c.id, c.contract_number, c.client_id, c.tier_id,
                      c.start_date, c.end_date, cl.stripe_customer_id,
                      cl.company_name, t.monthly_base_fee, t.additional_agent_fee,
                      t.overage_hourly_rate, t.included_support_hours
               FROM contracts c
               JOIN clients cl ON c.client_id = cl.id
               JOIN maintenance_tiers t ON c.tier_id = t.id
               WHERE c.status = 'active'
                 AND c.end_date >= CURRENT_DATE"""
        )
        
        generated = []
        for contract in active_contracts:
            invoice_data = self._calculate_invoice_for_contract(contract)
            
            if invoice_data['total_amount'] > 0:
                # Create Stripe invoice
                stripe_invoice = stripe.Invoice.create(
                    customer=contract['stripe_customer_id'],
                    auto_advance=True,
                    collection_method='charge_automatically',
                    days_until_due=30,
                    metadata={
                        'contract_id': contract['id'],
                        'contract_number': contract['contract_number']
                    }
                )
                
                # Add line items
                stripe.InvoiceItem.create(
                    customer=contract['stripe_customer_id'],
                    invoice=stripe_invoice.id,
                    amount=int(invoice_data['base_amount'] * 100),  # cents
                    currency='usd',
                    description=f"AI Agent Maintenance - {contract['tier_name']} Tier"
                )
                
                if invoice_data['overage_amount'] > 0:
                    stripe.InvoiceItem.create(
                        customer=contract['stripe_customer_id'],
                        invoice=stripe_invoice.id,
                        amount=int(invoice_data['overage_amount'] * 100),
                        currency='usd',
                        description=f"Support overage - {invoice_data['overage_hours']} hours"
                    )
                
                stripe.Invoice.finalize_invoice(stripe_invoice.id)
                
                # Store in our database
                self.db.execute(
                    """INSERT INTO invoices (contract_id, invoice_number, 
                       period_start, period_end, base_amount, overage_hours,
                       overage_amount, additional_agents_fee, total_amount,
                       stripe_invoice_id, due_date)
                    VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""",
                    (contract['id'], f"INV-{datetime.now().strftime('%Y%m')}-{contract['contract_number']}",
                     invoice_data['period_start'], invoice_data['period_end'],
                     invoice_data['base_amount'], invoice_data['overage_hours'],
                     invoice_data['overage_amount'], invoice_data['additional_agents_fee'],
                     invoice_data['total_amount'], stripe_invoice.id,
                     self.today + timedelta(days=30))
                )
                
                generated.append({
                    'contract_id': contract['id'],
                    'invoice_total': invoice_data['total_amount'],
                    'stripe_invoice_id': stripe_invoice.id
                })
        
        return {
            'total_invoices_generated': len(generated),
            'total_revenue': sum(g['invoice_total'] for g in generated),
            'invoices': generated
        }

    def _calculate_invoice_for_contract(self, contract: dict) -> dict:
        """Calculate detailed invoice amounts for a single contract"""
        period_start = date(self.today.year, self.today.month, 1)
        period_end = date(
            self.today.year, 
            self.today.month + 1 if self.today.month < 12 else 1,
            1
        ) - timedelta(days=1)
        
        # Base fee
        base_amount = contract['monthly_base_fee']
        
        # Count agents on contract
        agent_count = self.db.query_one(
            """SELECT COUNT(*) as count FROM contract_agents 
               WHERE contract_id = %s""",
            (contract['id'],)
        )['count']
        
        max_included = contract.get('max_agents_included', 3)
        extra_agents = max(0, agent_count - max_included)
        additional_agents_fee = extra_agents * contract['additional_agent_fee']
        
        # Calculate support overage
        support_hours_used = self.db.query_one(
            """SELECT COALESCE(SUM(hours_logged), 0) as total
               FROM support_tickets
               WHERE contract_id = %s
                 AND created_at BETWEEN %s AND %s""",
            (contract['id'], period_start, period_end)
        )['total']
        
        overage_hours = max(
            0, 
            support_hours_used - contract['included_support_hours']
        )
        overage_amount = overage_hours * contract['overage_hourly_rate']
        
        total = base_amount + additional_agents_fee + overage_amount
        
        return {
            'period_start': period_start,
            'period_end': period_end,
            'base_amount': base_amount,
            'agent_count': agent_count,
            'extra_agents': extra_agents,
            'additional_agents_fee': additional_agents_fee,
            'support_hours_used': support_hours_used,
            'overage_hours': overage_hours,
            'overage_amount': overage_amount,
            'total_amount': total
        }

    def handle_payment_failure(self, invoice_id: str) -> None:
        """Handle failed payments - dunning process and contract status update"""
        invoice = self.db.query_one(
            """SELECT i.*, c.status as contract_status, c.id as contract_id
               FROM invoices i
               JOIN contracts c ON i.contract_id = c.id
               WHERE i.stripe_invoice_id = %s""",
            (invoice_id,)
        )
        
        if not invoice:
            return
        
        days_overdue = (self.today - invoice['due_date']).days
        
        if days_overdue >= 30 and invoice['contract_status'] == 'active':
            # Move contract to grace period after 30 days overdue
            self.db.execute(
                """UPDATE contracts SET status = 'grace_period', 
                   updated_at = NOW() WHERE id = %s""",
                (invoice['contract_id'],)
            )
            
            # Send suspension notice
            self._send_email_template(
                invoice['client_email'],
                'service_suspension_warning',
                {'days_overdue': days_overdue}
            )
        
        elif days_overdue >= 60:
            # Suspend services after 60 days
            self.db.execute(
                """UPDATE contracts SET status = 'suspended',
                   updated_at = NOW() WHERE id = %s""",
                (invoice['contract_id'],)
            )
            
            # Disable agent API access
            self._disable_agent_access(invoice['contract_id'])

    def _disable_agent_access(self, contract_id: str) -> None:
        """Revoke API keys and disable agent endpoints for a contract"""
        self.db.execute(
            """UPDATE ai_agents SET status = 'suspended'
               WHERE id IN (
                   SELECT agent_id FROM contract_agents 
                   WHERE contract_id = %s
               )""",
            (contract_id,)
        )

SLA Monitoring and Incident Management

Service Level Agreement (SLA) compliance is a cornerstone of maintenance contracts. An automated monitoring system tracks agent health, detects incidents, and measures resolution times against contractual obligations:

# SLA monitoring service with alerting

import asyncio
import aiohttp
from datetime import datetime, timedelta
from dataclasses import dataclass
from typing import List, Dict

@dataclass
class SLADefinition:
    severity: str
    response_time_minutes: int
    resolution_time_minutes: int
    availability_target_percent: float

class SLAMonitoringService:
    def __init__(self, db_pool, notification_client):
        self.db = db_pool
        self.notifier = notification_client
        
        self.sla_definitions = {
            'critical': SLADefinition('critical', 60, 240, 99.95),
            'high': SLADefinition('high', 240, 1440, 99.9),
            'medium': SLADefinition('medium', 480, 2880, 99.5),
            'low': SLADefinition('low', 1440, 5760, 99.0)
        }

    async def check_agent_health(self, agent_id: str) -> dict:
        """Perform comprehensive health check on an AI agent"""
        agent = await self.db.fetch_one(
            """SELECT a.*, c.id as contract_id, t.sla_response_hours,
                       t.sla_resolution_hours
               FROM ai_agents a
               JOIN contract_agents ca ON a.id = ca.agent_id
               JOIN contracts c ON ca.contract_id = c.id
               JOIN maintenance_tiers t ON c.tier_id = t.id
               WHERE a.id = %s AND a.status = 'active'
                 AND c.status = 'active'""",
            (agent_id,)
        )
        
        if not agent:
            return {'status': 'no_active_contract'}
        
        checks = {}
        
        # Check HTTP health endpoint
        try:
            async with aiohttp.ClientSession() as session:
                async with session.get(
                    f"{agent['deployment_url']}/health",
                    timeout=aiohttp.ClientTimeout(total=10)
                ) as resp:
                    checks['http_status'] = resp.status
                    checks['http_ok'] = resp.status == 200
        except Exception as e:
            checks['http_status'] = 'unreachable'
            checks['http_ok'] = False
            checks['error'] = str(e)
        
        # Check latency
        try:
            async with aiohttp.ClientSession() as session:
                start = datetime.now()
                async with session.get(
                    f"{agent['deployment_url']}/ping",
                    timeout=aiohttp.ClientTimeout(total=5)
                ) as resp:
                    latency_ms = (datetime.now() - start).total_seconds() * 1000
                    checks['latency_ms'] = round(latency_ms, 2)
                    checks['latency_ok'] = latency_ms < 2000
        except Exception:
            checks['latency_ms'] = None
            checks['latency_ok'] = False
        
        # Check error rate in last hour
        recent_errors = await self.db.fetch_val(
            """SELECT COUNT(*) FROM agent_logs
               WHERE agent_id = %s
                 AND level = 'ERROR'
                 AND timestamp > NOW() - INTERVAL '1 hour'""",
            (agent_id,)
        )
        
        total_requests = await self.db.fetch_val(
            """SELECT COUNT(*) FROM agent_logs
               WHERE agent_id = %s
                 AND timestamp > NOW() - INTERVAL '1 hour'""",
            (agent_id,)
        )
        
        error_rate = (recent_errors / max(total_requests, 1)) * 100
        checks['error_rate_percent'] = round(error_rate, 2)
        checks['error_rate_ok'] = error_rate < 5.0
        
        # Determine overall health
        is_healthy = all([
            checks.get('http_ok', False),
            checks.get('latency_ok', False),
            checks.get('error_rate_ok', False)
        ])
        
        if not is_healthy:
            await self._create_incident(agent, checks)
        
        return {
            'agent_id': agent_id,
            'healthy': is_healthy,
            'checks': checks,
            'timestamp': datetime.now().isoformat()
        }

    async def _create_incident(self, agent: dict, checks: dict) -> str:
        """Create SLA incident and notify relevant parties"""
        severity = self._determine_severity(checks)
        
        incident_id = await self.db.execute(
            """INSERT INTO sla_incidents 
               (contract_id, agent_id, incident_type, severity, detected_at,
                sla_target_hours)
               VALUES (%s, %s, %s, %s, %s, %s)
               RETURNING id""",
            (agent['contract_id'], agent['id'], 'health_check_failure',
             severity, datetime.now(),
             self.sla_definitions[severity].resolution_time_minutes / 60)
        )
        
        # Notify support team
        await self.notifier.send_pagerduty_alert({
            'incident_id': incident_id,
            'agent': agent['agent_name'],
            'client': agent['company_name'],
            'severity': severity,
            'checks': checks
        })
        
        # Log for contract reporting
        await self.db.execute(
            """INSERT INTO incident_notifications 
               (incident_id, channel, sent_at)
               VALUES (%s, 'pagerduty', %s)""",
            (incident_id, datetime.now())
        )
        
        return incident_id

    def _determine_severity(self, checks: dict) -> str:
        """Map health check results to SLA severity levels"""
        if checks.get('http_ok') is False:
            return 'critical'
        if checks.get('error_rate_percent', 0) > 20:
            return 'critical'
        if checks.get('error_rate_percent', 0) > 10:
            return 'high'
        if not checks.get('latency_ok', True):
            return 'medium'
        return 'low'

    async def generate_sla_report(self, contract_id: str, 
                                  month: int, year: int) -> dict:
        """Generate monthly SLA compliance report for client"""
        period_start = date(year, month, 1)
        period_end = date(
            year, month + 1 if month < 12 else 1, 1
        ) - timedelta(days=1)
        
        incidents = await self.db.fetch_all(
            """SELECT severity, detected_at, resolved_at, 
                       sla_target_hours, actual_resolution_hours,
                       sla_breached
               FROM sla_incidents
               WHERE contract_id = %s
                 AND detected_at BETWEEN %s AND %s""",
            (contract_id, period_start, period_end)
        )
        
        total_incidents = len(incidents)
        breached = sum(1 for i in incidents if i['sla_breached'])
        
        # Calculate uptime percentage
        total_minutes_in_period = (
            (period_end - period_start).days + 1
        ) * 24 * 60
        
        incident_minutes = sum(
            (i['actual_resolution_hours'] or i['sla_target_hours']) * 60
            for i in incidents
        )
        
        uptime = ((total_minutes_in_period - incident_minutes) / 
                  total_minutes_in_period) * 100
        
        report = {
            'contract_id': contract_id,
            'period': f"{year}-{month:02d}",
            'total_incidents': total_incidents,
            'sla_breaches': breached,
            'compliance_rate': round(
                ((total_incidents - breached) / max(total_incidents, 1)) * 100, 2
            ),
            'uptime_percentage': round(uptime, 4),
            'incidents_by_severity': {},
            'recommendations': []
        }
        
        # Severity breakdown
        for severity in ['critical', 'high', 'medium', 'low']:
            count = sum(1 for i in incidents if i['severity'] == severity)
            if count > 0:
                report['incidents_by_severity'][severity] = count
        
        # Generate recommendations
        if breached > 0:
            report['recommendations'].append(
                "Review incident response procedures for faster resolution times"
            )
        
        if uptime < 99.5:
            report['recommendations'].append(
                "Consider upgrading to Enterprise tier for predictive monitoring"
            )
        
        return report

Best Practices for AI Agent Maintenance Contracts

Define Clear Scope Boundaries

Nothing erodes maintenance contract profitability faster than scope creep. Clearly delineate what's included and what constitutes billable change work:

# Example scope definition embedded in contract metadata

scope_definition = {
    "maintenance_included": [
        "weekly_health_checks",
        "monthly_model_retraining_with_existing_architecture",
        "security_patches_critical_and_high",
        "api_version_compatibility_updates",
        "cost_optimization_within_20_percent_baseline",
        "incident_response_per_sla_table"
    ],
    "change_requests_billable": [
        "new_agent_capabilities_or_tools",
        "additional_data_source_integrations",
        "model_provider_m

— Ad —

Google AdSense will appear here after approval

← Back to all articles