Dify-chatflow-iteration

質問:Difyプラットフォーム(どのバージョン)は、オーケストレーションプロセス中に反復ノード内に反復ノードをネストする機能をサポートしていますか?

以前私も同様の要件に遭遇したことがあり、同じフロー内でイテレーションやループをさらにネストさせることができませんでした。その際の対処法として、内側のイテレーションをサブフロー(新しいワークフローを作成し、ツールとして公開)に抽出しました。

参考になれば幸いです。

ご回答ありがとうございます。私も同様の方法を試してみましたが、イテレーション内でworkflowを公開するツールを呼び出すとエラーが発生し、まだ解決方法が見つかっていません。

Difyのバージョン:v1.4.1

エラーメッセージ:

{“event”: “error”, “conversation_id”: “fc5c8beb-7b1b-481f-a3ee-1f0157250820”, “message_id”: “7e74f498-dffb-4f5a-ab52-6440cdff222c”, “created_at”: 1764059934, “code”: “invalid_param”, “status”: 400, “message”: “実行失敗: ‘AnonymousUserMixin’ オブジェクトに ‘session_id’ 属性がありません”}

image

私はクラウド版で試してみたところ、動作しました。

2つのアプリ:

app:
  description: ''
  icon: 🤖
  icon_background: '#FFEAD5'
  mode: advanced-chat
  name: Outer iteration
  use_icon_as_answer_icon: false
dependencies: []
kind: app
version: 0.5.0
workflow:
  conversation_variables: []
  environment_variables: []
  features:
    file_upload:
      allowed_file_extensions:
      - .JPG
      - .JPEG
      - .PNG
      - .GIF
      - .WEBP
      - .SVG
      allowed_file_types:
      - image
      allowed_file_upload_methods:
      - local_file
      - remote_url
      enabled: false
      fileUploadConfig:
        audio_file_size_limit: 50
        batch_count_limit: 5
        file_size_limit: 15
        image_file_batch_limit: 10
        image_file_size_limit: 10
        single_chunk_attachment_limit: 10
        video_file_size_limit: 100
        workflow_file_upload_limit: 10
      image:
        enabled: false
        number_limits: 3
        transfer_methods:
        - local_file
        - remote_url
      number_limits: 3
    opening_statement: ''
    retriever_resource:
      enabled: true
    sensitive_word_avoidance:
      enabled: false
    speech_to_text:
      enabled: false
    suggested_questions: []
    suggested_questions_after_answer:
      enabled: false
    text_to_speech:
      enabled: false
      language: ''
      voice: ''
  graph:
    edges:
    - data:
        isInIteration: false
        isInLoop: false
        sourceType: start
        targetType: code
      id: 1767664259503-source-1767664274225-target
      source: '1767664259503'
      sourceHandle: source
      target: '1767664274225'
      targetHandle: target
      type: custom
      zIndex: 0
    - data:
        isInIteration: false
        isInLoop: false
        sourceType: code
        targetType: iteration
      id: 1767664274225-source-1767664632458-target
      source: '1767664274225'
      sourceHandle: source
      target: '1767664632458'
      targetHandle: target
      type: custom
      zIndex: 0
    - data:
        isInIteration: true
        isInLoop: false
        iteration_id: '1767664632458'
        sourceType: iteration-start
        targetType: tool
      id: 1767664632458start-source-1767664645351-target
      source: 1767664632458start
      sourceHandle: source
      target: '1767664645351'
      targetHandle: target
      type: custom
      zIndex: 1002
    - data:
        isInIteration: false
        isInLoop: false
        sourceType: iteration
        targetType: answer
      id: 1767664632458-source-1767664662774-target
      source: '1767664632458'
      sourceHandle: source
      target: '1767664662774'
      targetHandle: target
      type: custom
      zIndex: 0
    nodes:
    - data:
        selected: false
        title: User Input
        type: start
        variables: []
      height: 73
      id: '1767664259503'
      position:
        x: 0
        y: 49
      positionAbsolute:
        x: 0
        y: 49
      selected: false
      sourcePosition: right
      targetPosition: left
      type: custom
      width: 242
    - data:
        code: "function main({query}) {\n    return {\n        result: query.split('').filter(it\\\n          => !!it.trim())\n    }\n}\n"
        code_language: javascript
        outputs:
          result:
            children: null
            type: array[string]
        selected: false
        title: Code
        type: code
        variables:
        - value_selector:
          - sys
          - query
          value_type: string
          variable: query
      height: 52
      id: '1767664274225'
      position:
        x: 342
        y: 60
      positionAbsolute:
        x: 342
        y: 60
      selected: false
      sourcePosition: right
      targetPosition: left
      type: custom
      width: 242
    - data:
        error_handle_mode: terminated
        flatten_output: true
        height: 172
        is_parallel: true
        iterator_input_type: array[string]
        iterator_selector:
        - '1767664274225'
        - result
        output_selector:
        - '1767664645351'
        - output
        output_type: array[string]
        parallel_nums: 10
        selected: false
        start_node_id: 1767664632458start
        title: Iteration
        type: iteration
        width: 620
      height: 172
      id: '1767664632458'
      position:
        x: 684
        y: 0
      positionAbsolute:
        x: 684
        y: 0
      selected: true
      sourcePosition: right
      targetPosition: left
      type: custom
      width: 620
      zIndex: 1
    - data:
        desc: ''
        isInIteration: true
        selected: false
        title: ''
        type: iteration-start
      draggable: false
      height: 48
      id: 1767664632458start
      parentId: '1767664632458'
      position:
        x: 60
        y: 62
      positionAbsolute:
        x: 744
        y: 62
      selectable: false
      sourcePosition: right
      targetPosition: left
      type: custom-iteration-start
      width: 44
      zIndex: 1002
    - data:
        isInIteration: true
        isInLoop: false
        is_team_authorization: true
        iteration_id: '1767664632458'
        paramSchemas:
        - auto_generate: null
          default: ''
          form: llm
          human_description:
            en_US: ''
            ja_JP: ''
            pt_BR: ''
            zh_Hans: ''
          label:
            en_US: text
            ja_JP: text
            pt_BR: text
            zh_Hans: text
          llm_description: ''
          max: null
          min: null
          name: text
          options: []
          placeholder:
            en_US: ''
            ja_JP: ''
            pt_BR: ''
            zh_Hans: ''
          precision: null
          required: true
          scope: null
          template: null
          type: string
        params:
          text: ''
        plugin_id: null
        plugin_unique_identifier: null
        provider_icon:
          background: '#FFEAD5'
          content: 🤖
        provider_id: a8faebfb-0feb-4063-96d4-78de859d17c5
        provider_name: Inner iteration
        provider_type: workflow
        selected: false
        title: Inner iteration
        tool_configurations: {}
        tool_description: ''
        tool_label: Inner iteration
        tool_name: repeat_and_concat_emoji
        tool_node_version: '2'
        tool_parameters:
          text:
            type: mixed
            value: '{{#1767664632458.item#}}'
        type: tool
      height: 52
      id: '1767664645351'
      parentId: '1767664632458'
      position:
        x: 184
        y: 60
      positionAbsolute:
        x: 868
        y: 60
      selected: false
      sourcePosition: right
      targetPosition: left
      type: custom
      width: 242
      zIndex: 1002
    - data:
        answer: '{{#1767664632458.output#}}'
        selected: false
        title: Answer
        type: answer
        variables: []
      height: 103
      id: '1767664662774'
      position:
        x: 1404
        y: 34
      positionAbsolute:
        x: 1404
        y: 34
      selected: false
      sourcePosition: right
      targetPosition: left
      type: custom
      width: 242
    viewport:
      x: 185.71703578532265
      y: 301.09544880644967
      zoom: 0.5638670037341258
  rag_pipeline_variables: []

および

app:
  description: ''
  icon: 🤖
  icon_background: '#FFEAD5'
  mode: workflow
  name: Inner iteration
  use_icon_as_answer_icon: false
dependencies: []
kind: app
version: 0.5.0
workflow:
  conversation_variables: []
  environment_variables: []
  features:
    file_upload:
      allowed_file_extensions:
      - .JPG
      - .JPEG
      - .PNG
      - .GIF
      - .WEBP
      - .SVG
      allowed_file_types:
      - image
      allowed_file_upload_methods:
      - local_file
      - remote_url
      enabled: false
      fileUploadConfig:
        audio_file_size_limit: 50
        batch_count_limit: 5
        file_size_limit: 15
        image_file_batch_limit: 10
        image_file_size_limit: 10
        single_chunk_attachment_limit: 10
        video_file_size_limit: 100
        workflow_file_upload_limit: 10
      image:
        enabled: false
        number_limits: 3
        transfer_methods:
        - local_file
        - remote_url
      number_limits: 3
    opening_statement: ''
    retriever_resource:
      enabled: true
    sensitive_word_avoidance:
      enabled: false
    speech_to_text:
      enabled: false
    suggested_questions: []
    suggested_questions_after_answer:
      enabled: false
    text_to_speech:
      enabled: false
      language: ''
      voice: ''
  graph:
    edges:
    - data:
        isInIteration: false
        isInLoop: false
        sourceType: start
        targetType: code
      id: 1767664421409-source-1767664444690-target
      source: '1767664421409'
      sourceHandle: source
      target: '1767664444690'
      targetHandle: target
      type: custom
      zIndex: 0
    - data:
        isInIteration: false
        isInLoop: false
        sourceType: code
        targetType: iteration
      id: 1767664444690-source-1767664515327-target
      source: '1767664444690'
      sourceHandle: source
      target: '1767664515327'
      targetHandle: target
      type: custom
      zIndex: 0
    - data:
        isInIteration: true
        isInLoop: false
        iteration_id: '1767664515327'
        sourceType: iteration-start
        targetType: code
      id: 1767664515327start-source-1767664525741-target
      source: 1767664515327start
      sourceHandle: source
      target: '1767664525741'
      targetHandle: target
      type: custom
      zIndex: 1002
    - data:
        isInIteration: false
        isInLoop: false
        sourceType: iteration
        targetType: end
      id: 1767664515327-source-1767664551992-target
      source: '1767664515327'
      sourceHandle: source
      target: '1767664551992'
      targetHandle: target
      type: custom
      zIndex: 0
    nodes:
    - data:
        selected: false
        title: User Input
        type: start
        variables:
        - default: ''
          hint: ''
          label: text
          max_length: 48
          options: []
          placeholder: ''
          required: true
          type: paragraph
          variable: text
      height: 109
      id: '1767664421409'
      position:
        x: 0
        y: 146
      positionAbsolute:
        x: 0
        y: 146
      selected: false
      sourcePosition: right
      targetPosition: left
      type: custom
      width: 242
    - data:
        code: "def main(text: str) -> dict:\n    \"\"\"将输入的字符串重复 3 次,并将其拆分为单个字符的列表。\n\n    参数:\n        text (str): 输入的字符串。\n        \n    返回:\n       \n          dict: 包含结果列表的字典。\n    \"\"\"\n    # 1. text * 3 对应 JS 的 text.repeat(3)\n   \n          # 2. list(...) 对应 JS 的 .split(\"\"), 将字符串转换为字符列表\n    return {\n   \n          \"result\": list(text * 3)\n    }"
        code_language: python3
        outputs:
          result:
            children: null
            type: array[string]
        selected: false
        title: Code
        type: code
        variables:
        - value_selector:
          - '1767664421409'
          - text
          value_type: string
          variable: text
      height: 52
      id: '1767664444690'
      position:
        x: 342
        y: 175
      positionAbsolute:
        x: 342
        y: 175
      selected: false
      sourcePosition: right
      targetPosition: left
      type: custom
      width: 242
    - data:
        error_handle_mode: terminated
        flatten_output: true
        height: 402
        is_parallel: false
        iterator_input_type: array[string]
        iterator_selector:
        - '1767664444690'
        - result
        output_selector:
        - '1767664525741'
        - result
        output_type: array[string]
        parallel_nums: 10
        selected: false
        start_node_id: 1767664515327start
        title: Iteration
        type: iteration
        width: 547
      height: 402
      id: '1767664515327'
      position:
        x: 684
        y: 0
      positionAbsolute:
        x: 684
        y: 0
      selected: false
      sourcePosition: right
      targetPosition: left
      type: custom
      width: 547
      zIndex: 1
    - data:
        desc: ''
        isInIteration: true
        selected: false
        title: ''
        type: iteration-start
      draggable: false
      height: 48
      id: 1767664515327start
      parentId: '1767664515327'
      position:
        x: 60
        y: 62
      positionAbsolute:
        x: 744
        y: 62
      selectable: false
      sourcePosition: right
      targetPosition: left
      type: custom-iteration-start
      width: 44
      zIndex: 1002
    - data:
        code: "\ndef main(item: str):\n    return {\n        \"result\": f\"{item} \\U0001F60A\"\n    }\n"
        code_language: python3
        isInIteration: true
        isInLoop: false
        iteration_id: '1767664515327'
        outputs:
          result:
            children: null
            type: string
        selected: false
        title: Code 2
        type: code
        variables:
        - value_selector:
          - '1767664515327'
          - item
          value_type: string
          variable: item
      height: 52
      id: '1767664525741'
      parentId: '1767664515327'
      position:
        x: 184
        y: 60
      positionAbsolute:
        x: 868
        y: 60
      selected: true
      sourcePosition: right
      targetPosition: left
      type: custom
      width: 242
      zIndex: 1002
    - data:
        outputs:
        - value_selector:
          - '1767664515327'
          - output
          value_type: array[string]
          variable: output
        selected: false
        title: Output
        type: end
      height: 88
      id: '1767664551992'
      position:
        x: 1331
        y: 157
      positionAbsolute:
        x: 1331
        y: 157
      sourcePosition: right
      targetPosition: left
      type: custom
      width: 242
    viewport:
      x: 0
      y: 0
      zoom: 0.7
  rag_pipeline_variables: []

午前中に返信した際、一つの状況を忘れてしまいました :joy: 。Dify内でプレビューする場合は、おっしゃる通りの方法で呼び出すことができますが、フロントエンドからAPIでDifyにリクエストを送る場合、エラーが発生します。

Service APIの呼び出し方法を指しているのでしょうか?こちらで試してみましたが、問題ありませんでした。

エラーメッセージから見ると、呼び出し時のUserに何らかの問題があるように思われます。

Service API を通じて呼び出されているため、User の問題かもしれないと考えたが、まだ解決方法が見つからない。