01code interpreter に渡す前に、ファイルの形式・大きさ・数を点検する確認済

Copilot Studio のエージェントは code interpreter で Python を生成・実行し、CSV や Excel を分析する(プレビュー)。1 ファイル 16 MB まで、最大 10 ファイル。プロンプトの code interpreter は 1 回に複数のファイルを分析できない。渡す前に手元で点検する。

考え方と手順
  1. エージェントのチャットに渡すファイルは、形式(.csv・.xlsx)、1 ファイルの大きさ、ファイルの数を点検する
  2. プロンプト(prompt builder)に渡すときは、1 回に 1 ファイルにする
  3. Microsoft が十分に試した組み合わせは Excel と CSV の検索・集計なので、それ以外の形式は結果を特に確かめる
  4. 条件に合わないファイルは、分けるか列を絞ってから渡す
Python手元で動く
from pathlib import Path

# Limits from the Copilot Studio docs (structured data in agents, preview)
AGENT_MAX_MB = 16
AGENT_MAX_FILES = 10
TESTED_TYPES = {".csv", ".xlsx"}   # types in Microsoft's extensively tested scenarios


def precheck(paths, mode="agent"):
    paths = [Path(p) for p in paths]
    problems = []
    if mode == "prompt":
        # prompts: one uploaded file per run; no size limit is documented
        if len(paths) > 1:
            problems.append(f"prompt takes one file, got {len(paths)}")
        return problems
    if len(paths) > AGENT_MAX_FILES:
        problems.append(f"too many files: {len(paths)} > {AGENT_MAX_FILES}")
    for p in paths:
        size_mb = p.stat().st_size / (1024 * 1024)
        if size_mb > AGENT_MAX_MB:
            problems.append(f"{p.name}: {size_mb:.1f} MB > {AGENT_MAX_MB} MB")
        if p.suffix.lower() not in TESTED_TYPES:
            problems.append(f"{p.name}: {p.suffix} is outside the tested CSV/Excel scenarios")
    return problems


files = ["samples/ledger.csv", "samples/request_ledger.xlsx", "samples/doc_a.docx"]
for mode in ("agent", "prompt"):
    issues = precheck(files, mode)
    print(mode, "OK" if not issues else "issues:")
    for i in issues:
        print("  -", i)
実行結果(2026-09-12)
agent issues:
  - doc_a.docx: .docx is outside the tested CSV/Excel scenarios
prompt issues:
  - prompt takes one file, got 3
Copilot に書かせる指示の例

Copilot Studio の code interpreter に渡すファイルの一覧を受け取り、エージェント用(1 ファイルの上限・ファイル数の上限・CSV と xlsx 以外の警告)とプロンプト用(1 ファイルだけ)の点検結果を表示する Python の関数を書いて。上限の値は定数にまとめること。

注意

構造化データの分析はプレビューで、上限や動作は変わりうる。点検の数値は取得した日の文書のものなので、使う前に文書を見直す。プロンプト側の大きさの上限は取得したページに書かれていない。code interpreter を使うエージェントはユーザー認証の設定が要る。分析の結果は元のデータで確かめる。

利用条件
Copilot Studio のライセンスが要り、コードの生成と実行はプレミアム機能として数えられる。公開クラウドのみ(ソブリンクラウドは未対応)。code interpreter は環境ごとに有効にする必要があり、既定はオフ。
試験
手元で実行して確認(2026-09-12、Python 3.12.10 (venv) / Windows 11)
実践編
Copilot Chat ── 添付できるファイル形式と長い資料の分け方
出典
Microsoft Learn「Use code interpreter to analyze structured data (preview)」
Microsoft Learn「Use code interpreter in a prompt to generate and execute Python code」
確認日
2026-09-12(第 1 版)
出典の該当箇所
The size limit for each file that can be analyzed by code interpreter, irrespective of file type, is 16 MB. You can upload a maximum of 10 files.
Analyzing multiple files uploaded in a single prompt isn't supported.
By using code interpreter, Copilot Studio agents can generate and run Python code when they need to respond to user prompts.
Code interpreter must be enabled for each environment before you can use it. The default setting is Off.

02Predict API で code interpreter のプロンプトを呼び、実行コードを受け取る確認済

code interpreter を有効にしたプロンプトは、Dataverse Web API の Predict アクションで呼べる。応答の predictionOutput には、生成した本文に加えて、実行した Python のコード(code)と実行ログ(logs)が入る。

考え方と手順
  1. プロンプトは Copilot Studio か Power Apps の画面で作り、code interpreter を有効にする(API では作れない)
  2. msdyn_aimodels を msdyn_name で検索し、プロンプトの行の ID を控える
  3. msdyn_aimodels(ID)/Microsoft.Dynamics.CRM.Predict に POST する。version は "2.0"、プロンプトの入力は requestv2 に入れる
  4. overrideHttpStatusCode が 202 のときは、overrideLocation に GET してポーリングする
  5. 応答の code と logs を保存し、結果を使う前に人が読む
Python要サインイン(Microsoft Entra)
import os
import time

import requests
from azure.identity import InteractiveBrowserCredential

ENV_URL = os.environ.get("DATAVERSE_URL", "https://example.crm.dynamics.com")
MODEL_ID = os.environ.get("AI_MODEL_ID", "")   # msdyn_aimodelid of the prompt
DRY_RUN = os.environ.get("DRY_RUN", "1") != "0"
API = f"{ENV_URL}/api/data/v9.2"
HEADERS = {"Accept": "application/json", "OData-MaxVersion": "4.0", "OData-Version": "4.0"}


def predict_body(inputs):
    # Prompt inputs travel in requestv2 as an open type; keys must match the prompt's input names
    return {"version": "2.0",
            "requestv2": {"@odata.type": "#Microsoft.Dynamics.CRM.expando", **inputs}}


def wait_seconds(value, default=5):
    # overrideRetryAfter format is not documented; fall back to a fixed wait
    try:
        return max(1, int(float(value)))
    except (TypeError, ValueError):
        return default


def output_of(resp):
    v2 = resp["responsev2"]
    out = v2["predictionOutput"]
    return {"status": v2.get("operationStatus"), "text": out.get("text", ""),
            "code": out.get("code", ""), "logs": out.get("logs", ""),
            "files": [f.get("file_name") for f in out.get("files", [])]}


def main():
    cred = InteractiveBrowserCredential(tenant_id=os.environ["TENANT_ID"], client_id=os.environ["CLIENT_ID"])
    token = cred.get_token(f"{ENV_URL}/user_impersonation").token
    session = requests.Session()
    session.headers.update({**HEADERS, "Authorization": f"Bearer {token}"})
    url = f"{API}/msdyn_aimodels({MODEL_ID})/Microsoft.Dynamics.CRM.Predict"
    body = predict_body({"question": "Count requests by document type"})
    if DRY_RUN:
        print("DRY_RUN: would POST", url, body)
        return
    r = session.post(url, json=body, timeout=120)
    r.raise_for_status()
    data = r.json()
    for _ in range(30):
        if str(data.get("overrideHttpStatusCode")) != "202":
            break
        time.sleep(wait_seconds(data.get("overrideRetryAfter")))
        data = session.get(data["overrideLocation"], timeout=60).json()
    result = output_of(data)
    print(result["status"], result["files"])
    print(result["code"])


if __name__ == "__main__":
    main()
実行結果(2026-09-12)
Success ['summary.csv']
version: 2.0 | wait: 5 3
Copilot に書かせる指示の例

Python と requests で、Dataverse の Predict アクションを呼ぶ関数を書いて。本文は version "2.0" と requestv2(@odata.type は #Microsoft.Dynamics.CRM.expando)。overrideHttpStatusCode が 202 なら overrideLocation をポーリングし、predictionOutput の text・code・logs・files の名前を返すこと。環境の URL と ID は環境変数から読み、既定では送信しないこと。

注意

Predict の呼び出しは AI Builder の容量を使う。容量が無いと 403(EntitlementNotAvailable)、同時に送りすぎると 500(MaxConcurrentPlexCallsReachedException)が返る。後者は Retry-After が無いので、間を空けて送り直す。overrideRetryAfter の形式は文書に無いので、読めないときは一定の間隔で待つ。code は実行したコードそのものか、その説明の置き換えである。

利用条件
code interpreter は環境ごとに有効にする必要があり、既定はオフ。Copilot Studio のライセンスが要る。サインインは委任の権限で、公開クライアントでは <環境の URL>/user_impersonation のスコープを使う。
必要なもの
requests 2.34.2, azure-identity 1.25.3
試験
サインインの手前まで実行して確認(Microsoft 365 には接続していない)・集計・判定の部分を見本データで実行して確認(2026-09-12、Python 3.12.10 (venv) / Windows 11、requests 2.34.2、azure-identity 1.25.3)
出典
Microsoft Learn「Code interpreter for developers」
Microsoft Learn「Use OAuth authentication with Microsoft Dataverse」
Microsoft Learn「Predict Action」
確認日
2026-09-12(第 1 版)
出典の該当箇所
In case the prediction isn't completed, 202 indicates that a polling is necessary, otherwise null.
The version parameter. The value is always "2.0".
Python Source code or placeholder describing executed code.
use a "<environment-url>/user_impersonation" scope for a public client.

03Predict の応答から実行コード・ログ・生成ファイルを取り出して保存する確認済

Predict の応答の predictionOutput には、実行した Python(code)、実行ログ(logs)、生成ファイル(files の base64_content)が入る。これらをファイルに保存し、欠損値の削除や絞り込みの行に印を付けて、人がコードを読んでから結果を使う。

考え方と手順
  1. Predict の応答の JSON を保存する
  2. responsev2.operationStatus が Success かを確かめる
  3. predictionOutput.code を .py に、logs を .txt に保存する
  4. files の base64_content を復号し、file_name の名前で保存する(パスの部分は捨てる)
  5. dropna や drop_duplicates など、行の数を変える処理の行に印を付け、条件が意図どおりかを読む
Python手元で動く
import base64
import json
from pathlib import Path

SRC = "samples/excel_predict_response.json"   # a saved Predict response
OUT = Path("out_predict")
OUT.mkdir(exist_ok=True)

resp = json.loads(Path(SRC).read_text(encoding="utf-8"))
v2 = resp["responsev2"]
if v2.get("operationStatus") != "Success":
    raise SystemExit(f"prediction did not succeed: {v2.get('operationStatus')}")
out = v2["predictionOutput"]

code = out.get("code", "")
(OUT / "executed_code.py").write_text(code, encoding="utf-8")
(OUT / "logs.txt").write_text(out.get("logs", ""), encoding="utf-8")
for f in out.get("files", []):
    name = Path(f["file_name"]).name   # keep the base name only
    (OUT / name).write_bytes(base64.b64decode(f["base64_content"]))
    print("file:", name, f.get("content_type"))

print("code lines:", len(code.splitlines()), "| finish:", out.get("finishReason"))
# Lines that change the row count deserve a closer look
WATCH = ("dropna", "fillna", "drop_duplicates", ".query(")
for no, line in enumerate(code.splitlines(), 1):
    if any(w in line for w in WATCH):
        print(f"review line {no}: {line.strip()}")
実行結果(2026-09-12)
file: summary.csv text/csv
code lines: 7 | finish: stop
review line 3: df = df.dropna(subset=['指摘件数'])
Copilot に書かせる指示の例

Dataverse の Predict の応答 JSON を読み、predictionOutput の code を executed_code.py、logs を logs.txt に保存し、files を base64 から復号して保存する Python を書いて。コードの中で dropna・fillna・drop_duplicates・query を含む行を行番号付きで表示すること。

注意

code は実行したコードそのものではなく、説明の置き換えのこともある。その場合は logs と生成ファイルから確かめる。生成ファイルは開く前に中身の形式を確かめる。印を付ける語の一覧は目安で、読む代わりにはならない。応答には入力データの一部が含まれうるので、保存先の権限を絞る。

利用条件
応答の形は Code interpreter for developers の Web API の例に従う。Python の標準ライブラリだけで動く。
試験
手元で実行して確認(2026-09-12、Python 3.12.10 (venv) / Windows 11)
出典
Microsoft Learn「Code interpreter for developers」
確認日
2026-09-12(第 1 版)
出典の該当箇所
Generated file artifacts with file_name, content_type, and base64_content properties.
Python code execution log output (if provided).
operationStatus: A string value showing whether the operation succeeded. Expected value is Success.

04Copilot in Excel の回答の数値を pandas で別に計算して突き合わせる確認済

Copilot in Excel は Python による分析で答えを出し、ブックは変えない。同じ問いを手元の pandas で自分で計算し、回答の数値と表で突き合わせると、対象の列や絞り込みの取り違えを見つけやすい。

考え方と手順
  1. 回答の数値と、表示されたコードにある条件(使った列・絞り込み・集計の方法)を控える
  2. 同じブックを手元に保存し、pandas の read_excel で読む
  3. Copilot のコードを見ずに、自分で同じ問いの集計を書く
  4. 回答の数値を辞書に写し、差がある行と片方にしか無い行を出す
  5. 差があれば、Copilot のコードの絞り込みと欠損値の扱いを読み比べる
Python手元で動く
import pandas as pd

SRC = "samples/request_ledger.xlsx"
# Numbers copied from Copilot's answer to "average findings by department" (example)
copilot = {"営業部": 4.6, "広報部": 4.4, "人事部": 4.1}

df = pd.read_excel(SRC)
mine = df.groupby("依頼部署")["指摘件数"].mean().round(1)

check = pd.DataFrame({"copilot": pd.Series(copilot, dtype=float), "pandas": mine})
check["diff"] = (check["copilot"] - check["pandas"]).round(2)
print(check.to_string())

mismatch = check[(check["diff"].abs() > 0.05) | check.isna().any(axis=1)]
print("rows used:", len(df), "| mismatch:", list(mismatch.index))
実行結果(2026-09-12)
     copilot  pandas  diff
人事部      4.1     4.1   0.0
営業部      4.6     4.6   0.0
広報部      4.4     4.2   0.2
rows used: 40 | mismatch: ['広報部']
Copilot に書かせる指示の例

pandas で request_ledger.xlsx を読み、依頼部署ごとの指摘件数の平均(小数第 1 位)を計算して、別に貼り付けた辞書の値と並べ、差が 0.05 を超える行と片方にしか無い部署を表示するコードを書いて。

注意

Copilot の回答と自分の計算が一致しても、どちらも同じ誤った範囲を見ている可能性はある。対象の行数も合わせて確かめる。挿入した静的な表や画像は更新されないので、元データを直したら計算し直す。構造化されていないデータは対象外である。

利用条件
直接の回答は Excel for Microsoft 365 の Copilot で使える(Copilot のライセンスが要る)。検算のコードは手元の Python と pandas で動かす。
必要なもの
pandas 3.0.5, openpyxl 3.1.5
試験
手元で実行して確認(2026-09-12、Python 3.12.10 (venv) / Windows 11、pandas 3.0.5、openpyxl 3.1.5)
実践編
Excel ── Python による分析で質問に答えさせる
出典
Microsoft Support「Get direct answers to your data analysis questions」
pandas「pandas.read_excel」
確認日
2026-09-12(第 1 版)
出典の該当箇所
Copilot does not modify your workbook. Sometimes, it may return a static table or image visualization that you can insert into your sheet, but these aren’t refreshable.
You can expand the code to see how the answer was generated.

05advanced analysis のコードを、xl() の代わりを置いて手元で動かす確認済

advanced analysis モードのコードは Python in Excel のセル用で、xl() で表を読む。手元に xl() と同じ名前の関数を置き、保存したブックから同じ表を読ませると、コードを書き換えずに実行して Excel 側の結果と比べられる。

考え方と手順
  1. advanced analysis モードのコードを Python セルとして挿入するか、コードを写す
  2. ブックを保存して手元に置く
  3. コードが xl() に渡す参照の名前を、保存したブックのシートに対応させる辞書を作る
  4. 同じ名前の xl() を定義し、写したコードをそのまま実行する
  5. Python in Excel で既定で読み込まれる pandas などは、手元では import を明示する
Python手元で動く
import pandas as pd   # pre-imported in Python in Excel; explicit here

BOOK = "samples/request_ledger.xlsx"
# Map each reference used in the copied code to a sheet in the saved book
REFS = {"RequestLedger[#All]": "依頼台帳"}


def xl(ref, headers=False):
    # Local stand-in for Python in Excel's xl(): reads saved cell values only
    return pd.read_excel(BOOK, sheet_name=REFS[ref], header=0 if headers else None)


# ---- code copied from the Python cell (unchanged) ----
df = xl("RequestLedger[#All]", headers=True)
df["依頼月"] = pd.to_datetime(df["依頼日"]).dt.to_period("M")
monthly = df.pivot_table(index="依頼月", columns="状態", values="依頼ID",
                         aggfunc="count", fill_value=0)
# ---- end of copied code ----

print(monthly.to_string())
print("rows read:", len(df))
実行結果(2026-09-12)
状態       受付  完了  差戻し  確認中
依頼月                      
2026-07   5   6    5    5
2026-08   0   8    6    5
rows read: 40
Copilot に書かせる指示の例

Python in Excel 用のコードを手元で動かしたい。xl(ref, headers=False) と同じ呼び出し方で、参照の名前を辞書でシート名に対応させ、pandas の read_excel で保存したブックから読む関数を書いて。headers=True のときは先頭行を見出しにすること。

注意

手元の xl() はセルの値を読むだけで、Excel の表の範囲や数式の再計算は再現しない。保存前の変更は反映されない。手元のライブラリの版は Python in Excel の環境と違うことがあるので、結果の差が版によるものかも疑う。

利用条件
advanced analysis モードは Copilot in Excel の直接の回答から入る(Copilot のライセンスが要る)。手元の実行には pandas と openpyxl を使う。
必要なもの
pandas 3.0.5, openpyxl 3.1.5
試験
手元で実行して確認(2026-09-12、Python 3.12.10 (venv) / Windows 11、pandas 3.0.5、openpyxl 3.1.5)
実践編
Excel ── Python による分析で質問に答えさせる
出典
Microsoft Support「Get direct answers to your data analysis questions」
Microsoft Support「Open-source libraries and Python in Excel」
確認日
2026-09-12(第 1 版)
出典の該当箇所
This opens a new sheet and runs Python code for deeper, customizable analysis. It’s ideal for users who want to: Explore more complex scenarios Modify and insert underlying Python code as a refreshable Python cell
The following open-source libraries are available with Python in Excel by default. They've been imported with the statements listed.
This means that Python formulas have access to read cell values within the workbook, based on the cell reference, or values from external data sources, through the Power Query connection name.

06Copilot が Python で書き込んだブックの変更を openpyxl で洗い出す確認済

Copilot で編集するとき、Python を実行して結果をブックに直接書き込める。編集の前にブックを別名で保存し、編集後と openpyxl でセルごとに比べると、変わったセル・増えたセル・増えたシートが一覧になる。

考え方と手順
  1. Copilot に編集させる前に、ブックを別名で保存する
  2. 編集後のブックも保存し、2 つを openpyxl の既定(数式は文字列のまま)で読む
  3. シート名と番地が同じで、値か数式が違うセルを出す
  4. 増えたシート・消えたシートと、既存のシートに増えたセルを出す
  5. 一覧を見て、意図しない変更があれば元のブックから戻す
Python手元で動く
from openpyxl import load_workbook

BEFORE = "samples/request_ledger.xlsx"      # copy saved before the Copilot edit
AFTER = "samples/excel_ledger_after.xlsx"   # workbook after the edit


def cells(path):
    wb = load_workbook(path)   # default mode: formulas as text, nothing recalculated
    found = {}
    for ws in wb.worksheets:
        for row in ws.iter_rows():
            for c in row:
                if c.value is not None:
                    found[(ws.title, c.coordinate)] = c.value
    return found, wb.sheetnames


a, sheets_a = cells(BEFORE)
b, sheets_b = cells(AFTER)
print("added sheets:", [s for s in sheets_b if s not in sheets_a])
print("removed sheets:", [s for s in sheets_a if s not in sheets_b])

changed = sorted(k for k in a.keys() & b.keys() if a[k] != b[k])
new_in_old_sheets = sorted(k for k in b.keys() - a.keys() if k[0] in sheets_a)
cleared = sorted(a.keys() - b.keys())
for k in changed:
    print("changed", k, repr(a[k]), "->", repr(b[k]))
print(f"changed={len(changed)} new_in_existing_sheets={len(new_in_old_sheets)} cleared={len(cleared)}")
実行結果(2026-09-12)
added sheets: ['集計']
removed sheets: []
changed ('依頼台帳', 'G3') '受付' -> '完了'
changed ('依頼台帳', 'H10') 9 -> 12
changed=2 new_in_existing_sheets=1 cleared=0
Copilot に書かせる指示の例

openpyxl で 2 つの xlsx(編集前と編集後)を読み、シートの増減、値か数式が変わったセル、既存のシートに増えたセル、消えたセルの数を表示する Python を書いて。どちらのファイルも書き換えないこと。

注意

比べるのはセルの値と数式の文字列で、書式・グラフ・ピボットテーブル・図形は対象外である。数式は計算しないので、数式の結果の差は Excel で開いて確かめる。大きなブックは時間とメモリを使う。変更の記録が要る業務では、この一覧を記録の代わりにしない。

利用条件
Copilot で編集するときの Python の実行は Windows・Mac・Web(Microsoft 365 Copilot のリリースノートによる)。比較のコードは手元の Python と openpyxl で動かす。
必要なもの
openpyxl 3.1.5
試験
手元で実行して確認(2026-09-12、Python 3.12.10 (venv) / Windows 11、openpyxl 3.1.5)
実践編
Excel ── ブックの変更履歴を Copilot に説明させる
出典
Microsoft Learn「Release Notes for Microsoft 365 Copilot」
Microsoft Support「Get started with Copilot in Excel」
確認日
2026-09-12(第 1 版)
出典の該当箇所
Edit with Copilot helps you work with Python in Excel by executing Python code for advanced analysis, automation, and data transformation with results outputted directly in your workbook.
Copilot updates your workbook using Excel's built-in features. Your content stays editable, and you're in control of everything that's modified.
data_only controls whether cells with formulae have either the formula (default) or the value stored the last time Excel read the sheet.