この記事は何?
AWS Bedrock Agent CoreのCode Interpreterをlang chainのエージェントから実行させてみた際の個人メモです。
正確でない部分もあると思いますので、間違いがあればコメント等でご指摘いただけると幸いです。
(あと、記事投稿してみたかったのです。claude codeに結構書かせています。)
なぜ試してみたのか
最近仕事でAIエージェントを開発しはじめました。
AIに計算処理を実行させるために任意のpythonコードをセキュアに実行できる環境が必要になりまして、なにか使えるものがないか探しています。
今は langchain-sandbox を利用していますが一度のやりとりに4,5秒のオーバーヘッドがかかっています。本体の処理とあわせると応答に結構時間がかかっています。。。
この問題の解決のためなにか使えるものがないか探しているうちにCode Interpreterを見つけたので試してみた次第です。
AWS Bedrock Agent Core Code Interpreter とは
基本情報
AWS Bedrock Agent Core Code Interpreterは、AIエージェントがPythonコードを安全に実行できるマネージドサービスです。
詳細な仕様:
- 実行時間: デフォルト15分、最大8時間まで延長可能
- リソース: 2vCPU/8GB メモリ
- セッション: 非アクティブ15分で自動終了、最大8時間
- 同時実行: 500セッション/アカウント
- ファイル: セッション内保存可能(直接DLは不可)
公式ドキュメント:
実装したエージェントについて
検証用にLangChainを使ってシンプルなCLIエージェントを実装しました。
構成:
-
main.py
: エージェント本体とCLIインターフェース -
tools.py
: 各種ツール関数(Code Interpreter含む)
リポジトリ: https://github.com/example/test-langchain-agent
主な機能:
- 日本語対応CLI(prompt_toolkit使用)
- AWS Code InterpreterでのPython実行
- 天気情報取得(モック)
- 数式計算
- TODO管理
AWS Code InterpreterでのPython実行
以外は適当にtoolしてとclaude君にお願いしたら吐き出されたtool達。
AWS Code Interpreterについて
基本的な仕組み
Code Interpreterは以下のような流れで動作します:
- セッション開始
- Pythonコード実行リクエスト
- ストリーミングで結果を受信
- 標準出力を結果として取得
実行結果のパース方法
# ストリーミングレスポンスから結果を抽出
outputs = []
for event in response["stream"]:
if "result" not in event:
continue
result_data = event["result"]
if "structuredContent" in result_data:
structured = result_data["structuredContent"]
stdout = structured.get("stdout", "")
if stdout and stdout.strip():
outputs.append(stdout.strip())
return "\\n".join(outputs)
AWS側の設定
IAMの設定をしたくらいで、ほかは何もしていないです。
IAMポリシー:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"bedrock-agentcore:StartCodeInterpreterSession",
"bedrock-agentcore:StopCodeInterpreterSession",
"bedrock-agentcore:InvokeCodeInterpreter"
],
"Resource": [
"arn:aws:bedrock-agentcore:us-west-2:*:code-interpreter/*"
]
}
]
}
実際に試してみた①(簡単な計算)
まずは基本的な計算から試してみました。
👤 あなた: 5+6をpython実行して計算して
🤖 エージェント:
> Entering new AgentExecutor chain...
Invoking: `execute_python_code` with `{'code': 'print(5 + 6)'}`
responded: [{'text': 'Pythonを使用して5+6の計算を実行します。AWS Code Interpreterツールを利用して、この計算を行います。', 'type': 'text', 'index': 0}, {'id': 'toolu_018pGqifimk3qWUT7zXvNNVb', 'input': {}, 'name': 'execute_python_code', 'type': 'tool_use', 'index': 1, 'partial_json': '{"code": "print(5 + 6)"}'}]
11
> Finished chain.
計算結果は11です。5と6を足し算すると、11になります。簡単な計算をPythonで実行してみました。他に何か計算や実行したいことはありますか?
動いていそう。応答速度も悪くない印象。
実行するとコンソール上でセッションが確認できる。
(何故かstatusやcreate timeなどのソートが機能してなかった。)
実際に試してみた②(そこそこのプログラム)
もう少し複雑なプログラムも試してみました。データ分析とグラフ作成を依頼してみます。
👤 あなた: 以下の処理をpythonで実行して:
1. numpyで100個の乱数を生成
2. pandasでDataFrameに変換
3. 統計情報を計算
4. matplotlibでヒストグラムを描画(説明のみ)
5. 結果をJSON形式で整理
🤖 エージェント:
> Entering new AgentExecutor chain...
Invoking: `execute_python_code` with `{'code': "import numpy as np\nimport pandas as pd\nimport json\n\n# 1. 100個の乱数を生成(標準正規分布から)\nrandom_numbers = np.random.randn(100)\n\n# 2. pandasのDataFrameに変換\ndf = pd.DataFrame(random_numbers, columns=['random_values'])\n\n# 3. 統計情報を計算\nstats = {\n 'mean': float(df['random_values'].mean()),\n 'median': float(df['random_values'].median()),\n 'std_dev': float(df['random_values'].std()),\n 'min': float(df['random_values'].min()),\n 'max': float(df['random_values'].max())\n}\n\n# 結果をJSONで出力\nprint(json.dumps(stats, indent=2))", 'description': '乱数生成、統計計算、JSON出力'}`
responded: [{'text': 'わかりました。Pythonで指定された処理を実行します。AWS Code Interpreterを使用して、numpy、pandas、matplotlibを使った処理を行います。', 'type': 'text', 'index': 0}, {'id': 'toolu_017dtjJKvQECpjbQraBQiUeS', 'input': {}, 'name': 'execute_python_code', 'type': 'tool_use', 'index': 1, 'partial_json': '{"code": "import numpy as np\\nimport pandas as pd\\nimport json\\n\\n# 1. 100個の乱数を生成(標準正規分布から)\\nrandom_numbers = np.random.randn(100)\\n\\n# 2. pandasのDataFrameに変換\\ndf = pd.DataFrame(random_numbers, columns=[\'random_values\'])\\n\\n# 3. 統計情報を計算\\nstats = {\\n \'mean\': float(df[\'random_values\'].mean()),\\n \'median\': float(df[\'random_values\'].median()),\\n \'std_dev\': float(df[\'random_values\'].std()),\\n \'min\': float(df[\'random_values\'].min()),\\n \'max\': float(df[\'random_values\'].max())\\n}\\n\\n# 結果をJSONで出力\\nprint(json.dumps(stats, indent=2))", "description": "乱数
生成、統計計算、JSON出力"}'}]
{
"mean": 0.04288713695716794,
"median": 0.23180287293885793,
"std_dev": 0.9862613135328473,
"min": -2.6967033174841593,
"max": 1.9745033725474803
}
Invoking: `execute_python_code` with `{'code': "import numpy as np\nimport matplotlib.pyplot as plt\n\n# 前回と同じ乱数を再生成\nrandom_numbers = np.random.randn(100)\n\n# ヒストグラムの描画\nplt.figure(figsize=(10, 6))\nplt.hist(random_numbers, bins=10, edgecolor='black')\nplt.title('Random Numbers Histogram')\nplt.xlabel('Value')\nplt.ylabel('Frequency')\nplt.savefig('histogram.png')\nplt.close()", 'description': 'ヒストグラムの描画と保存'}`
responded: [{'text': '統計情報の解説:\n- 平均値(mean): 約0.043\n- 中央値(median): 約0.232\n- 標準偏差(std_dev): 約0.986\n- 最小値(min): 約-2.697\n- 最大値(max): 約1.975\n\nmatplotlibでのヒストグラム描画については、コードを追加で実
行します。', 'type': 'text', 'index': 0}, {'id': 'toolu_01McBxMdMhvTF63DPxSNBiCA', 'input': {}, 'name': 'execute_python_code', 'type': 'tool_use', 'index': 1, 'partial_json': '{"code": "import numpy as np\\nimport matplotlib.pyplot as plt\\n\\n# 前回と同じ乱数を再生成\\nrandom_numbers = np.random.randn(100)\\n\\n# ヒストグラムの描画\\nplt.figure(figsize=(10, 6))\\nplt.hist(random_numbers, bins=10, edgecolor=\'black\')\\nplt.title(\'Random Numbers Histogram\')\\nplt.xlabel(\'Value\')\\nplt.ylabel(\'Frequency\')\\nplt.savefig(\'histogram.png\')\\nplt.close()", "description": "ヒストグラムの描画と保存"}'}]
実行完了(出力なし)[{'text': "ヒストグラムは 'histogram.png' として保存されました。通常、このファイルはデータ分析やレポート作成に使用されます。\n\nこの例では、numpy、pandas、matplotlibを使用して、乱数の生成、統計情報の計算、ヒストグラムの描
画を行いました。他に何か質問や実行したいことはありますか?", 'type': 'text', 'index': 0}]
> Finished chain.
ヒストグラムは 'histogram.png' として保存されました。通常、このファイルはデータ分析やレポート作成に使用されます。
この例では、numpy、pandas、matplotlibを使用して、乱数の生成、統計情報の計算、ヒストグラムの描画を行いました。他に何か質問や実行したいことはありますか?
こちらも問題なくできたようです。
気になるのはこれ: ヒストグラムは 'histogram.png' として保存されました。
ファイルも扱えるらしい。気になったのでこのあたりをもう少し試してみる。
実際に試してみた③(セッション内にファイルを保存)
上記で気になったので色々claudeにやらせた結果、以下の出力を得られた。
👤 あなた: "test.txt"というファイルに"Hello World"という内容を保存してから、ファイル一覧を表示して
🤖 エージェント:
> Entering new AgentExecutor chain...
Invoking: `save_file_to_code_interpreter` with `{'file_path': 'test.txt', 'content': 'Hello World'}`
responded: [{'text': 'わかりました。2つのステップで実行します:\n\n1. まず、"test.txt"に"Hello World"という内容を保存します。\n2. その後、ファイル一覧を表示します。\n\nそれでは、最初にフ
ァイルを保存します:', 'type': 'text', 'index': 0}, {'id': 'toolu_014cEQoG6pXrEdoWvQ4GX33e', 'input': {}, 'name': 'save_file_to_code_interpreter', 'type': 'tool_use', 'index': 1, 'partial_json': '{"file_path": "test.txt", "content": "Hello World"}'}]
✅ ファイル 'test.txt' を保存しました(サイズ: 11 bytes)
Invoking: `list_code_interpreter_files` with `{}`
responded: [{'text': '次に、ファイル一覧を表示します:', 'type': 'text', 'index': 0}, {'id': 'toolu_019GZf77BBZqE3kFVwNS4NWn', 'input': {}, 'name': 'list_code_interpreter_files', 'type': 'tool_use', 'index': 1, 'partial_json': ''}]
📁 Code Interpreterセッション内のファイル:
📁 .ipython/ (ディレクトリ)
📁 log/ (ディレクトリ)
📄 test.txt (11 bytes, 更新: 2025-08-16 00:45:27)[{'text': 'ご覧の通り、"test.txt"が正常に作成され、ファイル一覧に表示されています。ファイルのサイズは11バイト("Hello World"の文字数)で、
現在のセッションに保存されました。\n\n他に何かお手伝いできることはありますか?', 'type': 'text', 'index': 0}]
> Finished chain.
ご覧の通り、"test.txt"が正常に作成され、ファイル一覧に表示されています。ファイルのサイズは11バイト("Hello World"の文字数)で、現在のセッションに保存されました。
セッションにファイルを保存でき、あとからでもそれを見ることができるようだ。
ファイルダウンロード機能はないらしい。
公式ドキュメントによると、ファイルはセッション内でのみ利用可能で、セッション終了時にクリーンアップされる、とのこと。
必要に応じて、ファイル内容をテキストやBase64で出力として取得する方法が実用的のようだ。
感想・まとめ
良かった点
- AWSの設定はIAMのみ。リソース管理不要で楽。
- pandas、matplotlib、numpyなど主要ライブラリが最初から利用可能で良い
- 複雑な(?)プログラムもそのまま実行できた
- ファイルや変数がセッション内で保持される。何かに使えそう
課題・注意点
- セッション外への直接ダウンロード機能はない
- 長大な結果の場合はS3出力などの工夫が必要そう
- あまり使わないかもだがsession一覧が見づらい
(sessionの名前空間を自分で設定できるといいな。使用状況把握などに使いたい)
総合的な印象
langchain-sandboxの代替として十分検討できそう。
使えるならaws上の開発環境、本番環境に導入したい。
その他
あと、開発しているプロダクトではローカル開発環境があり、そこでも動作するようにしたい。
参考リンク: