> For the complete documentation index, see [llms.txt](https://docs.roboflow.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.roboflow.com/workflows/ja/gaido/developer-guide/execution-engine-changelog.md).

# Execution Engine 変更履歴

以下に Execution Engine の変更履歴があります。

## 未リリース

**変更点**

ユーザー向けのコンパイルまたは実行動作の変更をここに追加してください。保守担当者はリリース時にこの見出しを Execution Engine と inference のバージョンに置き換えます。

* ローカルのワークフローモデルの読み込み中に発生したモデルアクセス失敗は、一般的な HTTP 500 エラーとして表示されるのではなく、HTTP 402、403、423 のステータスをそのまま保持するようになりました。

***

## Execution Engine `v1.15.0` | inference `1.3.9`

* **リモートの HTTP 501 エラーは、内部 URL を公開せずにそのステータスを保持します** — リモートで実行された Workflow のステップが HTTP 501 を返した場合、Execution Engine は内部の送信元 URL を含む一般的な HTTP 500 ではなく、同じステータスと API メッセージを持つクライアント起因の Workflow エラーを表示するようになりました。

## Execution Engine `v1.14.0` | inference `1.3.8`

**変更点**

* **出力シリアライゼーションが文字列として宣言された kind を受け入れるようになりました** — 出力 kind が単なる文字列として宣言されていた場合（例： `"string"`）で、 `Kind` オブジェクトではなかったとき、出力シリアライゼーションは `TypeError: unhashable type: 'list'`でクラッシュし、ワークフロー全体が HTTP 500 として表示されていました。こうした kind は名前で解決されるようになり、対応するシリアライザが適用されます（その kind に対するシリアライザが登録されていない場合は、未加工の値がそのまま渡されます）。
* **Blocks は依存リソースを宣言できるようになりました** — `WorkflowBlockManifest` にインスタンスメソッドが追加されました `discover_dependent_resources() -> Optional[List[DependentResource]]` これにより、解析済みのステップが実行で使用する外部リソースを宣言できるため、呼び出し元（プラットフォーム、事前読み込み、認可の事前チェック用ツール）はワークフロー定義からそれらを静的に列挙できます。エンベロープは Execution Engine によって管理され、リソース種別は `roboflow_platform_model`, `roboflow_platform_project` および `third_party_model`で、それぞれ型付きでシリアライズ可能な（pydantic）メタデータエンティティを持ちます。Platform-model エントリは使用の性質も示します： `required_action` (`access` — モデルエンティティはプラットフォーム上で到達可能である必要があるだけ、対して `execution` — モデルは実行される）および、execution の場合は `execution_location` (`local` / `remote` / `environment_defined` のとき、ローカリティは実行時に `WORKFLOWS_STEP_EXECUTION_MODE`によって決定されます）。独自のローカリティ上書きを持つ Blocks はその場でそれを指定します。— SAM3 画像ブロックは `SAM3_EXEC_MODE=remote` のとき何も宣言せず（プロキシ実行は設定された model id を無視し、固定の SAM3 をサーバー側で実行します）、 `environment_defined` それ以外の場合は宣言します。 `None` を返す（デフォルト）ということは、そのブロックが依存関係を宣言しないことを意味します。これは `[]`とは異なり、外部リソースが不要であることを宣言します。ワークフローセレクタ（`$inputs.<name>` / `$steps.<name>.<property>`）であるフィールド値は、そのまま報告されます。各メタデータエンティティは `requires_runtime_resolution()` を公開し、そのような参照を具体的な識別子と区別します。最終的な id がフィールド値から合成される宣言（ `clip/<version>`のような family プレフィックス、カタログ検索など）は、さらにシリアライズ不能な `model_id_resolver` callable を付与し、置換された入力値を実行される id に変換します。この callable はシリアライズ、JSON schema、等価性から除外されます。モデル、Roboflow プロジェクト、または third-party ホストモデルを参照するすべてのコアブロックがこのメソッドを実装し、各実装は `run()` が実際に読み込むモデル識別子（version フィールドから合成された id を含む。例： `clip/<version>`）をそのまま反映します。Project 宣言は静的 manifest 値から決定される有効化制御に従います。Roboflow model ブロックは、 `disable_active_learning` が文字通り `True` （デフォルト）であれば active-learning target を落とし、dataset-upload ブロックは `disable_sink` が文字通り `True`のとき何も宣言しません。セレクタ由来の制御は、保守的な「必要かもしれない」宣言を保持します。イントロスペクションは `active_learning_target_dataset` プロパティで停止します。明示的な target なしで active learning が有効な場合、model id から project は導出されません。モデルマネージャの外でモデル重みを読み込むブロック（ `AutoModel.from_pretrained`を使う SAM2/SAM3 の video tracker）については、当面このメソッドを実装しないことを意図しています。— それらの依存関係は未宣言のままです（`None`).
* **動的（カスタム Python）ブロックは未知の依存関係を報告します** — 動的ブロック用に生成された manifest は `None` から `discover_dependent_resources()`を返します。Python 本体は静的解析からは見えないため、「未知」だけが正直な答えです。
* **エンジン初期化時に宣言済み Roboflow モデルの事前読み込みをオプトインで実施** — `ExecutionEngine.init(...)` は新しいオプション引数 `dependencies_pre_init` を受け取ります（デフォルト `None`）：事前読み込みする依存リソース種別名のリストで、現時点でサポートされる値は `roboflow_platform_model` のみです。これを有効にすると、エンジンはコンパイル済みのすべてのステップの宣言済み依存関係を推定し（`deduce_blocks_dependencies` を compiler utils で使用）、実行用に宣言された具体的な Roboflow platform model を model manager に登録します（どちらも `init_parameters`から取得され、API key も同様です）。これは `init()` の間に行われ、どの run よりも前に実施されるため、初回推論の遅延を予測可能にします。 `$inputs.<name>` を参照する宣言は init 時には読み込めません。 **最初の** `run()` 1 回だけ、つまり実行時入力の検証後に行われるため、無効なリクエストは単一の試行を消費せず、ダウンロードも引き起こしません。エンジンは提供された実行時パラメータ（入力デフォルトを適用）に対してそれらを解決し、宣言の `model_id_resolver` を適用します（添付されている場合。たとえば、置換された CLIP version は `clip/<version>`を事前読み込みし、実行で使われる id を正確に用います）。その後、識別子が具体化したモデルを登録します。resolver が `None` を返す場合、置換値は静的に解決不能であると宣言されます（例：Qwen の微調整済み sentinel ラベルで、最終 id が別の入力に依存する場合）。その依存関係はスキップされ、実行時に解決されます。resolver が処理できない送信入力値（例：未知の catalog ラベル）は `RuntimeInputError`を発生させます。登録は各ブロックの実際のローダーを反映します。宣言にはシリアライズ不能な `model_registration_kwargs` を含めることができます（例： `endpoint_type=CORE_MODEL` は CLIP / OCR / SAM2 / YOLO-World 系のコアモデルに対して、対応する `load_core_model()`に一致します）。各事前読み込みパスの後、エンジンは登録されたモデルが依然として model manager に存在することを検証し、サイズ／メモリ制約のある manager がそれらの一部を退避させた場合は警告を記録します（それらは実行時に遅延再読み込みされます）。事前読み込みは、実効的なステップ実行モード（明示的な `step_execution_mode` init パラメータ、または `WORKFLOWS_STEP_EXECUTION_MODE` デフォルト）に従います： `environment_defined` 宣言は、ステップがローカルに実行される場合のみ事前読み込みされます。 `local` 宣言は常に事前読み込みされます。一方、access のみの宣言（重みは取得しない）、リモート実行、および `$steps.…`由来の識別子は事前読み込みされません。 `InferencePipeline.init_with_workflow(...)` はこれをオプトインの `workflows_dependencies_pre_init` パラメータとして公開します（デフォルト `None` — 事前読み込みなし）— 動画処理では予測可能な起動が最も役立ちます。

## Execution Engine `v1.13.0` | inference `v1.3.7`

**変更点**

* **オフラインモードではリモート Workflow ステップ実行を拒否します** — `OFFLINE_MODE` が有効な場合、コンパイラは `StepExecutionMode.REMOTE` をステップ初期化時に拒否するため（`WorkflowEnvironmentConfigurationError`）、Workflows はネットワークアクセスなしでリモート inference client を開けません。ローカルステップ実行はウォーム済みキャッシュに対して引き続き動作します。
* **適切なモデルアクセス失敗ステータスコード** - ローカルのワークフローモデルの読み込み中に発生したモデルアクセス失敗は、一般的な HTTP 500 エラーとして表示されるのではなく、HTTP 402、403、423 のステータスをそのまま保持するようになりました。

## Execution Engine `v1.12.0` | inference `v1.3.2`

**変更点**

**将来解決** - 一部のステップは今後 `Future` オブジェクトを出力する場合があり、クライアントが出力を必要とするまで出力解決を遅延します。下流ブロックではこれらの future は [step\_input\_assembler](https://github.com/roboflow/inference/blob/main/inference/core/workflows/execution_engine/v1/executor/execution_data_manager/step_input_assembler.py) で解決され、出力構築では [output\_constructor](https://github.com/roboflow/inference/blob/main/inference/core/workflows/execution_engine/v1/executor/output_constructor.py) と座標変換が行われます。

## Execution Engine `v1.11.0` | inference `v1.3.1`

**変更点**

* **dict の step selector に対するケース別実行ブランチ** - フロー制御ブロックが `Dict[str, StepSelector]` プロパティ内に step selector を宣言している場合（ `List[StepSelector]`ではなく）、コンパイラは辞書のキーごとに個別の実行ブランチを作成するようになりました。以前は単一プロパティ内のすべての selector が 1 つのブランチを共有していたため、ブロックが対象へ独立してルーティングできませんでした。ブランチ名には辞書キーが含まれるようになりました（例： `Branch[$steps.switch -> cases[red]]`）。リストプロパティ（たとえば `next_steps`）内の selector は従来の共有ブランチ動作を維持するため、既存のブロックには影響しません。この変更により新しい `roboflow_core/switch_case@v1` ブロックが有効になります（`graph_constructor.establish_control_flow_edge`).
* **修正: 重複するブランチ名を持つ非 SIMD フロー制御マスク** - 1 つのリストプロパティを通じて複数のターゲットを選択する非 SIMD のフロー制御ステップが `Attempted to re-register maks for execution branch`を発生させていました。ブランチマスクの登録は、登録前にブランチ名を重複排除するようになり、このクラッシュを修正しました（例： `ContinueIf` で複数の `next_steps`; `execution_data_manager.manager._register_control_flow_output_for_non_simd_step`).

## Execution Engine `v1.10.1` | inference `v1.2.12`

**変更点**

* **ネストされた inner workflow 内の dynamic blocks** - コンパイラは現在、ルート workflow とすべてのネストされた `dynamic_blocks_definitions` child（深さ優先）から収集し、 `inner_workflow` ごとに重複排除し、 `manifest.block_type` で統合したリストをルート定義に持ち上げてから `compile_dynamic_blocks` およびインライン化を行います。ネストされた workflow spec にのみ定義されたカスタム Python ブロックタイプを使う child ステップは、インライン化後に正しくコンパイルおよび実行されます。

## Execution Engine `v1.10.0` | inference `v1.2.10`

**変更点**

* 静的値と selector が混在する値を持つ辞書を認識する機能を追加しました。以前のバージョンでは、キーから selector へのマッピングを持つ辞書のみが認識されていたため、一部のブロックが実行時に参照先の値へ正しく接続されませんでした。この変更は互換性を壊しませんが、過去に壊れていた特定のブロックを修正します。

## Execution Engine `v1.9.0` | inference `v1.2.0`

{% hint style="info" %}
**新機能: コンパイル時インライン化によるネストされたワークフロー**

このリリースでは **`roboflow_core/inner_workflow@v1`** ブロックが追加され、ワークフローが別の workflow 定義を埋め込めるようになりました（インライン JSON または `workflow_workspace_id` / `workflow_id` / 任意の `workflow_version_id`から解決）。子入力は親から **`parameter_bindings`** で接続されます（child の `inputs[].name` → 親 selector）。コンパイル時にエンジンはネストされたステップを親グラフに **インライン化** します。実行は通常のステップと同じ経路を使います（別個のネストランタイムはありません）。
{% endhint %}

**変更点**

* **Inner workflow ブロック** - 新しいフロー制御ブロックタイプ `roboflow_core/inner_workflow@v1` が `roboflow_core`に登録されました。親出力は child workflow の JsonField 出力を `$steps.<inner_step_name>.<child_output_name>` として参照できます。インライン化が selector を書き換えるまでの間です。
* **コンパイルパイプライン** - ルート定義を解析する前に、コンパイラは次を行います。(1) **正規化** 参照（デフォルト: Roboflow API + `workflows_core.api_key`、またはカスタム `workflows_core.inner_workflow_spec_resolver`), (2) **構成を検証** （非循環性、最大ネスト深度、最大 inner-workflow 数）、(3) **インライン化** すべての inner workflow ステップを通常のステップにインライン化し、その後 parse、workflow specification の検証、実行グラフ構築を続けます。
* **制限（環境変数）** - `WORKFLOWS_MAX_INNER_WORKFLOW_DEPTH` を受け取ります（デフォルト `4`）はルートからの包含深度を上限にします。 `WORKFLOWS_MAX_INNER_WORKFLOW_COUNT` を受け取ります（デフォルト `32`）は nested 定義内の `inner_workflow` ステップの総数を上限にします。
* **ドキュメント** - 参照してください [Inner workflows (nested definitions)](/workflows/ja/gaido/developer-guide/inner-workflows.md) を、使用方法、bindings、制限、例について。

## Execution Engine `v1.8.0` | inference `v1.1.1`

{% hint style="info" %}
**追加的な変更 + バグ修正による 1 件の breaking change（想定される影響は最小限）**

このリリースでは Execution Engine を拡張し、フロー制御によってガードされたステップ（たとえば `ContinueIf` block の後のステップ）を、 **データ由来の lineage がなくても** 実行できるようにしました。つまり、上流ステップからバッチ指向の入力を受け取らない場合でも実行できます。lineage と実行次元は、フロー制御の前段ステップから導出できるようになりました。既存のワークフローには影響しません。

導入された breaking change の 1 つは、 `Batch.remove_by_indices` がネストされた batch に対して持つバグ修正によるものです（下記参照）。影響は最小限と見込まれます。
{% endhint %}

**変更点**

* **フロー制御 lineage** - コンパイラは、フロー制御ステップ（たとえば `ContinueIf`の後のブランチ）から来る lineage を追跡するようになりました。新しい **control flow lineage support** の概念は、ステップにバッチ指向のデータ入力がなくてもフロー制御ステップが前段にある場合に使われます。そのステップの実行スライスと batch 構造は、それらのフロー制御前段から取得されます。
* **互換性チェックの緩和** - 以前は、 `verify_compatibility_of_input_data_lineage_with_control_flow_lineage` が `ControlFlowDefinitionError` を、フロー制御の前段はあるがデータ由来 lineage はないステップに対して発生させていたため、そのようなステップはコンパイルできませんでした。そのチェックは現在緩和されています。ステップに入力データ lineage がない場合、互換性は強制されず、代わりにそのステップの lineage はフロー制御の前段ステップの lineage から導出されます。厳格なチェックは、ステップが *持つ* データ由来 lineage を持つ場合に引き続き実行され、フロー制御とデータ lineage の互換性を保証します。
* **新しいステップパターン** - フロー制御によってのみトリガーされ、batch データを消費しないステップが正しく実行されるようになりました。たとえば、 `ContinueIf` の後にメール通知を送信したり、その他の副作用ステップを実行したりできます。 `message_parameters`のようなパラメータにデータを接続しなくても構いません。このステップは、制御しているステップから lineage と次元を取得し、フロー制御ブランチごとに 1 回実行されます。
* **`Batch.remove_by_indices` ネストされた batch に関する挙動修正** -  `Batch.remove_by_indices`を使って index を削除する際、ネストされた `Batch` 要素は同じ index セットで再帰的にフィルタされるようになりました。その結果、削除された index のエントリ（ `None` の値を含む）もネストされた batch から正しく除去されるようになりました。以前は最上位の batch しかフィルタされず、ネストされた batch は変更されませんでした。

  デフォルトでは `WorkflowBlock`, `accepts_empty_values()`は `False`です。これを迂回していた間、そのような入力を消費するブロックは、たとえば `StitchDetectionsBatchBlock`:

  ```python
  def run(
      self,
      images: Batch[WorkflowImageData],
      images_predictions: Batch[Batch[sv.Detections]],
  ) -> BlockResult:
      result = []
      for image, image_predictions in zip(images, images_predictions):
          image_predictions = [deepcopy(p) for p in image_predictions if len(p)]
          for p in image_predictions:
              coords = p["parent_coordinates"][0]
      ...
  ```

  この変更の影響を受ける唯一のコアブロックは `DimensionCollapseBlockV1` ブロックです。個々の入力を None 値を除外せずに batch に包んでいたためです。

  ```python
  class DimensionCollapseBlockV1(WorkflowBlock):

    @classmethod
    def get_manifest(cls) -> Type[WorkflowBlockManifest]:
        return BlockManifest

    def run(self, data: Batch[Any]) -> BlockResult:
        return {"output": [e for e in data]}
  ```

  このブロックの出力を下流アプリケーションで使うと、それらが自分で値をフィルタしない限り、完全に失敗するか、None 値を静かに処理してしまう可能性がありました。

  上記を踏まえると、影響は最小限だと見込んでいます。

## Execution Engine `v1.7.0` | inference `v0.59.0`

{% hint style="warning" %}
**ワークフロー内のステップエラーに関する breaking change**

の無効な HTTP 応答コードに関連するバグを修正するために `inference-server` が Workflows 実行リクエストを処理する際の動作を変更する必要がありました。その結果、この変更は Roboflow Hosted Platform および `inference>=0.59.0`に直ちに適用され、Roboflow platform と連携する Workflow blocks が、クライアント設定ミス（無効な Roboflow API key、無効な model ID など）によって失敗した場合、 `StepExecutionError` （およびサーバーからの HTTP 500 応答）を発生させる代わりに、 `ClientCausedStepExecutionError` （および 400、401、403、404 などの対応する HTTP 応答コード）を発生させます。
{% endhint %}

この変更の影響を受けるシナリオ一覧：

* Roboflow model を使用するブロックが無効な model ID を定義している - これからは `ClientCausedStepExecutionError` をステータスコード 400 で発生させます
* Roboflow model を使用するブロックが無効な API key を定義している - これからは `ClientCausedStepExecutionError` をステータスコード 401 で発生させます
* Roboflow model を使用するブロックが無効な API key、またはリソースへアクセスするための有効な scope を持つ key がないことを定義している - これからは `ClientCausedStepExecutionError` をステータスコード 403 で発生させます
* Roboflow model を使用するブロックが存在しない model を定義している - これからは `ClientCausedStepExecutionError` をステータスコード 404 で発生させます

{% hint style="info" %}
**復活させる `レガシー` エラーハンドリング**

必要であれば、エラーハンドラのレガシーな挙動を復活させることができます。移行期間に役立つ場合があります。必要なのは環境変数を設定するだけです `DEFAULT_WORKFLOWS_STEP_ERROR_HANDLER=legacy`.
{% endhint %}

## Execution Engine `v1.6.0` | inference `v0.53.0`

{% hint style="info" %}
**変更には注意が必要な場合があります**

このリリースでは、次の内容に関するアップグレードと新機能が導入されます **既存のワークフローに変更は不要です** 既存のワークフローに対して。最新の Execution Engine の機能を活用するには、いくつかのブロックをアップグレードする必要がある場合があります。
{% endhint %}

以前の Execution Engine には、特定の種類のブロック、特に Single Instruction, Multiple Data（SIMD）モードで動作するブロックとやり取りする際に大きな制約がありました。これらのブロックは、入力のバッチを一度に処理し、各要素に同じ操作を適用し、バッチ全体の結果を返すように設計されています。

たとえば、 `run(...)` のようなブロックのメソッドは次のようになります:

```python
def run(self, image: Batch[WorkflowImageData], confidence: float):
    pass
```

マニフェストでは、 `image` フィールドはバッチを受け付けるものとして宣言されています。

問題は、入力画像がバッチで動作しないブロックから来た場合に発生していました。そのような場合、Execution Engine は個々の画像からバッチを構築できず、しばしば次のような厄介なコンパイルエラーを引き起こしていました:

```
step `$steps.model` のプロパティ `images` に接続された無効な参照が検出されました - step のプロパティ 
はバッチ指向の入力を厳密に必要としますが、入力セレクタには非バッチ指向の入力が保持されています - これは 
ワークフロー構築に関する問題を示しています - 通常、この問題はバッチ指向でない step の入力が 
バッチでない step の出力や、バッチでない入力で埋められているときに発生します。
```

Execution Engine では `v1.6.0`、この制約は取り除かれ、次の挙動が導入されました:

* 特定の入力がバッチ指向である必要があると検出されると、 **Auto Batch Casting** と呼ばれる手順が適用されます。これにより、入力は自動的に `Batch[T]`に変換されます。すべてのバッチモード入力はすでにマニフェストで明示的に示されているため、以下に記載する例外を除き、ほとんどのブロックは内部変更なしにこのアップグレードの恩恵を受けられます。
* 自動バッチキャストされるパラメータの次元数（ネストの深さ）は、ワークフロー内の特定のブロックのコンテキストとそのマニフェストに基づいて、コンパイル時に決定されます。ほかにバッチ指向の入力が存在する場合（ *lineage サポート*と呼ばれます）、Execution Engine は自動キャストされたバッチを構築する際にそれらを参照として使用します。これにより、各バッチ次元の要素数が、その step に渡される他のデータと一致することが保証されます（実際のバッチ入力が与えられた場合にアサートされるはずだったことをシミュレートします）。 *lineage サポート*lineage サポートがない場合、またはブロックのマニフェストがそれを要求する場合（たとえば、入力の次元オフセットが設定されている場合）、不足している次元は [`torch.unsqueeze(...)` 操作と同様に生成されます](https://docs.pytorch.org/docs/stable/generated/torch.unsqueeze.html).
* その後、step の出力は Auto Batch Casting のコンテキストの有無に対して評価されます。その評価に基づいて、出力はバッチまたはスカラーとして保存され、キャストの影響がローカルにとどまるようにします。唯一の例外は、ブロック自体によって導入される出力次元数の変更です。その副作用として、次のことが可能になりました:
  * **スカラーから出力バッチを作成する** （step が次元数を増やす場合）、および
  * **バッチをスカラーに縮小する** （ブロックが次元数を減らす場合）。
* 2つの潜在的な摩擦点があります。まず **バッチを受け付けないブロックが** （したがって、バッチを受け付ける入力を明示しない） **出力次元数を減らす**場合です。以前のバージョンでは、Execution Engine は次元ラッピングを適用することでこれに対処していました。すべてのバッチ指向入力は追加の `Batch[T]` 次元でラップされ、ブロックの `run(...)` メソッドがリスト次元にわたる reduce 操作を実行できるようにしていました。しかし Auto Batch Casting では、そのようなブロックは、特定の入力がスカラーなのかバッチなのかについて Execution Engine に明確なシグナルを提供しなくなるため、キャストが非決定的になります。これに対処するため、新しいマニフェストメソッドが導入されました: `get_parameters_enforcing_auto_batch_casting(...)`。このメソッドは、次元数が減少したときにバッチキャストを強制すべきパラメータのリストを返さなければなりません。ほかのコンテキストで使われることは想定されていません。

{% hint style="warning" %}
**既存ブロックへの新メソッドの影響**

定義する `get_parameters_enforcing_auto_batch_casting(...)` メソッドは、上記のケースで Auto Batch Casting 機能を完全に利用するための要件としては厳密ではありません。ブロックが変更されない場合、唯一の影響は、以前は **失敗していた** コンパイルエラーのワークフローが動作するようになったり、 **実行時エラー**で失敗したりする可能性があることです。これはブロックの `run(...)` メソッド実装の詳細に依存します。
{% endhint %}

* 2つ目の摩擦点は、 `get_parameters_accepting_batches_and_scalars(...)` を使ってバッチとスカラーの両方をサポートする入力フィールドを宣言しているブロックがある場合に発生します。デフォルトでは、Execution Engine はそのようなパラメータに対する自動キャストをスキップします。というのも、このメソッドは歴史的に **ブロック自体がスカラーをバッチへブロードキャストする能力を持つことを宣言する手段が常にあったためです** — 参照 [の実装 `roboflow_core/detections_transformation@v1`](https://github.com/roboflow/inference/blob/main/inference/core/workflows/core_steps/transformations/detections_transformation/v1.py) ブロックです。ある意味で、Auto Batch Casting は *冗長* なので、それらのブロックはそのままにしておき、新しいバージョンでは `get_parameters_enforcing_auto_batch_casting(...)` の代わりに `get_parameters_accepting_batches_and_scalars(...)` を使うようにアップグレードすることを提案します。
* 以前のバージョンでは、次元数の縮小はレベル 2 以上（つまりネストされたバッチに対してのみ）でしか発生しないという厳しい制約がありました。この制約は今では取り除かれています。次元数の縮小ブロックはスカラーに対しても動作できるようになり、出力次元数はゼロの地面で「跳ね返る」ようになります。

1つの **出力の構築方法に重要な変更があります。** 以前の Execution Error では、ブロックが `Batch[X]` を第一の次元レベルで直接生成することは許可されていませんでした - その領域は入力バッチへのマッピング用に予約されていました。バージョン `v1.6.0`から、この制約は取り除かれました。

以前は、出力は常に要素のリストとして返されていました:

* 入力バッチに対応したもの、または
* 入力がスカラーだけだった場合の単一要素のリストです。

ここで疑問が生じました。ブロックが第一の次元レベルでバッチを生成するようになった場合、どうすべきでしょうか。単純に `zip(...)` して入力ベースの出力と組み合わせることはできません。なぜなら、新しく生成されたバッチのサイズが入力要素数と一致しない可能性があり、操作が曖昧になるからです。

これを解決するため、次のルールを採用しました:

* サイズ 1 の **「ダミー」入力バッチ**.
* があるかのように状況を扱う
* スカラー入力から生成されたすべてのバッチは、見かけより 1 段深くネストされているとみなす
* ということです。これはブロードキャストの原則に従うもので、そのような出力をすべての要素に対して一貫して拡張できるようにします。実行の結果、入力バッチが消失する場合がありますが、その場合でも新しい第一レベルの次元が現れたときは、出力の整合性を保つために仮想的にネストされます。

**例:**

```
（入力なし） IMAGE FETCHER BLOCK --> image --> OD MODEL --> predictions --> CROPS --> 出力は: ["crops": [<crop>, <crop>, ...]] 
```

重要なのは **以前に作成された有効なワークフローから生成された結果は同じままです** この変更は、新しい機能を活用するために作成された新規ワークフローにのみ影響します。

### 移行ガイド

<details>

<summary>`get_parameters_enforcing_auto_batch_casting(...)` メソッドの追加</summary>

出力次元数を減らし、バッチ指向の入力を定義していないブロックは、実装がラップされていることを前提とするすべての入力を宣言する必要があります `Batch[T]` というブロックマニフェストの新しいクラスメソッドで `get_parameters_enforcing_auto_batch_casting(...)`

```python
from typing import List, Literal, Type, Union

import supervision as sv

from inference.core.utils.drawing import create_tiles
from inference.core.workflows.execution_engine.entities.base import (
    Batch,
    OutputDefinition,
    WorkflowImageData,
)
from inference.core.workflows.execution_engine.entities.types import (
    IMAGE_KIND,
    OBJECT_DETECTION_PREDICTION_KIND,
    Selector,
)
from inference.core.workflows.prototypes.block import (
    BlockResult,
    WorkflowBlock,
    WorkflowBlockManifest,
)

class BlockManifest(WorkflowBlockManifest):
    type: Literal["my_plugin/tile_detections@v1"]
    crops: Selector(kind=[IMAGE_KIND])
    crops_predictions: Selector(
        kind=[OBJECT_DETECTION_PREDICTION_KIND]
    )
    scalar_parameter: Union[float, Selector()]

    @classmethod
    def get_output_dimensionality_offset(cls) -> int:
        return -1

    @classmethod
    def get_parameters_enforcing_auto_batch_casting(cls) -> List[str]:
        return ["crops", "crops_predictions"]

    @classmethod
    def describe_outputs(cls) -> List[OutputDefinition]:
        return [
            OutputDefinition(name="visualisations", kind=[IMAGE_KIND]),
        ]

class TileDetectionsBlock(WorkflowBlock):

    @classmethod
    def get_manifest(cls) -> Type[WorkflowBlockManifest]:
        return BlockManifest

    def run(
        self,
        crops: Batch[WorkflowImageData],
        crops_predictions: Batch[sv.Detections],
        scalar_parameter: float,
    ) -> BlockResult:
        print("これは自動バッチキャストされないパラメータです！", scalar_parameter)
        annotator = sv.BoxAnnotator()
        visualisations = []
        for image, prediction in zip(crops, crops_predictions):
            annotated_image = annotator.annotate(
                image.numpy_image.copy(),
                prediction,
            )
            visualisations.append(annotated_image)
        tile = create_tiles(visualisations)
        return {"visualisations": tile}
```

* の行で `34-36` 強制的な自動バッチキャスティングの対象となるフィールドの宣言を追加する必要があります
* 上記の結果として、run メソッドの入力パラメータ（行 `53-54`）は次のようにラップされます `Batch[T]` Execution Engine によって。

</details>

## Execution Engine `v1.5.0` | inference `v0.38.0`

{% hint style="info" %}
**この変更に対応する必要はありません**

この変更により、Workflows ユーザー側での対応は不要です。これは単なるパフォーマンス最適化です。
{% endhint %}

* の init メソッドで新しいパラメータが公開されました `BaseExecutionEngine` クラス - `executor` Python のインスタンスを受け取ることができる `ThreadPoolExecutor` を execution engine で使用できます。この変更により、 `BaseExecutionEngine.run(...)` は専用インスタンスを必要としなくなります `ThreadPoolExecutor` これまでのように必要です。さらに、スレッド生成を大幅に制限するため、一部の環境ではメリットになる可能性もあります。
* 変更後も、Execution Engine は同時実行されるステップ数の上限を維持します。これは、一度に executor を通過するステップ数を制限することで実現されます（Execution Engine はもはや `ThreadPoolExecutor` 生成を制御しておらず、pool に利用可能な worker がより多く存在する可能性があるためです）。

<details>

<summary>Execution Engine に `ThreadPoolExecutor` を注入する方法</summary>

```python
from concurrent.futures import ThreadPoolExecutor
workflow_init_parameters = { ... }
with ThreadPoolExecutor(max_workers=...) as thread_pool_executor:
    execution_engine = ExecutionEngine.init(
        init_parameters=workflow_init_parameters,
        max_concurrent_steps=4,
        workflow_id="your-workflow-id",
        executor=thread_pool_executor,
    )
    runtime_parameters = {
      "image": cv2.imread("your-image-path")
    }
    results = execution_engine.run(runtime_parameters=runtime_parameters)
```

</details>

## Execution Engine `v1.4.0` | inference `v0.29.0`

* 新しい kind を追加 - [`secret`](/workflows/ja/gaido/developer-guide/kinds/secret.md) 資格情報を表すために。 **対応不要** 既存のブロックについては不要ですが、今後は、ブロックがシークレット値をパラメータとして受け取る必要がある場合に、ブロック開発者はこの kind を使用することが期待されます。
* 次で導入された結果シリアライズの問題を修正しました `v1.3.0` — 誤って、Execution Engine はバッチ指向でない出力をシリアライズしていませんでした。
* ステップ用の入力準備に関する Execution Engine のバグを修正しました。以前は非 SIMD ステップについて、実行時に入力を収集する際に、 `WorkflowBlockManifest.accepts_empty_input()` メソッドの結果が無視されており、1つの非 SIMD ステップが下流ブロックへ空の値を渡しているときにバグが発生していました。さらに、次の変更を踏まえて `v1.3.0`、非 SIMD ブロックが下流の SIMD ステップへの入力を容易に供給できるようになったため、上流の非 SIMD ブロックが空でない結果を返したかを確認する必要があります（SIMD ブロックは空の結果を受け付けない場合があるためです）。この確認が追加されました。 **対応不要** 既存ブロックについてですが、この修正によって以前壊れていたワークフローが修正される場合があります。

## Execution Engine `v1.3.0` | inference `v0.27.0`

* 各 kind に serializer と deserializer を定義できるようにする変更を導入しました。この変更により、Workflows プラグインと Execution Engine の結合が分離され、ワイヤ越しのデータ転送を必要とする外部システムとエコシステムを統合できるようになります。 [ブロックのバンドル](/workflows/ja/gaido/developer-guide/block-bundling.md) ページはその変更を反映して更新されました。
* *Kinds* で定義された `roboflow_core` プラグインには適切な serializer と deserializer が用意されました
* Workflows Compiler と Execution Engine は次のように強化されました: **あらゆる&#x20;*****kind のバッチ指向入力をサポートする***。以前のバージョンとは異なり、 `v1.3.0`は次のものしか受け取れませんでした: `image` および `video_metadata` video\_metadata kinds をバッチ指向入力として（kind と内部データ形式が不適切かつ不要に結び付けられていた結果として **Execution Engine のレベルで導入された**）。この変更の結果:
  * **新しい入力型が導入されました:** `WorkflowBatchInput` は今後、バッチ指向入力を表すために使用すべきです（そして、それらを `WorkflowParameters`). `WorkflowBatchInput` に明確に分離しつつ、ユーザーが両方を定義できるようにします [*kind のバッチ指向入力をサポートする*](/workflows/ja/gaido/developer-guide/kinds.md) データの [*次元数*](/workflows/ja/gaido/developer-guide/workflow-execution.md#steps-interactions-with-data)。新しい入力型は、実質的にこれまでのすべてのバッチ指向入力を包含する上位集合です: `WorkflowImage` および `WorkflowVideoMetadata`、これらは **引き続きサポートされます**が、 **Execution Engine で削除されます `v2`**。新しい入力形式への調整を推奨しますが、現時点では必須ではありません。というのも、Execution Engine は現在、入力データの明示的な定義を必要としているためです *kind のバッチ指向入力をサポートする* 。これは将来的にはそうでなくなる可能性があります。というのも、多くの場合、バッチ指向データは *kind のバッチ指向入力をサポートする* コンパイラによって推測できるためです（ただし、この機能は現時点では未実装です）。
  * **新しいセレクタ型アノテーションが導入されました** — 単に `Selector(...)`. `Selector(...)` は次のものを置き換える想定です `StepOutputSelector`, `WorkflowImageSelector`, `StepOutputImageSelector`, `WorkflowVideoMetadataSelector` および `WorkflowParameterSelector` をブロックマニフェストで使用し、特定のステップのマニフェストプロパティが特定の *kind のバッチ指向入力をサポートする*。言及した旧アノテーション型は **非推奨と見なすべきです**。移行することを推奨します `Selector(...)`.
  * セレクタ型アノテーションの簡素化により、旧セレクタはブロックのどのパラメータに関する情報をもはや提供しなくなります `run(...)` メソッドは Execution Engine によって次のようにラップされた状態で提供されます [`Batch[X]` コンテナ](/workflows/ja/gaido/developer-guide/data-representations.md#batch)。旧セレクタ型アノテーションおよび `block_manifest.accepts_batch_input()` メソッドの代わりに、バッチ指向データが渡されることを期待するパラメータを明示的に定義する2つのメソッドへの切り替えを提案します（`block_manifest.get_parameters_accepting_batches()`）と *バッチ* および *スカラー* 値（`block_manifest.get_parameters_accepting_batches_and_scalars()`）。の戻り値は `block_manifest.accepts_batch_input()` 2つの新しいメソッドの結果に基づいて構築されます。この変更は **非破壊的**です。なぜなら、バッチを処理できた既存のブロックはすべて `block_manifest.accepts_batch_input()` メソッドを実装して `True` おり、バッチ指向データを示す適切なセレクタ型アノテーションを使用していたはずだからです
* これらの変更により、次のことが可能になりました **任意のワークフローを、ステップのサブセットを実行する複数のワークフローに分割する**ことができ、デバッガーのようなツールの構築が可能になります。

**破壊的変更の予定 - Execution Engine `v2.0.0`**

* `WorkflowImage` および `WorkflowVideoMetadata` 入力は Workflows エコシステムから削除されます。
* `StepOutputSelector,` WorkflowImageSelector`,` StepOutputImageSelector`,` WorkflowVideoMetadataSelector`および`WorkflowParameterSelector\` 型アノテーションは Workflows エコシステムから削除されます。{% hint %}

### 移行ガイド

<details>

<summary>Kinds の serializer と deserializer</summary>

Workflows プラグインを作成する際に、Workflows 用のカスタム serializer と deserializer を導入できます *kinds*。そのためには、プラグインのメインモジュール（ `load_blocks(...)` 関数を置くのと同じ場所）に、次の辞書を配置するだけです:

```python
from typing import Any

def serialize_kind(value: Any) -> Any:
  # ここに、次の処理に使用されるコードを置きます
  # 内部の Workflows データ表現を変換して 
  # 外部表現へ変換します（JSON でワイヤ越しに送信でき、
  # Python のデフォルト JSON エンコーダーを使用します）。
  pass

def deserialize_kind(parameter_name: str, value: Any) -> Any:
  # ここに、デコードに使用されるコードを置きます 
  # ワイヤ越しに送信されたデータを Execution Engine に取り込み
  # 適切な内部 Workflows データ表現へ変換します
  # ブロックが理解できる形式です。
  pass

KINDS_SERIALIZERS = {
    "name_of_the_kind": serialize_kind,
}
KINDS_DESERIALIZERS = {
    "name_of_the_kind": deserialize_kind,
}
```

</details>

<details>

<summary>セレクタ向けの新しい型アノテーション - `Batch[X]` 入力を持たないブロック</summary>

ブロックマニフェストは **任意で** 次を使用するように更新できます `Selector` 以下のように:

```python
from typing import Union
from inference.core.workflows.prototypes.block import WorkflowBlockManifest
from inference.core.workflows.execution_engine.entities.types import (
    INSTANCE_SEGMENTATION_PREDICTION_KIND,
    OBJECT_DETECTION_PREDICTION_KIND,
    FLOAT_KIND,
    WorkflowImageSelector,
    StepOutputImageSelector,
    StepOutputSelector,
    WorkflowParameterSelector,
)

class BlockManifest(WorkflowBlockManifest):

    reference_image: Union[WorkflowImageSelector, StepOutputImageSelector]
    predictions: StepOutputSelector(
        kind=[
            OBJECT_DETECTION_PREDICTION_KIND,
            INSTANCE_SEGMENTATION_PREDICTION_KIND,
        ]
    )
    confidence: WorkflowParameterSelector(kind=[FLOAT_KIND]) 
```

次のように変更するだけです:

```python
from inference.core.workflows.prototypes.block import WorkflowBlockManifest
from inference.core.workflows.execution_engine.entities.types import (
    INSTANCE_SEGMENTATION_PREDICTION_KIND,
    OBJECT_DETECTION_PREDICTION_KIND,
    FLOAT_KIND,
    IMAGE_KIND,
    Selector,
)

class BlockManifest(WorkflowBlockManifest):
    reference_image: Selector(kind=[IMAGE_KIND])
    predictions: Selector(
        kind=[
            OBJECT_DETECTION_PREDICTION_KIND,
            INSTANCE_SEGMENTATION_PREDICTION_KIND,
        ]
    )
    confidence: Selector(kind=[FLOAT_KIND]) 
```

</details>

<details>

<summary>セレクターの新しい型アノテーション - `Batch[X]` 入力を持つブロック</summary>

ブロックマニフェストは **任意で** 次を使用するように更新できます `Selector` 以下のように:

```python
from typing import Union
from inference.core.workflows.prototypes.block import WorkflowBlockManifest
from inference.core.workflows.execution_engine.entities.types import (
    INSTANCE_SEGMENTATION_PREDICTION_KIND,
    OBJECT_DETECTION_PREDICTION_KIND,
    FLOAT_KIND,
    WorkflowImageSelector,
    StepOutputImageSelector,
    StepOutputSelector,
    WorkflowParameterSelector,
)

class BlockManifest(WorkflowBlockManifest):

    reference_image: Union[WorkflowImageSelector, StepOutputImageSelector]
    predictions: StepOutputSelector(
        kind=[
            OBJECT_DETECTION_PREDICTION_KIND,
            INSTANCE_SEGMENTATION_PREDICTION_KIND,
        ]
    )
    data: Dict[str, Union[StepOutputSelector(), WorkflowParameterSelector()]]
    confidence: WorkflowParameterSelector(kind=[FLOAT_KIND]) 

    @classmethod
    def accepts_batch_input(cls) -> bool:
        return True
```

次のように変更するだけです:

```python
from inference.core.workflows.prototypes.block import WorkflowBlockManifest
from inference.core.workflows.execution_engine.entities.types import (
    INSTANCE_SEGMENTATION_PREDICTION_KIND,
    OBJECT_DETECTION_PREDICTION_KIND,
    FLOAT_KIND,
    IMAGE_KIND,
    Selector,
)

class BlockManifest(WorkflowBlockManifest):
    reference_image: Selector(kind=[IMAGE_KIND])
    predictions: Selector(
        kind=[
            OBJECT_DETECTION_PREDICTION_KIND,
            INSTANCE_SEGMENTATION_PREDICTION_KIND,
        ]
    )
    data: Dict[str, Selector()]
    confidence: Selector(kind=[FLOAT_KIND]) 

    @classmethod
    def get_parameters_accepting_batches(cls)W -> List[str]:
        return ["predictions"]

    @classmethod
    def get_parameters_accepting_batches_and_scalars(cls) -> List[str]:
        return ["data"]
```

次の点にご留意ください:

* その `data` 元の例のプロパティは、両方を受け入れることができました **バッチ** data と **スカラー** 値を、バッチ指向データのセレクター（`StepOutputSelector`) と *スカラー* data（`WorkflowParameterSelector`）。現在では同じことが、 `Selector(...)` 型アノテーションと、 `get_parameters_accepting_batches_and_scalars(...)` メソッドからの戻り値によって表現されています。

</details>

<details>

<summary>Workflow 定義における新しい入力</summary>

いずれかを使用していた方は `WorkflowImage` または `WorkflowVideoMetadata` Workflow 定義内での入力を **任意で** へ移行できます `WorkflowBatchInput`。移行の例は以下のとおりです:

```json
{
  "inputs": [
    {"type": "WorkflowImage", "name": "image"},
    {"type": "WorkflowVideoMetadata", "name": "video_metadata"}
  ]
}
```

次のように変更するだけです:

```json
{
  "inputs": [
    {
      "type": "WorkflowBatchInput",
      "name": "image",
      "kind": ["image"]
    },
    {
      "type": "WorkflowBatchInput",
      "name": "video_metadata",
      "kind": ["video_metadata"]
    }
  ]
}
```

**空欄のままにすると `kind のバッチ指向入力をサポートする` フィールドが空だと、画像のようないくつかのデータが正しくデシリアライズされない可能性があります。**

**注意**

データのシリアライズ方法が `roboflow_core` プラグイン内で気に入らない場合は、 *kinds*、プラグインに関数を登録して Execution Engine に読み込むだけで、シリアライザ／デシリアライザとして最後に定義されたものが使用されます。

</details>

## Execution Engine `v1.2.0` | inference `v0.23.0`

* その [`video_metadata` kind のバッチ指向入力をサポートする](/workflows/ja/gaido/developer-guide/kinds/video-metadata.md) は非推奨となり、私たちは **今後のブロック構築においての使用を強く推奨しません**。代替として、 [`image` kind のバッチ指向入力をサポートする](/workflows/ja/gaido/developer-guide/kinds/image.md) は、 [`video_metadata` kind のバッチ指向入力をサポートする](/workflows/ja/gaido/developer-guide/kinds/video-metadata.md)と同じメタデータをサポートするよう拡張され、これは任意で指定できるようになりました。この更新は **非破壊的** 既存ブロック向けですが、 **一部の古いブロック** 画像を生成する **互換性がなくなる可能性があります** と **将来の** 動画処理ブロック。

<details>

<summary>ブロックの互換性問題の可能性</summary>

前述のとおり、 `video_metadata` を内部表現のオプションフィールドとして追加すると、 [`image` kind のバッチ指向入力をサポートする](/workflows/ja/gaido/developer-guide/kinds/image.md) (`WorkflowImageData` クラス）と、 [`image` kind のバッチ指向入力をサポートする](/workflows/ja/gaido/developer-guide/kinds/image.md) を出力する既存ブロックと、 `video_metadata` が `image` 表現の一部であることに依存する将来の動画処理ブロックとの間に、いくらかの摩擦が生じる可能性があります。

問題が生じるのは、 **デフォルト** 値を `video_metadata` に対して `image` 入力から明示的にコピーしなくても提供できる一方で、上流で追加されたデフォルト以外のメタデータが失われる可能性があるためです。これにより、 `video_metadata` それに依存する下流のブロックが期待どおりに動作しなくなる可能性があります。

既存のすべての `roboflow_core` ブロックはこれに対応するよう更新しましたが、外部リポジトリでこの変更前に作成されたブロックは、出力画像が動画処理ブロックで使用されるワークフローで問題を引き起こす可能性があります。

</details>

* 非推奨の [`video_metadata` kind のバッチ指向入力をサポートする](/workflows/ja/gaido/developer-guide/kinds/video-metadata.md) はまだ使用可能ですが、Execution Engine バージョン `v2.0.0`.

{% hint style="warning" %}
**破壊的変更の予定 - Execution Engine `v2.0.0`**

[`video_metadata` kind のバッチ指向入力をサポートする](/workflows/ja/gaido/developer-guide/kinds/video-metadata.md) は非推奨となり、 `v2.0.0`
{% endhint %}

* 上記の変更により、 [`image` kind のバッチ指向入力をサポートする](/workflows/ja/gaido/developer-guide/kinds/image.md) の内部表現が新しい `video_metadata` プロパティを含むよう更新されました。このプロパティはコンストラクタで任意に設定できます。指定されない場合は、適切なデフォルト値を持つ既定値が使用されます。ブロック内でのメタデータ操作を簡略化するために、次の 2 つの新しいクラスメソッドを導入しました: `WorkflowImageData.copy_and_replace(...)` および `WorkflowImageData.create_crop(...)`。詳細については、更新された [`WoorkflowImageData` 使用ガイド](/workflows/ja/gaido/developer-guide/data-representations.md#workflowimagedata).
