Amazon Bedrock エージェントに搭載されている Code Interpreter を試してみた

記事タイトルとURLをコピーする

みなさんこんにちは。マネージドサービス部MSS課の塩野(正)です。

7/10~7/11にかけてAWS Summit New Yorkが開催されており、色々とアップデートが飛んできていているようです。

aws.amazon.com

先月東京で開催されたAWS Summit Tokyoでもかなり生成AIのアップデートが多く発表されており、awsとして生成AIの領域に力を入れている印象ですが、 AWS Summit New Yorkでも同様に生成AIが話題となっています。

そんな中で一つ気になったものを今回取り上げてみたいと思います。

aws.amazon.com

Code interpretation allows agents to dynamically generate and execute code snippets within a secure sandboxed environment, extending the capabilities of Agents for complex use cases such as data analysis, data visualization, and optimization problems.

コード解釈により、エージェントは安全なサンドボックス環境内で動的にコードスニペットを生成し実行することができ、データ分析、データ可視化、最適化問題などの複雑なユースケース向けにエージェントの機能を拡張することができます。

アップデートの内容は上記の通りですが、アップデート分の引用を見ると「サンドボックスの中でコードを動的に生成し、実行するよ」という機能になります。 似たような機能をもつものとして、オープンソースのOpen Interpreterが近いものになりますが、下記ブログは過去にOpen Interpreterを試した時のブログになります。

Open Interpreterを使うと、指示した内容についてコード生成してくれて、生成してくれたコードを実行して、問題があればコードを修正してくれるという一連の処理を1回の会話で完結してくれるというツールです。この部分だけ聞いていると、めっちゃ便利なように聞こえますね。もちろんOpen Interpreterといったツールを使用しても生成したコードはそのまま100点満点の状態で仕上がる訳ではありませんが、ある程度の状態に持っていくことはできますのでそこから最後の仕上げに別のツールを駆使しながら開発を進めることで開発効率を上げることができるという、そんな世界観をもつツールのAmazon Bedrock版がプレビューでリリースされたというのは個人的にかなり衝撃的でした。

blog.serverworks.co.jp

じゃ、さっそく味見をしてみましょう♪

Amazon Bedrockのエージェント機能について

まず、大前提としてCode interpreterはAmazon Bedrockのエージェント機能の一部になります。

そのためAmazon Bedrockのエージェント機能を先に理解する必要がありますが、 このエージェントを使用するとユーザーに代わってタスクを自動的に処理したり、ユーザーに代わって質問に答えることができる機能になります。

docs.aws.amazon.com

つまり、ユーザーに代わって自動的に処理するタスクの一つとして、サンドボックスでコードを実行することができる機能がついたよというアップデートになります。

ざっくりとまとめると、下記のようなタスクの実行ができるということです。

  • 特定のタスクに対するユーザーの要求を理解し、タスクを実行できるコードを生成し、コードを実行し、コード実行の結果を提供する
  • データの分析、視覚化、評価を実行するためのコードを生成する
  • アップロードしたファイルから情報を抽出し、その情報を処理してユーザーのクエリに回答する

例えば、.csv などのデータファイルを解析してその内容を回答させるとか、csvやexcelに書かれた売り上げデータを計算させるとか、 ざっくりとした用途がこのあたりになりますが、これらを実行するために通常ならpythonなどでコードを作成してそのコードを実行してとなるところが そのコード生成をお手伝いしますよ!というのがAmazon BedrockエージェントのCode interpreter機能という風に解釈できます。

試してみた

エージェントの作成とCode interpreterの有効化

Code interpreterがAmazon Bedrockのエージェント機能になりますので、まずはBedrockのエージェントを作成するところから始めます。Amazon Bedrockの画面でエージェントのページを開き、エージェント作成をクリックします。

名前は何でもよいのですが、ここではagent-test01と名前をつけました。

次にエージェントの設定になります。基本的にそのままで問題はありませんが、LLMのモデルによって性能がことなりますので、 ここではデフォルトで選択されているClaude V2.1ではなくClaude 3 Sonnetを選択しました。

次にエージェント向けの指示をします。 今回は検証が目的のため、この後の工程でエラーが出ないよう簡単な指示内容を記載します。

Additional settingsの中にCode Interpreter Preview の項目があり、標準ではdisableにチェックが入っています。 今回はCode Interpreterの機能検証になりますので、Code Interpreterの機能を有効化します。

本番利用を想定する場合はもっと詳細なエージェント向けの指示やらガードレールやら色々チューニングが必要になりますが、 今回は挙動を確かめるための検証になりますので、設定はこれくらいにして設定の保存を行います。

設定を保存すると「エージェントが最新の変更をテストできるように準備します。」と表示されます。 ここは何も考えずに準備をクリックしてください。ちなみに準備をクリックしなかった場合、Code Interpreterは正常に動作しませんでした。

それでは実際にコードが生成されるかどうか試してみましょう。 今回はプログラムがサンドボックス環境で動作するかどうかという点の確認になりますので、なるべく簡単なプロンプトを意図的に使用しています。

出力結果によると、print("hello world") というコードを実行すると、"hello world"と出力されるとのことです。 内容的に違和感はありませんが、回答内容は現時点で違和感しかありません(笑)

どうやらトレース情報が見れるようですので、トレースを見てみましょう。

今回の処理は3つのステップで実行されたようです。順番に見てみましょう。

トレース ステップ 1

どうやらこちらが設定した内容以上に色々とバックエンドでプロンプトの指示が入っているようですね。

rationaleの内容を見る限り、いくつかのステップに分けて処理をするというタスクがつみあげられているように見えます。 少し細かく見てみましょう。

この質問に対応するには、以下の手順が必要だと思います

1. Pythonコードを書いてhello worldを出力する
2. そのコードを実行して動作を確認する
3. 実行結果をユーザーに報告する

まずはPythonコードを書く必要があります。

上記のタスクをエージェントが細かく処理しているように見えますね。

<上記省略>

[{\"content\":\"pythonでhello worldと表示するコードを作成して、動作確認をしてください\",\"role\":\"user\"}]}",
    "traceId": "189a556d-12fc-4c6b-af59-e5fc9958a4cd-0",
    "type": "ORCHESTRATION"
  },
  "rationale": {
    "text": "この質問に対応するには、以下の手順が必要だと思います:\n\n1. Pythonコードを書いてhello worldを出力する\n2. そのコードを実行して動作を確認する\n3. 実行結果をユーザーに報告する\n\nまずはPythonコードを書く必要があります。",
    "traceId": "189a556d-12fc-4c6b-af59-e5fc9958a4cd-0"
  }
}

トレース ステップ 2

パッと見はトレース ステップ 1 と同じように見えますね(笑)
では中身の方も見てみましょう。

まず、コードは<code>print(\\\"hello world\\\")</code>の部分を見る限り動くかどうかは別にして生成されていそうです。
次に目についたのがstdoutの項に記載してある「406: The function call format is incorrect.」の部分で、どうやらファンクション呼び出しのフォーマットに問題ありそうなエラーが出ていました。

<上記省略>

3. 実行結果をユーザーに報告するまずはPythonコードを書く必要があります。</thinking><function_calls><invoke>    <tool_name>python_repl</tool_name>    <parameters>        <code>print(\\\"hello world\\\")</code>    </parameters></function_calls>\",\"role\":\"assistant\"},{\"content\":\"<function_results><error><tool_name><invoke>    <tool_name>python_repl</tool_name>    <parameters>        <code>print(\\\"hello world\\\")</code>    </parameters></tool_name><stdout>406: The function call format is incorrect. The format for function calls must be: <invoke> <tool_name>$TOOL_NAME</tool_name> <parameters> <$PARAMETER_NAME>$PARAMETER_VALUE</$PARAMETER_NAME>...</parameters></invoke>.</stdout></error></function_results>\",\"role\":\"user\"}]}",
    "traceId": "189a556d-12fc-4c6b-af59-e5fc9958a4cd-1",
    "type": "ORCHESTRATION"
  },
  "rationale": {
    "text": "申し訳ありません。関数呼び出しの形式が正しくありませんでした。もう一度試してみます。",
    "traceId": "189a556d-12fc-4c6b-af59-e5fc9958a4cd-1"
  }
}

トレース ステップ 3

前回と同じというか、おそらくこの部分の表示はこういう仕様なのでしょう。
肝心のトレースの中身の方も見てみましょう。

結局、うまく動作できずに「このコード試したら動くんじゃね?知らんけどw」という回答になっているようでした。(おいおい・・・

<上記省略>

3. 実行結果をユーザーに報告するまずはPythonコードを書く必要があります。</thinking><function_calls><invoke>    <tool_name>python_repl</tool_name>    <parameters>        <code>print(\\\"hello world\\\")</code>    </parameters></function_calls>\",\"role\":\"assistant\"},{\"content\":\"<function_results><error><tool_name><invoke>    <tool_name>python_repl</tool_name>    <parameters>        <code>print(\\\"hello world\\\")</code>    </parameters></tool_name><stdout>406: The function call format is incorrect. The format for function calls must be: <invoke> <tool_name>$TOOL_NAME</tool_name> <parameters> <$PARAMETER_NAME>$PARAMETER_VALUE</$PARAMETER_NAME>...</parameters></invoke>.</stdout></error></function_results>\",\"role\":\"user\"},{\"content\":\"<thinking>申し訳ありません。関数呼び出しの形式が正しくありませんでした。もう一度試してみます。</thinking><function_calls><invoke>    <tool_name>python_repl</tool_name>    <parameters>        <code>print(\\\"hello world\\\")</code>    </parameters></function_calls>\",\"role\":\"assistant\"},{\"content\":\"<function_results><error><tool_name><invoke>    <tool_name>python_repl</tool_name>    <parameters>        <code>print(\\\"hello world\\\")</code>    </parameters></tool_name><stdout>406: The function call format is incorrect. The format for function calls must be: <invoke> <tool_name>$TOOL_NAME</tool_name> <parameters> <$PARAMETER_NAME>$PARAMETER_VALUE</$PARAMETER_NAME>...</parameters></invoke>.</stdout></error></function_results>\",\"role\":\"user\"}]}",
    "traceId": "189a556d-12fc-4c6b-af59-e5fc9958a4cd-2",
    "type": "ORCHESTRATION"
  },
  "rationale": {
    "text": "申し訳ありません。関数呼び出しの形式が正しくないようです。この問題に対応するには、別の方法を試す必要があります。",
    "traceId": "189a556d-12fc-4c6b-af59-e5fc9958a4cd-2"
  },
  "observation": {
    "finalResponse": {
      "text": "pythonでhello worldと表示するコードは以下の通りです:\n\nprint(\"hello world\")\n\nこのコードを実行すると、\"hello world\"と出力されます。"
    },
    "traceId": "189a556d-12fc-4c6b-af59-e5fc9958a4cd-2",
    "type": "FINISH"
  }
}

おまけ

今回は失敗でしたがさすがにこれではブログを閉められないので、うまくいったパターンも紹介しておきます。

[{\"content\":\"pythonでhello worldと表示するコードを作成して、動作確認をしてください\",\"role\":\"user\"},{\"content\":\"<thinking>この質問に対して、以下の手順で対応します:1. Pythonコードを作成する2. get::codeinterpreteraction::executeツールを使ってコードを実行する3. 実行結果を確認する4. 最終的な回答をまとめる</thinking><function_calls><invoke><tool_name>get::codeinterpreteraction::execute</tool_name><parameters><code>print(\\\"hello world\\\")</code></parameters></invoke></function_calls>\",\"role\":\"assistant\"},{\"content\":\"<function_results><result><tool_name>get::codeinterpreteraction::execute</tool_name><stdout>'code_execution_output': hello world\\,\\'is_error': False,\\'is_timeout': False,\\'generated_files': []</stdout></result></function_results>\",\"role\":\"user\"}]}",
    "traceId": "3b5159b2-d492-451f-9d59-fd9c5ac25775-1",
    "type": "ORCHESTRATION"
  },
  "rationale": {
    "text": "コードが正しく実行され、\"hello world\"と出力されました。これで質問に対する回答は完了です。",
    "traceId": "3b5159b2-d492-451f-9d59-fd9c5ac25775-1"
  },
  "observation": {
    "finalResponse": {
      "text": "以下のPythonコードを実行すると、\"hello world\"と表示されます:\n\nprint(\"hello world\")\n\n実際に実行してみると、期待通り\"hello world\"と出力されることを確認できました。"
    },
    "traceId": "3b5159b2-d492-451f-9d59-fd9c5ac25775-1",
    "type": "FINISH"
  }
}

下記はJSONを少し見やすく加工したものになりますが、code_execution_outputの後に「hello world」と表示されており、is_error や is_timeout が False になっていることを加味すると、 コードが実行されその出力が「hello world」だったということが客観的に確認できるのではないかと考えております。

<result>
  <tool_name>get::codeinterpreteraction::execute</tool_name>
  <stdout>
    'code_execution_output': hello world\\,\\
    'is_error': False,\\
    'is_timeout': False,\\
    'generated_files': []
  </stdout>
</result>

まとめ

まだまだプレビュー段階のため、ここからもっと安定してGAした時にはすごく使いやすくなっているといいなと期待しています。 また、今回はプレイグラウンドで実際にコードが実行されるかどうかという観点で試しただけですので、もっと使いやすい使い方がきっとあるのではないかと考えていますが、こうした自動コード生成がこれからどんどん進化してくるとプロダクト開発のスピードが上がって生産性向上につながるかもしれませんね。

◆ 塩野 正人
◆ マネージドサービス部 所属
◆ X(Twitter):@shioccii
◆ 過去記事はこちら

前職ではオンプレミスで仮想化基盤の構築や運用に従事。現在は運用部隊でNew Relicを使ってサービス改善に奮闘中。