> 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/hi/developer-guide/developer-guide/inner-workflows.md).

# आंतरिक वर्कफ़्लो

Inner workflow block के साथ एक Workflow परिभाषा को दूसरे के अंदर एम्बेड करें, और कम्पाइलर उसे कैसे inline करता है।

यह **आंतरिक वर्कफ़्लो** ब्लॉक (`roboflow_core/inner_workflow@v1`) आपको एक वर्कफ़्लो परिभाषा को दूसरे के भीतर एम्बेड करने देता है। पर **कंपाइल समय**, इंजन किसी भी सहेजे गए वर्कफ़्लो संदर्भों को हल करता है, सत्यापित करता है **संयोजन** (नेस्टिंग सीमाएँ और चक्र), सत्यापित करता है **पैरामीटर बाइंडिंग्स**, फिर **इनलाइन करता है** चाइल्ड के चरणों को पैरेंट में। कंपाइल होने के बाद कोई अलग “नेस्टेड रन” नहीं होता: ग्राफ़ वैसा ही होता है जैसे आपने वे चरण पैरेंट स्तर पर लिखे हों।

यह पृष्ठ ब्लॉक, कंपाइल-समय पाइपलाइन, सीमाएँ, और एक न्यूनतम Python उदाहरण का वर्णन करता है। सामान्य संकलन चरणों के लिए, देखें [वर्कफ़्लो परिभाषा का संकलन](/workflows/hi/developer-guide/developer-guide/compiler.md).

{% hint style="info" %}
यह सुविधा Execution Engine में लागू की गई है **v1**। आंतरिक वर्कफ़्लो ब्लॉक का `run()` मेथड रनटाइम पर कभी उपयोग नहीं होती; चरण कंपाइलेशन के दौरान हटा दिया जाता है।
{% endhint %}

## आंतरिक वर्कफ़्लो ब्लॉक

प्रत्येक आंतरिक वर्कफ़्लो चरण पैरेंट की `steps` सूची में `type: "roboflow_core/inner_workflow@v1"`.

### आप चाइल्ड परिभाषा कैसे प्रदान करते हैं

आपको प्रदान करना होगा **या**:

* **`workflow_definition`**: एक पूर्ण नेस्टेड वर्कफ़्लो JSON ऑब्जेक्ट (रूट वर्कफ़्लो जैसी ही संरचना: `version`, `inputs`, `steps`, `outputs`), **या**
* **`workflow_workspace_id`** और **`workflow_id`**, वैकल्पिक **`workflow_version_id`**, ताकि कंपाइल समय पर एक सहेजा गया वर्कफ़्लो स्पेक लोड किया जा सके।

आपको **नहीं** एक ही चरण पर एक inline `workflow_definition` और reference फ़ील्ड्स दोनों सेट नहीं करने चाहिए।

### `parameter_bindings`

`parameter_bindings` एक ऑब्जेक्ट है जिसकी **keys** हैं **names** के **चाइल्ड वर्कफ़्लो के** उसकी `inputs` array में मौजूद entries की। प्रत्येक **मान** एक **सेलेक्टर** (या ऐसा मान जिसे इंजन coerce कर सके) से **पैरेंट** scope से, आम तौर पर:

* `$inputs.<parent_input_name>` पैरेंट वर्कफ़्लो इनपुट के लिए, या
* `$steps.<parent_step_name>.<output_property>` पिछले पैरेंट चरणों द्वारा उत्पन्न डेटा के लिए।

**नियम:**

* प्रत्येक चाइल्ड इनपुट जो **को** पैरेंट से एक मान की आवश्यकता होती है, उसे parameter\_bindings में होना चाहिए `parameter_bindings`, **सिवाय** type वाले inputs `WorkflowParameter` / `InferenceParameter` जो एक **non-null** `default_value` चाइल्ड परिभाषा में घोषित करते हैं। उन्हें छोड़ा जा सकता है; परिभाषा inline होने पर चाइल्ड का डिफ़ॉल्ट लागू होता है।
* जो keys चाइल्ड input names नहीं हैं, उन्हें कंपाइल समय पर अस्वीकार कर दिया जाता है।
* चाइल्ड चरणों को पैरेंट डेटा के माध्यम से उपयोग करना चाहिए **`$inputs.<child_input_name>`** नेस्टेड परिभाषा में; कंपाइलर इन संदर्भों को inline करने के दौरान बंधे हुए पैरेंट सेलेक्टर्स (या इंजेक्ट किए गए डिफ़ॉल्ट्स) से बदल देता है।

### पैरेंट से चाइल्ड आउटपुट्स का संदर्भ देना

नेस्टेड वर्कफ़्लो का `outputs` array निर्धारित करती है **JsonField** entries के साथ एक `name` और `सेलेक्टर`। कंपाइलेशन के बाद, पैरेंट आंतरिक चरण को एक तार्किक ब्लॉक की तरह मानता है, जिसके outputs उन JsonField **`name`** मानों के नाम पर होते हैं।

पैरेंट से आप उन्हें इस प्रकार संदर्भित करते हैं:

```
$steps.<inner_step_name>.<child_output_name>
```

जहाँ `<child_output_name>` है `name` चाइल्ड के JsonField का field `outputs`, जरूरी नहीं कि अंतिम चरण का नाम हो।

## कंपाइल-समय पाइपलाइन (Execution Engine v1)

जब `compile_workflow_graph` चलता है, तो आंतरिक वर्कफ़्लो निम्नलिखित से गुजरते हैं **पहले** मुख्य “वर्कफ़्लो परिभाषा पार्स करें” चरण से:

1. **संदर्भ समाधान (सामान्यीकरण)**\
   कोई भी चरण जो उपयोग करता है `workflow_workspace_id` / `workflow_id` (और वैकल्पिक `workflow_version_id`) को एक inline `workflow_definition`में हल किया जाता है। यह नेस्टेड परिभाषाओं के भीतर पुनरावर्ती रूप से होता है।
   * डिफ़ॉल्ट resolver Roboflow API और **`workflows_core.api_key`** को workflow init parameters में उपयोग करता है (जब तक workspace `"local"` न हो या आप कोई custom resolver न दें)।
   * init parameter से ओवरराइड करें **`workflows_core.inner_workflow_spec_resolver`**: एक `कॉल करने योग्य` (workspace\_id, workflow\_id, workflow\_version\_id, init\_parameters) -> dict
2. **जो चाइल्ड वर्कफ़्लो JSON लौटाता है।**\
   इंजन एक **संयोजन ग्राफ़**बनाता है: प्रति `inner_workflow` चरण के लिए पैरेंट वर्कफ़्लो के fingerprint से चाइल्ड परिभाषा के fingerprint तक एक edge। फिर यह जाँचता है:
   * ग्राफ़ **चक्रीय-रहित** (कोई A → B → … → A नहीं),
   * **नेस्टिंग गहराई** रूट से **`WORKFLOWS_MAX_INNER_WORKFLOW_DEPTH`**,
   * की **कुल संख्या** आंतरिक-वर्कफ़्लो चरणों (edges) की **`WORKFLOWS_MAX_INNER_WORKFLOW_COUNT`**।\
     देखें [सीमाएँ और environment variables](#limits-and-environment-variables) नीचे।
3. **इनलाइनिंग**\
   प्रत्येक `inner_workflow` चरण सामान्य चरणों में विस्तारित होता है: चाइल्ड चरणों के नाम बन जाते हैं **`{inner_step_name}__{child_step_name}`** (टकराव handling के साथ), selectors फिर से लिखे जाते हैं (`$inputs` / `$steps` चाइल्ड में, और पैरेंट संदर्भों को `$steps.<inner_step_name>…`), फिर आंतरिक चरण हटा दिया जाता है। संकलन का शेष भाग (parse, workflow specification validation, execution graph construction, step initialization) केवल एक सपाट वर्कफ़्लो देखता है।
4. **पार्सिंग और सत्यापन**\
   समतल JSON को ब्लॉक मैनिफ़ेस्ट्स के साथ पार्स किया जाता है, `validate_workflow_specification` चलता है, और निष्पादन ग्राफ़ किसी भी अन्य वर्कफ़्लो की तरह बनाया जाता है।

## उदाहरण (Python)

निम्नलिखित पैटर्न इससे मेल खाता है `examples/workflows/inner_workflows/main.py` इस रिपॉजिटरी में उदाहरण: id द्वारा एक सहेजा गया वर्कफ़्लो resolve करें, पैरेंट image को चाइल्ड के अपेक्षित input नाम में bind करें, फिर downstream पैरेंट चरण से चाइल्ड output का उपयोग करें।

```python
import json
import os

from inference.core.managers.base import ModelManager
from inference.core.registries.roboflow import RoboflowModelRegistry
from inference.core.workflows.core_steps.common.entities import StepExecutionMode
from inference.core.workflows.execution_engine.core import ExecutionEngine
from inference.models.utils import ROBOFLOW_MODEL_TYPES

WORKFLOW_DEFINITION = {
    "version": "1.0",
    "inputs": [
        {"type": "WorkflowImage", "name": "image"},
    ],
    "steps": [
        {
            "type": "roboflow_core/inner_workflow@v1",
            "name": "inner",
            "workflow_workspace_id": "your-workspace",
            "workflow_id": "your-workflow-id",
            "workflow_version_id": "optional-version-id",
            "parameter_bindings": {
                "image": "$inputs.image",
            },
        },
        {
            "type": "roboflow_core/roboflow_classification_model@v2",
            "name": "classification",
            "images": "$steps.inner.dynamic_crop_output",
            "model_id": "resnet50",
        },
    ],
    "outputs": [
        {
            "type": "JsonField",
            "name": "predictions",
            "selector": "$steps.classification.predictions",
        },
    ],
}

if __name__ == "__main__":
    model_registry = RoboflowModelRegistry(ROBOFLOW_MODEL_TYPES)
    model_manager = ModelManager(model_registry=model_registry)

    execution_engine = ExecutionEngine.init(
        workflow_definition=WORKFLOW_DEFINITION,
        init_parameters={
            "workflows_core.model_manager": model_manager,
            "workflows_core.api_key": os.getenv("ROBOFLOW_API_KEY"),
            "workflows_core.step_execution_mode": StepExecutionMode.LOCAL,
        },
    )

    result = execution_engine.run(
        runtime_parameters={
            "image": {
                "type": "file",
                "value": "/path/to/your/image.jpg",
            },
        },
    )

    print(json.dumps(result, indent=2, default=str))
```

workspace, workflow, version, model, output selectors, और image path को उन मानों से बदलें जो आपके सहेजे गए वर्कफ़्लो और पैरेंट ग्राफ़ से मेल खाते हों। मुख्य आवश्यकता यह है कि **`parameter_bindings`** keys मेल खाएँ **चाइल्ड** वर्कफ़्लो के `inputs[].name` फ़ील्ड्स।

## सीमाएँ और environment variables

| चर                                   | डिफ़ॉल्ट | अर्थ                                                                                                                                       |
| ------------------------------------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| `WORKFLOWS_MAX_INNER_WORKFLOW_DEPTH` | `4`      | अधिकतम **गहराई** रूट वर्कफ़्लो से संयोजन ग्राफ़ की: प्रत्येक प्रत्यक्ष `inner_workflow` चाइल्ड किसी पथ पर एक स्तर के रूप में गिना जाता है। |
| `WORKFLOWS_MAX_INNER_WORKFLOW_COUNT` | `32`     | अधिकतम **संख्या** की `inner_workflow` पूरी नेस्टेड परिभाषा में चरणों की (प्रत्येक आंतरिक चरण संयोजन ग्राफ़ में एक edge है)।                |

**चक्र:** संयोजन ग्राफ़ एक **DAG**होना चाहिए। आपके पास नेस्टेड संदर्भों का चक्र नहीं हो सकता (उदाहरण के लिए, workflow A में B को एम्बेड करना, और B में A को एम्बेड करना), भले ही प्रत्येक वर्कफ़्लो का प्रति-चरण निष्पादन ग्राफ़ चक्रीय-रहित हो।

उल्लंघन कंपाइल-समय त्रुटियाँ उत्पन्न करते हैं (`InnerWorkflowNestingDepthError`, `InnerWorkflowTotalCountError`, `InnerWorkflowCompositionCycleError`, आदि) जिनके संदेश गहराई, संख्या, या चक्र की भागीदारी का वर्णन करते हैं।

## संबंधित पठन

* [वर्कफ़्लो परिभाषाएँ](/workflows/hi/developer-guide/developer-guide/definitions.md) - JSON संरचना, inputs, steps, outputs
* [कंपाइलर](/workflows/hi/developer-guide/developer-guide/compiler.md) - समग्र संकलन चरण
* [वर्कफ़्लो निष्पादन](/workflows/hi/developer-guide/developer-guide/workflow-execution.md) - संकलन के बाद का रनटाइम व्यवहार
