Skip to Main Content
DocsTemplates & ModulesModularization and Reuse

Modularization and Reuse

Publish the complete workflow as a module, and then reuse it through the input/output contract and version strategy of sub_workflow.

When you reach the second and third workflows, you will find that a certain piece of logic appears repeatedly - pulling ASA data, sending Slack messages, and generating Excel reports. If you continue to copy and paste, you will have to change three places to change one place, the test will be repeated, and the version will be out of control. It’s time to do modularization at this time.

Templates Vs Modules Again

Template = a snapshot of the starting document, which evolves independently after cloning; module = a sub-process that can be referenced, and the caller will automatically benefit after the upgrade. The two are not substitutes, but complementary. This page talks about modules.

What Is A "Module"

A module is essentially a complete workflow with a module contract. The contract additionally discloses:

  • inputs — Parameters that the caller must pass in (with name, type, required, default value, description)
  • outputs — The structured result generated after execution (can be directly referenced by the caller)
  • version — Semantic version number to facilitate caller locking
yaml
name: my-team-text-formatter
version: "1.0.0"

module:
  enabled: true
  display_name: "团队文本格式化"
  contract_version: "1.0.0"
  inputs:
    - name: text
      type: string
      required: true
      maps_to_variable: text
    - name: prefix
      type: string
      required: false
      default: "[INFO]"
      maps_to_variable: prefix
  outputs:
    - name: formatted_text
      type: string
      source: "{{var:formatted_text}}"

variables:
  text: ""
  prefix: "[INFO]"
  formatted_text: ""

workflow:
  - step: format_text
    code:
      language: python
      script: |
        import os
        prefix = os.environ.get("WF_VAR_PREFIX", "[INFO]")
        text = os.environ.get("WF_VAR_TEXT", "")
        print(f"FORMATTED={prefix} {text}")
    extract:
      - pattern: 'FORMATTED=(.*)'
        variable: formatted_text
    idempotent: true

After having the contract, the sub_workflow step of the caller (parent workflow) will:

  • Check required input, output mappings and references when editing and validating;
  • The runtime passes in inputs in a separate sub-execution scope and returns only explicitly mapped outputs;
  • The editor can display input, output and version information according to the contract.

How the Parent Workflow Calls the Module

yaml
workflow:
  - step: build_report
    agent: writer
    input: "生成今日运营摘要"

  - step: format_report
    sub_workflow:
      name: my-team-text-formatter
      version_strategy: range
      version_range: "^1.0.0"
      inputs:
        text: "{{steps.build_report.output}}"
        prefix: "[日报]"
      outputs:
        formatted_text: formatted_text
    depends_on:
      - build_report

  - step: save_result
    agent: writer
    depends_on:
      - format_report
    input: "请检查并整理:{{formatted_text}}"

Key points:

  • name Fill in the module workflow name, or select a specific workflow in the editor.
  • inputs corresponds to the input name in the module contract.
  • outputs The left side is the parent workflow variable, and the right side is the output name exposed by the module; after the call is completed, the parent variable is directly referenced.
  • The module output in the example is available via {{formatted_text}} Read.

Turn Existing Workflows Into Modules: Promote to Module

The current "Promote to module" applies to the entire workflow and will not be automatically extracted from the selected steps in the canvas. Process:

  1. First organize the logic to be reused into a workflow with clear boundaries and save it.
  2. Select "Promote to module" in the editor's More menu or workflow settings.
  3. In the pop-up window:
    • Fill in the display name, description, classification and contract version;
    • Declare the values that need to be passed in from the parent workflow as inputs;
    • Declare the results that the parent workflow is allowed to read as outputs, and fill in the source for each output.
  4. After saving, this workflow will appear as a module in the module library; the original workflow content will not be replaced or deleted.
Promote’s Mental Model

Modules can be understood as functions with public parameters and return values. Currently, it is necessary to organize the target logic into a complete workflow, and then upgrade the entire workflow into a module.

Module Upgrade and Version Compatibility

The module contract has contract_version, and the parent workflow can be selected in sub_workflow:

  • version_strategy: latest — Use the latest version currently parsable.
  • version_strategy: pinned + pinned_version — Lock a specific version.
  • version_strategy: range + version_range — Resolved by version range.

What is a "compatible change"?

  • ✓ Add an optional input (required/default values are not considered broken)
  • ✓ Add an output field
  • ✗ Delete/rename input
  • ✗ Delete/rename output
  • ✗ Change input type

When making changes that break compatibility, the semantic version should be upgraded to the next MAJOR. The platform does not enforce, but is protected when the caller locks ^X.Y.Z.

Loop Detection

Module A cannot indirectly reference itself. The platform performs detection on two levels:

  1. Static detection at release time — When saving a module, DFS scans the dependency graphs of all other modules it references and refuses to save if there are loops.
  2. Runtime dynamic detection — If a cycle resolved by the runtime occurs during execution (for example, it is referenced after a conditional branch), an error will be thrown immediately.

Maximum recursion depth depends on the plan: Free does not support sub_workflow; Pro allows 3 levels, Team 5, and Enterprise 8. This is the depth of the parent → child → grandchild call chain, not the number of fan-out calls at one level.

Variable Isolation

The module runs as a "child WorkflowExecutionContext", completely isolated from the parent context:

  • The parent's variables/steps outputs/agents are not inherited to the child by default;
  • The child's internal step output will not overflow to the parent - the parent can only see the outputs declared in the contract;
  • The only way to pass data across parent and child is inputs / outputs (explicit contract).

If a sub-workflow requires Agent or knowledge base inheritance, you should use the explicit inheritance configuration provided by sub_workflow and do not rely on implicit sharing.

Demote from module: Change the module back to normal workflow

Demote will unmark the module of the current workflow and return it to the normal workflow; it will not automatically expand the module steps to each caller.

  1. Open the module itself and select "Downgrade to normal workflow" in the workflow settings, which can also be entered from the operation menu of the workflow list;
  2. If there is a parent workflow that references the module, the system will list the references and prevent direct downgrade;
  3. Only confirm that these callers have been adjusted before continuing. Forced downgrade will not rewrite the parent workflow for you, and the original sub_workflow reference may become invalid at runtime.

Downgrading does not delete the workflow content; it simply removes the module contract and module identity. Built-in modules cannot be downgraded.

Where to Manage All Modules

The main navigation "Module Library" on the left displays the modules available for the current account. Depending on the module source, it can be:

  • Browse and search modules, then filter or sort them by the fields available in the current UI;
  • Instantiate the Market module as an editable workflow, or update references in the library when there is a new version of the Market;
  • Uninstall the downloaded market module; before uninstalling, you need to confirm that no workflow still refers to it by name;
  • For the module you promoted, maintain the contract in the original workflow settings or downgrade it to a normal workflow. There are currently no module ownership transfer operations.

When To Make Modules

  • ✓ The same piece of logic appears in more than 2 workflows
  • ✓ A logically stable and clear external contract (typically "sending messages/checking reports/generating Markdown")
  • ✓ A single workflow has exceeded 15 steps, and its readability has decreased.
  • ✗ A piece of logic is only used once and will not be reused in the future - directly inlined
  • ✗ A small utility function of 2–3 lines - code reuse using code steps is more natural than modules

Next

Last Updated · 2026-07-30

Was this page helpful?