やったこと
簡単な数理最適化問題を解くAIエージェントをClaude Agent SDKとAmazon Bedrock AgentCoreを使ってさくっと作成してみました。
問題は、数理最適化問題ベンチマークIndustryORから引用したものとなります。(以下の記事でも扱われた問題です。)
Claude Agent SDK とは
Anthropic提供のAIエージェント構築用のライブラリです。PythonとTypeScriptで利用できます。
概要について、公式ドキュメントでは、以下のように説明されています。
Agent SDK は、Claude Code を強化する同じツール、エージェントループ、およびコンテキスト管理を提供
要は、Claude Codeの仕組みをそのまま利用可能で、簡単に高性能のAIエージェントを構築することができます。
また、素のAnthropicのClaude APIの他、AWS、GCP、Azure経由でも利用可能で、お使いの環境に合わせた設定が可能です。(実際、この記事では、Amazon Bedrockを利用しています。)
詳しくは以下を参照ください。
数理最適化問題を解くAIエージェントを作る
FAST (Fullstack AgentCore Solution Template)
できるだけサクッと作るために、Amazon Bedrock AgentCoreのフルスタックテンプレートである「FAST」をベースとして作成しました。
FASTの構成図は下記の通りで、AgentCoreの各種サービスが一式揃っており環境構築の手間が少ないことが特徴です。この記事では、エージェントのメインの実行基盤としてRuntimeと、最適化計算用にCodeInterpreterを利用します。
また、以下のように最低限のUIも用意してくれており、チャットを通じて簡単にAIエージェントを呼び出すことができます。
環境構築やデプロイ方法については、上記リポジトリのREADMEに記載されています。また、日本語記事だと下記でも紹介されています。(非常にわかりやすかったです。)
ちなみに、「FAST」は Fullstack AgentCore Solution Template の略らしいです。その名の通りですね。
Claude Agent SDKによる数理最適化問題を解くAIエージェント
早速、Claude Agent SDKを利用し数理最適化問題を解くAIエージェントを作っていくのですが、実はFASTにはAIエージェントのテンプレートPythonコードがいくつか事前用意されており、その中にClaude Agent SDKを利用したテンプレートも含まれています。
具体的には以下の通りです。(ちなみに他にも、StrandsやLangGraphを利用した例の他、マルチエージェントの実装例もあります。)
タイトルにもある通りサクッと作りたいので、こちらをベースとして利用したいと思います。
具体的に作成したAIエージェントは、下記に格納しております。
といっても、テンプレートとの主な差分は、以下のシステムプロンプトのみとなります。(テンプレートが優秀でした・・・)
"""あなたは数理最適化の専門家です。
自然言語で与えられた最適化問題を以下の手順で解いてください:
1. 問題を分析する(決定変数・目的関数・制約条件を整理)
2. PuLP を使った Python コードを作成する
3. mcp__codeint__execute_code ツールでコードを実行する
4. 最適解を分かりやすく日本語で説明する
ルール:
- PuLP はインストール済み(import pulp で利用可能)
- コードインタープリターセッション: 最初の呼び出しでは code_int_session_id に空文字列 "" を渡すこと。ツールの返り値に含まれるセッションIDを、以降の呼び出しで必ず使い回すこと。セッションIDを自分で生成・推測してはならない
- 単位や整数変数or連続変数については注意深く確認すること
"""
ポイントとして、内部でAgentCore CodeInterpreterを呼び出すツール(mcp__codeint__execute_code)を使いPythonコードを生成するよう指示しています。これにより、AIエージェントのホスト環境から隔離された環境でコードを実行させることができるようになります。
Claude Agent SDKでは、create_sdk_mcp_serverによってインプロセスに動作するカスタムツールを定義可能であり、CodeInterpreterとの橋渡しにはこちらを利用しています。
その抜粋を以下に示します。こちらは、既にテンプレートに用意されているものです。
from typing import Any
from claude_agent_sdk import create_sdk_mcp_server, tool
from .client import CodeInterpreterClient
client = CodeInterpreterClient()
@tool(
"execute_code",
"Execute code using Code Interpreter.",
{"code": str, "language": str, "code_int_session_id": str},
)
async def execute_code(args: dict[str, Any]) -> dict[str, Any]:
result = client.execute_code(
args.get("code"),
args.get("language", "python"),
args.get("code_int_session_id", ""),
)
response_text = result.model_dump_json(indent=2)
return {"content": [{"type": "text", "text": response_text}]}
# -------------- 省略 --------------
code_int_mcp_server = create_sdk_mcp_server(
name="codeinterpretertools",
version="1.0.0",
tools=[execute_code, execute_command, write_files, read_files],
)
もう一つのポイントとして、プロンプトの中に数理最適化ライブラリである PuLPを明示的に使うよう促す文言を加えています。
そもそも数理最適化問題は、問題の定式化(モデリング)→アルゴリズムによる求解という手続きを踏むのですが、PuLPはまさにこの「定式化」の部分をPythonコードとして自然に表現できるライブラリです。また、アルゴリズムによる求解についても、CBCと呼ばれるソルバーが標準搭載1されています。よって、LLMにPuLPを使うよう指示することで、定式化を経て厳密な解を得るコードが生成されやすくなります。
CodeInterpreterには、様々なライブラリがプリインストールされていますが、そこにPuLPも含まれています。そのため、CodeInterpreterを利用することで、特に事前の環境設定なしで、AIエージェントにPuLPを使わせることができます。プリインストールされているライブラリについては、以下をご参照ください。
あとは、細かい他のポイントです。
- PuLPがインストール済みであることをプロンプトに明記しています。これにより、不要なインストール確認やインストール実行を防ぐようにしています
- コードインタープリター実行時に、存在しないセッションを探しにいってしまうことがあったので、それを防止するようなプロンプトを加えています
- 整数変数or連続変数や単位の解釈間違いが発生することがあったので、注意するようプロンプトに追記しています(これは問題文があいまいなことも理由ではありますが・・・)
- 余計なツールを使わないように、Agent SDKのオプションのパーミッションモードに
dontAskを指定しています- パーミッションモードについては以下をご参照ください
動作確認
デプロイをした後、チャットUIで動作確認をします。
使用する問題は、冒頭でも述べた通り、数理最適化問題のベンチマークであるIndustryORの3つ目の問題で、具体的には、純利益を最大化するような折りたたみテーブルの生産計画を求める問題となります。ベンチマークセットでは、正解として最適値も提供されており、この問題の最適値は10349920.0となっています。
UIから入力するプロンプトを以下に示します。AIエージェント側のプロンプトに必要事項は記載しているので、こちらは簡素となっています。
以下の問題を解いて
{ここに問題文を貼り付ける}
問題文の全訳(by Claude)はこちら
折りたたみテーブルを専門とするある企業が、総純利益を最大化するために、6ヶ月間(1月〜6月)の最適な生産・人員計画を策定する必要があります。この計画では、毎月の自社生産量、外注数量、および人員管理(採用・解雇)を詳細に定める必要があります。
初期条件(1月開始時点):
- 初期従業員数:1,000人
- 初期在庫:15,000台
収益とコスト構造:
- 販売価格:販売1台あたり300元
- 原材料費:自社生産の場合のみ、1台あたり90元
- 外注費:第三者サプライヤーから調達する完成品1台あたり200元(すべて込みのコスト)
- 在庫保管費:月末時点で保有する在庫1台あたり15元
- 受注残コスト:翌月に繰り越される未充足需要(品切れ)1台あたり35元
労働・生産パラメータ:
- 労働要件:自社生産1台あたり5労働時間が必要
- 通常労働:各従業員は月160時間の通常勤務時間(1日8時間×20日)を提供する。会社は完全に稼働しているかどうかにかかわらず、この160時間に対して1時間あたり30元の通常賃金を支払う。
- 時間外労働:従業員は残業することができる。全従業員の月間残業時間の合計は、従業員1人あたり20時間を超えることができない。残業賃金は1時間あたり40元。
- 人員管理:会社は毎月、従業員を採用または解雇することができる。新規採用コストは1人あたり5,000元、解雇コストは1人あたり8,000元。
需要と充足ロジック:
- ある月に充足されなかった需要は受注残として翌月以降に繰り越され、充足されなければならない。
- 会社は前月からの繰越在庫、当月の自社生産品、および外注品を使用して、注文(当月需要と受注残の両方)を充足する。
終端条件(6月末時点):
- 期末在庫は少なくとも10,000台以上でなければならない。
- 受注残はすべて解消されていなければならない(すなわち、期末受注残はゼロ)。
需要予測:
| 月 | 1月 | 2月 | 3月 | 4月 | 5月 | 6月 |
|---|---|---|---|---|---|---|
| 需要予測 | 20,000 | 40,000 | 42,000 | 35,000 | 19,000 | 18,500 |
以上の情報をもとに、最適な6ヶ月間の操業計画を策定せよ。
それでは、プロンプトを入力しAIエージェントを実行してみます。実行すると、まずは問題分析を行います。モデリングをするために必要な決定変数と目的関数を整理しています。
その後、定義したツールmcp__codeint__execute_codeを使って、コードを実行します。
2回ツールが呼び出されているので、詳細を確認してみます。タブを開いてみると、生成されたコードが確認できます。
確認すると1つ目がPuLPを使って最適化問題のモデリングと求解を、2回目が結果の整形を行っていることが分かります。また、1回目の実行ではcode_int_session_idが""であることに対し、2回目では空ではない値が指定されおり、セッションの指定も良しなにやってくれていることが分かります。
その後、結果が出力されます。正解である、最適値:10349920がしっかり求められており、また結果も見やすく整形してくれています。
まとめ
本記事では、簡単な数理最適化問題を解くAIエージェントをClaude Agent SDKとAmazon Bedrock AgentCoreを使ってさくっと作成し、実際に問題を解く様子を確認しました。
今回は比較的簡単な問題を扱ったので、シンプルな構成で実現できましたが、より難しい実務的な問題に対しては、非同期にしたり、RAGをしたり、S3経由でファイル入出力をさせたりなど、いくつかの工夫が必要になるかなと思います。(これも、AgentCore周りで実現できそうなのでいつか試してみて紹介します。)






