宣言型ワークフロー (Declarative Workflows)
マルチエージェントのオーケストレーションをコードではなく YAML で定義します。「宣言型
ワークフロー」は Microsoft Agent Framework の Declarative Workflow であり、その実行グラフ --
順次ステップ・条件分岐・ループ・foreach・エージェント呼出 -- を手組みではなくファイルから
コンパイルします。ワークフローは宣言型エージェントと同じ画面で
一緒に管理し、トップレベルの kind フィールドで区別します。kind: Prompt はエージェント、
kind: Workflow はワークフローです。
重要な原則は宣言型エージェントと同じです。YAML は仕様であり、構築は ChatWalaʻau が所有します。 ワークフローはエージェントを名前で参照するだけで、資格情報・プロバイダ・サンプリングパラメータを 一切持ちません。参照される各エージェントは単体のときと同じように ChatWalaʻau が構築するため、 モデル・オプション・エージェント単位のツールはそのエージェントの仕様に由来します。
できること
- YAML を実行グラフにコンパイル。
kind: Workflowの YAML をDECLARATIVE_AGENTS_DIR(エージェントと同じフォルダ) に置くと、ChatWalaʻau が Microsoft Agent Framework のWorkflowFactoryでコンパイルします。専用ディレクトリや有効化フラグは不要 -- フォルダ未設定 ならワークフローは単に存在しません。 - 宣言型エージェントをオーケストレーション。 ワークフローの
InvokeAzureAgentステップがkind: Promptエージェント (組込み CORE エージェントを含む) を呼び出します。ChatWalaʻau が 各エージェントを自前のエージェント/プロバイダ経路で解決・構築するため、資格情報とモデルルーティングは ChatWalaʻau の管理下に留まります。InvokeAzureAgentは宣言型 Prompt エージェントのみに 解決され、生の Foundry エージェントを構築することはありません。 - フルアクションサーフェス。 Microsoft Agent Framework の宣言型アクション 23 種すべてを オーサリングできます。カテゴリ別 (下記) に、変数・制御フロー・出力・エージェント・ツール・ HTTP・人間参加・ワークフロー制御を扱えます。
- エージェントと同じ画面で管理。 Prompt エージェントとワークフローは1つの管理モーダル
(サイドバーフッターのロボットアイコン) で管理し、
Prompt/Workflowタグで区別します。Prompt エージェントを有効化するか、ワークフローをチャットで実行として選択します (選択は記憶されます)。 - 2 つの実行方法。
- チャットで -- 管理モーダルを開き、ワークフローのRun in chatを押します。次のメッセージが ワークフローを駆動し、進捗がアシスタントメッセージ内にライブ表示され、メッセージにワークフロー名が ラベル表示されます。ワークフロー実行対象の間は、メッセージ単位のモデル / Reasoning / Verbosity / 構造化出力の操作は非表示になります。各ステップのモデルは呼び出すエージェントに固定されるためです。 その代わりに表示される名前は戻り道でもあります -- クリックすると Declarative Agents & Workflows モーダルが開きます。
- バックグラウンドジョブで -- 同じワークフローを Pipeline ジョブとして実行し、run 履歴と ログを取得します。長時間・無人実行向けです。
- 実行中の様子を図で見る。 実行インジケータの Diagram を押すと実行キャンバスが開きます。 チャットの上に重なる移動・サイズ変更可能なウィンドウで、ワークフロー図がステップごとに点灯します。 下記の実行を見るを参照してください。
- 人間に一時停止して尋ねる。
QuestionとRequestExternalInputは run を中断してオペレータに 尋ねます -- チャットでは実行キャンバス上の入力フォーム (インタラクティブ)、Pipeline ポータルでは 「入力待ち」状態 (バックグラウンド)。回答すると、変数を保ったまま同じ run が再開します。 - 図として作成。 Create -> New Workflow (と各ワークフローの編集 / 削除) でフルスクリーン エディタを開きます。ステップの視覚的な DAG キャンバス、各ステップのフォーム (「エージェント呼出」ステップは Prompt エージェントを選択)、直接編集もできるライブ YAML プレビュー。 制御フローのステップは入れ子のコンテナノード (下記) として描画され、分岐やループはキャンバス上でも 形を保ちます。保存はチェックポイントです -- 保存してもエディタは開いたままで、図も選択状態も維持 されます。ボタンは初回が Create、以降は Save で、2 回目以降の保存は同じワークフローを更新し、 閉じるのは Close だけです。
- 誤りは見える化。 未対応のアクショ ン、Prompt エージェントでないエージェントへの参照、クラスが 有効化されていない境界越えアクションは警告としてフラグされ、ワークフローの実行をブロックします -- そのため検証を通過したワークフローは必ず実行できます。
kind フィールド
kind | 何か | 実行方法 |
|---|---|---|
Prompt | 単一エージェント | 唯一の有効エージェント (人格) として有効化。 |
Workflow | オーケストレーション | 会話ごとに実行対象として選択、またはバックグラウンドジョブで実行。 |
ワークフローは人格ではありません。選択しても有効エージェントは変わらず、OpenAI 互換 API や Teams では使われません (これらは常に有効な Prompt エージェントを実行します)。ワークフローは Web アプリ専用です。
アクションサーフェス
Microsoft Agent Framework の宣言型アクション 23 種すべてをオーサリングでき、カテゴリ別に整理 されています。境界越えの 3 クラス (Tool と HTTP) は既定で無効で、環境変数でクラスごとに 有効化します -- 境界越えアクションを参照してください。
| カテゴリ | アクション種別 |
|---|---|
| Variable | SetVariable, SetMultipleVariables, SetTextVariable, ResetVariable, ClearAllVariables, ParseValue, EditTableV2 |
| Control Flow | If, ConditionGroup, Foreach, BreakLoop, ContinueLoop, GotoAction |
| Output | SendActivity |
| Agent | InvokeAzureAgent (宣言型 Prompt エージェントを呼び出す) |
| Tool | InvokeFunctionTool, InvokeMcpTool -- 隔離・オプトイン |
| HTTP | HttpRequestAction -- 隔離・オプトイン |
| Human-in-the-Loop | Question, RequestExternalInput |
| Workflow Control | EndWorkflow, EndConversation, CreateConversation |
全アクション共通の kind / id / displayName
| エレメント | 必須 | 内容 |
|---|---|---|
kind | ○ | アクションの種類。 |
id | ○ | アクショ ンを一意に識別する ID。GotoAction の移動先にも使用します。エディタは常に付与します。 |
displayName | 任意 | 表示名。実行中の進捗インジケータでそのステップの名前として表示されます。 |
変数と名前空間
変数パスは常に 名前空間.名前 の形です。名前空間なしの名前は保存時・読み込み時・コンパイル時
に自動で Local. が補われるため、counter と入力すれば Local.counter になります。
| 名前空間 | 内容 |
|---|---|
Local.* | ワークフロー内部の読み書き可能な変数。 |
Workflow.Inputs.* | 起動時に渡された入力値。読み取り専用。 |
Workflow.Outputs.* | 呼び出し元へ返す出力値。 |
System.* | 会話 ID などランタイム提供値。 |
エディタの各変数入力欄は、そのワークフローに既に存在する変数を候補として表示します -- ワークフロー
内で既に使われている Local.* の名前と、inputs: / outputs: で宣言済みの名前です。書き込み
フィールドでは読み取り専用の Workflow.Inputs.* は候補に出ません。候補リストは「作成済みの変数を
再利用する」ためのものなので、名前空間だけ (Local.) は候補に出しませ ん -- それは変数ではなく
プレフィックスであり、選んでも入力欄が中途半端な値のままになるためです。記法は各欄の
プレースホルダーが示します。候補の名前空間プレフィックスは、どう入力しても必ず 1 つだけになります --
ループ変数を Local.item と書いても候補は Local.item であり Local.Local.item にはならず、
裸の count は Local.count として提示されます。
ランタイムが受け付けないパス (Workflow.Inputs.*、Workflow 単体、未知の Workflow.<名前>、空の
パス) への書き込みはブロッキング警告となり、実行中のエラーではなく実行前に報告されます。
ランタイムが認識しない名前空間 (例: topic.x) は正当なカスタム名前空間として扱われ、記述した
ままに保持されます。エディタが候補として提案しないだけです。
実行を見る
すべてのワークフロー実行は、アシスタントメッセージ内にコンパクトな進捗インジケータを表示します。 発生順のステップ、完了したステップのチェック、スキップされたステップの専用マーク、失敗した ステップのエラーが分かります。
一目見る以上のことをしたいときは、そのインジケータの Diagram を押して実行キャンバスを開きます。
- 自動で開きます。 ワークフローにメッセージを送る とキャンバスが立ち上がります。Diagram ボタンを先に押す必要はありません。このボタンは、閉じたキャンバスを呼び戻すためのものです。
- パネルではなくウィンドウです。 タイトルバーをドラッグで移動、右下角をドラッグでサイズ変更 できます。左右ペインの境界線もドラッグでき、図とステップログのどちらにも必要な幅を割り当て られます。広いモニタなら会話と図を左右に並べられます。
- 閉じても失われません。 閉じるボタンはウィンドウを隠すだけで、その実行が集めた内容はすべて 保持されます。もう一度 Diagram を押せば、ノードの状態もログもそのままの同じキャンバスが 戻ります。
- 実行ごとに 1 つ。 別の実行を始めると最初のキャンバスを置き換えるのではなく新しく開くので、 失敗した実行と成功した実行を見比べられます。同時表示が 3 つを超えると最も古いものが隠れます (破棄はされません)。
- 通った経路だけでなくグラフ全体。 図は最初のステップが報告する前にワークフローファイルから 描画されるため、入らなかった分岐も画面に残ります。これは重要です。ランタイムは通らなかった 分岐について一切イベントを出さないため、実行だけから組み立てた図では、スキップされた経路を そもそも表示できません。
- エンジンの都合ではなく、あなたのステップ。 Agent Framework は自前の補助実行体
(エントリ結合、
Ifごとの条件評価器)を動かしますが、これらはステップとして表示されません。 条件評価器はあなたが書いたIfを点灯させ、ステップ数も表示と一致します。 - ステップごとのログ。 ステップをクリックすると、何を出力したか、何で失敗したか、どのループ 反復だったかが分かります。大きなペイロードは明示マーク付きで切り詰められます。
- 実行には影響しません。 キャンバスはビューアです。閉じても実行には無関係で、メッセージ内 インジケータはどちらでも機能します。
- 過去の実行も戻ります。 チャットを読み込み直すと、各ワークフローターンのステップ一覧・ ステップごとのログ・変数が復元され、Diagram でその実行のキャンバスを再表示できます。 ログは保存時に上限が掛かる(長い実行やループの多い実行は直近の分を保持)ため、復元後は 実行時よりやや少なく表示されることがあります。
- 必要なときは自分で開きます。 入力待ちで停止した実行や失敗した実行は、自らキャンバスを 表示します。表示されていないウィンドウでは質問に答えられないためです。それ以外の実行は Diagram を押すまで静かにしています。
変数を見る
キャンバスには変数ペインがあり、実行の進行につれて Local. / Workflow.Inputs.* /
Workflow.Outputs.* / System.* / Agent.* の各名前空間を表示します。設 定は不要です。
名前が秘匿情報らしい値 (api_key / client_secret / token など) は *** に置換され、長い値は
切り詰められますが、これは名前ベースのヒューリスティックであり保証ではありません。
Local.x や Local.response に入れた秘匿情報は表示されます。
これを無効化する設定はありません。ワークフロー変数を露出させてはならない環境では、実行キャンバスへ アクセスさせないでください。また、そもそもワークフロー変数に秘匿情報を置かないでください (HTTP / MCP / ツールの各 jailed ハンドラは自前で資格情報を保持するため、ワークフローが資格情報を 運ぶ必要はありません)。
このペインは純粋に診断用です。変数を読むことがワークフローの動作を変えることはありません。
読み取りは各 superstep 境界で行われます。Agent Framework が保留中の変数書き込みを確定するのが この位置だからです。したがって値は、それを設定したステップ の終了時に現れ、ステップの途中では 現れません。
ユーザーへの質問
Question は回答が来るまでワークフローを一時停止します。choices の各要素は value /
label のペアで、allowFreeText は自由入力を許可するかを文書上で明示するため常に出力され
ます。
- kind: Question
id: ask_priority
displayName: 優先度を質問
question:
text: 優先度を選択してください
variable: Local.priority
choices:
- value: high
label: 高
- value: low
label: 低
allowFreeText: false
default: medium
このステップに到達すると、接続を保持し続けるのではなくターンを一時停止します。ステップは
「入力待ち」となり、実行キャンバスに選択肢付きのプロンプト (および allowFreeText が false で
なければ自由入力欄) が表示されます。回答を送信するとフォームはすぐ閉じ、同じ run が継続します。Local. 変数は
保持されているため、質問より後のステップは入力した値を参照できます。同じ返信も継続します。
質問の前に出力した内容と後に出力した内容は 1 つのメッセージにまとまり、空行で区切られます。
一時停止しないワークフローと同じ見え方です。ターンが終了する方式なので、
未回答のまま放置してもページのリロードに耐えます。
回答待ちのワークフローは、それを開始したプロセスが保持しています。ロードバランサ配下で複数の バックエンドワーカーを動かす場合は、質問を行うワークフローにスティッキールーティングを使うか、 バックグラウンドの Pipeline レーンで実行してください。一時停止中の run が失われている場合 (サーバ再起動など) は、誤った状態に対して黙って新しい run を始めるのではなく、説明付きで回答を 拒否します。
各アクションのフィールドは、インストール済みの Microsoft Agent Framework ランタイ ムが実際に読む
名前です。SetTextVariable は text、SetMultipleVariables は assignments リスト、ParseValue
は value (および任意の valueType)、EditTableV2 は item (および任意の key / index) を
受け取ります。旧フィールド名で書かれたワークフローは、最初に検証または実行された時点で自動的に
移送されます。ファイル自体が書き換わるのは保存したときだけです。
制御フローは入れ子
制御フローは DAG エディタで入れ子のコンテナノードとしてオーサリングし、YAML のツリーと正確に 一致します -- フラットな分岐/合流エッジではありません。
-
If--thenレーンとelseレーンを持つコンテナ。 -
Foreach-- 本体レーンを 1 つ持つコンテナ。ヘッダにはソース・item 名・index 名を表示。BreakLoop/ContinueLoopはループコンテナの内側でのみオーサリング可能。BreakLoopは囲んでいるループを抜け、ContinueLoopは次の要素へスキップします。0.125.0 で修正0.125.0 より前は、
BreakLoopがContinueLoopとまったく同じ挙動でした (どちらでも ループは最後まで実行されていました)。その挙動を前提に作られたワークフローは、今後 ループを早期に抜けます。 -
ConditionGroup-- 条件ごとに 1 レーン (ラベル付き)、加えてelseActionsレーン。 -
GotoAction-- ターゲットアクションへのラベル付きエッジとして描画 (唯一の後方エッジ)。
YAML の入れ子がスコープを定義するため、コンテナノードとファイルはロスなく往復します。プレビュー ペインで raw YAML を直接編集することも常に可能です。
境界越えアクション (オプトイン)
3 つのアクションクラスは、ランタイムが通常は閉じている資格情報 / プロバイダ / ネットワークの境界を 越えます。これらは既定で無効で、環境変数によりクラス単位で有効化します。クラスが無効の場合、その アクションの使用はブロッキング警告となり、「フラグを有効化」できる旨のメッセージが表示されます -- そのためワークフローが黙って外部に到達することはありません。
InvokeFunctionTool-- 呼び出すエージェントが持つのと同じ関数サーフェスのみを実行します (コーディングは引き続きCODING_ENABLEDでゲート)。WORKFLOW_FUNCTION_ACTIONS_ENABLEDで有効化。InvokeMcpTool-- 既に構成済みかつゲーティングストアで有効化された MCP サーバ/ツール のみに到達します。新しいサーバを導入することはできません。WORKFLOW_MCP_ACTIONS_ENABLEDで 有効化。HttpRequestAction-- 送信 HTTP リクエストを行い、WORKFLOW_HTTP_ALLOWED_HOSTS(空 = すべて拒否) に制限されます。SSRF ガードは許可リストに関わらず loopback・private・ link-local・metadata アドレスをブロックします。WORKFLOW_HTTP_ACTIONS_ENABLEDで有効化し、WORKFLOW_HTTP_TIMEOUT_MSが各リクエストを上限化します。
設定
| 変数 | 既定 | 目的 |
|---|---|---|
DECLARATIVE_AGENTS_DIR | (未設定) | ワークフロー (とエージェント) を探索するフォルダ。未設定=ワークフローなし。オーサリングには書込可能が必要。 |
WORKFLOW_MAX_ITERATIONS | 100 | 暴走ループ / コストガード。ワークフローのステップ数を上限化 (YAML の maxTurns はより小さいフォールバックとして適用)。 |
WORKFLOW_FUNCTION_ACTIONS_ENABLED | false | InvokeFunctionTool の隔離ハンドラを有効化 (エージェント相当の関数サーフェスのみ)。 |
WORKFLOW_MCP_ACTIONS_ENABLED | false | InvokeMcpTool の隔離ハンドラを有効化 (構成済み+ゲーティングストア有効の MCP サーバ/ツールのみ)。 |
WORKFLOW_HTTP_ACTIONS_ENABLED | false | HttpRequestAction の隔離ハンドラを有効化。 |
WORKFLOW_HTTP_ALLOWED_HOSTS | (空 = すべて拒否) | HttpRequestAction のカンマ区切りホスト許可リスト。SSRF ガードは loopback / private / link-local / metadata アドレスを引き続きブロック。 |
WORKFLOW_HTTP_TIMEOUT_MS | 10000 | HttpRequestAction のリクエストごとのタイムアウト。 |
例
ワークフローは任意の inputs / outputs、maxTurns の上限、トップレベルの actions リストを
宣言します。制御フローのアクションは子アクションをインライン (then / else、actions、
conditions) で保持します。
name: workflow-name
description: workflow description
maxTurns: 100
inputs:
inputName:
type: string
description: input description
outputs:
outputName:
type: string
actions:
- kind: SetVariable
id: initialize
displayName: 入力を読み取る # 任意。実行中のステップ名として表示
variable: Local.value
value: =Workflow.Inputs.inputName
- kind: If
id: branch
condition: =Not(IsBlank(Local.value))
then:
- kind: InvokeAzureAgent
id: invoke_agent
agent:
name: MyAgent # kind:Prompt の宣言型エージェントに解決される
input:
messages: =Local.value
output:
responseObject: Local.AgentResult
else:
- kind: SendActivity
id: invalid_input
activity:
text: Input is empty.
- kind: SetVariable
id: set_output
variable: Workflow.Outputs.outputName
value: =Local.AgentResult.summary
- kind: EndWorkflow
id: finish
DECLARATIVE_AGENTS_DIR 配下に保存し、Declarative Agents & Workflows モーダル (サイドバー
フッターのロボットアイコン) を開いてワークフローを選択し、Run in chat を押します。または
バックグラウンドジョブとして実行します。