Power Appsのキャンバスアプリは、画面・コントロール・Power Fx式をすべて.pa.yamlというYAMLで持っています。画面構成やPower Fx式はアプリから抽出でき、要件との対応や設計判断の理由だけを人が補えば設計書になります。この記事では、.pa.yamlの取り出し方4通り、画面一覧・変数・画面遷移を設計書に落とすPythonスクリプトとその実行結果、そして2026年に増えた「YAMLを編集して戻す」公式ルートの使い分けを、2026年11月1日時点の公式ドキュメントで確認しながら説明します。
まとめ
| 工程 | 使うもの | 要点 |
|---|---|---|
| 取り出し | Git統合 / pac canvas download / .msapp展開 / MCPサーバー | 入力は\Src配下の.pa.yamlだけ |
| 検証 | pa.schema.yaml v3.0 + jsonschema | =忘れと旧形式は検出、綴り誤りは素通り |
| 解析・整形 | PyYAML + 自前スクリプト | 画面・データソース・変数・画面遷移・式一覧 |
| 説明文 | OpenAI SDK / AI Builderのプロンプト | 数え上げは機械、文章だけ生成AI |
判断の要点は4つです。現行のソース形式は.pa.yamlで、.fx.yamlとpac canvas unpackはもう使いません。設計書を作る目的なら.pa.yamlは読むだけで足り、編集して戻す必要はありません。編集して戻す場合は、Git統合の軽微な編集・コード ビューの貼り付け・MCPサーバー経由の3ルートを中心に検討します。そして、Word形式の技術文書が1本欲しいだけならPowerDocuで足ります。スクリプトは、自社書式への対応、Git連携による継続生成、独自の解析項目が必要な場合に選びます。
.pa.yamlが現行形式で、.fx.yamlは廃止済み
「Power Apps YAML」で検索すると.pa.yamlの記事と.fx.yamlの記事が混在しますが、これは世代の違いです。Microsoft Learnのキャンバス アプリのソース コード ファイル (pa.yaml)は、形式の履歴を次のように整理しています。
| 形式 | 拡張子 | 状態 |
|---|---|---|
| 試験段階(Experimental) | *.fx.yaml | 廃止(開発停止) |
| 早期プレビュー | – | 廃止(版情報なし) |
| ソース コード | *.pa.yaml | アクティブ |
.pa.yamlの位置づけと読み取り専用の意味
同じページは.pa.yamlをStudioでの変更をレビューするためのファイルと位置づけ、読み取り専用で変更は無視され失われる可能性があり、アプリの読み込み時にも使われないと明記しています。.msappを展開して手元の.pa.yamlを書き換えても、アプリには何も起きません。設計書の生成は読むだけなので、この制約には触れません。
pac canvas unpackと.fx.yamlの扱い
2023年前後の記事はpac canvas unpackで.fx.yamlを作る手順を載せていますが、2026年10月25日更新のPower Platform CLI canvasコマンドのリファレンスは、packとunpackを非推奨と明記し、ソース管理にはGit統合を使うよう案内しています。--layoutのExperimentalも「将来のリリースで削除」とされ、残っている選択肢はSourceCodeです。packにはSourceCodeレイアウト限定で「\Srcの*.pa.yamlから読み込む」動作を止める--disable-load-from-yamlが載っていますが、コマンド自体がプレビューかつ非推奨なので、新しく組む手順の土台にはしないでください。
.pa.yamlを取り出す4つの経路
取り出し方は4つあり、環境に何が入っているかで選べるものが変わります。
| 経路 | 前提 | 向く用途 |
|---|---|---|
| Power Platform Git統合 | マネージド環境・システム管理者ロール・Git接続 | コミットごとの継続生成 |
| pac canvas download | pac CLIと認証プロファイル | 単発の取得・バッチ |
| .msappの直接展開 | なし(ZIP展開のみ) | CLIを入れられない端末 |
| Canvas Authoring MCPサーバー | .NET SDK 10と共同編集 | AIエージェントと並走 |
Power Platform Git統合によるリポジトリ同期
キャンバスアプリのソース管理機能は2025年9月15日に一般提供になり、GitプロバイダーはAzure DevOpsとGitHubに対応しています。接続すると.pa.yamlがリポジトリのcanvasフォルダーに変換なしで同期されるので、.msappを扱う必要がなくなります。プッシュをトリガーに設計書を再生成する運用なら、この経路が第一候補です。
pac canvas downloadによるソース抽出
Git統合を入れていない環境では、Power Platform CLI(2026年10月21日公開の2.14.1が最新)で直接取得します。pac canvas listで対象アプリを確かめ、pac canvas downloadに展開先を指定する-dを付けます。
pac canvas list
pac canvas download --name "経費申請アプリ" -d ./src --overwrite
.msappファイルの直接展開
CLIを入れられない端末では、Studioの「名前を付けて保存」で落とした.msappをZIPとして展開できます。公式ドキュメントもPowerShellでの展開例を載せています。
Expand-Archive -Path "C:\path\to\yourFile.msapp" -DestinationPath "C:\path\to\destination"
展開した\Srcには、アプリ全体のApp.pa.yaml、画面ごとの[画面名].pa.yaml、コンポーネントを収めたフォルダーが入ります。.msapp内のJSONは保存と読み込みのサイクルで安定しないため、ソースとして使わないよう公式が注意しています。本記事では、安定したソース形式として扱える\Src配下の.pa.yamlを入力に限定します。
Canvas Authoring MCPサーバーによるライブアプリの取得
Microsoft LearnのAI コード生成ツールを使用してキャンバス アプリを作成および編集する(ms.date 2026年8月27日)で手順が公開されています。GitHub CopilotやClaude Codeなどのコーディングエージェントにcanvas-appsプラグインを入れ、Power Apps Studioの共同編集セッションへ接続する仕組みです。中核のMicrosoft.PowerApps.CanvasAuthoring.McpServerは、2026年4月のプレビュー版から8月31日に1.1.5、10月9日に1.1.29へ進んでいます。
設計書の材料集めで効くのは、プラグインのリポジトリが挙げるツールのうち2つです。sync_canvasは現在のアプリの状態を落としてローカルの.pa.yamlを上書きするので、ダウンロードやGit連携を挟まずに最新の構造を得られます。get_data_source_schemaは接続済みデータソースの列名とデータ型を返します。.pa.yamlのDataSourcesにはテーブルの論理名しか無いため、列定義まで設計書に載せたい場合はこのツールで補えます。Dataverseのテーブルなら、Web APIのメタデータ照会で列定義を取る方法もあります。
前提条件は重めです。.NET SDK 10.0以降、Studioでの共同編集の有効化(設定 > Updates > 共同編集)が要り、アプリは事前に作成・保存しておく必要があります。接続中はStudioのタブを開いたままにしなければならず、セッションが切れたら/configure-canvas-mcpからやり直しです。週次で全アプリの設計書を回すような無人バッチには向きません。
.pa.yamlの構造とYAMLが壊れる条件
v3.0スキーマ(pa.schema.yaml)のトップレベルキーはApp、Screens、ComponentDefinitions、DataSources、EditorStateの5つです。2026年11月1日時点でスキーマのディレクトリはv3.0だけで、最終更新は2025年10月13日でした。
画面・コンポーネント・コントロールの入れ子
画面は名前をキーにしたマップ、コントロールはChildrenの配列で表され、配列の順序がそのまま重なり順になります。コンポーネントはComponentDefinitionsの下にDefinitionType: CanvasComponentで定義され、画面側ではControl: CanvasComponentとComponentNameで参照します。以下は公式スキーマの検証を通した4ファイルで、以降の実行結果はこれをそのまま入力にしています。
##### src/App.pa.yaml
App:
Properties:
StartScreen: =scrList
OnStart: |
=Set(gblUser, User().FullName);
ClearCollect(colStatus, ["申請中", "承認済", "差戻し"])
DataSources:
Requests:
Type: Table
Parameters:
TableLogicalName: cr123_request
##### src/scrList.pa.yaml
Screens:
scrList:
Properties:
OnVisible: |
=UpdateContext({locFilter: "申請中"})
Children:
- cmpHeader:
Control: CanvasComponent
ComponentName: HeaderComponent
Properties:
HeaderText: ="申請一覧"
- galRequests:
Control: Gallery
Variant: BrowseLayout_Vertical_TwoTextOneImageVariant_ver5.0
Properties:
Items: =Sort(Filter(Requests, Status = locFilter), Created, SortOrder.Descending)
OnSelect: =Navigate(scrDetail, ScreenTransition.Cover)
- btnNew:
Control: Classic/Button
Properties:
Text: ="新規申請"
OnSelect: =Set(gblEditMode, true); Navigate(scrDetail)
##### src/scrDetail.pa.yaml
Screens:
scrDetail:
Children:
- txtTitle:
Control: Classic/TextInput
Properties:
Default: =If(gblEditMode, "", galRequests.Selected.Title)
- btnSubmit:
Control: Classic/Button
Properties:
Text: ="申請する"
OnSelect: |
=Patch(Requests, Defaults(Requests), {Title: txtTitle.Text, Status: "申請中"});
Navigate(scrList, ScreenTransition.UnCover)
##### src/Components/HeaderComponent.pa.yaml
ComponentDefinitions:
HeaderComponent:
DefinitionType: CanvasComponent
CustomProperties:
HeaderText:
PropertyKind: Input
DataType: Text
Properties:
HeaderText: ="タイトル"
Children:
- lblHeader:
Control: Label
Properties:
Text: =HeaderComponent.HeaderText
コントロールで必須のキーはControlだけです。スキーマの入力補完スニペットにはControl: Componentと書かれた箇所がありますが、この値では検証が通りません。定数定義のCanvasComponentを正としてください。
Power Fx式でYAMLが壊れる条件
サンプルでOnStart・OnVisible・OnSelectの一部だけが|で始まる複数行形式になっているのは、1行の式がYAMLとして壊れるのを避けるためです。.fx.yaml世代のPower Fx YAML式の文法は、番号記号#とコロン:を1行の数式では一切使えないと定めていましたが、この禁止をそのまま.pa.yamlに当てはめることはできません。YAMLの1行の値で問題になるのは「コロン+空白」と「空白+#」の組み合わせです。PyYAML 6.0.3で確かめると、="#abc"や{Title:x}(コロンの後に空白なし)は読めましたが、OnVisible: =UpdateContext({locFilter: "申請中"})はmapping values are not allowed hereで解析が止まり、=x #cは#以降がコメントとして消えました。Studioが出力するレコードはコロンの後に空白が入るため、レコード表記を含む式は複数行形式で書くことを勧めます。
.pa.yamlから設計書を生成するスクリプト
構造が分かれば、設計書の生成は木構造の走査と正規表現の組み合わせです。画面設計書でよく求められる項目のうち、画面と部品の一覧、データソース、変数とコレクション、画面遷移、イベント処理の式までを機械で出します。
画面・変数・画面遷移を出力するPythonスクリプト
実行前にpython3 -m pip install PyYAML==6.0.3 jsonschema==4.26.0で依存ライブラリを入れ、次のコードをpa2doc.pyとして保存します。
"""*.pa.yaml から画面設計書(Markdown)を生成する"""
import glob, os, re, sys, yaml
VAR_PATTERNS = [
("グローバル変数", re.compile(r"\bSet\(\s*(\w+)")),
("コレクション", re.compile(r"\b(?:Clear)?Collect\(\s*(\w+)")),
]
CONTEXT_CALL = re.compile(r"\bUpdateContext\(\s*\{([^}]*)\}")
NAVIGATE = re.compile(r"\bNavigate\(\s*(\w+)\s*(?=[,)])")
def walk(children, screen, parent, rows):
for item in children or []:
for name, body in item.items():
body = body or {}
rows.append({"screen": screen, "name": name, "parent": parent,
"type": body.get("Control", ""),
"props": body.get("Properties") or {}})
walk(body.get("Children"), screen, name, rows)
def collect(src_dir):
app, sources, rows = {}, {}, []
pattern = os.path.join(src_dir, "**", "*.pa.yaml")
for path in sorted(glob.glob(pattern, recursive=True)):
with open(path, encoding="utf-8") as f:
doc = yaml.safe_load(f) or {}
app.update((doc.get("App") or {}).get("Properties") or {})
sources.update(doc.get("DataSources") or {})
for kind, key in (("画面", "Screens"), ("コンポーネント", "ComponentDefinitions")):
for owner, body in (doc.get(key) or {}).items():
body = body or {}
rows.append({"screen": owner, "kind": kind, "name": owner, "parent": "-",
"type": body.get("DefinitionType", "Screen"),
"props": body.get("Properties") or {}})
walk(body.get("Children"), owner, owner, rows)
rows.insert(0, {"screen": "App", "kind": "アプリ", "name": "App", "parent": "-",
"type": "App", "props": app})
return sources, rows
def formulas(rows):
for r in rows:
for prop, value in r["props"].items():
text = str(value).strip()
if text.startswith("="):
yield r, prop, text
def to_markdown(sources, rows):
owners = [r for r in rows if r["parent"] == "-"]
out = ["# 画面設計書(.pa.yaml から自動生成)", "", "## データソース", "",
"| 名前 | 種別 | パラメータ |", "| --- | --- | --- |"]
for name, body in sources.items():
params = ", ".join("%s=%s" % kv for kv in (body.get("Parameters") or {}).items())
out.append("| %s | %s | %s |" % (name, body.get("Type", ""), params or "-"))
for o in owners[1:]:
out += ["", "## %s: %s" % (o["kind"], o["screen"]), "",
"| 要素 | 種類 | 親 | プロパティ |", "| --- | --- | --- | --- |"]
for r in [r for r in rows if r["screen"] == o["screen"]]:
out.append("| %s | %s | %s | %s |" % (
r["name"], r["type"], r["parent"], ", ".join(r["props"]) or "-"))
found = {}
for r, prop, text in formulas(rows):
where = "%s.%s.%s" % (r["screen"], r["name"], prop)
for label, pat in VAR_PATTERNS:
for var in pat.findall(text):
found.setdefault((label, "アプリ全体", var), []).append(where)
for body in CONTEXT_CALL.findall(text):
for var in re.findall(r"(\w+)\s*:", body):
found.setdefault(("コンテキスト変数", r["screen"], var), []).append(where)
out += ["", "## 変数とコレクション", "",
"| 種類 | スコープ | 名前 | 設定箇所 |", "| --- | --- | --- | --- |"]
for (label, scope, var), wheres in sorted(found.items()):
out.append("| %s | %s | %s | %s |" % (label, scope, var, ", ".join(wheres)))
out += ["", "## 画面遷移", "", "```mermaid", "flowchart LR"]
for r, prop, text in formulas(rows):
for target in NAVIGATE.findall(text):
out.append(" %s -->|%s.%s| %s" % (r["screen"], r["name"], prop, target))
out.append("```")
out += ["", "## Power Fx 式一覧", "",
"| 所属 | 要素 | プロパティ | 式 |", "| --- | --- | --- | --- |"]
for r, prop, text in formulas(rows):
out.append("| %s | %s | %s | %s |" % (
r["screen"], r["name"], prop, text.replace("|", "\\|").replace("\n", "<br>")))
return "\n".join(out)
if __name__ == "__main__":
print(to_markdown(*collect(sys.argv[1])))
globを再帰にしているのは、コンポーネントが\Src直下ではなくサブフォルダーに置かれるためです。walkも再帰で、コンテナーがChildrenを入れ子にしても中身を取りこぼしません。画面とコンポーネント自身のPropertiesも1行として積んでいるので、OnVisibleのような画面レベルのイベントも設計書に残ります。
Python 3.14.6での実行結果
上の4ファイルをsrcに置き、Python 3.14.6とPyYAML 6.0.3で実行した全出力です。画面遷移の節はMermaid記法で、GitHubのMarkdownではそのまま図になります。Azure DevOpsのWikiはflowchart構文に対応していないため、先頭のflowchart LRをgraph LRに変えて貼ります。
$ python3 pa2doc.py src
# 画面設計書(.pa.yaml から自動生成)
## データソース
| 名前 | 種別 | パラメータ |
| --- | --- | --- |
| Requests | Table | TableLogicalName=cr123_request |
## コンポーネント: HeaderComponent
| 要素 | 種類 | 親 | プロパティ |
| --- | --- | --- | --- |
| HeaderComponent | CanvasComponent | - | HeaderText |
| lblHeader | Label | HeaderComponent | Text |
## 画面: scrDetail
| 要素 | 種類 | 親 | プロパティ |
| --- | --- | --- | --- |
| scrDetail | Screen | - | - |
| txtTitle | Classic/TextInput | scrDetail | Default |
| btnSubmit | Classic/Button | scrDetail | Text, OnSelect |
## 画面: scrList
| 要素 | 種類 | 親 | プロパティ |
| --- | --- | --- | --- |
| scrList | Screen | - | OnVisible |
| cmpHeader | CanvasComponent | scrList | HeaderText |
| galRequests | Gallery | scrList | Items, OnSelect |
| btnNew | Classic/Button | scrList | Text, OnSelect |
## 変数とコレクション
| 種類 | スコープ | 名前 | 設定箇所 |
| --- | --- | --- | --- |
| グローバル変数 | アプリ全体 | gblEditMode | scrList.btnNew.OnSelect |
| グローバル変数 | アプリ全体 | gblUser | App.App.OnStart |
| コレクション | アプリ全体 | colStatus | App.App.OnStart |
| コンテキスト変数 | scrList | locFilter | scrList.scrList.OnVisible |
## 画面遷移
```mermaid
flowchart LR
scrDetail -->|btnSubmit.OnSelect| scrList
scrList -->|galRequests.OnSelect| scrDetail
scrList -->|btnNew.OnSelect| scrDetail
```
## Power Fx 式一覧
| 所属 | 要素 | プロパティ | 式 |
| --- | --- | --- | --- |
| App | App | StartScreen | =scrList |
| App | App | OnStart | =Set(gblUser, User().FullName);<br>ClearCollect(colStatus, ["申請中", "承認済", "差戻し"]) |
| HeaderComponent | HeaderComponent | HeaderText | ="タイトル" |
| HeaderComponent | lblHeader | Text | =HeaderComponent.HeaderText |
| scrDetail | txtTitle | Default | =If(gblEditMode, "", galRequests.Selected.Title) |
| scrDetail | btnSubmit | Text | ="申請する" |
| scrDetail | btnSubmit | OnSelect | =Patch(Requests, Defaults(Requests), {Title: txtTitle.Text, Status: "申請中"});<br>Navigate(scrList, ScreenTransition.UnCover) |
| scrList | scrList | OnVisible | =UpdateContext({locFilter: "申請中"}) |
| scrList | cmpHeader | HeaderText | ="申請一覧" |
| scrList | galRequests | Items | =Sort(Filter(Requests, Status = locFilter), Created, SortOrder.Descending) |
| scrList | galRequests | OnSelect | =Navigate(scrDetail, ScreenTransition.Cover) |
| scrList | btnNew | Text | ="新規申請" |
| scrList | btnNew | OnSelect | =Set(gblEditMode, true); Navigate(scrDetail) |
変数抽出と画面遷移の検出範囲
変数と画面遷移は式の文字列を正規表現で拾っているため、検出できる範囲には限りがあります。Set・Collect・ClearCollect・Navigateの第1引数が識別子で直接書かれていれば拾えます。Navigateの正規表現は識別子の直後に,か)が続くことを条件にしているので、Navigate(If(gblEditMode, scrDetail, scrList))のように遷移先を式で決める書き方は、Ifを画面名と誤認せずに読み飛ばします。一方で、引用符付きの識別子、UpdateContext({locRecord: {Title: "a"}, locReady: true})のような入れ子のレコード(Titleを変数と誤認しlocReadyを取りこぼします)、Navigateの第3引数で渡すコンテキスト変数、Withの一時変数、名前付き数式(App.Formulas)には対応していません。文字列リテラル中のSet(も変数として数えます。設計書に載せる前に、変数一覧と画面遷移は式一覧の原式と照合してください。完全な抽出が要るなら、正規表現ではなくPower Fxの構文解析が必要です。
整形前のスキーマ検証とその検出範囲
スキーマはJSON Schema draft-07なので、jsonschema 4.26.0のDraft7Validatorで検証できます。
curl -O https://raw.githubusercontent.com/microsoft/PowerApps-Tooling/refs/heads/master/schemas/pa-yaml/v3.0/pa.schema.yaml
import glob, yaml
from jsonschema import Draft7Validator
with open("pa.schema.yaml", encoding="utf-8") as f:
validator = Draft7Validator(yaml.safe_load(f))
for path in sorted(glob.glob("src/**/*.pa.yaml", recursive=True)):
with open(path, encoding="utf-8") as f:
doc = yaml.safe_load(f)
errors = sorted(validator.iter_errors(doc), key=lambda e: list(e.path))
print(path, "OK" if not errors else [(list(e.path), e.message) for e in errors])
上の4ファイルはすべてOKでした。不正なYAMLを3種類読ませた結果は次のとおりです。
| 入力 | 検証結果 |
|---|---|
| 存在しないコントロール名(Classic/Buton) | 通過してしまう |
式の先頭の=忘れ |
検出 |
旧.fx.yamlのScreen1 As screen: |
検出 |
コントロール名が素通りするのは、スキーマのControlTypeId-1P-controls-enumの実体がtrue、つまり任意の文字列を受け入れる定義だからです。綴り誤りは検出できませんが、旧形式のファイルを掴んだケースと=忘れは確実に落ちるので、整形前の早期チェックとしては十分です。公式はスキーマが開発中で内容が不完全な場合があると断っているため、検証に組み込むならスキーマの取得日を記録してください。
.pa.yamlを編集して戻せる3つの公式ルート
「.pa.yamlは読み取り専用」という一文だけを読むと、テキストでの編集は一切できないように見えます。ここでは、非推奨のpac canvas packを除き、公式資料に記載された書き戻しの3ルートを比較します。いずれも展開した.msappの中身を書き換えるのとは別の仕組みです。
| ルート | 単位 | 制約 |
|---|---|---|
| Git統合でリポジトリを直接編集 | ファイル | 軽微な変更のみ・コードコンポーネント入りは不可 |
| コード ビューで貼り付け | コントロール | Appオブジェクト不可・ビュー内では編集不可 |
| MCPサーバー経由(compile_canvas) | アプリ全体 | 共同編集セッションとStudioのタブが必要 |
Git統合での軽微な直接編集
Git統合のキャンバスアプリ向けページは「軽微な編集は、リポジトリで直接行うことができます」と書き、変更は環境へプルしたときにアプリへ復元されるとしています。ただし大きな変更は避けるよう求めており、アプリがコードコンポーネント(PCF)を含む場合はリポジトリ内の.pa.yamlを直接編集できません。ブランチ上のコードは公開済みアプリとして扱う、という前提も付いています。設計書の生成で見つかったラベル文言の誤りを直す、といった用途が上限と考えてください。
コード ビューによるコントロール単位の複製
Studioのツリー ビューでコントロールを右クリックし「ビュー コード」を選ぶと、そのコントロールと子コントロールのYAMLが表示され、コピーできます。外部で手を入れたYAMLを貼り付けると、検証を通ったうえで新しいコントロールとして追加されます。コード ビューのページによれば、Appオブジェクトは表示もコピーもできず、ビューの中で直接編集することもできません。既存のコントロールを書き換えるのではなく、複製して差し替える操作になります。
MCPサーバー経由のYAML検証とアプリへの適用
MCPサーバーのcompile_canvasは、ローカルの.pa.yamlをPower Appsのオーサリング サービスで検証してアプリへ適用します。エージェントが生成・修正したYAMLは共同編集セッションを通じてStudioに同期されます。公式はAIが生成したコードの検証責任は利用者にあるとし、本番前に開発用のアプリで確かめるよう求めています。画面の追加や式の一括修正には強い一方で、設計書の正確さを担保する手段ではありません。設計書はあくまで同期後の.pa.yamlを前章のスクリプトに通して作ります。
生成AIで説明文を補うときの書き方
残るのは「この画面が何をするのか」という説明文です。生成AIに任せるのは画面の概要文、Power Fx式の意図の言語化、テスト観点の書き出しまでにし、スクリプトの表を渡してから文章だけを書かせます。
現行SDKでのopenai.Completion.create廃止と例外
この分野の解説には、openai.Completion.createにengine="text-davinci-003"を渡すコードが今も残っています。2026年10月31日公開のopenai 3.42.0で実行すると、APIに届く前に例外になりました。
EXC TYPE: APIRemovedInV1
MSG: You tried to access openai.Completion, but this is no longer supported in openai>=1.0.0 - see the README at https://github.com/openai/openai-python for the API.
モデル側も止まっています。OpenAIの廃止一覧では、text-davinci-003の推奨代替だったgpt-3.5-turbo-instruct自身が2026年9月28日に停止しました(代替はgpt-5.6-terra)。古い記事のコードはSDKの呼び方とモデル名の両方を直す必要があり、移行先も2年ほどで入れ替わっています。
Responses APIでの書き換え
実行には環境変数OPENAI_API_KEYとOPENAI_MODELが必要です。次は関数定義の例で、describe_screenを呼ぶと説明文が返ります。入力は画面名と部品名・種類だけなので、イベント処理の意図まで書かせたいときは式一覧の行もinputに加えます。
import os
from openai import OpenAI
client = OpenAI()
def describe_screen(screen_name, controls):
body = "\n".join("%s (%s)" % (c["name"], c["type"]) for c in controls)
res = client.responses.create(
# モデルIDは短期間で入れ替わるため、公式のモデル一覧で確認して環境変数で渡す
model=os.environ["OPENAI_MODEL"],
instructions="Power Appsの画面設計書に載せる説明文を、事実のみで2文以内で書く。",
input="画面名: %s\nコントロール:\n%s" % (screen_name, body),
max_output_tokens=300,
)
return res.output_text
model・instructions・input・max_output_tokensの引数名とoutput_textは、openai 3.42.0の型定義で存在を確かめています。モデルIDを環境変数に逃がしているのは、上の停止の経緯のように提供終了や移行が起きても、コードを書き換えずに設定だけで切り替えるためです。
AI Builderのプロンプトとクレジット終了の影響
Pythonの実行環境を用意できない場合は、AI Builderのプロンプトを使えます。Power Appsでは、データとして追加したプロンプトを'プロンプト名'.Predict(TextInput1.Text)の形でPower Fxから呼べます。Power Automate側のアクション名は2025年5月から「プロンプトを実行する」に変わっており、旧名「プロンプトを使用して GPT でテキストを作成する」で探しても見つかりません。
費用の前提は2026年11月1日に変わりました。AI Builderクレジットの終了に関するページによると、この日以降に新規購入・更新するライセンスにはシードされたAI Builderクレジットが付与されません(既存分は契約期間の終了まで有効)。AI Builderの機能はAI Builderクレジットを先に消費し、残高が無ければCopilot Creditsを使います。ライセンスを更新した組織では、従来のライセンス付帯クレジットに代わる容量(Copilot Credits)を確保しておく必要があるため、全画面の説明文を毎回作り直す設計は避け、差分のあった画面だけを生成し直します。二つのクレジットの見積もり方はPower AutomateのCopilotとAI Builderとは?生成できる範囲とクレジット二重通貨の見積もりを実装目線で解説、画像系の料率はPower Appsで画像認識を組む方法|AI Builderの物体検出・プロンプトと費用で整理しています。
PowerDocuと自前スクリプトの使い分け
Power Platformには設計文書を生成する既成ツールがあります。目的が「Word形式の技術文書が1本欲しい」だけなら、スクリプトを書く必要はありません。
| 手段 | 入力 | 出力 | 書式の自由度 |
|---|---|---|---|
| PowerDocu v-3.0.1 | .msapp / ソリューション.zip | Word / Markdown | 項目は固定・Wordテンプレート可 |
| 本記事のスクリプト | .pa.yaml | Markdown(任意に変更可) | 高 |
| MCP接続のエージェント | ライブのアプリ | 文章 | 高(数え漏れの恐れ) |
PowerDocuはMITライセンスのWindows向けツールで、最新リリースはv-3.0.1(2026年3月25日)です。キャンバスアプリは.msappかソリューションの.zipで読み込み、単体の.pa.yamlは入力にできません。Git統合のリポジトリから直接回したい、社内の設計書テンプレートの項目順に合わせたい、Mermaidの遷移図を同じ文書に載せたい、という要件があるときに自前スクリプトの出番になります。Power Automateのフローまで同じ文書に入れたいならPowerDocuのほうが早く、フローとアプリの役割分担はPower AppsとPower Automateの違いとは?成果物・起動条件・ライセンス境界で選び分けるで整理しています。
この自動化が向かない場面
次のケースでは、.pa.yaml起点の設計書生成を採用すべきではありません。
モデル駆動型アプリが対象のケース
.pa.yamlはキャンバスアプリのソース形式です。モデル駆動型アプリはテーブルとフォームの定義で構成されるため、Dataverseのメタデータから設計書を組む別の手法になります。モデル駆動型アプリにAIでページを足す話はPower Appsの生成ページ(Generative pages)とは?作り方・制限と日本リージョンでの使い方で扱っています。
.pa.yamlに載らない情報が主題のケース
取り出せるのはアプリ本体の構造です。接続の認証情報、環境変数の実値、セキュリティロールによる権限、連携するPower Automateフローの中身は.pa.yamlに含まれません。要件との対応や設計判断の理由も同様です。SharePointリストの列設計のようにデータ側に重心がある設計書は、SharePointリストとは?列設計・ビュー・5000件のしきい値とPower Apps連携を実装目線で解説のようにデータ側から書き起こすほうが漏れません。自動生成の出力をそのまま「詳細設計書」として納品すると、判断の根拠が書かれていない文書になります。
反対に、画面数が多く手作業の棚卸しが破綻しているアプリや、担当者が替わって現物しか手掛かりがないアプリでは、効果がはっきり出ます。既存アプリの棚卸しから改修計画までを外部に任せたい場合は、Power Platform(PowerApps)導入支援サービスで相談を受けています。
よくある質問
Power AppsのYAMLファイルはどこにありますか?
キャンバスアプリの.msappファイルの中です。展開すると\SrcフォルダーにApp.pa.yamlと画面ごとの[画面名].pa.yamlが入っています。Git統合を使っている環境ならリポジトリのcanvasフォルダーで、Studioではコントロールを右クリックした「ビュー コード」で、コントロール単位のYAMLを確認できます。
.pa.yamlを編集してアプリに反映できますか?
展開した.msappの中の.pa.yamlを書き換えても反映されません。反映には、Git統合のリポジトリでの軽微な直接編集、コード ビューへの貼り付け、Canvas Authoring MCPサーバー経由の適用が主な選択肢です。CLIのpackにもSourceCodeレイアウトでの読み込みがありますが、非推奨のため新しい運用には勧めません。コードコンポーネントを含むアプリは、リポジトリでの直接編集の対象外です。
pac canvas unpackはもう使えないのですか?
コマンドは残っていますが、公式リファレンスでpackとunpackは非推奨とされ、コマンド表でもプレビュー扱いです。ソース管理はGit統合、単発の取得はpac canvas downloadに寄せるのが安全です。
openai.yamlとPower AppsのYAMLは同じものですか?
別物です。openai.yamlという名前のファイルには、OpenAIのCodexでスキルのフォルダーに置くagents/openai.yamlという使用例があり、Codexのスキル仕様では表示名やアイコンなどのUIメタデータ、呼び出し方針、ツールの依存関係を書く任意ファイルと説明されています。Power Appsの.pa.yamlはキャンバスアプリの画面とPower Fx式を表すソース形式で、スキーマも用途も重なりません。
ChatGPTにyamlファイルを丸ごと読ませて設計書を作らせても問題ありませんか?
構造の抽出を任せる用途には向きません。.pa.yamlにはデータソース名やPower Fx式がそのまま入っているので、外部サービスへ送ってよいかを社内規程で確認する必要があります。画面数やコントロール数の数え上げをモデルに任せると取りこぼしも起きます。数える処理はスクリプト、説明文の生成だけをモデルに任せる分担にしてください。遷移図を手で整えたいときは、出力したMermaidをMermaid記法の使い方|無料のLive Editor(mermaid.live)でフローチャート・シーケンス図を作成の手順で編集できます。