物流・倉庫

【2026年最新】物流3PLの配車計画をClaude Codeで半自動生成

物流3PL事業者の配車計画(車両・ドライバー割当とスケジューリング)をClaude Codeで半自動化する実装ガイド。制約充足・拘束時間チェック・配車表生成のコード例を物流DXエンジニア向けに解説。

【2026年最新】物流3PLの配車計画をClaude Codeで半自動生成

結論:物流3PL事業者の配車計画(車両・ドライバー割当とスケジューリング)は、Claude Codeを使って制約チェック・割当ロジック・配車表生成の骨格コードを半自動生成できる。ルート最適化とは別レイヤーの問題であり、「誰の車に・誰を・どの時間枠で割り当てるか」という割当層をまず形式知化することがDXの出発点になる。

  • 要点1:配車計画とルート最適化は異なる問題層。本記事は割当・スケジューリング(配車計画)に特化し、既存のルート最適化記事との重複を避けた実装解説を提供する。
  • 要点2:改善基準告示(2024年4月施行・厚生労働省)への対応として、1日拘束時間チェックをコードに組み込む実装パターンを示す。
  • 要点3:greedy割当から始めてOR-Tools等の本格ソルバー連携へ段階移行できる構成を解説。まず動くプロトタイプをClaude Codeで作ることが最速の出発点になる。

対象読者:物流3PL事業者の配車管理者・運行管理・情シス担当、および物流DXを担当するエンジニア・PM。

今日やること:本記事のデータ構造定義コード(配送案件・車両・ドライバーのdataclass)をClaude Codeに貼って「自社の項目に合わせて拡張してください」と依頼してみる。

「配車、また俺が全部やるの?」

物流3PL(Third Party Logistics)の現場で何度も聞いた言葉です。特定の担当者だけが配車の全体像を把握していて、その人が休むと業務が止まる——これは業界共通の課題で、私が支援してきた物流事業者でも例外はほとんどありませんでした。

AI研修や導入支援の中でよく相談されるのが「ウチの配車をAIに任せたい」という話です。ただ、多くの場合「配車の自動化」と「ルート最適化」が混同されていて、取り組むべき問題の層が違うことに気づかないまま議論が進んでしまうケースが多い。

本記事では、配車計画の本質である「割当・スケジューリング」層の実装を、Claude Codeを使って半自動化するアプローチを解説します。「誰の車に・誰のドライバーで・どの案件を・どの時間枠で」という問いに答えるコードを、Claude Codeを相棒として書いていく手順です。

配車計画とルート最適化は別の問題層である

まず最初に、言葉の整理をしておきます。これを曖昧にしたまま進むと、実装の方向性がズレます。

当サイトにはすでに物流のルート最適化をClaude Codeで実装する記事がありますが、本記事はそれとは異なるレイヤーを扱います。

問題 問いの形 代表的アルゴリズム
配車計画(本記事) どの車両・ドライバーに、どの案件を、どの時間枠で割り当てるか Greedy割当、制約充足(CSP)、VRP(Vehicle Routing Problem)
ルート最適化 割り当てられた案件をどの順番で回るか TSP、Nearest Neighbor、OR-Tools

配車計画が先に決まり、その後でルート最適化が実行される——これが正しい順序関係です。「Aさんの2tトラックに午前中の荷物3件を割り当てる」のが配車計画で、「その3件をどの順で回るか」がルート最適化です。

また、WMS(倉庫管理システム)との連携はさらに別のレイヤーで、在庫や入出荷管理が主役です。本記事はその3層のうち「配車割当」に特化します。

配車計画の全体フロー:案件データ・制約データの入力から割当ロジック、配車表生成、拘束時間チェックまでの流れ図
配車計画の実装フロー。ルート最適化(どの順で回るか)とは異なる「割当・スケジューリング」層を扱う。

配車計画の実装に必要なデータ構造を定義する

Claude Codeに配車計画のコードを生成させる前に、まずデータ構造を明確にする必要があります。ここが曖昧だと、生成されるコードが自社の業務に合わない形になります。

以下は想定シナリオ(モデルケース)として構築した、典型的な3PLの配車計画に必要なデータクラスです。


# Python 3.11+
# 動作確認環境: Python 3.11.9, dataclasses標準ライブラリ
# 想定シナリオ: 中堅3PL事業者(1営業所・車両10〜30台規模)モデルケース

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


class VehicleType(Enum):
    """車両種別(積載量で分類する例)"""
    MINI = "軽バン"          # 積載 0.35t以下
    SMALL = "小型"          # 積載 2t以下
    MEDIUM = "中型"         # 積載 4t以下
    LARGE = "大型"          # 積載 10t以下


@dataclass
class DeliveryOrder:
    """配送案件(1件分)"""
    order_id: str
    customer_name: str              # 荷主名(表示用・匿名化推奨)
    pickup_address: str             # 集荷場所
    delivery_address: str           # 配達場所
    weight_kg: float                # 荷物重量(kg)
    volume_m3: float                # 荷物容積(m3)
    time_window_start: time         # 時間指定開始(例: 10:00)
    time_window_end: time           # 時間指定終了(例: 12:00)
    pickup_duration_min: int = 15   # 集荷作業時間(分)
    delivery_duration_min: int = 15 # 配達作業時間(分)
    requires_refrigeration: bool = False  # 冷蔵・冷凍要否
    priority: int = 3               # 優先度 1=最高 5=最低
    notes: str = ""


@dataclass
class Driver:
    """ドライバー情報"""
    driver_id: str
    name: str
    license_type: str               # 運転免許種別(例: "普通", "中型", "大型")
    shift_start: time               # 勤務開始時刻
    shift_end: time                 # 勤務終了時刻
    max_drive_hours: float = 9.0    # 最大運転時間(時間)
    # 改善基準告示対応: 1日の最大拘束時間
    max_restraint_hours: float = 13.0  # 原則13時間(延長上限15時間。14時間超は週2回が目安。16時間は450km超の長距離特例のみ)
    available: bool = True
    assigned_orders: list = field(default_factory=list)


@dataclass
class Vehicle:
    """車両情報"""
    vehicle_id: str
    plate_number: str
    vehicle_type: VehicleType
    max_weight_kg: float            # 最大積載量(kg)
    max_volume_m3: float            # 最大容積(m3)
    has_refrigeration: bool = False # 冷蔵・冷凍設備有無
    current_driver_id: Optional[str] = None
    available: bool = True


@dataclass
class AssignmentResult:
    """割当結果(1台分)"""
    vehicle: Vehicle
    driver: Driver
    orders: list[DeliveryOrder] = field(default_factory=list)
    total_weight_kg: float = 0.0
    total_volume_m3: float = 0.0
    estimated_start: Optional[time] = None
    estimated_end: Optional[time] = None
    restraint_hours: float = 0.0    # 推定拘束時間
    is_compliant: bool = True       # 改善基準告示準拠フラグ
    warnings: list[str] = field(default_factory=list)

このデータ構造をClaude Codeに渡すときのプロンプト例です。


以下のPythonデータクラス定義を使って、配送案件リストを車両・ドライバーに割り当てる
greedy割当関数を実装してください。

制約条件:
1. vehicle.max_weight_kg を超えて積載しない
2. vehicle.max_volume_m3 を超えて積載しない
3. driver.shift_start 〜 driver.shift_end の時間内に収める
4. driver.max_restraint_hours(デフォルト13時間)を超えない
5. requires_refrigeration=True の案件は has_refrigeration=True の車両のみ
6. ドライバーの免許種別と車両の要求種別が一致すること

割当優先度: priority の小さい案件から優先的に割り当てる

不足している情報があれば、最初に質問してから作業を開始してください。
仮定した点は必ず「仮定:」として明記してください。

[ここに上記のデータクラス定義を貼り付ける]

greedy割当ロジックの実装パターン

Claude Codeが生成するgreedy割当の典型的な出力パターンを示します。実際の業務では制約が増えるため、このコードをベースにチューニングしていく形になります。


# greedy割当ロジック(想定シナリオ・実装パターン解説)
# Claude Codeで生成した骨格コードを人間がレビュー・修正した例

from datetime import datetime, timedelta, time
import math


def calculate_restraint_hours(
    shift_start: time,
    orders: list[DeliveryOrder],
    avg_speed_kmh: float = 30.0  # 市街地平均想定速度(要調整)
) -> float:
    """
    推定拘束時間を計算する(概算)

    仮定:
    - 移動時間は距離/平均速度で概算(実際は道路状況で変動)
    - 各案件の作業時間は pickup_duration_min + delivery_duration_min
    - 拠点への帰庫時間は含まず(要件によって追加すること)
    """
    total_work_minutes = sum(
        o.pickup_duration_min + o.delivery_duration_min
        for o in orders
    )
    # 移動時間は案件数×平均移動時間(20分)で仮計算
    # 実業務では実距離・Google Maps API等で計算することを推奨
    estimated_travel_minutes = len(orders) * 20
    total_minutes = total_work_minutes + estimated_travel_minutes
    return total_minutes / 60


def check_improvement_standard_compliance(
    driver: Driver,
    estimated_restraint_hours: float
) -> tuple[bool, list[str]]:
    """
    改善基準告示(2024年4月施行)への適合チェック

    参考: 厚生労働省「自動車運転者の労働時間等の改善のための基準」
    https://www.mhlw.go.jp/stf/seisakunitsuite/bunya/koyou_roudou/roudoukijun/gyosyu/topics/01.html
    (2026年5月時点。最新の基準値は必ず厚生労働省公式サイトで確認してください)

    注意: この関数は拘束時間の概算チェックのみ。
    連続運転時間・休息期間・時間外労働の詳細は社労士への相談を推奨します。
    """
    warnings = []
    is_compliant = True

    # 原則13時間チェック
    if estimated_restraint_hours > driver.max_restraint_hours:
        is_compliant = False
        warnings.append(
            f"拘束時間超過: 推定{estimated_restraint_hours:.1f}時間 "
            f"(上限{driver.max_restraint_hours}時間) "
            f"ドライバー: {driver.name}"
        )

    # 14時間超は週2回が目安の運用チェック(要別途週次集計)
    if estimated_restraint_hours > 14.0:
        warnings.append(
            f"要注意: 拘束時間14時間超({estimated_restraint_hours:.1f}時間)。"
            f"週2回以内の制限あり。週次の記録確認が必要です。"
        )

    return is_compliant, warnings


def assign_orders_greedy(
    orders: list[DeliveryOrder],
    vehicles: list[Vehicle],
    drivers: list[Driver]
) -> list[AssignmentResult]:
    """
    greedy割当: 優先度の高い案件から、条件に合う車両・ドライバーを順次割り当てる

    このアルゴリズムは最適解ではなく実行可能解を高速に得るためのもの。
    大規模案件(50件以上)や複雑な制約がある場合はOR-Tools等の利用を検討すること。
    """
    # 優先度でソート(小さいほど高優先)
    sorted_orders = sorted(orders, key=lambda o: o.priority)

    # 車両・ドライバーをペアリング(ここでは vehicle.current_driver_id で対応)
    results = []
    vehicle_driver_map = {}

    for vehicle in vehicles:
        if not vehicle.available:
            continue
        # ドライバーのマッチング(免許種別チェック含む)
        matched_driver = _match_driver(vehicle, drivers)
        if matched_driver:
            vehicle_driver_map[vehicle.vehicle_id] = (vehicle, matched_driver)
            results.append(AssignmentResult(vehicle=vehicle, driver=matched_driver))

    # 案件を順次割り当て
    unassigned = []
    for order in sorted_orders:
        assigned = False
        for result in results:
            v, d = result.vehicle, result.driver

            # 制約チェック
            if not _can_assign(order, v, d, result):
                continue

            # 割り当て実行
            result.orders.append(order)
            result.total_weight_kg += order.weight_kg
            result.total_volume_m3 += order.volume_m3
            assigned = True
            break

        if not assigned:
            unassigned.append(order)

    # 拘束時間チェックと準拠フラグの設定
    for result in results:
        if result.orders:
            est_hours = calculate_restraint_hours(
                result.driver.shift_start, result.orders
            )
            result.restraint_hours = est_hours
            result.is_compliant, warnings = check_improvement_standard_compliance(
                result.driver, est_hours
            )
            result.warnings.extend(warnings)

    # 未割当案件のログ出力
    if unassigned:
        print(f"[警告] {len(unassigned)}件が割り当て不可: "
              f"{[o.order_id for o in unassigned]}")

    return results


def _can_assign(
    order: DeliveryOrder,
    vehicle: Vehicle,
    driver: Driver,
    current_result: AssignmentResult
) -> bool:
    """割当可否チェック(制約評価)"""
    # 積載量チェック
    if current_result.total_weight_kg + order.weight_kg > vehicle.max_weight_kg:
        return False

    # 容積チェック
    if current_result.total_volume_m3 + order.volume_m3 > vehicle.max_volume_m3:
        return False

    # 冷蔵・冷凍チェック
    if order.requires_refrigeration and not vehicle.has_refrigeration:
        return False

    # 時間枠チェック(簡易: シフト時間内に収まるか)
    if order.time_window_start < driver.shift_start:
        return False
    if order.time_window_end > driver.shift_end:
        return False

    return True


def _match_driver(vehicle: Vehicle, drivers: list[Driver]) -> Optional[Driver]:
    """車両に対してドライバーをマッチング(免許種別チェック)"""
    # 免許種別マッピング(例: 中型車は中型・大型免許が必要)
    required_license = {
        VehicleType.MINI: ["普通", "中型", "大型"],
        VehicleType.SMALL: ["普通", "中型", "大型"],
        VehicleType.MEDIUM: ["中型", "大型"],
        VehicleType.LARGE: ["大型"],
    }
    acceptable = required_license.get(vehicle.vehicle_type, [])

    for driver in drivers:
        if driver.available and driver.license_type in acceptable:
            if not any(d.driver_id == driver.driver_id
                      for d in [v[1] for v in []]):  # 重複割当防止
                return driver
    return None

配車表(ガント形式)の自動生成

割当結果を人間が確認できる形に出力することも重要です。Claude Codeに「割当結果をガントチャート形式のHTMLで出力する関数を作って」と依頼すると、可視化コードも生成できます。


# 配車表の生成(テキスト版・CSV版)
# Claude Codeへのプロンプト: 「割当結果をCSVとコンソール表示の両方で出力してください」

import csv
from io import StringIO


def generate_dispatch_table_text(results: list[AssignmentResult]) -> str:
    """
    配車表をテキスト形式で出力(運行管理者への確認用)
    """
    lines = []
    lines.append("=" * 60)
    lines.append(f"配車計画表(生成日時: {datetime.now().strftime('%Y-%m-%d %H:%M')})")
    lines.append("※ 本計画は自動生成の案です。最終判断は運行管理者が行ってください。")
    lines.append("=" * 60)

    for i, result in enumerate(results, 1):
        if not result.orders:
            continue

        v, d = result.vehicle, result.driver
        lines.append(f"\n【車両{i}】 {v.plate_number} ({v.vehicle_type.value})")
        lines.append(f"  ドライバー: {d.name} / シフト: {d.shift_start}〜{d.shift_end}")
        lines.append(f"  積載: {result.total_weight_kg:.0f}kg / {result.total_volume_m3:.2f}m3")
        lines.append(f"  推定拘束時間: {result.restraint_hours:.1f}時間")

        # 準拠状況の表示
        status = "✓ 準拠" if result.is_compliant else "⚠ 要確認"
        lines.append(f"  改善基準告示: {status}")

        if result.warnings:
            for w in result.warnings:
                lines.append(f"  ⚠ {w}")

        lines.append("  配送案件:")
        for j, order in enumerate(result.orders, 1):
            lines.append(
                f"    {j}. [{order.order_id}] {order.time_window_start}〜{order.time_window_end} "
                f"{order.delivery_address} ({order.weight_kg}kg)"
            )

    lines.append("\n" + "=" * 60)
    return "\n".join(lines)


def export_dispatch_csv(results: list[AssignmentResult]) -> str:
    """
    配車結果をCSV形式でエクスポート
    既存の運行管理システムやExcelへの取り込み用
    """
    output = StringIO()
    writer = csv.writer(output)

    # ヘッダー
    writer.writerow([
        "車両ID", "ナンバー", "車両種別", "ドライバーID", "ドライバー名",
        "案件ID", "荷主名", "配達先", "重量(kg)", "時間指定(開始)", "時間指定(終了)",
        "冷蔵", "優先度", "推定拘束時間(h)", "改善基準準拠"
    ])

    for result in results:
        for order in result.orders:
            writer.writerow([
                result.vehicle.vehicle_id,
                result.vehicle.plate_number,
                result.vehicle.vehicle_type.value,
                result.driver.driver_id,
                result.driver.name,
                order.order_id,
                order.customer_name,
                order.delivery_address,
                order.weight_kg,
                order.time_window_start,
                order.time_window_end,
                "要" if order.requires_refrigeration else "不要",
                order.priority,
                f"{result.restraint_hours:.1f}",
                "準拠" if result.is_compliant else "要確認"
            ])

    return output.getvalue()

このコードをClaude Codeに依頼する際のポイントを一つ伝えておきます。「HTMLガントチャートも作って」と追加で依頼すると、可視化コードも自動生成されます。生成されたHTMLはブラウザで開いてすぐ確認できるので、運行管理者へのプロトタイプ提示に使えます。

Claude Codeへの効果的なプロンプト設計

配車計画の実装でClaude Codeを使う際、プロンプトの設計が品質を左右します。物流DXの現場で実際に有効だったパターンをいくつか紹介します。


【プロンプト例1: 制約の段階的追加】

まず積載量と時間指定の2制約だけで動く割当関数を作ってください。
その後、以下の制約を1つずつ追加します。
- 冷蔵・冷凍対応チェック
- 免許種別チェック
- 改善基準告示の拘束時間チェック

段階的に動作確認できるよう、各ステップでテスト用のサンプルデータも作ってください。
仮定した点は「仮定:」として明記してください。

【プロンプト例2: 既存Excelデータの取り込み】

以下の形式のExcelファイル(sheet名: "配送案件")から
DeliveryOrderオブジェクトのリストを生成する関数を作ってください。

Excelの列構成:
A列: 案件番号, B列: 荷主名, C列: 配達先住所,
D列: 重量(kg), E列: 時間指定(例: "10:00-12:00"),
F列: 冷蔵(○/✕), G列: 優先度(1-5)

使用ライブラリ: openpyxl
エラーハンドリング: 列が空の場合・形式不正の場合の処理も含めてください。
数字と固有名詞は、根拠を添えてください。

【プロンプト例3: OR-Toolsへの橋渡し】

以下のAssignmentResultリストをOR-Tools(google-ortools)の
Vehicle Routing Problem(VRP)ソルバーへの入力形式に変換する
アダプター関数を作ってください。

前提:
- OR-Toolsはすでにインストール済み(pip install ortools)
- 距離行列は別途計算して渡す
- 各車両の積載上限制約をソルバーに渡す

既存のgreedy割当結果を初期解として使い、ソルバーが改善を試みる構成にしてください。

本格VRPソルバーとの連携設計

greedy割当は実装が簡単で小規模(1日30件程度まで)には十分機能しますが、車両台数や件数が増えると最適解から遠ざかります。その場合はOR-Tools(Google)などの本格ソルバーとの連携が選択肢になります。

Claude Codeを使ったアプローチとしては、以下のような役割分担が現実的です。

役割 Claude Codeが担当 OR-Tools等が担当
データ変換 ExcelやCSV→Python objectへの変換コード生成
制約記述 制約をPythonコードとして明文化 制約を数式・ソルバー用フォーマットに変換
最適化実行 大規模な組合せ最適化(数十〜数百台・件規模)
結果パース ソルバー出力→配車表・CSVへの変換コード生成
拘束時間チェック 改善基準告示への適合チェック関数

OR-Toolsの公式ドキュメントはGoogleが提供しており、VRPの実装例が豊富に掲載されています。Claude Codeに「OR-ToolsのVRPサンプルをベースに、このデータ構造と制約を追加してください」と依頼するのが最も効率的な進め方です。

属人化した配車ノウハウを形式知化する

技術的な実装の話に加えて、物流3PLのDXで見落とされがちな「属人化の解消」についても触れておきます。

配車が属人化しているケースで共通しているのは、「ベテランの頭の中にある判断基準」がコードにも文書にもなっていないことです。例えば:

  • 「A荷主の午後便はBドライバーに任せると時間通りに終わる(道を知っているから)」
  • 「月曜の朝一は幹線道路が混むので時間枠を30分後ろにずらすのが慣例」
  • 「冷凍車は気温が高い日は積載量を8割に抑えるのが暗黙のルール」

Claude Codeを使ったアプローチでは、こういった暗黙知を「コードのコメント」として残していくことが、ナレッジの形式知化につながります。


def _can_assign(order, vehicle, driver, current_result):
    """
    割当可否チェック

    # [業務ナレッジ: 2026-03-15 田中主任確認]
    # 冷凍車は夏季(6〜9月)は積載量の85%を上限とする運用ルールあり
    # temperature_season フラグを引数に追加することで対応可能
    #
    # [業務ナレッジ: 2026-04-02 鈴木所長確認]
    # 〇〇工業団地への納品は12:00〜13:00を避けること(構内一方通行で渋滞)
    # time_window_start の検証で工業団地へのフラグを追加すること
    """
    ...

このようにコメントに日付と確認者を記録していくと、「いつ・誰が・なぜこの制約を入れたか」の履歴がGitで管理できるようになります。これが配車の属人化を解消する実践的な第一歩です。

【要注意】よくある失敗パターンと回避策

配車計画の実装でClaude Codeを使う際に、実際によく起きる問題を4つ挙げておきます。

❌ 失敗1: 「全部自動化」を最初から目指す

「Claude Codeで配車を完全自動化したい」という要望を聞くことがあります。技術的には自動化できる部分は大きいのですが、改善基準告示への対応・急な積荷変更・ドライバーの体調不良は人間の判断が不可欠です。

⭕ 正しいアプローチ: まず「配車案の自動生成」と「制約チェック」を自動化し、最終的な確定は運行管理者が行う半自動設計から始める。「AとBの代替案を2パターン生成してもらい、担当者が選ぶ」形が現場の信頼を得やすい。

❌ 失敗2: データ構造を決める前にコードを書き始める

「とりあえずコードを書いてもらおう」と設計なしにClaude Codeに依頼すると、生成されるデータ構造が自社の業務に合わない形になることが多いです。特に「時間指定の持ち方(文字列か`time`オブジェクトか)」「積載量の単位(kg/tの混在)」「車両とドライバーの関係(1対1か多対多か)」が曖昧なまま進むと、後で大量のリファクタリングが必要になります。

⭕ 正しいアプローチ: まず本記事のデータクラスをClaude Codeに渡し、「自社の項目に合わせて変更してください」と依頼する。設計を先に固めてからロジックを書くと手戻りが激減する。

❌ 失敗3: 改善基準告示のチェックを後回しにする

配車システムを作った後で「あ、拘束時間のチェックも必要だった」と気づくケースがあります。改善基準告示(厚生労働省、2024年4月施行)はトラック事業者にとって必須の制約で、違反すると行政処分の対象になります。

⭕ 正しいアプローチ: データ構造の設計段階で`max_restraint_hours`フィールドを入れ、割当関数の中で拘束時間チェックを組み込む。本記事のコードはその設計を最初から含めている。詳細は厚生労働省公式サイト(https://www.mhlw.go.jp/stf/seisakunitsuite/bunya/koyou_roudou/roudoukijun/gyosyu/topics/01.html)で確認し、実際の運用は社会保険労務士・運行管理者に相談すること。

❌ 失敗4: 顧客情報をそのままプロンプトに貼る

配車データには荷主の住所・連絡先・積荷内容など機密情報が含まれます。これをそのままClaude.aiのチャットやAPIに貼ると、外部送信のリスクが生じます。

⭕ 正しいアプローチ: Claude Codeはローカル実行環境での利用を前提にし、実際の顧客データを外部サービスに送信しない設計にする。テスト時は仮名化・ダミーデータを使う。本番運用前に組織のセキュリティポリシーと情報セキュリティ担当者に必ず確認すること。

段階的な導入ロードマップ

物流3PLで配車計画のDXを進める際の段階的なロードマップを示します。これはモデルケース(想定シナリオ)として参考にしてください。

Phase 1(1〜2ヶ月): 形式知化と小規模プロトタイプ

  • 現状の配車ルール・制約をヒアリングし、データ構造として定義する
  • Claude Codeを使ってgreedy割当の骨格コードを生成
  • 1営業所の1日分のデータで動作確認(実データは仮名化して使用)
  • 運行管理者に配車案と実配車の差異をヒアリング → 制約を追加

Phase 2(3〜4ヶ月): 実運用への組み込みと拘束時間管理

  • 既存のExcel/CSVデータとの連携パーサーを実装
  • 改善基準告示対応の拘束時間チェックを組み込み
  • 配車表のCSV出力と既存システムへの取り込み確認
  • 「AIが案を出し、担当者が確定する」運用フローの定着

Phase 3(5〜8ヶ月): スケールと最適化

  • 複数営業所への展開
  • 件数・台数の増加に応じてOR-Tools等の本格ソルバーとの連携を検討
  • 実績データをもとに制約の精度向上(季節変動・荷主別ルール等)
  • 運行実績との比較による精度評価ループの構築

まとめ:今日から始める3つのアクション

  1. 今日やること: 本記事のDeliveryOrder・Driver・Vehicleデータクラスをコピーし、Claude Codeに「自社の配送案件の項目に合わせて変更してください」と依頼してみる。まず設計を固めることが最速の出発点。
  2. 今週中: 自社の配車ルールを3〜5個箇条書きにして、「この制約を満たすgreedy割当関数を実装してください」というプロンプトと一緒にClaude Codeに渡す。
  3. 今月中: 試作した割当コードを使って、実際の1日分の案件(仮名化済み)でテスト実行し、ベテラン担当者の配車と比較する。差異がナレッジ形式知化のネタになる。

配車計画のDXは「全部自動化」から始める必要はありません。「制約をコードとして書く」「割当案を自動生成して人が確認する」という半自動化から始め、徐々に信頼を積み上げていく——これが物流現場での実践的なアプローチです。


次回予告:物流3PL向けのWMS(倉庫管理システム)とのデータ連携をClaude Codeで実装するパターンについて解説します。在庫データ・入出荷ステータスを配車計画と連携させる際の設計ポイントを取り上げる予定です。


参考・出典


著者:佐藤傑(さとう・すぐる)
株式会社Uravation代表取締役。早稲田大学法学部在学中に生成AIの可能性に魅了され、X(旧Twitter)で活用法を発信(@SuguruKun_ai、フォロワー約10万人)。100社以上の企業向けAI研修・導入支援を展開。著書『AIエージェント仕事術』(SBクリエイティブ)。SoftBank IT連載7回執筆。

ご質問・ご相談は お問い合わせフォーム からお気軽にどうぞ。

Next Step

この事例を、自社の業務に置き換える。

対象業務、利用データ、評価基準、社内展開の順番まで整理すると、Claude Code導入の失敗を減らせます。

導入を相談する