Strands AgentsのビルトインツールでAgentCore Code Interpreterに明示的にファイルを渡す・取り出す

Strands AgentsのビルトインツールでAgentCore Code Interpreterに明示的にファイルを渡す・取り出す

2026.01.07

はじめに

こんにちは、スーパーマーケットが大好きなコンサルティング部の神野です。

先日、下記の記事でStrands AgentsのCode Interpreterビルトインツールについて紹介しました。

https://dev.classmethod.jp/articles/strands-agents-builtin-tools-code-interpreter/

この記事を書いた後、ふとCode Interpreterにファイルを明示的に渡してコードを実行したい場合はどうするんだろう・・・?と気になりました。

エージェント任せでコードを作成および実行するのは便利ですが、例えば事前にCSVファイルをサンドボックスに配置してから分析させたいケースもありますよね。

下記公式ドキュメントの例のように CodeInterpreter を直接使う方法であれば、下記のようにファイルを明示的に書き込めました。

https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/code-interpreter-file-operations.html

以前のコード例
from bedrock_agentcore.tools.code_interpreter_client import CodeInterpreter

code_client = CodeInterpreter('us-east-1')
code_client.start()

# ファイルを明示的に書き込む
files_to_create = [
    {"path": "data.csv", "text": data_content},
    {"path": "stats.py", "text": stats_content}
]
code_client.invoke("writeFiles", {"content": files_to_create})

# コードを実行
code_client.invoke("executeCode", {"code": "exec(open('stats.py').read())", "language": "python"})

今回はStrands Agentsのビルトインツールである AgentCoreCodeInterpreter でも同じように実装できるのか気になったので調べてみました。

結論

AgentCoreCodeInterpreter には write_files() メソッドが用意されており、明示的にファイルを書き込むことができます。

ファイルを明示的に書き込む例
from strands_tools.code_interpreter import AgentCoreCodeInterpreter
from strands_tools.code_interpreter.models import WriteFilesAction, FileContent

code_interpreter = AgentCoreCodeInterpreter(region="us-west-2")

# 明示的にファイルを書き込む
code_interpreter.write_files(WriteFilesAction(
    type="writeFiles",  # 必須フィールド
    content=[
        FileContent(path="data.csv", text=data_content),
        FileContent(path="stats.py", text=stats_content)
    ]
))

これでエージェント任せにせず、事前にファイルをサンドボックスに配置できます。
今回はツールの詳細を確認していきます。

実装の詳細を見てみる

GitHubで確認してみます。

https://github.com/strands-agents/tools/blob/main/src/strands_tools/code_interpreter/agent_core_code_interpreter.py

AgentCoreCodeInterpreterの操作メソッド

AgentCoreCodeInterpreter クラスにはファイル操作だけでなく、コード実行やコマンド実行のメソッドも用意されています。

メソッド 対応するPydanticモデル 説明
execute_code() ExecuteCodeAction コードを実行
execute_command() ExecuteCommandAction シェルコマンドを実行
write_files() WriteFilesAction サンドボックスにファイルを書き込む
read_files() ReadFilesAction サンドボックスからファイルを読み込む
list_files() ListFilesAction ディレクトリ内容を一覧表示
remove_files() RemoveFilesAction ファイルを削除

各メソッドを呼び出す際は、対応するPydanticモデルのインスタンスを引数として渡します。例えば write_files() を使う場合は WriteFilesAction を、execute_code() を使う場合は ExecuteCodeAction を渡す形ですね。

試してみる

前提

項目 バージョン
Python 3.12
strands-agents 1.20.0
strands-agents-tools 0.2.18

環境構築

uvを使ってプロジェクトをセットアップします。

プロジェクト作成
uv init
uv add strands-agents strands-agents-tools bedrock-agentcore bedrock-agentcore-starter-toolkit aws-opentelemetry-distro

後でAgentCoreへのデプロイも行うため、bedrock-agentcore、bedrock-agentcore-starter-toolkitやaws-opentelemetry-distroもインストールしておきます。

サンプルファイルの準備

まず、分析対象のCSVファイルdata.csvと分析スクリプトstats.pyを用意します。
このファイルをCode Interpreterに配置します。

data.csv
name,age,score,department
田中太郎,28,85,営業
佐藤花子,34,92,開発
鈴木一郎,25,78,マーケティング
高橋美咲,31,88,開発
伊藤健太,29,95,営業
渡辺真理,27,72,マーケティング
山本大輔,33,91,開発
中村愛,26,83,営業
小林拓也,30,87,開発
加藤由美,32,79,マーケティング
stats.py
import pandas as pd

# データ読み込み
df = pd.read_csv('data.csv')

print("=== データ分析結果 ===\n")

# 基本統計
print("【基本統計】")
print(f"データ件数: {len(df)}件")
print(f"平均年齢: {df['age'].mean():.1f}歳")
print(f"平均スコア: {df['score'].mean():.1f}点")

# 部署別集計
print("\n【部署別平均スコア】")
dept_stats = df.groupby('department')['score'].agg(['mean', 'count'])
for dept, row in dept_stats.iterrows():
    print(f"  {dept}: {row['mean']:.1f}点 ({int(row['count'])}名)")

# 最高スコア
top = df.loc[df['score'].idxmax()]
print(f"\n【最高スコア】")
print(f"  {top['name']} ({top['department']}): {top['score']}点")

実装

ファイルを明示的に書き込んでから、エージェントにコード実行だけを任せる実装です。

test_file_upload.py
from strands import Agent
from strands.models import BedrockModel
from strands_tools.code_interpreter import AgentCoreCodeInterpreter
from strands_tools.code_interpreter.models import WriteFilesAction, FileContent

# モデル設定
model = BedrockModel(
    model_id="us.anthropic.claude-sonnet-4-5-20250929-v1:0",
    region_name="us-west-2"
)

code_interpreter = AgentCoreCodeInterpreter(region="us-west-2")

# ローカルファイルを読み込み
with open("data.csv", "r") as f:
    data_content = f.read()
with open("stats.py", "r") as f:
    stats_content = f.read()

print("=== ファイル内容確認 ===")
print(f"data.csv: {len(data_content)} bytes")
print(f"stats.py: {len(stats_content)} bytes")

# 明示的にファイルを書き込む(エージェント任せにしない)
print("\n=== サンドボックスにファイル書き込み中... ===")
result = code_interpreter.write_files(WriteFilesAction(
    type="writeFiles",  # 必須フィールド
    content=[
        FileContent(path="data.csv", text=data_content),
        FileContent(path="stats.py", text=stats_content)
    ]
))
print(f"書き込み結果: {result}")

# エージェントはexecuteCodeだけ使う
print("\n=== エージェント実行 ===")
agent = Agent(
    model=model,
    tools=[code_interpreter.code_interpreter],
    system_prompt="Code Interpreterには既にdata.csvとstats.pyがあります。executeCodeでコードを実行してください。"
)

response = agent("stats.pyを実行して結果を教えて")
print(f"\n=== 結果 ===")
print(response)

WriteFilesAction には type="writeFiles" を必ず指定し、FileContent でパスとテキスト内容を指定します。write_files() でエージェント実行前にファイルを配置しておき、システムプロンプトでファイルが既に存在することをエージェントに伝えています。

実行

実行コマンド
uv run test_file_upload.py
実行結果
=== ファイル内容確認 ===
data.csv: 180 bytes
stats.py: 559 bytes

=== サンドボックスにファイル書き込み中... ===
書き込み結果: {'status': 'success', 'content': [{'text': "[{'type': 'text', 'text': 'Successfully wrote all 2 files'}]"}]}

=== エージェント実行 ===
stats.pyを実行します。
Tool #1: code_interpreter
stats.pyを実行しました。結果は以下の通りです:

## データ分析結果

**【基本統計】**
- データ件数: 10件
- 平均年齢: 29.5歳
- 平均スコア: 85.0点

**【部署別平均スコア】**
- マーケティング: 76.3(3)
- 営業: 87.7(3)
- 開発: 89.5(4)

**【最高スコア】**
- 伊藤健太 (営業): 95点

開発部門が最も高い平均スコア(89.5点)を記録しており、営業の伊藤健太さんが最高スコアの95点を獲得しています。

ファイルが正常に書き込まれ、エージェントがそのファイルを使ってコードを実行できていますね!
Code Interpreterのファイルを読み込む機能にも注目してみます。

ReadFilesActionでサンドボックスからファイルを取り出す

ReadFilesAction はサンドボックス内のファイルを読み取るためのものです。
ローカルファイルを読むものではありません。

例えば、コード実行で生成されたCSVや画像ファイルを取り出したい場合に使用します。実際に試してみましょう。

サンドボックスでグラフを生成してファイルを取り出す

以下のコードで、サンドボックス内でグラフを生成し、生成されたファイルをローカルに取り出してみます。

test_read_files.py
from strands import Agent
from strands.models import BedrockModel
from strands_tools.code_interpreter import AgentCoreCodeInterpreter
from strands_tools.code_interpreter.models import (
    WriteFilesAction,
    FileContent,
    ReadFilesAction,
    ListFilesAction,
    ExecuteCodeAction,
)
import base64

# モデル設定
model = BedrockModel(
    model_id="us.anthropic.claude-sonnet-4-5-20250929-v1:0",
    region_name="us-west-2"
)

code_interpreter = AgentCoreCodeInterpreter(region="us-west-2")

# ローカルファイルを読み込み
with open("data.csv", "r") as f:
    data_content = f.read()

print("=== Step 1: サンドボックスにCSVファイルを書き込み ===")
result = code_interpreter.write_files(WriteFilesAction(
    type="writeFiles",
    content=[
        FileContent(path="data.csv", text=data_content),
    ]
))
print(f"書き込み結果: {result}")

print("\n=== Step 2: グラフを生成するコードを実行 ===")
chart_code = """
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib
matplotlib.use('Agg')  # GUIなしで描画

# データ読み込み
df = pd.read_csv('data.csv')

# 部署名を英語にマッピング
dept_mapping = {
    'マーケティング': 'Marketing',
    '営業': 'Sales',
    '開発': 'Development'
}
df['department_en'] = df['department'].map(dept_mapping)

# 部署別平均スコアを計算
dept_scores = df.groupby('department_en')['score'].mean().sort_values(ascending=True)

# グラフ作成
plt.figure(figsize=(10, 6))
bars = plt.barh(dept_scores.index, dept_scores.values, color=['#3498db', '#2ecc71', '#e74c3c'])

# 値をバーの横に表示
for bar, value in zip(bars, dept_scores.values):
    plt.text(value + 0.5, bar.get_y() + bar.get_height()/2, f'{value:.1f}',
             va='center', fontsize=12)

plt.xlabel('Average Score', fontsize=12)
plt.ylabel('Department', fontsize=12)
plt.title('Average Score by Department', fontsize=14, fontweight='bold')
plt.xlim(0, 100)
plt.tight_layout()

# 画像として保存
plt.savefig('chart.png', dpi=100, bbox_inches='tight')
plt.close()

print("chart.png generated")

# CSVレポートも生成
report = df.groupby('department').agg({
    'score': ['mean', 'min', 'max', 'count']
}).round(1)
report.columns = report.columns.droplevel(0)  # MultiIndexを解除
report = report.reset_index()  # departmentをカラムに
report.to_csv('report.csv', index=False)
print("report.csv generated")
"""

result = code_interpreter.execute_code(ExecuteCodeAction(
    type="executeCode",
    code=chart_code,
    language="python"
))
print(f"実行結果: {result}")

print("\n=== Step 3: サンドボックス内のファイル一覧を確認 ===")
result = code_interpreter.list_files(ListFilesAction(
    type="listFiles",
    path="."
))
print(f"ファイル一覧: {result}")

print("\n=== Step 4: 生成されたファイルを読み取り ===")
result = code_interpreter.read_files(ReadFilesAction(
    type="readFiles",
    paths=["report.csv", "chart.png"]
))
print(f"読み取り結果: {result}")

# 結果をパースしてローカルに保存
print("\n=== Step 5: ファイルをローカルに保存 ===")

# read_filesの結果をパース
import ast
content_str = result['content'][0]['text']
resources = ast.literal_eval(content_str)

for resource in resources:
    if resource['type'] == 'resource':
        res = resource['resource']
        uri = res['uri']
        mime_type = res['mimeType']
        filename = uri.split('/')[-1]

        print(f"\nファイル: {filename} (MIME: {mime_type})")

        if 'text' in res:
            # テキストファイルの場合
            with open(f"output_{filename}", "w") as f:
                f.write(res['text'])
            print(f"  → output_{filename} に保存しました")
            print(f"  内容プレビュー:\n{res['text'][:200]}")

        elif 'blob' in res:
            # バイナリファイルの場合
            blob_data = res['blob']
            with open(f"output_{filename}", "wb") as f:
                f.write(blob_data)
            print(f"  → output_{filename} に保存しました ({len(blob_data)} bytes)")

print("\n=== 完了 ===")

実行結果

コードが書けたので、実行してみます。

実行コマンド
uv run test_read_files.py
実行結果(クリックで展開)
=== Step 1: サンドボックスにCSVファイルを書き込み ===
書き込み結果: {'status': 'success', 'content': [{'text': "[{'type': 'text', 'text': 'Successfully wrote all 1 files'}]"}]}

=== Step 2: グラフを生成するコードを実行 ===
実行結果: {'status': 'success', 'content': [{'text': "[{'type': 'text', 'text': 'chart.png generated\\nreport.csv generated'}]"}]}

=== Step 3: サンドボックス内のファイル一覧を確認 ===
ファイル一覧: {'status': 'success', 'content': [{'text': "[{'type': 'resource_link', 'mimeType': 'image/png', 'uri': 'file:///chart.png', 'name': 'chart.png', 'description': 'File'}, {'type': 'resource_link', 'mimeType': 'text/csv', 'uri': 'file:///data.csv', 'name': 'data.csv', 'description': 'File'}, {'type': 'resource_link', 'mimeType': 'text/csv', 'uri': 'file:///report.csv', 'name': 'report.csv', 'description': 'File'}]"}]}

=== Step 4: 生成されたファイルを読み取り ===
読み取り結果: {'status': 'success', 'content': [{'text': '[{\'type\': \'resource\', \'resource\': {\'uri\': \'file:///report.csv\', \'mimeType\': \'text/csv\', \'text\': \'department,mean,min,max,count\\nマーケティング,76.3,72,79,3\\n営業,87.7,83,95,3\\n開発,89.5,87,92,4\\n\'}}, {\'type\': \'resource\', \'resource\': {\'uri\': \'file:///chart.png\', \'mimeType\': \'image/png\', \'blob\': b\'...(バイナリデータ省略)...\'}}]'}]}

=== Step 5: ファイルをローカルに保存 ===

ファイル: report.csv (MIME: text/csv)
  → output_report.csv に保存しました
  内容プレビュー:
department,mean,min,max,count
マーケティング,76.3,72,79,3
営業,87.7,83,95,3
開発,89.5,87,92,4

ファイル: chart.png (MIME: image/png)
  → output_chart.png に保存しました (25031 bytes)

=== 完了 ===

ポイントだけ解説していきます。

list_files() でサンドボックス内のファイル一覧を確認すると、生成されたファイルが確認できます。

ファイル一覧の結果
{'status': 'success', 'content': [{'text': "[
  {'type': 'resource_link', 'mimeType': 'image/png', 'uri': 'file:///chart.png', 'name': 'chart.png', 'description': 'File'},
  {'type': 'resource_link', 'mimeType': 'text/csv', 'uri': 'file:///data.csv', 'name': 'data.csv', 'description': 'File'},
  {'type': 'resource_link', 'mimeType': 'text/csv', 'uri': 'file:///report.csv', 'name': 'report.csv', 'description': 'File'}
]"}]}

read_files() で取得したファイルは、ファイル種別によって返却形式が異なります。

ファイル種別 返却形式
CSV (text/csv) text フィールドにテキストで返却
PNG (image/png) blob フィールドにバイナリで返却

ローカルにファイルを保存する

取得したファイルをローカルに保存するには、シンプルに返却形式に応じて処理を分けました。

ファイル保存処理
import ast

content_str = result['content'][0]['text']
resources = ast.literal_eval(content_str)

for resource in resources:
    if resource['type'] == 'resource':
        res = resource['resource']
        uri = res['uri']
        mime_type = res['mimeType']
        filename = uri.split('/')[-1]

        if 'text' in res:
            # テキストファイルの場合
            with open(f"output_{filename}", "w") as f:
                f.write(res['text'])

        elif 'blob' in res:
            # バイナリファイルの場合
            blob_data = res['blob']
            with open(f"output_{filename}", "wb") as f:
                f.write(blob_data)

これでサンドボックスで生成されたグラフ画像やCSVファイルをローカルに取り出すことができました!ちなみに取得した画像は下記のように生成されていました。バッチリ取り出せていますね。

CleanShot 2026-01-06 at 22.25.33@2x

また、CSVの内容は下記のようになっていました。

report.csv
department,mean,min,max,count
マーケティング,76.3,72,79,3
営業,87.7,83,95,3
開発,89.5,87,92,4

部署別の統計情報が実行結果として取得できていますね!

エージェントに自律的な分析を任せる

ここまでは 事前に用意したコードを実行する例を見てきました。
今までの実装は全然Agentらしくなく単純にCode Interpreterでコードを実行しているだけなので、曖昧な指示を与えてツールをどう使うか単純に気になったのでみてみます。

実際にAgentCoreにデプロイしてトレースを確認してみます!

実装

test_agent_analysis.py
from bedrock_agentcore.runtime import BedrockAgentCoreApp
from strands import Agent
from strands.models import BedrockModel
from strands_tools.code_interpreter import AgentCoreCodeInterpreter
from strands_tools.code_interpreter.models import WriteFilesAction, FileContent

app = BedrockAgentCoreApp()

# 分析対象のサンプルデータ
SAMPLE_DATA = """name,age,score,department
田中太郎,28,85,営業
佐藤花子,34,92,開発
鈴木一郎,25,78,マーケティング
高橋美咲,31,88,開発
伊藤健太,29,95,営業
渡辺真理,27,72,マーケティング
山本大輔,33,91,開発
中村愛,26,83,営業
小林拓也,30,87,開発
加藤由美,32,79,マーケティング"""

@app.entrypoint
def main(payload):
    model = BedrockModel(
        model_id="us.anthropic.claude-sonnet-4-5-20250929-v1:0",
        region_name="us-west-2"
    )

    code_interpreter = AgentCoreCodeInterpreter(region="us-west-2")

    # サンドボックスにCSVファイルを書き込む
    code_interpreter.write_files(WriteFilesAction(
        type="writeFiles",
        content=[FileContent(path="data.csv", text=SAMPLE_DATA)]
    ))

    # エージェントに曖昧な指示を出す
    agent = Agent(
        model=model,
        tools=[code_interpreter.code_interpreter],
        system_prompt="あなたはデータアナリストです。Code Interpreterにはdata.csvがあります。ユーザーの質問に対して、自分でコードを書いて分析してください。"
    )

    # 曖昧な指示:エージェントが自分で判断して分析
    response = agent("data.csvを分析して、興味深い洞察を3つ教えてください")
    return response

if __name__ == "__main__":
    app.run()

興味深い洞察を3つ教えてという曖昧な指示を与えます。
システムプロンプトには自分でコードを書いて分析してください。と指示しているのでどういったコードを書いて分析をするのか確認してみます。

AgentCore Runtimeへデプロイ

まずはconfigureコマンドで設定を行います。
対話形式で進めていきますが基本自動作成で、Direct Code Deployで展開することにします。

uv run agentcore configure --entrypoint test_agent_analysis.py
# 基本自動作成の選択肢を選ぶ、Direct Code Deployを選択

設定が完了したら、launchコマンドでAgentCore Runtimeへデプロイします。

デプロイコマンド
uv run agentcore launch 

デプロイが完了したら、エージェントを実行します。

実行コマンド
uv run agentcore invoke '{"prompt": ""}'

Response:
data.csvを分析した結果、以下の**3つの興味深い洞察**が見つかりました:

## 📊 洞察1: 開発部署が圧倒的に優秀かつ安定している
- **開発部署の平均スコア**: 89.5点(全部署中トップ)
- **スコアの安定性**: 標準偏差わずか2.38で、最も一貫したパフォーマンス
- 開発部署は4人中全員が87点以上を取得しており、チーム全体として高い水準を維持

一方、マーケティング部署は平均76.3点と約13点も低く、最も改善の余地があります。

## 📈 洞察2: 年齢とスコアに中程度の正の相関(0.562)がある
- **若手(~27歳)**: 平均77.7点
- **中堅(28-30歳)**: 平均89.0点(最も高い!)
- **ベテラン(31歳~)**: 平均87.5点

意外にも、**28-30歳の中堅層が最も高いパフォーマンス**を示しています。これは経験と活力のバランスが取れた年齢層であることを示唆して
おり、単純な「年齢が高いほど良い」という関係ではないことが分かります。

## 🏆 洞察3: トップパフォーマーは年齢が高く、開発部署に集中
- **上位30%(3人)の特徴**:
  - 平均年齢: 32.0歳(全体平均29.5歳より高い)
  - 平均スコア: 92.7点
  - **部署分布**: 開発2人、営業1人(マーケティング0人)

トップパフォーマーの2/3が開発部署に所属しており、開発部署が優秀人材を集めているか、育成環境が優れている可能性があります。マーケティング部署からはトップパフォーマーが1人も出ていない点は要注意です。

実行結果が返却されました!どういったコードを実行して分析したのか確認してみます。

トレースを確認

CleanShot 2026-01-07 at 07.56.05@2x

おお、雑な指示だったからかスパンの数も多いですね。簡単にどんな処理を行ったのかを確認してみます。

トレースを確認すると、エージェントの動作の流れがよくわかります。実際のトレースから抜粋してみていきます。

まず、エージェントは最初にseabornを含むコードを実行しようとしました。

Event 3: gen_ai.choice (body)
"code": "import pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport seaborn as sns\n\n# データの読み込み\ndf = pd.read_csv('data.csv')\n..."

ですがサンドボックス環境にseabornがインストールされていなかったためエラーが発生しています。
この辺りは提供されているライブラリなどシステムプロンプトに教えてあげるとスムーズかもしれませんね。

Event 7: gen_ai.tool.message (body)
"ModuleNotFoundError: No module named 'seaborn'"

エージェントはこのエラーを受けて、seabornを除外したコードに自動的に修正して再実行しました。

Event 9: gen_ai.choice (body)
"code": "import pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\n\n# データの読み込み\ndf = pd.read_csv('data.csv')\n\n# 基本情報の確認\nprint('データの形状:', df.shape)\nprint('\n最初の数行:')\nprint(df.head(10))\n..."

実行結果として、データの基本情報が返されています。

Event 16: gen_ai.tool.message (body)
データの形状: (10, 4)

最初の数行:
   name  age  score department
0  田中太郎   28     85         営業
1  佐藤花子   34     92         開発
...

基本統計量:
            age      score
mean   29.50000  85.000000
std     3.02765   7.118052

データの構造を把握した後、エージェントは3つの洞察を導き出すための分析コードを自分で作成して実行しています。

Event 18: gen_ai.choice (body)
"code": "# 洞察1: 部署別の分析\ndept_score = df.groupby('department')['score'].agg(['mean', 'count'])\n\n# 洞察2: 年齢とスコアの関係\ncorrelation = df['age'].corr(df['score'])\ndf['age_group'] = pd.cut(df['age'], bins=[0, 27, 30, 35], labels=['若手(~27歳)', '中堅(28-30歳)', 'ベテラン(31歳~)'])\n\n# 洞察3: トップパフォーマー分析\ntop_threshold = df['score'].quantile(0.7)\n..."

実行結果として、各洞察の分析結果が返されています。

Event 28: gen_ai.tool.message (body)
=== 洞察1: 部署別パフォーマンス分析 ===
部署別の平均スコア:
                 mean  count
department                  
開発          89.500000      4
営業          87.666667      3
マーケティング     76.333333      3

=== 洞察2: 年齢とスコアの相関分析 ===
年齢とスコアの相関係数: 0.562
年齢層別の平均スコア:
若手(~27歳)    77.666667
中堅(28-30歳)  89.000000
ベテラン(31歳~)  87.500000

=== 洞察3: トップパフォーマー分析 ===
上位30%のスコア閾値: 88.9
トップパフォーマーの特徴:
人数: 3人
平均年齢: 32.0歳
平均スコア: 92.7点
部署別分布: 開発2人、営業1人

さらにエージェントは追加の詳細分析も自発的に実行しています。

Event 30: gen_ai.choice (body)
"code": "# さらに詳細な分析\nfor dept in df['department'].unique():\n    dept_data = df[df['department'] == dept]\n    print(f'  スコアの標準偏差: {dept_data[\"score\"].std():.2f}')\n..."
Event 43: gen_ai.tool.message (body)
=== 追加分析 ===
営業: スコアの標準偏差: 6.43
開発: スコアの標準偏差: 2.38
マーケティング: スコアの標準偏差: 3.79

最高スコア: 95点 - 伊藤健太 (営業, 29歳)
最低スコア: 72点 - 渡辺真理 (マーケティング, 27歳)

処理は全体で約41秒かかっていました。

Event 48: Invocation completed successfully (41.517s)

こういったプロセスを踏まえて最終的にエージェントは下記回答を作成したといった流れになります。
こうやって流れを追いかけてどういった行動をしたのかを見るのは面白いですね。期待した動きをしていなければプロンプトを見ながら適宜修正していく、またはEvaluationsで評価を見ながら直していくと動きがより良くなっていく感じがしますね。

今回は雑な指示を与えたので、エージェントの行動回数が多かった気がしますが、どういったアクションをとっていったらいいのかを明示的に指示することで効率的に動いてもらえると思います。

data.csvを分析した結果、以下の**3つの興味深い洞察**が見つかりました:

## 📊 洞察1: 開発部署が圧倒的に優秀かつ安定している
- **開発部署の平均スコア**: 89.5点(全部署中トップ)
- **スコアの安定性**: 標準偏差わずか2.38で、最も一貫したパフォーマンス
- 開発部署は4人中全員が87点以上を取得しており、チーム全体として高い水準を維持

一方、マーケティング部署は平均76.3点と約13点も低く、最も改善の余地があります。

## 📈 洞察2: 年齢とスコアに中程度の正の相関(0.562)がある
- **若手(~27歳)**: 平均77.7点
- **中堅(28-30歳)**: 平均89.0点(最も高い!)
- **ベテラン(31歳~)**: 平均87.5点

意外にも、**28-30歳の中堅層が最も高いパフォーマンス**を示しています。これは経験と活力のバランスが取れた年齢層であることを示唆して
おり、単純な「年齢が高いほど良い」という関係ではないことが分かります。

## 🏆 洞察3: トップパフォーマーは年齢が高く、開発部署に集中
- **上位30%(3人)の特徴**:
  - 平均年齢: 32.0歳(全体平均29.5歳より高い)
  - 平均スコア: 92.7点
  - **部署分布**: 開発2人、営業1人(マーケティング0人)

トップパフォーマーの2/3が開発部署に所属しており、開発部署が優秀人材を集めているか、育成環境が優れている可能性があります。マーケティング部署からはトップパフォーマーが1人も出ていない点は要注意です。

おわりに

決まったファイルを確実に実行したい場合は write_files()read_files() メソッドを使って明示的にファイル操作する方法がビルトインツールでも可能です。必要に応じて活用していきたいですね!

本記事が少しでも参考になりましたら幸いです。最後までご覧いただきありがとうございましたー!

この記事をシェアする

FacebookHatena blogX

関連記事