Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Agent SkillsによるAGI4OPT(最適化のためのAGI)

Agent SkillsによるAGI4OPT(最適化のためのAGI)

Agent Skillsを用いて様々な最適化を行うシステムを作成
人間では入力が難しい問題も、入力可能
ユーザーの工夫でSkillを進化させることも可能
新しい時代のIBPを作成可能

Avatar for MIKIO KUBO

MIKIO KUBO

April 03, 2026
Tweet

More Decks by MIKIO KUBO

Other Decks in Business

Transcript

  1. 自然言語からAMPLコードを生成 name: ampl_code_generator description: Generates and executes AMPL optimization models

    from natural language descriptions. 入力例 大学のキャンパスに新しい食品店がオープンしました。この店は年中無休、24時間営業となります。 毎日、3つの8時間シフトがあります。 朝番は6:00から14:00、夕番は14:00から22:00、夜勤は22:00から翌日の6:00までです。 夜間(夜勤)は従業員1名のみですが、日中(朝番と夕番)は2名です。ただし、日曜日は各シフトとも1名 のみとなります。 各従業員の週労働時間は最大40時間を超えず、シフト間には12時間の休息を取らなければなりません。 週休日に関しては、ある日曜日に休む従業員は、その週の土曜日も同様に休むことが望ましいです。 原則として、利用可能な従業員は10名いますが、これは明らかに過剰人員です。 必要とされる従業員が少なければ少ないほど、他の店舗のためのリソースが多くなります。 1週間の最適なシフトを作成してください。
  2. from amplpy import AMPL ampl = AMPL() ampl.eval( r""" set

    EMPLOYEES; set DAYS ordered; set SHIFTS; param demand {DAYS, SHIFTS} >= 0; var x {EMPLOYEES, DAYS, SHIFTS} binary; # 1 if employee works shift var y {EMPLOYEES} binary; # 1 if employee is used var work_sat {EMPLOYEES} binary; var work_sun {EMPLOYEES} binary; var sat_off_pref_violation {EMPLOYEES} >= 0; minimize Total_Employees_And_Penalty: 1000 * sum {e in EMPLOYEES} y[e] + sum {e in EMPLOYEES} sat_off_pref_violation[e]; subject to Staffing {d in DAYS, s in SHIFTS}: sum {e in EMPLOYEES} x[e, d, s] = demand[d, s]; subject to Activate_If_Assigned {e in EMPLOYEES, d in DAYS, s in SHIFTS}: x[e, d, s] <= y[e]; subject to Max_Weekly_Shifts {e in EMPLOYEES}: sum {d in DAYS, s in SHIFTS} x[e, d, s] <= 5; # 5 shifts * 8h = 40h subject to At_Most_One_Shift_Per_Day {e in EMPLOYEES, d in DAYS}: sum {s in SHIFTS} x[e, d, s] <= 1; # 12h rest constraints between consecutive days subject to Evening_To_Morning_Rest {e in EMPLOYEES, d in DAYS: ord(d) < card(DAYS)}: x[e, d, "Evening"] + x[e, next(d), "Morning"] <= 1; subject to Night_To_Morning_Rest {e in EMPLOYEES, d in DAYS: ord(d) < card(DAYS)}: x[e, d, "Night"] + x[e, next(d), "Morning"] <= 1; subject to Night_To_Evening_Rest {e in EMPLOYEES, d in DAYS: ord(d) < card(DAYS)}: x[e, d, "Night"] + x[e, next(d), "Evening"] <= 1; # Sunday/Saturday preference (soft): if Sunday is off, Saturday should also be off subject to Saturday_Work_Def {e in EMPLOYEES}: work_sat[e] >= sum {s in SHIFTS} x[e, "Sat", s] / 3; subject to Sunday_Work_Def {e in EMPLOYEES}: work_sun[e] >= sum {s in SHIFTS} x[e, "Sun", s] / 3; subject to Sat_Off_Preference {e in EMPLOYEES}: sat_off_pref_violation[e] >= work_sat[e] - work_sun[e]; """ ) 出力コード (AMPL部分)
  3. employees = [f"E{i}" for i in range(1, 11)] days =

    ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"] shifts = ["Morning", "Evening", "Night"] demand = {} for d in days: for s in shifts: if d == "Sun": demand[(d, s)] = 1 else: demand[(d, s)] = 2 if s in ["Morning", "Evening"] else 1 ampl.set["EMPLOYEES"] = employees ampl.set["DAYS"] = days ampl.set["SHIFTS"] = shifts ampl.param["demand"].set_values(demand) ampl.option["solver"] = "highs" ampl.solve() print("Objective value:", ampl.obj["Total_Employees_And_Penalty"].value()) print("Employees used:", int(sum(ampl.var["y"].get_values().to_pandas().iloc[:, 0] > 0))) print("Schedule (nonzero assignments):") print(ampl.var["x"].get_values()) コード(Python –amplpy- 部分)
  4. 実行結果 # AMPL Execution Results: code_02.py ## Problem Description Employee

    Shift Scheduling: Minimize the number of employees and penalties for shift preference violations. ## Execution Output Summary (Detailed schedule truncated for brevity) - **Objective Value:** 8000.0 (approximate, based on 8 employees) - **Employees Used:** 8 ## Summary of Findings - The optimal schedule uses 8 employees to cover all shifts across 7 days. - Shift constraints (12h rest, max 5 shifts/week) and demand are satisfied.
  5. AMPLコードからWebアプリ生成 name: ampl_streamlit_converter description: Converts an AMPL/Python script into an

    interactive Streamlit application. 入力例 Amplpyのコード code_02.py からstreamlit アプリを生成して.
  6. 出力されたコードとアプリ """AmplpyのコードのStreamlit化 ## セッションキー - ampl: AMPLオブジェクト - sets: キーが名前で、値がpd.DataFrameの辞書

    - params: キーが名前で、値がpd.DataFrameの辞書 - file_uploader_{キー}: st.file_uploaderのキー (update_fileで使用) - data_editor_{キー}: st.data_editorのキー(未使用) """ import streamlit as st import ast import contextlib import re from textwrap import dedent from typing import Any import pandas as pd from amplpy import AMPL, Set …
  7. より難しいケーススタディ Agent Skillをつかって,https://scmopt.github.io/ampl/04case.html で公開している18のケーススタディで amplpyとwebアプリを生成 1. ナースプラクティショナーの人員配置 2. シフト最適化 3.

    中規模食品卸売業者の店舗配送ルート最適化 4. 部品メーカーにおける月次生産計画最適化 5. 部品メーカーにおける3ヶ月生産・在庫最適化計画 6. 新製品発売における広告キャンペーン最適化 7. 地域プロバスケットボールリーグの試合スケジュール最適化 8. 日次電力供給計画のコスト最小化 9. 農場の季節別作物栽培計画による収益最大化 10. 国内線航空会社のフリートアサインメントと基本スケジュール最適化 11. 小規模航空路線網における乗務ペアリング最適化 12. 大学学部の授業教室・時間割割り当て最適化 13. 森林公園における希少動物生息地の監視センサーネットワーク設計 14. 時間帯ごとに複数の仕事をもつシフトスケジューリング問題 15. 均等化を考慮したチーム割当問題 16. 献立問題 17. エア・フロンティア航空の月間乗務員スケジュール作成 18. ケーススタディ:首都圏フーズ物流の挑戦「最適化が導く共同配送計画」
  8. 生産スケジューリング name: scheduling_with_production-scheduler description: Solves scheduling problems (job shop, flow

    shop, project scheduling, etc.) using the production-scheduler library with constraint programming. 入力例 段取り時間付きのスケジューリング問題を解いてください。 マシン1台で3つのジョブを処理します。 - Job1: 処理時間 4時間, 納期 10時間 - Job2: 処理時間 3時間, 納期 8時間 - Job3: 処理時間 5時間, 納期 15時間 段取り時間: Job1→Job2: 2時間, Job2→Job3: 1時間, Job1→Job3: 3時間 納期遅れの合計を最小化してください。
  9. 指定された条件でスケジューリングの最適化を実行しました。 ソルバー(production-scheduler)を実行した ところ、**納期遅れの合計を「0」にする最適解(総遅れ時間0時間)**が得られました。 最適なスケジューリング順序 Job2 → Job1 → Job3 の順序で処理を行うのが最適です。

    ジョブ 開始時間 終了時間 納期 遅れ時間 備考 Job2 時間 0 時間 3 8 0 最初に処理 Job1 時間 3 時間 7 10 0 Job2→Job1は段取り時間なし Job3 時間 10 時間 15 15 0 Job1終了後、3時間の段取り時間を経て開始 なぜこの順序が良いのか? 最初は Job1 → Job2 の順序などが考えられますが、そうすると途中で強制的に2時間の段取り時間ペナルティ が発生してしまいます。 **Job2 → Job1 の順序には依存関係の段取り時間が指定されていない(0時間扱いになる)**ため、スムーズ にジョブをこなすことができます。 最後に Job1 → Job3 の段取り時間(3時間)を挟んでも、Job3 の納期(15時間)には15時間目ぴったりで間 に合うため、すべてのジョブを納期通りに完了させることができます。 結果 (Gemini 3.1 Pro)
  10. スケジューリング最適化(OptSeqソルバー) name: optseq_scheduler description: OptSeq Optimization Skill for Scheduling Problems

    --- # OptSeq Scheduler Skill This skill allows an AI agent to solve complex scheduling problems using the `optseq` solver. It supports defining activities, modes, resources, and temporal constraints, and returns optimized schedules with visualizations.
  11. 入力例 1: 以下の問題を optseq_scheduler skillを用いて解け。 あなたは航空機会社のコンサルタントだ. あなたの仕事は,着 陸した航空機をなるべく早く離陸させるためのスケジュールを たてることだ. 航空機は,再び離陸する前に幾つかの作業をこ

    なさなければならない. まず,乗客と荷物を降ろし,次に機内 の掃除をし,最後に新しい乗客を搭乗させ,新しい荷物を積み 込む. 当然のことであるが, 乗客を降ろす前に掃除はできず, 掃除をした後でないと新しい乗客を入れることはできず, 荷物 をすべて降ろし終わった後でないと,新しい荷物は積み込むこ とができない. また,この航空機会社では, 乗客用のゲート の都合で,荷物を降ろし終わった後でないと新しい乗客を搭乗 させることができないのだ. 作業時間は,乗客降ろし 13 分, 荷物降ろし 25 分,機内清掃 15 分,新しい乗客の搭乗 27 分, 新しい荷物の積み込み 22 分とする. さて,最短で何分で離陸 できるだろうか? ご指定の条件を optseq_scheduler スキルに入力し、航空機離陸 までの最短スケジュールを計算しました。 結果として、**最短「55分」**で離陸できることがわかりました。 最適なスケジュールの流れ 作業は以下の順序と時間で行われます: 乗客降ろし と 荷物降ろし (同時並行で開始) 乗客降ろし: 0分 〜 13分 荷物降ろし: 0分 〜 25分 で完了 機内清掃 乗客が降りた段階ですぐに開始します。 清掃: 13分 〜 28分 で完了 新しい荷物の積み込み 荷物降ろしが終了した段階ですぐに開始します。 荷物積み込み: 25分 〜 47分 で完了 新しい乗客の搭乗(最終工程) 「機内清掃」と「荷物降ろし」の両方が完了する 28分時点 を 待ってからの開始になります。 乗客搭乗: 28分 〜 55分 で完了 この結果、すべての作業が遅延なく実行できた場合のトータル時 間は「55分」となります。 結果
  12. 4作業3機械のスケジューリング問題を考える. 各作業はそれぞれ 3つの子作業(これを以下では作業とよぶ)1, 2, 3 から成り, この順序で処理しなくてはならない. 各作業を処理する機械, および処理日数は,以下の表の通りである. |

    |小作業1 | 小作業2 | 小作業3 | | :--- | :---: | :---: | :---: | | 作業1 | 機械1: 7日 | 機械2: 10日 | 機械3: 4日 | | 作業2 | 機械3: 9日| 機械1: 5日 | 機械2 : 11日 | | 作業3 | 機械1 : 3日 | 機械3: 9日 |機械2 : 12日 | | 作業4 | 機械2 : 6日 | 機械3: 13日 | 機械1 : 9日| 目的は最大完了時刻最小化とする. ここでは,さらに以下のような複雑な条件がついているものと仮定する. 1. 各作業の初めの 2日間は作業員資源を必要とする操作がある. この操作は平日のみ, かつ 1日あたり高々2個しか行うことができない. 2. 各作業は,1日経過した後だけ,中断が可能. 3. 機械1での作業は,最初の1日は2個まで並列処理が可能. 4. 機械2に限り, 特急処理が可能.特急処理を行うと処理日数は4日で済むが, 全体で1度しか行うことはできない. 5. 機械1において, 作業1を処理した後は作業2を処理しなくてはならない. 入力例 2:以下の問題を optseq_scheduler skillを用いて解け。
  13. 結果 (Gemini 3.1 Pro) ご提示いただいた複雑な条件(作業員リソースの平日/並列指定、中断条件、特急処理、特定の処理順序)をすべて JSON フォーマットに落とし込み、optseq_scheduler にて最適化計算を実行しました。 計算結果として、すべての制約を満たす**最大完了時刻(Makespan)は「35日」**となりました。 最適化における注目の動き

    リソースと曜日の制約 作業員数や平日のカレンダー制限がある中、機械2を使う作業(J4_1)などは条件に合わせてうまく開始 を数日待機させ実行されています。 機械1の順序指定 「機械1において、作業1の後は作業2」という制約に従い、J1_1を7日で終えた直後、少しの間隔を空けてか らJ2_2 が着手されるように制御されています。 機械2の特急処理チケットの活用 機械2だけ可能な「1回限りの特急処理(通常12日→4日)」は、全体の終盤となる J3_3 の工 程(31日〜35日)で効果的に使用され、全体の完了日数をギュッと縮める決定打になっています。 作成した全体の計算結果やスケジュール構成は自動生成された walkthrough.mdにてご確認いただけます。また、可視化用のガ ントチャートは ./output/gantt_chart.html に出力されておりますので、ブラウザで開いてより詳細なマシンの稼働時間帯をご 覧ください。
  14. 配送最適化(MOAI-dispatcher) name: solving_with_moai-dispatcher description: Solves Vehicle Routing Problems (VRP) using

    the moai-dispatcher library supporting CVRP, VRPTW, multi-depot, and heterogeneous fleet. 入力例 配送(delivery)と集荷(pickup)の両方があるルートを最適化してください。 車両容量は40。 デポ: (50, 50) クライアント: - C1: (30, 30), delivery 10, pickup 5 - C2: (70, 70), delivery 5, pickup 15 - C3: (30, 70), delivery 20, pickup 0 - C4: (70, 30), delivery 0, pickup 10 全ての需要を満たす最適な巡回順を教えてください。
  15. 配達(delivery)と集荷(pickup)が同時に発生する配送ルート問題(VRPSPD)について、 moai-dispatcher を使用して最適化を実行いたしました。 結果として、車両の積載上限(40)を一度も超過しない総移動距離200の最適ルートが導出され ました。 最適な巡回順 Depot → C3 →

    C1 → C4 → C2 → Depot 各地点での積載量の推移 必要な配達量の合計は 35 です。そのため、車両は最初にデポから 35 の荷物を積んで出発します。 Depot: 35 を積んで出発 C3: 20配達 / 0集荷 → 車内の荷物上限は 15 (35 - 20 + 0) C1: 10配達 / 5集荷 → 車内の積載量は 10 (15 - 10 + 5) C4: 0配達 / 10集荷 → 車内の積載量は 20 (10 - 0 + 10) C2: 5配達 / 15集荷 → 車内の積載量は 30 (20 - 5 + 15) Depot: 30(回収した合計)を積んだ状態でデポに帰還 最大積載量は出発時の 35(< 40)であり、すべての制約を満たして効率的に巡回できているこ とがわかります。 結果 (Gemini 3.1 Pro)
  16. 配送最適化(METROソルバー) name: solving_vrp description: Solves Vehicle Routing Problems (VRP) using

    the metro library. 入力例 metro を使って、集荷(PickUp)してから配送(Delivery)するルートを最適化してください。 車両1台、出発地: 横浜駅 (139.6222, 35.4663)、容量 [30]。 Shipment 1: - 集荷: 川崎 (139.6969, 35.5309), サービス時間 300秒 - 配送: 相模大野 (139.4379, 35.5345), サービス時間 300秒 - amount: [10] Shipment 2: - 集荷: 町田 (139.4466, 35.5419), サービス時間 300秒 - 配送: 藤沢 (139.4870, 35.3386), サービス時間 300秒 - amount: [15]
  17. ジオコーディングAPIの呼び出し name: geocoding description: A skill to perform geocoding, reverse

    geocoding, and travel matrix calculations using Moai Lab APIs. このSkillを使って,緯度経度から地点情報を抽出,地点間の移動 距離(時間)を計算 その結果を用いて配送最適化ソルバーMETROを呼び出して解を 算出
  18. 結果 (Gemini 3.1 Pro) metroソルバーを用いて、集荷(Pickup)と配送(Delivery)がペアになったShipments要件のルート最適化 を実行いたしました。 結果として、総移動時間:6374秒 の最適な巡回ルートが導出されました。 最適な巡回順と積載量の推移 車両は横浜駅を空の状態で出発し、以下の順に巡回します。

    Start: 横浜駅 (積載量 0) 集荷 (Shipment 1): 川崎 (積載量 10へ増加) 配送 (Shipment 1): 相模大野 (荷物をすべて下ろし、積載量 0へ減少) 集荷 (Shipment 2): 町田 (積載量 15へ増加) 配送 (Shipment 2) / End: 藤沢 (荷物をすべて下ろす。終点設定がないためここで終了) 実行結果のポイント 初期要件通り、それぞれの荷物は「集荷地点 → 配送地点」という順序を必ず守って同じ車両で運搬されるよ うにスケジュールされています。 車両容量は最大「30」ですが、川崎の荷物(10)を相模大野で下ろしてから町田の荷物(15)を積み込んで いるため、ルート中の最大積載量は「15」となり、容量超過となることはありません。 移動時間(6374秒)に加えて、全4拠点でのサービス時間(合計1200秒)が考慮され、総所要時間は7574秒 と計算されています。
  19. 得られたルートを可視化してください. name: vrp_visualization description: Visualizes VRP routes and points on

    an interactive map using Plotly. 配送結果の可視化Skill が呼び出される. 指定されたルートを地図上で可視化したHTMLファイルを生成し ました。 結果は vrp_map.html として保存されています。 お渡ししたHTMLファイルをブラウザ(ChromeやSafariなど) で開いていただきますと、以下のような情報をインタラクティブ な地図上でご確認いただけます。 車両ごとの色分けされた走行ルート 横浜駅(Start/End)、川崎・町田(Pickup)、相模大野・藤沢 (Delivery)の各ポイントの場所 ポイントにカーソルを合わせることで表示される詳細情報
  20. 時系列予測 name: timeseries_forecasting description: Performs time series forecasting on CSV

    data using MOAI-Forecast. 入力例: [data/demand_with_promo.csv] を使って、今後の販売数の予測を行ってください。 カラム構成: - `date`: 日付情報 - `cust`: 顧客ID - `prod`: 商品ID - `promo_0`: プロモ0 - `promo_1`: プロモ1 - `demand`: 販売数 今後30日間の予測を行い、結果をグラフで表示して `data/demand_forecast.csv` に保存 してください。
  21. MOAI-Forecast を使用して、指定された cust (顧客ID)と prod (商品ID)の組み合わせごとの需要 (demand)を対象に、今後30日間の予測を実行いたしました。 実行内容と結果 商品と顧客の組み合わせを一意の item_id

    として統合したうえで、時系列データとして処理しました。 モデリングのトレーニングが完了し、30日先までの予測結果データ(平均値および予測区間 10%〜90% などの 数値データ)はご指定通り usage/data/demand_forecast.csv に保存されています。 過去の需要推移と今後の予測範囲を重ね合わせたグラフが作成され、usage/data/forecast_plot.png に出力さ れました。 結果 (Gemini 3.1 Pro)
  22. サプライチェーンネットワーク最適化 description: SCML Optimization Agent Skill for initializing and optimizing

    Pydantic-based supply chain models via scml # SCML Optimization Skill This skill enables the Agent to run supply chain network optimizations based on the `scml` library structure. It constructs mathematical optimization models (LP/MIP) from a Pydantic-based JSON schema and solves them using the CBC solver.
  23. 以下のCSVファイルに記述されたデータを使用して、一般物流ネットワーク設計最適化モデル (General Logistics Network Design Problem) を構築し、解いてください。 - 供給者データ: `usage/data_general_lndp/suppliers.csv`

    (拠点, 製品, 供給量) - 生産データ: `usage/data_general_lndp/production.csv` (工場, 製品, 構成部品, ライン, 固定費用, 単位生 産コスト, 容量) - 輸送データ: `usage/data_general_lndp/transportation.csv` (始点, 終点, 製品, モード, 固定費用, 単位輸 送コスト, 容量) - 顧客データ: `usage/data_general_lndp/customers.csv` (拠点, 製品, 需要量) 各工場では複数の製品を生産でき、各製品には構成部品(BOM)が定義されています。生産ラインや輸送 ルートにはそれぞれ固定費用と容量制限があります。 すべての顧客需要を最小の総コスト(固定費 + 生産費 + 輸送費)で充足するような、最適な調達・生産・ 配送計画を立ててください。 最適化が完了したら、稼働させる生産ライン、使用する輸送ルート、および各拠点の在庫バランスを Markdownの表形式で表示してください。 入力例 plant,product,components,line,fixed_cost,variable_cost,capacity plant,juice1,"apple:2,melon:1,bottle:1",line1,50.0,10.0,100 plant,juice1,"apple:2,melon:1,bottle:1",line2,100.0,5.0,100 plant,juice2,"apple:2,melon:2,bottle:1",line1,50.0,10.0,100 plant,juice2,"apple:2,melon:2,bottle:1",line2,100.0,5.0,100 production.csv
  24. ③ 各拠点の在庫フローバランス 工場(plant)視点で入庫・消費(生産)・出荷される素材をまとめると、 下記のように調達した原料を過不足なくそのまま作り切る「ジャスト インタイム」にて在庫ゼロを達成しています。 ご指定いただいた4つのCSVデータすべてを読み込み、SCML(Supply Chain Modeling Language)を用いて一般物流ネットワーク設計最適化モ デル(GLNDP)を構築・求解しました。

    結果として、総コスト「630.0」 ですべての需要を最小費用で満たす最適 なサプライチェーンネットワークが算出されました。 要件で求められていた各計画は以下の通りです: ① 稼働させる生産ライン 需要(juice1: 10, juice2: 10)を満たすため、工場(plant)の生産ライン を稼働させます。 ※ 計算上、line1とline2で費用が同一直線上に並んでい ましたが、ソルバーは最終的に line2 を採用しました。 工場 生産製品 稼働ライン 生産量 plant juice1 line2 10.0 plant juice2 line2 10.0 ② 使用する輸送ルート 各BOM(部品構成表)を満たすために必要な原料は「apple: 40、melon: 30、bottle: 20」となり、それぞれ最も安価で無駄のないルートが選択さ れました。 始点 (source) 終点 (sink) 対象製品 輸送モード 輸送量 source1 plant apple vehicle 40.0 source1 plant melon vehicle 30.0 source2 plant bottle ship 20.0 plant customer juice1 ship 10.0 plant customer juice2 ship 10.0 拠点 製品名 入庫 (In) 生産消費・出荷 (Out) 差異 (在庫) plant apple 40.0 (source1から) 40.0 (BOMとして消費) 0.0 plant melon 30.0 (source1から) 30.0 (BOMとして消費) 0.0 plant bottle 20.0 (source2から) 20.0 (BOMとして消費) 0.0 plant juice1 10.0 (生産によって生成) 10.0 (customerへ出荷) 0.0 plant juice2 10.0 (生産によって生成) 10.0 (customerへ出荷) 0.0 結果 (Gemini 3.1 Pro)