AI Logistics Agent: Digital Employee for Supply Chain Automation
Logistics companies spend up to 70% of operator time on shipment monitoring and exception handling. With 100 shipments per day, an operator manually checks statuses 5–10 times, taking up to 4 hours. Each delay reduces customer loyalty and increases penalties. We developed an AI agent that automates supply chain operational tasks: route planning, shipment tracking, carrier communication, exception handling (delays, damage, shortages), KPI monitoring, and report generation. A human operator steps in only for non-standard situations requiring negotiation. The result — manual labor reduced by 55% and on-time delivery increased to 89%. Average annual cost savings: 2,500,000 rubles for 500 shipments/day.
How the AI Agent Reduces the Load on Logisticians?
The agent works in three stages: data collection, analysis via LLM, and automatic action execution. For tracking, it connects to carrier APIs (DPD, CDEK, PEC, etc.) every 2 hours and compares actual status with expected. When a delay is detected, the system calculates downtime and decides: notify the recipient, rebook delivery, or escalate to a manager. On average, the agent processes an exception 3 times faster than a human.
from langgraph.graph import StateGraph, END
from langchain_openai import ChatOpenAI
from typing import TypedDict, Annotated, Optional
import operator
llm = ChatOpenAI(model="gpt-4o", temperature=0)
class ShipmentState(TypedDict):
shipment_id: str
shipment_data: dict
tracking_history: list[dict]
anomalies: Annotated[list, operator.add]
actions_taken: Annotated[list, operator.add]
escalation_required: bool
escalation_reason: Optional[str]
class ShipmentMonitor:
async def check_shipment(self, shipment_id: str) -> ShipmentState:
"""Full shipment status check"""
# Get data
shipment = await logistics_db.get_shipment(shipment_id)
tracking = await carrier_api.get_tracking(shipment["tracking_number"])
expected_eta = shipment["expected_delivery"]
current_eta = tracking.get("estimated_delivery")
anomalies = []
# Check delay
if current_eta and current_eta > expected_eta:
delay_hours = (current_eta - expected_eta).total_seconds() / 3600
anomalies.append({
"type": "delivery_delay",
"severity": "high" if delay_hours > 24 else "medium",
"details": f"Delay {delay_hours:.0f} hours, new date: {current_eta}",
})
# No updates
last_update = tracking.get("last_event_time")
hours_since_update = (datetime.now() - last_update).total_seconds() / 3600 if last_update else 99
if hours_since_update > 48:
anomalies.append({
"type": "no_tracking_update",
"severity": "medium",
"details": f"No updates {hours_since_update:.0f} hours",
})
# LLM analysis for anomalies
escalation_required = False
escalation_reason = None
if anomalies:
assessment = await self.assess_anomalies(shipment, anomalies)
escalation_required = assessment["requires_escalation"]
escalation_reason = assessment.get("reason")
return ShipmentState(
shipment_id=shipment_id,
shipment_data=shipment,
tracking_history=tracking.get("events", []),
anomalies=anomalies,
actions_taken=[],
escalation_required=escalation_required,
escalation_reason=escalation_reason,
)
async def assess_anomalies(self, shipment: dict, anomalies: list) -> dict:
"""LLM assesses whether escalation is needed"""
response = await llm.ainvoke(f"""Assess the shipment situation.
Shipment: {json.dumps(shipment, ensure_ascii=False)}
Anomalies: {json.dumps(anomalies, ensure_ascii=False)}
Determine:
1. Does the situation require immediate escalation to manager?
2. What automatic actions can be taken?
3. Should the recipient be notified?
Return JSON: {{"requires_escalation": bool, "reason": "...", "auto_actions": [...], "notify_recipient": bool}}""")
return json.loads(response.content)
Routing uses a hybrid approach: for small problems (up to 20 points) — LLM with chain-of-thought, for large ones — an algorithmic solver with AI post-processing. This yields optimal routes accounting for time windows, load capacity, and traffic. Learn more about Vehicle Routing Problem.
class RouteOptimizer:
async def optimize_delivery_routes(
self,
deliveries: list[dict], # [{id, address, time_window, weight}]
vehicles: list[dict], # [{id, capacity, location}]
date: str,
) -> dict:
"""Optimize delivery routes (Vehicle Routing Problem)"""
# For small tasks — via LLM with reasoning
if len(deliveries) <= 20:
return await self.llm_route_optimizer(deliveries, vehicles)
# For large — algorithmic approach + LLM for exceptions
return await self.algorithmic_route_optimizer(deliveries, vehicles)
async def llm_route_optimizer(self, deliveries: list, vehicles: list) -> dict:
response = await llm.ainvoke(f"""Compose optimal delivery routes.
Deliveries:
{json.dumps(deliveries, ensure_ascii=False, indent=2)}
Vehicles:
{json.dumps(vehicles, ensure_ascii=False, indent=2)}
Consider: time windows, load capacity, minimize total distance.
Return JSON: {{"routes": [{{"vehicle_id": "...", "stops": [delivery_ids_in_order]}}]}}""")
return json.loads(response.content)
Exception handling is built on playbooks — predefined scenarios for typical situations: delay, damage, customs hold, incorrect address. The agent performs automatic actions (notifications, claim creation, rebooking) and escalates only when automation is insufficient.
class ExceptionHandler:
EXCEPTION_PLAYBOOKS = {
"delivery_delay": {
"auto_actions": ["notify_recipient", "update_crm", "rebook_if_urgent"],
"escalate_if": lambda hours: hours > 72,
},
"damaged_goods": {
"auto_actions": ["create_claim", "notify_sender", "photo_request"],
"escalate_always": True,
},
"customs_hold": {
"auto_actions": ["get_customs_details", "notify_broker"],
"escalate_if": lambda days: days > 3,
},
"address_not_found": {
"auto_actions": ["contact_recipient", "check_database"],
"escalate_if": lambda attempts: attempts > 2,
},
}
async def handle_exception(self, exception: dict) -> dict:
exception_type = exception["type"]
playbook = self.EXCEPTION_PLAYBOOKS.get(exception_type)
if not playbook:
return await self.generic_exception_handler(exception)
actions_taken = []
# Execute automatic actions
for action in playbook.get("auto_actions", []):
result = await self.execute_action(action, exception)
actions_taken.append({"action": action, "result": result})
# Check if escalation needed
escalate = playbook.get("escalate_always", False)
if not escalate and "escalate_if" in playbook:
escalate_fn = playbook["escalate_if"]
escalate = escalate_fn(exception.get("delay_hours") or exception.get("hold_days") or exception.get("attempts", 0))
if escalate:
await self.escalate_to_manager(exception, actions_taken)
return {"actions_taken": actions_taken, "escalated": escalate}
The analytics module daily collects key metrics and generates a KPI report in natural language. The report includes deviations from norms and recommendations for improvement.
class LogisticsAnalytics:
async def daily_kpi_report(self) -> str:
"""Daily KPI report for logistics"""
# Data from DB
metrics = await asyncio.gather(
self.get_on_time_delivery_rate(),
self.get_damage_rate(),
self.get_carrier_performance(),
self.get_cost_per_shipment(),
self.get_exception_rate(),
)
report = await llm.ainvoke(f"""Create a KPI report for logistics for {datetime.now().strftime('%d.%m.%Y')}.
Metrics:
- On-time delivery: {metrics[0]['rate']:.1%} (target: {metrics[0]['target']:.1%})
- Damage rate: {metrics[1]['rate']:.3%}
- Top carriers by performance: {metrics[2]}
- Cost per shipment: {metrics[3]['avg']:,.0f} rub
- Exception rate: {metrics[4]['rate']:.2%}
Format: brief summary (3 sentences), deviations from norms, recommendations.""")
return report.content
What Does Hybrid Routing Offer?
The hybrid approach allows processing up to 500 delivery points per minute, combining algorithmic speed with LLM flexibility. For standard routes with time windows, an algorithmic optimizer is used; for non-standard requests (urgent delivery, priority changes), the LLM with reasoning is engaged. This reduces average routing time by 40% compared to a purely algorithmic approach.
Implementation Results: 55% Reduction in Manual Labor
| Metric | Without AI | With AI | Improvement |
|---|---|---|---|
| Manual exception handling | 180 cases/day | 45 cases/day | -75% |
| On-time delivery rate | 82% | 89% | +7 p.p. |
| Correct claim processing | 62% | 91% | +29 p.p. |
| Time on operational work | 100% | 45% | -55% |
| Average annual cost savings | — | 2,500,000 rubles | — |
Exception handling time comparison:
| Exception type | Human (min) | AI agent (sec) | Speedup |
|---|---|---|---|
| Delivery delay | 12 | 45 | 16x |
| Goods damage | 25 | 120 | 12.5x |
| Customs hold | 30 | 90 | 20x |
| Incorrect address | 8 | 30 | 16x |
These numbers come from our practical case with an FMCG distributor handling 500 shipments per day. Our specialists have extensive experience integrating AI solutions into logistics, use proven stacks (LangGraph, OpenAI GPT-4o, ChromaDB), and provide a guarantee for each stage. Implementation can reduce operational costs by several million rubles annually for a company with a volume of 200+ shipments per day. Savings on operational expenses — from 2,000,000 to 3,000,000 rubles per year at a volume of 500 shipments.
Implementation Stages
- Audit of current processes and integrations — 1 week.
- Connection to carrier and warehouse APIs — 1–2 weeks.
- Development of tracking module and exception playbooks — 2–3 weeks.
- Configuration of routing and KPI analytics — 2–3 weeks.
- Testing on historical data and pilot launch — 1–2 weeks.
- Full launch and operator training — 1 week.
Total timeline: 8–12 weeks depending on the number of carriers and exception complexity.
Deliverables
- A working AI agent in your infrastructure (on-prem or cloud).
- Integration with 3–5 carriers (expandable upon request).
- Playbook for 5+ exception types (customizable).
- Daily KPI report in natural language.
- Documentation and operator team training.
- Access to agent dashboard and support for 30 days after launch.
Agent architecture: LangGraph for workflow orchestration, GPT-4o for natural language understanding, ChromaDB for vector retrieval. This stack ensures scalability and rapid response times.
We guarantee a minimum 50% reduction in manual exception handling. Payback period — from 6 months at a volume of 200+ shipments per day.
Our Expertise
Our team has 10+ years of experience in logistics and 5+ years in AI implementation, with over 50 successful projects across industries. We combine deep domain knowledge with cutting-edge AI to deliver measurable results.
To assess the applicability of the AI agent in your processes, contact us. Get a consultation on implementation — we will analyze your logistics processes and offer an optimal turnkey solution.







