Skip to content
Learn Agentic AI
Learn Agentic AI14 min read0 views

Building a Supply Chain Visibility Agent: End-to-End Shipment Tracking and Alerts

Build an AI agent that provides end-to-end supply chain visibility across ocean, air, rail, and truck shipments with milestone tracking, delay prediction, and automated stakeholder notifications.

The Supply Chain Visibility Problem

A single product might travel by truck from a factory to a port, by ocean vessel across the Pacific, by rail from the port to a distribution center, and by truck again for final delivery. Each leg involves a different carrier, a different tracking system, and different milestone events. Supply chain managers today toggle between five or more carrier portals, spreadsheets, and email threads to piece together where their goods are.

An AI visibility agent aggregates tracking data across all transport modes into a single timeline, predicts delays before they happen, and proactively notifies stakeholders when milestones are met or disruptions occur.

Multi-Modal Shipment Data Model

from dataclasses import dataclass, field
from datetime import datetime
from enum import Enum
from typing import Optional

class TransportMode(str, Enum):
    OCEAN = "ocean"
    AIR = "air"
    RAIL = "rail"
    TRUCK = "truck"

class MilestoneStatus(str, Enum):
    COMPLETED = "completed"
    IN_PROGRESS = "in_progress"
    PENDING = "pending"
    DELAYED = "delayed"
    EXCEPTION = "exception"

@dataclass
class Milestone:
    name: str
    mode: TransportMode
    location: str
    planned_date: datetime
    actual_date: Optional[datetime] = None
    status: MilestoneStatus = MilestoneStatus.PENDING
    carrier: str = ""
    reference: str = ""

@dataclass
class SupplyChainShipment:
    shipment_id: str
    po_number: str
    origin_country: str
    destination: str
    product: str
    quantity: int
    milestones: list[Milestone] = field(default_factory=list)
    stakeholders: list[dict] = field(default_factory=list)

Sample Shipment Data

SHIPMENTS = {
    "SC-70001": SupplyChainShipment(
        shipment_id="SC-70001",
        po_number="PO-2026-1234",
        origin_country="China",
        destination="Chicago, IL",
        product="Electronic Components",
        quantity=5000,
        milestones=[
            Milestone("Factory Pickup", TransportMode.TRUCK, "Shenzhen",
                      datetime(2026, 3, 1, 8, 0), datetime(2026, 3, 1, 9, 30),
                      MilestoneStatus.COMPLETED, "Local Trucking Co", "TRK-001"),
            Milestone("Port Departure", TransportMode.OCEAN, "Yantian Port",
                      datetime(2026, 3, 3, 6, 0), datetime(2026, 3, 3, 14, 0),
                      MilestoneStatus.COMPLETED, "COSCO", "COSU-1234567"),
            Milestone("Port Arrival", TransportMode.OCEAN, "Long Beach, CA",
                      datetime(2026, 3, 17, 8, 0), None,
                      MilestoneStatus.IN_PROGRESS, "COSCO", "COSU-1234567"),
            Milestone("Customs Clearance", TransportMode.TRUCK, "Long Beach, CA",
                      datetime(2026, 3, 18, 12, 0), None,
                      MilestoneStatus.PENDING, "Customs Broker LLC", "CB-5678"),
            Milestone("Rail Departure", TransportMode.RAIL, "Long Beach, CA",
                      datetime(2026, 3, 19, 6, 0), None,
                      MilestoneStatus.PENDING, "BNSF", "BNSF-9876"),
            Milestone("Rail Arrival", TransportMode.RAIL, "Chicago, IL",
                      datetime(2026, 3, 22, 10, 0), None,
                      MilestoneStatus.PENDING, "BNSF", "BNSF-9876"),
            Milestone("Final Delivery", TransportMode.TRUCK, "Chicago, IL",
                      datetime(2026, 3, 23, 14, 0), None,
                      MilestoneStatus.PENDING, "XPO Logistics", "XPO-4321"),
        ],
        stakeholders=[
            {"name": "Procurement Team", "email": "[email protected]", "role": "buyer"},
            {"name": "Warehouse Ops", "email": "[email protected]", "role": "receiver"},
            {"name": "Sales Team", "email": "[email protected]", "role": "downstream"},
        ],
    ),
}

Shipment Tracking Tool

from agents import function_tool

@function_tool
def track_shipment(
    shipment_id: Optional[str] = None,
    po_number: Optional[str] = None,
) -> str:
    """Track a supply chain shipment by ID or PO number with full milestone timeline."""
    shipment = None
    if shipment_id:
        shipment = SHIPMENTS.get(shipment_id)
    elif po_number:
        shipment = next(
            (s for s in SHIPMENTS.values() if s.po_number == po_number), None
        )

    if not shipment:
        return "Shipment not found. Please check the ID or PO number."

    lines = [
        f"=== Shipment {shipment.shipment_id} ===",
        f"PO: {shipment.po_number}",
        f"Product: {shipment.product} (qty: {shipment.quantity})",
        f"Route: {shipment.origin_country} -> {shipment.destination}\n",
        "Milestone Timeline:",
    ]

    for m in shipment.milestones:
        status_icon = {
            MilestoneStatus.COMPLETED: "DONE",
            MilestoneStatus.IN_PROGRESS: "ACTIVE",
            MilestoneStatus.PENDING: "PENDING",
            MilestoneStatus.DELAYED: "DELAYED",
            MilestoneStatus.EXCEPTION: "EXCEPTION",
        }[m.status]

        planned = m.planned_date.strftime("%m/%d %H:%M")
        actual = m.actual_date.strftime("%m/%d %H:%M") if m.actual_date else "---"

        delay_note = ""
        if m.actual_date and m.actual_date > m.planned_date:
            hours_late = (m.actual_date - m.planned_date).total_seconds() / 3600
            delay_note = f" (+{hours_late:.0f}h late)"

        lines.append(
            f"  [{status_icon}] {m.name} ({m.mode.value}) @ {m.location}\n"
            f"         Planned: {planned} | Actual: {actual}{delay_note}\n"
            f"         Carrier: {m.carrier} | Ref: {m.reference}"
        )

    return "\n".join(lines)

Delay Prediction Tool

The delay predictor analyzes current milestone performance to estimate downstream impact:

See AI Voice Agents Handle Real Calls

Book a free demo or calculate how much you can save with AI voice automation.

flowchart TD
    START["Building a Supply Chain Visibility Agent: End-to-…"] --> A
    A["The Supply Chain Visibility Problem"]
    A --> B
    B["Multi-Modal Shipment Data Model"]
    B --> C
    C["Sample Shipment Data"]
    C --> D
    D["Shipment Tracking Tool"]
    D --> E
    E["Delay Prediction Tool"]
    E --> F
    F["Stakeholder Notification Tool"]
    F --> G
    G["Assembling the Visibility Agent"]
    G --> H
    H["FAQ"]
    H --> DONE["Key Takeaways"]
    style START fill:#4f46e5,stroke:#4338ca,color:#fff
    style DONE fill:#059669,stroke:#047857,color:#fff
@function_tool
def predict_delays(shipment_id: str) -> str:
    """Predict potential delays for a shipment based on current milestone performance."""
    shipment = SHIPMENTS.get(shipment_id)
    if not shipment:
        return "Shipment not found."

    # Calculate cumulative delay from completed milestones
    total_delay_hours = 0.0
    for m in shipment.milestones:
        if m.actual_date and m.actual_date > m.planned_date:
            total_delay_hours += (m.actual_date - m.planned_date).total_seconds() / 3600

    # Find current active milestone
    active = next(
        (m for m in shipment.milestones
         if m.status == MilestoneStatus.IN_PROGRESS), None
    )

    predictions = []

    if total_delay_hours > 0:
        predictions.append(
            f"Cumulative delay so far: {total_delay_hours:.0f} hours"
        )

        # Predict impact on pending milestones
        for m in shipment.milestones:
            if m.status == MilestoneStatus.PENDING:
                # Simple propagation: delay carries forward minus buffer
                buffer_hours = 4.0 if m.mode == TransportMode.RAIL else 2.0
                predicted_delay = max(0, total_delay_hours - buffer_hours)
                if predicted_delay > 0:
                    predictions.append(
                        f"  {m.name}: likely {predicted_delay:.0f}h late "
                        f"(original: {m.planned_date.strftime('%m/%d %H:%M')})"
                    )

        # Check if final delivery is at risk
        final = shipment.milestones[-1]
        if total_delay_hours > 8:
            predictions.append(
                f"\nWARNING: Final delivery to {shipment.destination} "
                f"is at risk of missing the planned window."
            )
    else:
        predictions.append("No delays detected. Shipment is on schedule.")

    return "\n".join(predictions)

Stakeholder Notification Tool

@function_tool
def notify_stakeholders(
    shipment_id: str,
    message: str,
    roles: Optional[list[str]] = None,
    priority: str = "normal",
) -> str:
    """Send notifications to shipment stakeholders by role."""
    shipment = SHIPMENTS.get(shipment_id)
    if not shipment:
        return "Shipment not found."

    recipients = shipment.stakeholders
    if roles:
        recipients = [s for s in recipients if s["role"] in roles]

    if not recipients:
        return "No matching stakeholders found."

    notifications = [f"Notifications sent for {shipment_id} [{priority.upper()}]:"]
    for r in recipients:
        notifications.append(
            f"  -> {r['name']} ({r['role']}): {r['email']}"
        )
    notifications.append(f"\nMessage: {message}")

    return "\n".join(notifications)

Assembling the Visibility Agent

from agents import Agent, Runner

visibility_agent = Agent(
    name="Supply Chain Visibility",
    instructions="""You are a supply chain visibility assistant. Help logistics teams:
    1. Track shipments end-to-end across ocean, air, rail, and truck
    2. Predict delays based on current milestone performance
    3. Notify stakeholders proactively about status changes and delays
    Always explain delays in business impact terms (e.g., warehouse receiving impact).""",
    tools=[track_shipment, predict_delays, notify_stakeholders],
)

result = Runner.run_sync(
    visibility_agent,
    "What's the status of PO-2026-1234? Are there any predicted delays? "
    "If so, notify the warehouse team."
)
print(result.final_output)

FAQ

How do I aggregate data from real carriers across different transport modes?

Use supply chain visibility platforms like project44, FourKites, or Chain.io which aggregate tracking data across ocean (via AIS and carrier EDI), rail (Class I railroad APIs), and truck (ELD/GPS). These platforms normalize events into standard milestone formats. Subscribe to webhook events for real-time updates rather than polling.

How accurate can delay predictions be?

Simple delay propagation like shown here works for basic cascading delays. For higher accuracy, build a machine learning model trained on historical shipment data for your specific lanes. Features include origin port congestion, vessel schedule reliability, customs clearance times by commodity code, and seasonal patterns. Even a gradient-boosted model on 12 months of data can significantly outperform carrier ETAs.

How should the agent handle force majeure events like port strikes or natural disasters?

Build a disruption monitoring tool that checks news feeds, port status APIs, and weather services. When a disruption is detected in a region that affects active shipments, the agent should proactively identify all impacted shipments, estimate the delay, and notify stakeholders with recommended actions like rerouting or expediting alternative transport modes.


#SupplyChain #ShipmentVisibility #MultiModalTracking #DelayPrediction #Python #AgenticAI #LearnAI #AIEngineering

Share
C

Written by

CallSphere Team

Expert insights on AI voice agents and customer communication automation.

Try CallSphere AI Voice Agents

See how AI voice agents work for your industry. Live demo available -- no signup required.

Related Articles You May Like

Use Cases

Warehouse Dock Scheduling: How AI Voice Agents Streamline Driver Check-In and Reduce Wait Times

See how AI voice agents automate warehouse dock scheduling, driver check-in, and queue management to cut driver wait times by 60%.

AI Interview Prep

7 AI Coding Interview Questions From Anthropic, Meta & OpenAI (2026 Edition)

Real AI coding interview questions from Anthropic, Meta, and OpenAI in 2026. Includes implementing attention from scratch, Anthropic's progressive coding screens, Meta's AI-assisted round, and vector search — with solution approaches.

Learn Agentic AI

Building a Multi-Agent Data Pipeline: Ingestion, Transformation, and Analysis Agents

Build a three-agent data pipeline with ingestion, transformation, and analysis agents that process data from APIs, CSVs, and databases using Python.

Learn Agentic AI

Building a Research Agent with Web Search and Report Generation: Complete Tutorial

Build a research agent that searches the web, extracts and synthesizes data, and generates formatted reports using OpenAI Agents SDK and web search tools.

Learn Agentic AI

OpenAI Agents SDK in 2026: Building Multi-Agent Systems with Handoffs and Guardrails

Complete tutorial on the OpenAI Agents SDK covering agent creation, tool definitions, handoff patterns between specialist agents, and input/output guardrails for safe AI systems.

Learn Agentic AI

Build a Customer Support Agent from Scratch: Python, OpenAI, and Twilio in 60 Minutes

Step-by-step tutorial to build a production-ready customer support AI agent using Python FastAPI, OpenAI Agents SDK, and Twilio Voice with five integrated tools.