コルネの進捗や備忘録が記されたなにか

進捗や成果物や備忘録てきななにかを雑に更新していきます。

Power Apps や Copilot Studio のカスタム プロンプトでコードインタープリター機能を利用する


スポンサードリンク

はじめに

Power Apps や Copilot Studio の カスタム プロンプト(AI Builder)にて「コード インタープリターを有効化」する機能が追加されました。

こちらは現在 Preview 環境でのみ利用可能です。

Preview 環境は以下のように URL 内に"Preview"を付与することで試すことができます。

Power Apps
https://make.preview.powerapps.com/

Copilot Studio
https://copilotstudio.preview.microsoft.com/

Learn ではまだこの情報は多分公開されていないかな?と思いますが、こちらの公式 YouTube チャンネルにて機能が紹介されていましたので、併せてご確認していただけるといいと思います。

www.youtube.com

コード インタープリターを試す

コード インタープリターの有効化

Preview 環境でも設定を行わないと、以下のように

この環境またはテナントでコード インタープリターが無効化されています。管理者にお問い合わせください。

というメッセージが表示され利用できません。

この設定は、Power Platform 管理センターの
パイロット > 設定 > Copilot Studio > Copilot Studio でのコード生成と実行
より、この機能を有効化したい環境を選択することで設定することができます。

コードインタープリター機能を備えたカスタム プロンプトの作成

それではコードインタープリター機能を利用したカスタム プロンプトを作成していきます。

今回は Copilot Studio で作成していくことにします。

まずはプロンプトの作成を行いましょう。

設定を開いたら、コードインタープリターの有効化を行います。

これで準備は完了です。

あとは任意のプロンプトを記載します。

今回は渡されたデータより、インサイト情報の可視化を行うようなカスタム プロンプトの作成をしてみます。

指示の例

あなたのタスク:
{{分析対象のデータ}} より、 {{開始日時}} から {{終了日時}} までのデータを取得し、インサイト情報の可視化を行います。
グラフには日本語は利用せずに英語を利用するようにしてください。

グラフは画像として返却してください。

サンプルとしてテスト実行してみます。

テストとして、以下より日経平均株価のデータをお借りしました。

indexes.nikkei.co.jp

グラフがちゃんと作成されていますね!

「コード」を選択すると生成され実行された Python コードが確認できます。

import logging
from workerinterfaces import ExecutorInterface, ConnectorClient, ExecutionResult, read_file_from_input, write_file_to_output
from typing import Any, Dict
import pandas as pd
import io
import matplotlib.pyplot as plt
import matplotlib

class PromptExecutor(ExecutorInterface):
    async def execute(self, logger: logging.Logger, connector_client: ConnectorClient, input: Dict[str, Any]) -> ExecutionResult:
        logger.info("Starting execution for graph visualization with English labels")
        output = {"files": []}
        message_id = input.get("RequestId", "")
        StreamFileOutputs = input.get("StreamFileOutputs", False)

        data_input_id = "_5206_6790_5bfe_8c61_306e_30c7_30fc_30bf"
        start_input_id = "_958b_59cb_65e5_6642"
        end_input_id = "_7d42_4e86_65e5_6642"

        # Read the uploaded data as document
        file_result = read_file_from_input(input, message_id, data_input_id)

        if file_result is None:
            logger.error("No data file provided.")
            return ExecutionResult(400, {}, {"text": "No data file was provided.", "mimetype": "text/markdown"})

        # Try to read file as Excel (from BytesIO or from file if string path)
        try:
            if isinstance(file_result, io.BytesIO):
                df = pd.read_excel(file_result)
            elif isinstance(file_result, str):
                df = pd.read_excel(file_result)
            else:
                logger.error("Unsupported file input type.")
                return ExecutionResult(400, {}, {"text": "Unsupported file input type.", "mimetype": "text/markdown"})
        except Exception as e:
            logger.error("Failed to read Excel: %s", str(e))
            return ExecutionResult(400, {}, {"text": f"Failed to read Excel file: {str(e)}", "mimetype": "text/markdown"})

        logger.info("Excel file successfully loaded. Columns: %s", [str(c) for c in df.columns])

        # Start/end date extraction and parsing
        start_str = input.get(start_input_id)
        end_str = input.get(end_input_id)
        if not start_str or not end_str:
            logger.error("Start or end date not provided.")
            return ExecutionResult(400, {}, {"text": "Start or end date missing.", "mimetype": "text/markdown"})

        try:
            start_date = pd.to_datetime(start_str, errors="raise")
            end_date = pd.to_datetime(end_str, errors="raise")
        except Exception as e:
            logger.error("Failed to parse dates: %s", str(e))
            return ExecutionResult(400, {}, {"text": f"Failed to parse start/end date: {str(e)}", "mimetype": "text/markdown"})

        # Log column types
        col_types = {col: str(df[col].dtype) for col in df.columns}
        logger.info("Loaded column types: %s", col_types)

        # Enhanced datetime column detection and parsing
        datetime_column = None
        possible_datetime_cols = []
        for col in df.columns:
            # If column name contains "日付" (date in Japanese), likely a candidate
            if "日付" in col or "date" in col.lower():
                possible_datetime_cols.append(col)
            # Otherwise check dtype
            if pd.api.types.is_datetime64_any_dtype(df[col]):
                possible_datetime_cols.append(col)
        if not possible_datetime_cols:
            # fallback: try every column for convertible to datetime
            for col in df.columns:
                try:
                    _test = pd.to_datetime(df[col], errors="raise")
                    possible_datetime_cols.append(col)
                except Exception:
                    continue

        # If multiple candidates, choose the first
        if possible_datetime_cols:
            datetime_column = possible_datetime_cols[0]
        else:
            logger.error("No datetime-like column found to filter.")
            return ExecutionResult(400, {}, {"text": "No datetime column found for date filtering.", "mimetype": "text/markdown"})

        # Force parsing of datetime column; log before/after min/max
        raw_dates = df[datetime_column].copy()
        try:
            df[datetime_column] = pd.to_datetime(df[datetime_column], errors="coerce")
            logger.info("Parsed '%s' column as datetime. Nulls: %d. Min: %s, Max: %s",
                        datetime_column,
                        df[datetime_column].isnull().sum(),
                        df[datetime_column].min(),
                        df[datetime_column].max())
            if df[datetime_column].isnull().all():
                logger.error("Failed to parse any dates in '%s' column.", datetime_column)
                return ExecutionResult(400, {}, {"text": f"Could not parse any dates in column: {datetime_column}. Please check the file's format and try again.", "mimetype": "text/markdown"})
        except Exception as e:
            logger.error("Error parsing datetime column '%s': %s", datetime_column, str(e))
            return ExecutionResult(400, {}, {"text": f"Error parsing column '{datetime_column}' as datetime: {str(e)}", "mimetype": "text/markdown"})

        # Filter DataFrame by date
        before_rows = df.shape[0]
        filtered_df = df[(df[datetime_column] >= start_date) & (df[datetime_column] <= end_date)]
        after_rows = filtered_df.shape[0]
        logger.info("Filter: dates between %s and %s; Before: %d rows, After: %d rows",
                    start_date.date(), end_date.date(), before_rows, after_rows)

        if filtered_df.empty:
            min_date, max_date = df[datetime_column].min(), df[datetime_column].max()
            msg = (
                f"No records in the specified date range ({start_date.date()} – {end_date.date()}). "
                f"Detected date column: '{datetime_column}' with range [{min_date.date() if pd.notnull(min_date) else 'N/A'} – "
                f"{max_date.date() if pd.notnull(max_date) else 'N/A'}]. "
                "Please verify that your file's date values match the intended filter, format, and timezone."
            )
            logger.warning("Zero records after filter. %s", msg.replace('\n', ' '))  # Avoid newlines in log
            return ExecutionResult(400, {}, {"text": msg, "mimetype": "text/markdown"})

        # Find value and/or category columns (fallback: use remaining non-date columns)
        value_col = None
        for col in filtered_df.columns:
            if col != datetime_column and pd.api.types.is_numeric_dtype(filtered_df[col]):
                value_col = col
                break
        category_col = None
        for col in filtered_df.columns:
            if col != datetime_column and not pd.api.types.is_numeric_dtype(filtered_df[col]):
                category_col = col
                break

        matplotlib.use('Agg')  # Output as image
        plt.figure(figsize=(8,5))

        plot_generated = False
        if value_col:
            if category_col and filtered_df[category_col].nunique() <= 10:
                for key, grp in filtered_df.groupby(category_col):
                    plt.plot(grp[datetime_column], grp[value_col], marker='o', label=str(key))
                plt.xlabel(str(datetime_column))
                plt.ylabel(str(value_col))
                plt.title(f"Time Series by {category_col}")
                plt.legend(title=str(category_col))
                plot_generated = True
            else:
                plt.plot(filtered_df[datetime_column], filtered_df[value_col], marker='o')
                plt.xlabel(str(datetime_column))
                plt.ylabel(str(value_col))
                plt.title("Time Series")
                plot_generated = True
        elif category_col:
            cat_counts = filtered_df[category_col].value_counts().sort_values(ascending=False)
            cat_counts.plot(kind="bar")
            plt.xlabel(str(category_col))
            plt.ylabel("Count")
            plt.title(f"Counts by {category_col}")
            plot_generated = True
        else:
            group = filtered_df.groupby(filtered_df[datetime_column].dt.date).size()
            group.plot(kind="bar")
            plt.xlabel("Date")
            plt.ylabel("Count")
            plt.title("Record Count by Date")
            plot_generated = True

        if not plot_generated:
            logger.info("No appropriate columns for plotting.")
            return ExecutionResult(400, {}, {"text": "No appropriate data found for plotting.", "mimetype": "text/markdown"})

        image_name = "insight_chart.png"
        image_bytes = io.BytesIO()
        plt.tight_layout()
        plt.savefig(image_bytes, format="png")
        plt.close()
        image_bytes.seek(0)

        write_file_to_output(
            input,
            output,
            message_id,
            image_name,
            "image/png",
            image_bytes
        )

        output["text"] = (
            "# Data Insight Chart\n\n"
            f"![Insight Chart]({image_name})\n\n"
            "This chart provides a visualization of data in the specified period. "
            f"All labels and titles are in English as required.\n"
            f"\nFiltered on date column '{datetime_column}' for range [{start_date.date()} – {end_date.date()}]."
        )
        output["mimetype"] = "text/markdown"
        logger.info("Chart generated and image prepared.")

        return ExecutionResult(200, {}, output)

「実行の選択」では実行されたログを確認することもできます。

2025-08-24 10:08:35,245 - CodeExecution [code.py:12 in function execute] - INFO - Starting execution for graph visualization with English labels
2025-08-24 10:08:36,935 - CodeExecution [code.py:41 in function execute] - INFO - Excel file successfully loaded. Columns: ['データ日付', '終値', '始値', '高値', '安値']
2025-08-24 10:08:36,951 - CodeExecution [code.py:59 in function execute] - INFO - Loaded column types: {'データ日付': 'object', '終値': 'float64', '始値': 'float64', '高値': 'float64', '安値': 'float64'}
2025-08-24 10:08:36,951 - CodeExecution [code.py:91 in function execute] - INFO - Parsed 'データ日付' column as datetime. Nulls: 1. Min: 2022-01-04 00:00:00, Max: 2025-08-22 00:00:00
2025-08-24 10:08:36,966 - CodeExecution [code.py:107 in function execute] - INFO - Filter: dates between 2025-08-01 and 2025-08-24; Before: 892 rows, After: 15 rows
2025-08-24 10:08:37,263 - CodeExecution [code.py:195 in function execute] - INFO - Chart generated and image prepared.

問題なければ保存を行い、カスタム プロンプトの説明を記載します。

例えばこんな感じ。

Copilot Studio で利用する

先ほど作成したカスタム プロンプトをエージェントに追加して試してみます。

...が、現状 Copilot Studio くんがファイルの読み込みをなんかうまいことやってくれないので動かないですね...

ということで、仕方ないので Dataverse のデータから情報を返すようにします。

これで情報返ってくるようにはなったものの、テストの画面では画像上手く表示できないですね...

Copilot Chat にデプロイしてみます。

表示できない...

スナップショットを保存して、どういった結果が返ってきているのか見てみましょう。

{
    "text": "2025年7月1日から2025年8月24日までの日経平均株価のデータを取得し、インサイト情報を可視化しました。以下のリンクからグラフをご覧いただけます。\n\n![Nikkei Stock Chart](nikkei_stock_base_chart.png)\n\nこのグラフには、以下の情報が含まれています:\n- 終値(ベース)\n- 始値(ベース)\n- 高値(ベース)\n- 安値(ベース)\n\n何か他にご質問や追加の分析が必要でしたら、お知らせください。"
}

![Nikkei Stock Chart](nikkei_stock_base_chart.png) が返されていますね。
これでは画像表示できなくっても当然かと思います。

出力形式を「ドキュメント/画像」に変更すればいけるのでは?と思われるかもですが

ここは変更して保存しても反映が行われないため注意です。

ということで HTML ベースで出力してみてもらいましょう。

出力を JSON に変更して、生成された HTML をみてみると、いい感じに出力されていそうです。

<div>
    <script type="text/javascript">window.PlotlyConfig = { MathJaxConfig: 'local' };</script>
    <script charset="utf-8" src="https://cdn.plot.ly/plotly-3.0.0.min.js"></script>
    <div id="425cfa7c-4706-4f4f-ba04-ec9f0cba8c01" class="plotly-graph-div" style="height:100%; width:100%;"></div>
    <script
        type="text/javascript">                window.PLOTLYENV = window.PLOTLYENV || {}; if (document.getElementById("425cfa7c-4706-4f4f-ba04-ec9f0cba8c01")) { Plotly.newPlot("425cfa7c-4706-4f4f-ba04-ec9f0cba8c01", [{ "connectgaps": true, "line": { "color": "#3366CC" }, "mode": "lines+markers", "name": "Closing Price (Base)", "x": ["2025-08-03T15:00:00.000000000", "2025-08-04T15:00:00.000000000", "2025-08-05T15:00:00.000000000", "2025-08-06T15:00:00.000000000", "2025-08-07T15:00:00.000000000", "2025-08-11T15:00:00.000000000", "2025-08-12T15:00:00.000000000", "2025-08-13T15:00:00.000000000", "2025-08-14T15:00:00.000000000", "2025-08-17T15:00:00.000000000", "2025-08-18T15:00:00.000000000", "2025-08-19T15:00:00.000000000", "2025-08-20T15:00:00.000000000", "2025-08-21T15:00:00.000000000"], "y": { "dtype": "f8", "bdata": "ZmZmZlas40B7FK5HsczjQFK4HoVb6+NAzczMzGQM5EDD9Shcj2vkQArXo3DF2+RACtejcFUh5UAfhetRKNPkQLgehetJLuVAuB6F60lY5UB7FK5HSUPlQJqZmZkR8eRACtejcEXO5EB7FK5HKdHkQA==" }, "type": "scatter" }, { "connectgaps": true, "line": { "color": "#DC3912" }, "mode": "lines+markers", "name": "Opening Price (Base)", "x": ["2025-08-03T15:00:00.000000000", "2025-08-04T15:00:00.000000000", "2025-08-05T15:00:00.000000000", "2025-08-06T15:00:00.000000000", "2025-08-07T15:00:00.000000000", "2025-08-11T15:00:00.000000000", "2025-08-12T15:00:00.000000000", "2025-08-13T15:00:00.000000000", "2025-08-14T15:00:00.000000000", "2025-08-17T15:00:00.000000000", "2025-08-18T15:00:00.000000000", "2025-08-19T15:00:00.000000000", "2025-08-20T15:00:00.000000000", "2025-08-21T15:00:00.000000000"], "y": { "dtype": "f8", "bdata": "uB6F69mW40AAAAAAIMnjQIXrUbjOveNASOF6FIbb40BmZmZmdijkQNejcD1KjuRA7FG4Hl0K5UApXI\u002fCJQ\u002flQI\u002fC9ShM7uRAzczMzJw35UCamZmZ0WjlQOxRuB4VMeVAH4XrUejj5EC4HoXrudDkQA==" }, "type": "scatter" }, { "connectgaps": true, "line": { "color": "#109618" }, "mode": "lines+markers", "name": "High Price (Base)", "x": ["2025-08-03T15:00:00.000000000", "2025-08-04T15:00:00.000000000", "2025-08-05T15:00:00.000000000", "2025-08-06T15:00:00.000000000", "2025-08-07T15:00:00.000000000", "2025-08-11T15:00:00.000000000", "2025-08-12T15:00:00.000000000", "2025-08-13T15:00:00.000000000", "2025-08-14T15:00:00.000000000", "2025-08-17T15:00:00.000000000", "2025-08-18T15:00:00.000000000", "2025-08-19T15:00:00.000000000", "2025-08-20T15:00:00.000000000", "2025-08-21T15:00:00.000000000"], "y": { "dtype": "f8", "bdata": "AAAAAIix40CPwvUoLNnjQK5H4Xpc8uNAUrgehYMZ5EAK16NwPYbkQIXrUbj2\u002fuRAhetRuG435UD2KFyP+hflQClcj8KtMeVAcT0K12Nn5UAK16NwjWzlQFyPwvU4NOVAUrgehcP15EDXo3A9EtzkQA==" }, "type": "scatter" }, { "connectgaps": true, "line": { "color": "#FF9900" }, "mode": "lines+markers", "name": "Low Price (Base)", "x": ["2025-08-03T15:00:00.000000000", "2025-08-04T15:00:00.000000000", "2025-08-05T15:00:00.000000000", "2025-08-06T15:00:00.000000000", "2025-08-07T15:00:00.000000000", "2025-08-11T15:00:00.000000000", "2025-08-12T15:00:00.000000000", "2025-08-13T15:00:00.000000000", "2025-08-14T15:00:00.000000000", "2025-08-17T15:00:00.000000000", "2025-08-18T15:00:00.000000000", "2025-08-19T15:00:00.000000000", "2025-08-20T15:00:00.000000000", "2025-08-21T15:00:00.000000000"], "y": { "dtype": "f8", "bdata": "PQrXo1B140CPwvUovLzjQI\u002fC9SjkvONASOF6FIbb40CamZmZASTkQPYoXI9yjORAZmZmZgYA5UDD9Shc183kQFK4HoUb3uRApHA9Cscv5UCkcD0KfzLlQM3MzMyE3ORAmpmZmYnI5ECuR+F6bKvkQA==" }, "type": "scatter" }], { "template": { "data": { "barpolar": [{ "marker": { "line": { "color": "white", "width": 0.5 }, "pattern": { "fillmode": "overlay", "size": 10, "solidity": 0.2 } }, "type": "barpolar" }], "bar": [{ "error_x": { "color": "#2a3f5f" }, "error_y": { "color": "#2a3f5f" }, "marker": { "line": { "color": "white", "width": 0.5 }, "pattern": { "fillmode": "overlay", "size": 10, "solidity": 0.2 } }, "type": "bar" }], "carpet": [{ "aaxis": { "endlinecolor": "#2a3f5f", "gridcolor": "#C8D4E3", "linecolor": "#C8D4E3", "minorgridcolor": "#C8D4E3", "startlinecolor": "#2a3f5f" }, "baxis": { "endlinecolor": "#2a3f5f", "gridcolor": "#C8D4E3", "linecolor": "#C8D4E3", "minorgridcolor": "#C8D4E3", "startlinecolor": "#2a3f5f" }, "type": "carpet" }], "choropleth": [{ "colorbar": { "outlinewidth": 0, "ticks": "" }, "type": "choropleth" }], "contourcarpet": [{ "colorbar": { "outlinewidth": 0, "ticks": "" }, "type": "contourcarpet" }], "contour": [{ "colorbar": { "outlinewidth": 0, "ticks": "" }, "colorscale": [[0.0, "#0d0887"], [0.1111111111111111, "#46039f"], [0.2222222222222222, "#7201a8"], [0.3333333333333333, "#9c179e"], [0.4444444444444444, "#bd3786"], [0.5555555555555556, "#d8576b"], [0.6666666666666666, "#ed7953"], [0.7777777777777778, "#fb9f3a"], [0.8888888888888888, "#fdca26"], [1.0, "#f0f921"]], "type": "contour" }], "heatmap": [{ "colorbar": { "outlinewidth": 0, "ticks": "" }, "colorscale": [[0.0, "#0d0887"], [0.1111111111111111, "#46039f"], [0.2222222222222222, "#7201a8"], [0.3333333333333333, "#9c179e"], [0.4444444444444444, "#bd3786"], [0.5555555555555556, "#d8576b"], [0.6666666666666666, "#ed7953"], [0.7777777777777778, "#fb9f3a"], [0.8888888888888888, "#fdca26"], [1.0, "#f0f921"]], "type": "heatmap" }], "histogram2dcontour": [{ "colorbar": { "outlinewidth": 0, "ticks": "" }, "colorscale": [[0.0, "#0d0887"], [0.1111111111111111, "#46039f"], [0.2222222222222222, "#7201a8"], [0.3333333333333333, "#9c179e"], [0.4444444444444444, "#bd3786"], [0.5555555555555556, "#d8576b"], [0.6666666666666666, "#ed7953"], [0.7777777777777778, "#fb9f3a"], [0.8888888888888888, "#fdca26"], [1.0, "#f0f921"]], "type": "histogram2dcontour" }], "histogram2d": [{ "colorbar": { "outlinewidth": 0, "ticks": "" }, "colorscale": [[0.0, "#0d0887"], [0.1111111111111111, "#46039f"], [0.2222222222222222, "#7201a8"], [0.3333333333333333, "#9c179e"], [0.4444444444444444, "#bd3786"], [0.5555555555555556, "#d8576b"], [0.6666666666666666, "#ed7953"], [0.7777777777777778, "#fb9f3a"], [0.8888888888888888, "#fdca26"], [1.0, "#f0f921"]], "type": "histogram2d" }], "histogram": [{ "marker": { "pattern": { "fillmode": "overlay", "size": 10, "solidity": 0.2 } }, "type": "histogram" }], "mesh3d": [{ "colorbar": { "outlinewidth": 0, "ticks": "" }, "type": "mesh3d" }], "parcoords": [{ "line": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "parcoords" }], "pie": [{ "automargin": true, "type": "pie" }], "scatter3d": [{ "line": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scatter3d" }], "scattercarpet": [{ "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scattercarpet" }], "scattergeo": [{ "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scattergeo" }], "scattergl": [{ "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scattergl" }], "scattermapbox": [{ "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scattermapbox" }], "scattermap": [{ "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scattermap" }], "scatterpolargl": [{ "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scatterpolargl" }], "scatterpolar": [{ "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scatterpolar" }], "scatter": [{ "fillpattern": { "fillmode": "overlay", "size": 10, "solidity": 0.2 }, "type": "scatter" }], "scatterternary": [{ "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scatterternary" }], "surface": [{ "colorbar": { "outlinewidth": 0, "ticks": "" }, "colorscale": [[0.0, "#0d0887"], [0.1111111111111111, "#46039f"], [0.2222222222222222, "#7201a8"], [0.3333333333333333, "#9c179e"], [0.4444444444444444, "#bd3786"], [0.5555555555555556, "#d8576b"], [0.6666666666666666, "#ed7953"], [0.7777777777777778, "#fb9f3a"], [0.8888888888888888, "#fdca26"], [1.0, "#f0f921"]], "type": "surface" }], "table": [{ "cells": { "fill": { "color": "#EBF0F8" }, "line": { "color": "white" } }, "header": { "fill": { "color": "#C8D4E3" }, "line": { "color": "white" } }, "type": "table" }] }, "layout": { "annotationdefaults": { "arrowcolor": "#2a3f5f", "arrowhead": 0, "arrowwidth": 1 }, "autotypenumbers": "strict", "coloraxis": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "colorscale": { "diverging": [[0, "#8e0152"], [0.1, "#c51b7d"], [0.2, "#de77ae"], [0.3, "#f1b6da"], [0.4, "#fde0ef"], [0.5, "#f7f7f7"], [0.6, "#e6f5d0"], [0.7, "#b8e186"], [0.8, "#7fbc41"], [0.9, "#4d9221"], [1, "#276419"]], "sequential": [[0.0, "#0d0887"], [0.1111111111111111, "#46039f"], [0.2222222222222222, "#7201a8"], [0.3333333333333333, "#9c179e"], [0.4444444444444444, "#bd3786"], [0.5555555555555556, "#d8576b"], [0.6666666666666666, "#ed7953"], [0.7777777777777778, "#fb9f3a"], [0.8888888888888888, "#fdca26"], [1.0, "#f0f921"]], "sequentialminus": [[0.0, "#0d0887"], [0.1111111111111111, "#46039f"], [0.2222222222222222, "#7201a8"], [0.3333333333333333, "#9c179e"], [0.4444444444444444, "#bd3786"], [0.5555555555555556, "#d8576b"], [0.6666666666666666, "#ed7953"], [0.7777777777777778, "#fb9f3a"], [0.8888888888888888, "#fdca26"], [1.0, "#f0f921"]] }, "colorway": ["#636efa", "#EF553B", "#00cc96", "#ab63fa", "#FFA15A", "#19d3f3", "#FF6692", "#B6E880", "#FF97FF", "#FECB52"], "font": { "color": "#2a3f5f" }, "geo": { "bgcolor": "white", "lakecolor": "white", "landcolor": "white", "showlakes": true, "showland": true, "subunitcolor": "#C8D4E3" }, "hoverlabel": { "align": "left" }, "hovermode": "closest", "mapbox": { "style": "light" }, "paper_bgcolor": "white", "plot_bgcolor": "white", "polar": { "angularaxis": { "gridcolor": "#EBF0F8", "linecolor": "#EBF0F8", "ticks": "" }, "bgcolor": "white", "radialaxis": { "gridcolor": "#EBF0F8", "linecolor": "#EBF0F8", "ticks": "" } }, "scene": { "xaxis": { "backgroundcolor": "white", "gridcolor": "#DFE8F3", "gridwidth": 2, "linecolor": "#EBF0F8", "showbackground": true, "ticks": "", "zerolinecolor": "#EBF0F8" }, "yaxis": { "backgroundcolor": "white", "gridcolor": "#DFE8F3", "gridwidth": 2, "linecolor": "#EBF0F8", "showbackground": true, "ticks": "", "zerolinecolor": "#EBF0F8" }, "zaxis": { "backgroundcolor": "white", "gridcolor": "#DFE8F3", "gridwidth": 2, "linecolor": "#EBF0F8", "showbackground": true, "ticks": "", "zerolinecolor": "#EBF0F8" } }, "shapedefaults": { "line": { "color": "#2a3f5f" } }, "ternary": { "aaxis": { "gridcolor": "#DFE8F3", "linecolor": "#A2B1C6", "ticks": "" }, "baxis": { "gridcolor": "#DFE8F3", "linecolor": "#A2B1C6", "ticks": "" }, "bgcolor": "white", "caxis": { "gridcolor": "#DFE8F3", "linecolor": "#A2B1C6", "ticks": "" } }, "title": { "x": 0.05 }, "xaxis": { "automargin": true, "gridcolor": "#EBF0F8", "linecolor": "#EBF0F8", "ticks": "", "title": { "standoff": 15 }, "zerolinecolor": "#EBF0F8", "zerolinewidth": 2 }, "yaxis": { "automargin": true, "gridcolor": "#EBF0F8", "linecolor": "#EBF0F8", "ticks": "", "title": { "standoff": 15 }, "zerolinecolor": "#EBF0F8", "zerolinewidth": 2 } } }, "font": { "family": "Arial", "size": 14 }, "title": { "text": "Nikkei Stock Average (Base Prices)" }, "xaxis": { "title": { "text": "Date" } }, "yaxis": { "title": { "text": "Price (Base Currency)" } }, "legend": { "title": { "text": "Series" } } }, { "displayModeBar": false, "responsive": true }) };            </script>
</div>

こいつを利用してみると...

リンクを返しやがりましたね。

これは Copilot Chat で利用した場合も同様です。

以下のリンクから、2025年7月1日から2025年8月24日までの日経平均株価のデータを可視化したグラフをご覧いただけます。

日経平均株価のグラフ

このグラフには、期間中の終値始値、高値、安値が表示されています。詳細なインサイトや追加の分析が必要な場合は、お知らせください。

ダメだ!うまくいかない!!

試した限り、現状ファイルや画像はチャット内で利用できないっぽいですね...

まだ Preview なんで仕方ないかなー

ただ他の分析なんかは動きますので、単純にテキストを変換するようなものは問題なく利用できると思います!

Python を利用した分析などを行わせたい場合はこちらが活用できそうですね。

ライブラリ指定の際の注意点

例えば以下のような指示文で from matplotlib.animation import FuncAnimation を利用させるように指示をだしてみます。

指示

地球の円運動を説明するために可視化を行ってください。
from matplotlib.animation import FuncAnimation を用いてアニメーションで説明してください。

可視化の結果はアニメーション Gif として応答してください。

すると指定したライブラリを利用してコードの生成を行ってくれます。

ただし、以下のように googlefinance ライブラリを使って。とお願いした場合は、指定のライブラリは使えないとのエラーが返されます。

ちなみに yfinance もダメです。

どんなライブラリでも使えるわけではない。ということに注意しましょう。

おわりに

カスタム プロンプトでのコードインタープリター機能が利用できるようになったことで、エージェント活用の幅が広がりましたね!

ただ、肝心のエージェント側の入出力が追い付いてないっぽいので、何とかして欲しいですかね...

こうやったらうまくいったよーという報告あればお願いします!!!


スポンサードリンク