├── LICENSE ├── README.md ├── README_CH.md ├── README_EN.md ├── difyDslGenCheck.py ├── difyDslGenCheck_ch.py ├── difyDslGenCheck_en.py ├── dify_chatbot └── DifyWorkflowGeneate.yml ├── example ├── adoviser_bot.yml └── manual_search.yml ├── images ├── DifyWorkflowGenerator.jpg ├── DifyWorkflowGenerator_initial.jpg ├── adoviser_bot.png └── manual_search.jpg ├── requirements.txt └── workflow_generator_prompt.yml /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Tomatio13 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Dify ワークフロージェネレーター プロンプト 2 | 3 | ## 概要 4 | 5 | このリポジトリは、[Dify](https://dify.ai)のワークフローを生成するためのプロンプト定義を提供します。YAMLフォーマットで記述された詳細なプロンプト仕様に従って、様々なユースケースに対応したワークフローを作成することができます。 6 | 7 | ## 特徴 8 | 9 | - 3つの基本ノード(開始、LLM、終了)による単純なワークフロー生成 10 | - 高度な機能を持つノードタイプのサポート: 11 | - 質問分類器 12 | - 知識検索 13 | - HTTPリクエスト 14 | - JSONパース 15 | - IF/ELSEノード 16 | - codeノード 17 | - Variable Aggregatorノード 18 | 19 | ## ファイルの内容 20 | 21 | - workflow_generator_prompt.yml 22 | - ワークフロー生成プロンプトの定義 23 | - dify_chatbot/DifyWorkflowGeneate.yml 24 | - workflow_generator_prompt.ymlが適用されたDifyのチャットボット 25 | - exampl/manual_search.yml 26 | - ワークフロー生成の例 27 | 28 | ## 使用方法 29 | 30 | 1. git cloneしてください。 31 | ``` 32 | https://github.com/Tomatio13/DifyWorkFlowGenerator.git 33 | ``` 34 | 2. ワークフロー生成プロンプトdify_chatbot/DifyWorkflowGeneate.ymlをDifyにインポートしてください。 35 | インポートすると以下のような画面になります。 36 | ![Dify ワークフロージェネレーター](./images/DifyWorkflowGenerator_initial.jpg) 37 | 38 | *注意事項*: このプロントは、gpt-4oではなく、claude-3-5-sonnetで実行してください。gpt-4oでは、ワークフローが正しく生成されません。 39 | 40 | 3. 必要な情報を準備: 41 | - ワークフローの目的 42 | - 知識獲得の制御ブロックを利用する場合、ナレッジのdataset_idsを調べて下さい。 43 | - 調べ方 44 | ナレッジを含むワークフローを作成してください。 45 | 作成したワークフローのDSLをエクスポートして下さい。 46 | ```yml 47 | type: knowledge-retrieval 48 | title: Ubuntu知識取得 49 | dataset_ids: 50 | - 84782981-6a4d-4d19-9189-dd72fe435a57 51 | retrieval_mode: multiple 52 | ``` 53 | 上記にようにdataset_idsが記述されているのでメモしておいて下さい。 54 | 55 | 4. 以下の画像のようにプロンプトを作成して実行して下さい。 56 | ![Dify ワークフロージェネレーター](./images/DifyWorkflowGenerator.jpg) 57 | 図のようにDifyにインポート可能なYAMLファイルが生成されます。 58 | 5. 生成されたYAMLを別ファイルに貼り付けて、Difyにインポートして下さい。 59 | 6. 以下は、example/manual_search.ymlをインポートした画面です。 60 | ![Dify ワークフロージェネレーター](./images/manual_search.jpg) 61 | 62 | ## サンプル 63 | example/adoviser_bot.yml 64 | - 質問分類器、知識検索、IF/ELSE分岐、テンプレート変換、パラメータ抽出を利用したワークフロー 65 | ![ワークフローの画像](./images/adoviser_bot.png) 66 | 67 | ## サポートされるノードタイプ 68 | 69 | ### 基本ノード 70 | - 開始ノード:ユーザー入力の受付 71 | - テキスト入力(短文・段落) 72 | - 数値入力 73 | - ファイル入力(ドキュメント、画像、音声、動画) 74 | - LLMノード:OpenAI GPT-4による処理 75 | - 終了ノード:結果の出力 76 | 77 | ### 拡張ノード 78 | - HTTPリクエストノード:外部API連携 79 | - JSONパースノード:JSON処理 80 | - 質問分類器ノード:入力の分類 81 | - 知識検索ノード:データセットからの情報検索 82 | - IF/ELSEノード:条件分岐 83 | - codeノード:Pythonコードの実行 84 | - Variable Aggregatorノード:複数ノードからの出力を集約 85 | - Document Extractorノード:ドキュメントからのテキスト抽出 86 | - Template Transformノード:テンプレートベースの文字列生成 87 | - Answerノード:応答出力の制御 88 | - Parameter Extractorノード:テキストからのパラメータ抽出 89 | - YouTubeトランスクリプトノード:YouTube動画の字幕取得 90 | - JinaReaderノード:ウェブページのコンテンツ抽出 91 | - TavilySearchノード:ウェブ検索の実行 92 | 93 | ## ワークフロー例 94 | 95 | ### シンプルな処理フロー 96 | ```yaml 97 | 開始 → LLM → 終了 98 | ``` 99 | 100 | ### 分岐を含むフロー 101 | ```yaml 102 | 開始 → 質問分類器 → 知識検索 → LLM → 終了 103 | → 知識検索 → LLM → 終了 104 | ``` 105 | 106 | ### IF/ELSE分岐フロー 107 | ```yaml 108 | 開始 → IF/ELSE → LLM(True) → 終了 109 | → LLM(False) → 終了 110 | ``` 111 | 112 | ### 変数集約フロー 113 | ```yaml 114 | 開始 → LLM1 → Variable Aggregator → 終了 115 | → LLM2 ↗ 116 | ``` 117 | 118 | ### ドキュメント処理フロー 119 | ```yaml 120 | 開始(ファイル入力) → Document Extractor → LLM → 終了 121 | ``` 122 | 123 | ### テンプレート変換フロー 124 | ```yaml 125 | 開始 → Template Transform → LLM → 終了 126 | ``` 127 | 128 | ### 複合処理フロー 129 | ```yaml 130 | 開始(ファイル) → Document Extractor → Template Transform → LLM → 終了 131 | ``` 132 | 133 | ### 応答制御フロー 134 | ```yaml 135 | 開始 → LLM → Answer → 終了 136 | ``` 137 | 138 | ### 複合応答フロー 139 | ```yaml 140 | 開始 → LLM1 → Template Transform → Answer → 終了 141 | → LLM2 ↗ 142 | ``` 143 | 144 | ### パラメータ抽出フロー 145 | ```yaml 146 | 開始 → Parameter Extractor → LLM → 終了 147 | ``` 148 | 149 | ### 複合パラメータ処理フロー 150 | ```yaml 151 | 開始 → Parameter Extractor → Template Transform → Answer → 終了 152 | ``` 153 | 154 | ### YouTubeトランスクリプトフロー 155 | ```yaml 156 | 開始 → YouTubeトランスクリプト → LLM → 終了 157 | ``` 158 | 159 | ### ウェブコンテンツ処理フロー 160 | ```yaml 161 | 開始 → JinaReader → LLM → 終了 162 | ``` 163 | 164 | ### ウェブ検索フロー 165 | ```yaml 166 | 開始 → TavilySearch → LLM → 終了 167 | ``` 168 | 169 | ### 複合メディア処理フロー 170 | ```yaml 171 | 開始 → YouTubeトランスクリプト → Template Transform → LLM → 終了 172 | → JinaReader → ↗ 173 | ``` 174 | 175 | ## 制限事項 176 | 177 | - OpenAIのgpt-4oモデルのみサポート(変更は、Difyの画面上でモデル設定して下さい。) 178 | - codeノードでのboolean型の使用不可(number型で0/1を使用) 179 | - ファイル入力は以下の形式のみサポート: 180 | - ドキュメント(PDF、Word等) 181 | - 画像(JPG、PNG等) 182 | - 音声(MP3、WAV等) 183 | - 動画(MP4等) 184 | - Template Transformノードの制約: 185 | - 出力は常にstring型 186 | - Jinja2テンプレート構文のみサポート 187 | - 複雑な制御構文は非推奨 188 | - Answerノードの制約: 189 | - arrayObject型の変数は非対応 190 | - チャットモードでの特別な動作に注意 191 | - 変数参照は{{#ノードID.変数名#}}形式のみ 192 | - Parameter Extractorノードの制約: 193 | - パラメータ名は一意である必要がある 194 | - 必須パラメータは抽出必須 195 | - 画像処理は対応モデルのみ使用可能 196 | - 推論モードはpromptまたはfunction_callのみ 197 | - 未対応のノード: 198 | - イテレーションノード 199 | - 変数代入ノード 200 | - リスト処理 201 | - ツールノード全般 202 | - YouTubeトランスクリプトノードの制約: 203 | - 公開動画のみ対応 204 | - 字幕が存在する動画のみ対応 205 | - 指定言語の字幕が必要 206 | - JinaReaderノードの制約: 207 | - アクセス可能なウェブページのみ対応 208 | - JavaScript動的コンテンツは完全な取得が困難 209 | - プロキシ設定が必要な場合あり 210 | - TavilySearchノードの制約: 211 | - 検索結果数に制限あり(最大10件) 212 | - 一部のドメインでアクセス制限の可能性 213 | - 検索深度による処理時間の違いに注意 214 | 215 | ## difyDslGenCheck.pyについて 216 | *注意*: 本機能は実験的な機能のため、ワークフローの生成に失敗する可能性が多分にあります。Difyのワークフロー生成機能を利用して下さい。 217 | ### 機能 218 | - ワークフローの概要を元に、DSLファイルを生成する。 219 | - 生成したDSLファイルの構造が正しいかチェックする。 220 | - チェック結果を元に、DSLファイルを修正する。 221 | 222 | ### 使用方法 223 | 1. difyDslGenCheck.pyに生成したいワークフローの概要を記述して下さい。 224 | 225 | ```python 226 | wanted_workflow = """ 227 | プロンプト: 228 | 目的:旅行コンシェルジェのように旅行先の目的地の情報を調査するためのツール 229 | 1. 入力情報として、旅行先の地名を入力してもらう。 230 | 2. インターネットを検索し、旅行先の観光情報やグルメ情報が書かれたURLを3つ入手する。 231 | 3. 3つのURLから情報を取得する。3つは並列に処理すること。 232 | 4. 3つのURLから得た情報をLLに入力し、良好先の情報を整理して出力する。出力は、旅行情報雑誌に掲載できる文章に仕上げること。 233 | """ 234 | ``` 235 | 2. スクリプトを実行して下さい。 236 | ```bash 237 | export ANTHROPIC_API_KEY="your_anthropic_api_key" 238 | python -m venv dify_env 239 | source dify_env/bin/activate 240 | pip install -r requirements.txt 241 | python difyDslGenCheck.py 242 | ``` 243 | 244 | 245 | ## ライセンス 246 | 247 | MITライセンス 248 | 249 | ## 貢献について 250 | 251 | プルリクエストや課題の報告を歓迎します。 252 | 253 | ## 関連リンク 254 | 255 | - [Dify公式サイト](https://dify.ai) 256 | - [Difyドキュメント](https://docs.dify.ai) -------------------------------------------------------------------------------- /README_CH.md: -------------------------------------------------------------------------------- 1 | # Dify 工作流生成器提示词 2 | 3 | ## 概述 4 | 5 | 本仓库为[Dify](https://dify.ai)提供工作流生成的提示词定义。您可以按照YAML格式编写的详细提示词规范,创建适用于各种用例的工作流。 6 | 7 | ## 特点 8 | 9 | - 使用三个基本节点(开始、LLM、结束)生成简单工作流 10 | - 支持高级功能节点类型: 11 | - 问题分类器 12 | - 知识检索 13 | - HTTP请求 14 | - JSON解析 15 | - IF/ELSE节点 16 | - 代码节点 17 | - 变量聚合器节点 18 | 19 | ## 文件内容 20 | 21 | - workflow_generator_prompt.yml 22 | - 工作流生成提示词定义 23 | - dify_chatbot/DifyWorkflowGeneate.yml 24 | - 应用了workflow_generator_prompt.yml的Dify聊天机器人 25 | - example/manual_search.yml 26 | - 工作流生成示例 27 | 28 | ## 使用方法 29 | 30 | 1. 克隆仓库: 31 | ``` 32 | https://github.com/Tomatio13/DifyWorkFlowGenerator.git 33 | ``` 34 | 2. 将工作流生成提示词dify_chatbot/DifyWorkflowGeneate.yml导入到Dify中。 35 | 导入后,您将看到如下界面: 36 | ![Dify 工作流生成器](./images/DifyWorkflowGenerator_initial.jpg) 37 | 38 | *注意*:请使用claude-3-5-sonnet而不是gpt-4o运行此提示词。使用gpt-4o无法正确生成工作流。 39 | 40 | 3. 准备必要信息: 41 | - 工作流目的 42 | - 如果使用知识控制块,请查找dataset_ids: 43 | - 查找方法: 44 | 创建包含知识的工作流。 45 | 导出创建的工作流的DSL。 46 | ```yml 47 | type: knowledge-retrieval 48 | title: Ubuntu知识获取 49 | dataset_ids: 50 | - 84782981-6a4d-4d19-9189-dd72fe435a57 51 | retrieval_mode: multiple 52 | ``` 53 | 如上所示记录dataset_ids。 54 | 55 | 4. 按照下图所示创建并执行提示词: 56 | ![Dify 工作流生成器](./images/DifyWorkflowGenerator.jpg) 57 | 将生成如图所示可导入Dify的YAML文件。 58 | 5. 将生成的YAML复制到单独的文件中,并导入到Dify中。 59 | 6. 以下是导入example/manual_search.yml后的界面: 60 | ![Dify 工作流生成器](./images/manual_search.jpg) 61 | 62 | ## 示例 63 | example/adviser_bot.yml 64 | - 使用问题分类器、知识检索、IF/ELSE分支、模板转换和参数提取的工作流 65 | ![工作流图片](./images/adviser_bot.png) 66 | 67 | ## 支持的节点类型 68 | 69 | ### 基本节点 70 | - 开始节点:接收用户输入 71 | - 文本输入(短文本/段落) 72 | - 数值输入 73 | - 文件输入(文档、图片、音频、视频) 74 | - LLM节点:使用OpenAI GPT-4处理 75 | - 结束节点:输出结果 76 | 77 | ### 扩展节点 78 | - HTTP请求节点:外部API集成 79 | - JSON解析节点:JSON处理 80 | - 问题分类器节点:输入分类 81 | - 知识检索节点:从数据集搜索信息 82 | - IF/ELSE节点:条件分支 83 | - 代码节点:Python代码执行 84 | - 变量聚合器节点:聚合多个节点的输出 85 | - 文档提取器节点:从文档中提取文本 86 | - 模板转换节点:基于模板的字符串生成 87 | - 答案节点:响应输出控制 88 | - 参数提取器节点:从文本中提取参数 89 | - YouTube字幕节点:获取YouTube视频字幕 90 | - JinaReader节点:提取网页内容 91 | - TavilySearch节点:执行网络搜索 92 | 93 | ## 工作流示例 94 | 95 | ### 简单处理流程 96 | ```yaml 97 | 开始 → LLM → 结束 98 | ``` 99 | 100 | ### 包含分支的流程 101 | ```yaml 102 | 开始 → 问题分类器 → 知识检索 → LLM → 结束 103 | → 知识检索 → LLM → 结束 104 | ``` 105 | 106 | ### IF/ELSE分支流程 107 | ```yaml 108 | 开始 → IF/ELSE → LLM(True) → 结束 109 | → LLM(False) → 结束 110 | ``` 111 | 112 | ### 变量聚合流程 113 | ```yaml 114 | 开始 → LLM1 → 变量聚合器 → 结束 115 | → LLM2 ↗ 116 | ``` 117 | 118 | ### 文档处理流程 119 | ```yaml 120 | 开始(文件输入) → 文档提取器 → LLM → 结束 121 | ``` 122 | 123 | ### 模板转换流程 124 | ```yaml 125 | 开始 → 模板转换 → LLM → 结束 126 | ``` 127 | 128 | ### 复合处理流程 129 | ```yaml 130 | 开始(文件) → 文档提取器 → 模板转换 → LLM → 结束 131 | ``` 132 | 133 | ### 响应控制流程 134 | ```yaml 135 | 开始 → LLM → 答案 → 结束 136 | ``` 137 | 138 | ### 复合响应流程 139 | ```yaml 140 | 开始 → LLM1 → 模板转换 → 答案 → 结束 141 | → LLM2 ↗ 142 | ``` 143 | 144 | ### 参数提取流程 145 | ```yaml 146 | 开始 → 参数提取器 → LLM → 结束 147 | ``` 148 | 149 | ### 复合参数处理流程 150 | ```yaml 151 | 开始 → 参数提取器 → 模板转换 → 答案 → 结束 152 | ``` 153 | 154 | ### YouTube字幕流程 155 | ```yaml 156 | 开始 → YouTube字幕 → LLM → 结束 157 | ``` 158 | 159 | ### 网页内容处理流程 160 | ```yaml 161 | 开始 → JinaReader → LLM → 结束 162 | ``` 163 | 164 | ### 网络搜索流程 165 | ```yaml 166 | 开始 → TavilySearch → LLM → 结束 167 | ``` 168 | 169 | ### 复合媒体处理流程 170 | ```yaml 171 | 开始 → YouTube字幕 → 模板转换 → LLM → 结束 172 | → JinaReader → ↗ 173 | ``` 174 | 175 | ## 限制条件 176 | 177 | - 仅支持OpenAI的gpt-4o模型(请在Dify界面上更改模型设置) 178 | - 代码节点不支持布尔类型(使用数字类型的0/1) 179 | - 文件输入仅支持以下格式: 180 | - 文档(PDF、Word等) 181 | - 图片(JPG、PNG等) 182 | - 音频(MP3、WAV等) 183 | - 视频(MP4等) 184 | - 模板转换节点限制: 185 | - 输出始终为字符串类型 186 | - 仅支持Jinja2模板语法 187 | - 不建议使用复杂的控制语法 188 | - 答案节点限制: 189 | - 不支持arrayObject类型变量 190 | - 聊天模式下有特殊行为 191 | - 变量引用仅支持{{#节点ID.变量名#}}格式 192 | - 参数提取器节点限制: 193 | - 参数名必须唯一 194 | - 必须提取必需参数 195 | - 图像处理仅支持兼容模型 196 | - 推理模式仅限于prompt或function_call 197 | - 不支持的节点: 198 | - 迭代节点 199 | - 变量赋值节点 200 | - 列表处理 201 | - 工具节点 202 | - YouTube字幕节点限制: 203 | - 仅支持公开视频 204 | - 仅适用于有字幕的视频 205 | - 需要指定语言的字幕 206 | - JinaReader节点限制: 207 | - 仅支持可访问的网页 208 | - JavaScript动态内容可能无法完全获取 209 | - 可能需要代理设置 210 | - TavilySearch节点限制: 211 | - 搜索结果数量有限(最多10个) 212 | - 某些域名可能有访问限制 213 | - 搜索深度影响处理时间 214 | - TavilySearchノードの制約: 215 | ## 关于difyDslGenCheck.py 216 | *注意*:这是一个实验性功能,可能经常无法生成工作流。请使用Dify的工作流生成功能。 217 | ### 功能 218 | - 基于工作流概述生成DSL文件 219 | - 检查生成的DSL文件结构是否正确 220 | - 根据检查结果修改DSL文件 221 | 222 | 223 | ### 使用方法 224 | 1. 在difyDslGenCheck.py中描述您想要生成的工作流概述: 225 | 226 | ```python 227 | wanted_workflow = """ 228 | Prompt: 229 | 目的:一个像旅行顾问一样研究目的地信息的工具 230 | 1. 获取目的地名称作为输入信息。 231 | 2. 搜索互联网并获取3个包含该目的地旅游和美食信息的URL。 232 | 3. 从这3个URL中检索信息。并行处理这3个URL。 233 | 4. 将从3个URL获得的信息输入到LLM中,整理目的地信息并输出。输出应格式化为适合在旅游杂志上发表的文章。 234 | """ 235 | ``` 236 | 2. 执行脚本: 237 | ```bash 238 | export ANTHROPIC_API_KEY="your_anthropic_api_key" 239 | python -m venv dify_env 240 | source dify_env/bin/activate 241 | pip install -r requirements.txt 242 | python difyDslGenCheck_ch.py 243 | ``` 244 | 245 | ## 许可证 246 | 247 | MIT许可证 248 | 249 | ## 贡献 250 | 251 | 欢迎提交拉取请求和问题报告。 252 | 253 | ## 相关链接 254 | 255 | - [Dify官方网站](https://dify.ai) 256 | - [Dify文档](https://docs.dify.ai) 257 | -------------------------------------------------------------------------------- /README_EN.md: -------------------------------------------------------------------------------- 1 | # Dify Workflow Generator Prompt 2 | 3 | ## Overview 4 | 5 | This repository provides prompt definitions for generating workflows in [Dify](https://dify.ai). Following detailed prompt specifications written in YAML format, you can create workflows for various use cases. 6 | 7 | ## Features 8 | 9 | - Simple workflow generation using three basic nodes (Start, LLM, End) 10 | - Support for advanced node types: 11 | - Question Classifier 12 | - Knowledge Retrieval 13 | - HTTP Request 14 | - JSON Parser 15 | - IF/ELSE Node 16 | - Code Node 17 | - Variable Aggregator Node 18 | 19 | ## File Contents 20 | 21 | - workflow_generator_prompt.yml 22 | - Definition of workflow generation prompts 23 | - dify_chatbot/DifyWorkflowGeneate.yml 24 | - Dify chatbot with workflow_generator_prompt.yml applied 25 | - example/manual_search.yml 26 | - Example of workflow generation 27 | 28 | ## Usage 29 | 30 | 1. Clone the repository: 31 | ``` 32 | https://github.com/Tomatio13/DifyWorkFlowGenerator.git 33 | ``` 34 | 2. Import the workflow generation prompt dify_chatbot/DifyWorkflowGeneate.yml into Dify. 35 | After importing, you will see a screen like this: 36 | ![Dify Workflow Generator](./images/DifyWorkflowGenerator_initial.jpg) 37 | 38 | *Note*: Please run this prompt with claude-3-5-sonnet, not gpt-4o. Workflows will not be generated correctly with gpt-4o. 39 | 40 | 3. Prepare necessary information: 41 | - Purpose of the workflow 42 | - If using knowledge control blocks, look up the dataset_ids: 43 | - How to find them: 44 | Create a workflow that includes knowledge. 45 | Export the DSL of the created workflow. 46 | ```yml 47 | type: knowledge-retrieval 48 | title: Ubuntu Knowledge Retrieval 49 | dataset_ids: 50 | - 84782981-6a4d-4d19-9189-dd72fe435a57 51 | retrieval_mode: multiple 52 | ``` 53 | Note down the dataset_ids as shown above. 54 | 55 | 4. Create and execute the prompt as shown in the image below: 56 | ![Dify Workflow Generator](./images/DifyWorkflowGenerator.jpg) 57 | A YAML file that can be imported into Dify will be generated as shown in the figure. 58 | 5. Copy the generated YAML to a separate file and import it into Dify. 59 | 6. Below is a screen showing example/manual_search.yml after import: 60 | ![Dify Workflow Generator](./images/manual_search.jpg) 61 | 62 | ## Sample 63 | example/adviser_bot.yml 64 | - Workflow utilizing question classifier, knowledge retrieval, IF/ELSE branching, template transformation, and parameter extraction 65 | ![Workflow Image](./images/adviser_bot.png) 66 | 67 | ## Supported Node Types 68 | 69 | ### Basic Nodes 70 | - Start Node: Accepts user input 71 | - Text input (short text/paragraph) 72 | - Numeric input 73 | - File input (documents, images, audio, video) 74 | - LLM Node: Processing using OpenAI GPT-4 75 | - End Node: Output results 76 | 77 | ### Extended Nodes 78 | - HTTP Request Node: External API integration 79 | - JSON Parse Node: JSON processing 80 | - Question Classifier Node: Input classification 81 | - Knowledge Retrieval Node: Information search from datasets 82 | - IF/ELSE Node: Conditional branching 83 | - Code Node: Python code execution 84 | - Variable Aggregator Node: Aggregates output from multiple nodes 85 | - Document Extractor Node: Text extraction from documents 86 | - Template Transform Node: Template-based string generation 87 | - Answer Node: Response output control 88 | - Parameter Extractor Node: Parameter extraction from text 89 | - YouTube Transcript Node: YouTube video subtitle retrieval 90 | - JinaReader Node: Web page content extraction 91 | - TavilySearch Node: Web search execution 92 | 93 | ## Workflow Examples 94 | 95 | ### Simple Processing Flow 96 | ```yaml 97 | Start → LLM → End 98 | ``` 99 | 100 | ### Flow with Branching 101 | ```yaml 102 | Start → Question Classifier → Knowledge Retrieval → LLM → End 103 | → Knowledge Retrieval → LLM → End 104 | ``` 105 | 106 | ### IF/ELSE Branching Flow 107 | ```yaml 108 | Start → IF/ELSE → LLM(True) → End 109 | → LLM(False) → End 110 | ``` 111 | 112 | ### Variable Aggregation Flow 113 | ```yaml 114 | Start → LLM1 → Variable Aggregator → End 115 | → LLM2 ↗ 116 | ``` 117 | 118 | ### Document Processing Flow 119 | ```yaml 120 | Start(File Input) → Document Extractor → LLM → End 121 | ``` 122 | 123 | ### Template Transformation Flow 124 | ```yaml 125 | Start → Template Transform → LLM → End 126 | ``` 127 | 128 | ### Complex Processing Flow 129 | ```yaml 130 | Start(File) → Document Extractor → Template Transform → LLM → End 131 | ``` 132 | 133 | ### Response Control Flow 134 | ```yaml 135 | Start → LLM → Answer → End 136 | ``` 137 | 138 | ### Complex Response Flow 139 | ```yaml 140 | Start → LLM1 → Template Transform → Answer → End 141 | → LLM2 ↗ 142 | ``` 143 | 144 | ### Parameter Extraction Flow 145 | ```yaml 146 | Start → Parameter Extractor → LLM → End 147 | ``` 148 | 149 | ### Complex Parameter Processing Flow 150 | ```yaml 151 | Start → Parameter Extractor → Template Transform → Answer → End 152 | ``` 153 | 154 | ### YouTube Transcript Flow 155 | ```yaml 156 | Start → YouTube Transcript → LLM → End 157 | ``` 158 | 159 | ### Web Content Processing Flow 160 | ```yaml 161 | Start → JinaReader → LLM → End 162 | ``` 163 | 164 | ### Web Search Flow 165 | ```yaml 166 | Start → TavilySearch → LLM → End 167 | ``` 168 | 169 | ### Complex Media Processing Flow 170 | ```yaml 171 | Start → YouTube Transcript → Template Transform → LLM → End 172 | → JinaReader → ↗ 173 | ``` 174 | 175 | ## Limitations 176 | 177 | - Only supports OpenAI's gpt-4o model (change model settings on the Dify screen) 178 | - Boolean type not available in code nodes (use 0/1 with number type) 179 | - File input supports only the following formats: 180 | - Documents (PDF, Word, etc.) 181 | - Images (JPG, PNG, etc.) 182 | - Audio (MP3, WAV, etc.) 183 | - Video (MP4, etc.) 184 | - Template Transform Node constraints: 185 | - Output is always string type 186 | - Only supports Jinja2 template syntax 187 | - Complex control syntax not recommended 188 | - Answer Node constraints: 189 | - arrayObject type variables not supported 190 | - Special behavior in chat mode 191 | - Variable references only in {{#nodeID.variableName#}} format 192 | - Parameter Extractor Node constraints: 193 | - Parameter names must be unique 194 | - Required parameters must be extracted 195 | - Image processing only available with supported models 196 | - Inference mode limited to prompt or function_call 197 | - Unsupported nodes: 198 | - Iteration nodes 199 | - Variable assignment nodes 200 | - List processing 201 | - Tool nodes in general 202 | - YouTube Transcript Node constraints: 203 | - Only supports public videos 204 | - Only works with videos that have subtitles 205 | - Requires subtitles in specified language 206 | - JinaReader Node constraints: 207 | - Only supports accessible web pages 208 | - JavaScript dynamic content may not be fully retrieved 209 | - May require proxy settings 210 | - TavilySearch Node constraints: 211 | - Limited number of search results (max 10) 212 | - Possible access restrictions for some domains 213 | - Processing time varies with search depth 214 | 215 | ## About difyDslGenCheck.py 216 | *Note*: This is an experimental feature and may often fail to generate workflows. Please use Dify's workflow generation feature instead. 217 | ### Features 218 | - Generates DSL files based on workflow overview 219 | - Checks if the generated DSL file structure is correct 220 | - Modifies DSL files based on check results 221 | 222 | ### Usage 223 | 1. Describe the overview of the workflow you want to generate in difyDslGenCheck.py: 224 | 225 | ```python 226 | wanted_workflow = """ 227 | Prompt: 228 | Purpose: A tool to research destination information like a travel concierge 229 | 1. Get input of destination name as input information. 230 | 2. Search the internet and obtain 3 URLs containing tourist and gourmet information about the destination. 231 | 3. Retrieve information from the 3 URLs. Process the 3 URLs in parallel. 232 | 4. Input the information obtained from the 3 URLs to LLM, organize the destination information, and output it. The output should be formatted as an article suitable for publication in a travel magazine. 233 | """ 234 | ``` 235 | 2. Execute the script: 236 | ```bash 237 | export ANTHROPIC_API_KEY="your_anthropic_api_key" 238 | python -m venv dify_env 239 | source dify_env/bin/activate 240 | pip install -r requirements.txt 241 | python difyDslGenCheck_en.py 242 | ``` 243 | 244 | ## License 245 | 246 | MIT License 247 | 248 | ## Contributing 249 | 250 | Pull requests and issue reports are welcome. 251 | 252 | ## Related Links 253 | 254 | - [Dify Official Website](https://dify.ai) 255 | - [Dify Documentation](https://docs.dify.ai) -------------------------------------------------------------------------------- /difyDslGenCheck.py: -------------------------------------------------------------------------------- 1 | import os 2 | import operator 3 | from typing import Annotated, Any 4 | from pydantic import BaseModel, Field 5 | from langchain_anthropic import ChatAnthropic 6 | from langchain_core.runnables import ConfigurableField 7 | from langchain_core.prompts import ChatPromptTemplate 8 | from langchain_core.output_parsers import StrOutputParser 9 | from langgraph.graph import StateGraph, END 10 | import yaml 11 | import logging 12 | import re 13 | 14 | # ロギング設定 15 | def setup_logging(): 16 | logging.basicConfig( 17 | level=logging.INFO, 18 | format='%(asctime)s - %(levelname)s - %(message)s', 19 | datefmt='%Y-%m-%d %H:%M:%S' 20 | ) 21 | 22 | # 状態クラス 23 | class State(BaseModel): 24 | query: str = Field(..., description="ユーザが生成したいワークフローの内容") 25 | messages: Annotated[list[str], operator.add] = Field( 26 | default=[], description="回答履歴" 27 | ) 28 | current_judge: bool = Field(default=False, description="品質チェックの結果") 29 | judgement_reason: str = Field(default="", description="品質チェックの判定理由") 30 | operator_approved: bool = Field(default=False, description="オペレータによる承認状態") 31 | 32 | class Judgement(BaseModel): 33 | reason: str = Field(default="", description="判定理由") 34 | judge: bool = Field(default=False, description="判定結果") 35 | 36 | class WorkflowGenerator: 37 | def __init__(self): 38 | self.llm = ChatAnthropic(model="claude-3-5-sonnet-20241022", temperature=0.0) 39 | self.llm = self.llm.configurable_fields(max_tokens=ConfigurableField(id='max_tokens')) 40 | 41 | def load_prompt(self, file_path: str) -> dict: 42 | with open(file_path, 'r', encoding='utf-8') as file: 43 | return yaml.safe_load(file) 44 | 45 | def generate_workflow(self, state: State) -> dict[str, Any]: 46 | logging.info("workflow_generator_node: START") 47 | query = state.query 48 | role = "あなたはDifyのワークフローを生成するエキスパートです。" 49 | role_details = self.load_prompt("workflow_generator_prompt.yml") 50 | 51 | # 前回のチェックで問題があった場合、その理由を含めたプロンプトを作成 52 | if state.judgement_reason: 53 | prompt = ChatPromptTemplate.from_template( 54 | """{role_details}{query} 55 | 前回の生成で以下の問題が検出されました、修正して下さい: 56 | {judgement_reason}""".strip() 57 | ) 58 | else: 59 | prompt = ChatPromptTemplate.from_template( 60 | """{role_details}{query}""".strip() 61 | ) 62 | chain = prompt | self.llm.with_config({"max_tokens": 8192}) | StrOutputParser() 63 | answer = self._get_complete_answer(chain, role, role_details, query, state.judgement_reason) 64 | 65 | logging.info("workflow_generator_node: END") 66 | return {"messages": [answer]} 67 | 68 | def _get_complete_answer(self, chain, role, role_details, query, judgement_reason=""): 69 | answer = "" 70 | while True: 71 | try: 72 | current_answer = chain.invoke({ 73 | "role": role, 74 | "role_details": role_details, 75 | "query": query + ("\n既存の回答:" + answer if answer else ""), 76 | "judgement_reason": judgement_reason 77 | }) 78 | answer += current_answer 79 | break 80 | except Exception as e: 81 | if "maximum context length" not in str(e): 82 | raise e 83 | return answer 84 | 85 | def check_workflow(self, state: State) -> dict[str, Any]: 86 | logging.info("check_node: START") 87 | answer = state.messages[-1] 88 | prompt_data = self.load_prompt("workflow_generator_prompt.yml") 89 | 90 | prompt = ChatPromptTemplate.from_template( 91 | """ 92 | 生成されたワークフローがプロンプトに記載されているルールに従っているかをチェックして下さい。 93 | 問題がある場合は'False'、問題がない場合は'True'を回答して下さい。 94 | また、その判断理由も説明して下さい。 95 | プロンプト:{prompt_data} 96 | 回答: {answer} 97 | """ 98 | ) 99 | 100 | chain = prompt | self.llm.with_structured_output(Judgement) 101 | result: Judgement = chain.invoke({ 102 | "query": state.query, 103 | "answer": answer, 104 | "prompt_data": prompt_data 105 | }) 106 | 107 | logging.info(f"check_node: END {'with error' if not result.judge else ''}") 108 | return { 109 | "current_judge": result.judge, 110 | "judgement_reason": result.reason 111 | } 112 | def ask_operator(state: State) -> dict[str, Any]: 113 | logging.info("オペレータに確認中...") 114 | print(f"\n警告: 以下の問題が検出されました:\n{state.judgement_reason}") 115 | print("\n生成されたワークフロー:") 116 | print(state.messages[-1]) 117 | 118 | while True: 119 | response = input("\nこのワークフローを再作成しますか? (y/n): ").lower() 120 | if response == 'y': 121 | return {"operator_approved": False} 122 | elif response == 'n': 123 | return {"operator_approved": True} 124 | else: 125 | print("無効な入力です。y または n を入力してください。") 126 | 127 | def create_workflow_graph(generator: WorkflowGenerator) -> StateGraph: 128 | workflow = StateGraph(State) 129 | 130 | workflow.add_node("workflow_generator", generator.generate_workflow) 131 | workflow.add_node("check", generator.check_workflow) 132 | workflow.add_node("ask_operator", ask_operator) 133 | 134 | workflow.set_entry_point("workflow_generator") 135 | workflow.add_edge("workflow_generator", "check") 136 | 137 | workflow.add_conditional_edges( 138 | "check", 139 | lambda state: state.current_judge, 140 | {True: END, False: "ask_operator"} 141 | ) 142 | 143 | workflow.add_conditional_edges( 144 | "ask_operator", 145 | lambda state: state.operator_approved, 146 | {True: END, False: "workflow_generator"} 147 | ) 148 | 149 | return workflow.compile() 150 | 151 | 152 | def main(): 153 | setup_logging() 154 | 155 | wanted_workflow = """ 156 | 目的:料理のレシピを調べて記事にする 157 | 1.料理のレシピをインターネットで調べて、3つのURLを取得する 158 | 2.3つのURLから情報を取得する 159 | 3.3つのURLから得た情報をLLMに入力し、料理のレシピを整理して出力する 160 | """ 161 | 162 | generator = WorkflowGenerator() 163 | workflow = create_workflow_graph(generator) 164 | 165 | initial_state = State(query=wanted_workflow) 166 | result = workflow.invoke(initial_state) 167 | 168 | logging.info(f"判定: {result['current_judge']}") 169 | logging.info(f"判定理由: {result['judgement_reason']}") 170 | # メッセージから```yaml と ``` で囲まれた部分を抽出 171 | yaml_content = re.search(r'```yaml\n(.*?)```', result['messages'][-1], re.DOTALL) 172 | if yaml_content: 173 | logging.info(f"結果: \n {yaml_content.group(1)}") 174 | else: 175 | logging.error("YAMLコンテンツが見つかりませんでした。") 176 | 177 | if __name__ == "__main__": 178 | main() 179 | -------------------------------------------------------------------------------- /difyDslGenCheck_ch.py: -------------------------------------------------------------------------------- 1 | import os 2 | import operator 3 | from typing import Annotated, Any 4 | from pydantic import BaseModel, Field 5 | from langchain_anthropic import ChatAnthropic 6 | from langchain_core.runnables import ConfigurableField 7 | from langchain_core.prompts import ChatPromptTemplate 8 | from langchain_core.output_parsers import StrOutputParser 9 | from langgraph.graph import StateGraph, END 10 | import yaml 11 | import logging 12 | import re 13 | 14 | # 日志配置 15 | def setup_logging(): 16 | logging.basicConfig( 17 | level=logging.INFO, 18 | format='%(asctime)s - %(levelname)s - %(message)s', 19 | datefmt='%Y-%m-%d %H:%M:%S' 20 | ) 21 | 22 | # 状态类 23 | class State(BaseModel): 24 | query: str = Field(..., description="用户想要生成的工作流内容") 25 | messages: Annotated[list[str], operator.add] = Field( 26 | default=[], description="响应历史记录" 27 | ) 28 | current_judge: bool = Field(default=False, description="质量检查结果") 29 | judgement_reason: str = Field(default="", description="质量检查判断原因") 30 | operator_approved: bool = Field(default=False, description="操作员审批状态") 31 | 32 | class Judgement(BaseModel): 33 | reason: str = Field(default="", description="判断原因") 34 | judge: bool = Field(default=False, description="判断结果") 35 | 36 | class WorkflowGenerator: 37 | def __init__(self): 38 | self.llm = ChatAnthropic(model="claude-3-5-sonnet-20241022", temperature=0.0) 39 | self.llm = self.llm.configurable_fields(max_tokens=ConfigurableField(id='max_tokens')) 40 | 41 | def load_prompt(self, file_path: str) -> dict: 42 | with open(file_path, 'r', encoding='utf-8') as file: 43 | return yaml.safe_load(file) 44 | 45 | def generate_workflow(self, state: State) -> dict[str, Any]: 46 | logging.info("工作流生成节点:开始") 47 | query = state.query 48 | role = "您是生成Dify工作流的专家。" 49 | role_details = self.load_prompt("workflow_generator_prompt.yml") 50 | 51 | # 如果之前的检查中存在问题,则创建包含原因的提示 52 | if state.judgement_reason: 53 | prompt = ChatPromptTemplate.from_template( 54 | """{role_details}{query} 55 | 在上一次生成中检测到以下问题,请修复: 56 | {judgement_reason}""".strip() 57 | ) 58 | else: 59 | prompt = ChatPromptTemplate.from_template( 60 | """{role_details}{query}""".strip() 61 | ) 62 | chain = prompt | self.llm.with_config({"max_tokens": 8192}) | StrOutputParser() 63 | answer = self._get_complete_answer(chain, role, role_details, query, state.judgement_reason) 64 | 65 | logging.info("工作流生成节点:结束") 66 | return {"messages": [answer]} 67 | 68 | def _get_complete_answer(self, chain, role, role_details, query, judgement_reason=""): 69 | answer = "" 70 | while True: 71 | try: 72 | current_answer = chain.invoke({ 73 | "role": role, 74 | "role_details": role_details, 75 | "query": query + ("\n现有答案:" + answer if answer else ""), 76 | "judgement_reason": judgement_reason 77 | }) 78 | answer += current_answer 79 | break 80 | except Exception as e: 81 | if "maximum context length" not in str(e): 82 | raise e 83 | return answer 84 | 85 | def check_workflow(self, state: State) -> dict[str, Any]: 86 | logging.info("检查节点:开始") 87 | answer = state.messages[-1] 88 | prompt_data = self.load_prompt("workflow_generator_prompt.yml") 89 | 90 | prompt = ChatPromptTemplate.from_template( 91 | """ 92 | 请检查生成的工作流是否遵循提示中指定的规则。 93 | 如果存在问题,请回答'False',如果没有问题,请回答'True'。 94 | 同时,请解释您的判断原因。 95 | 提示:{prompt_data} 96 | 回答:{answer} 97 | """ 98 | ) 99 | 100 | chain = prompt | self.llm.with_structured_output(Judgement) 101 | result: Judgement = chain.invoke({ 102 | "query": state.query, 103 | "answer": answer, 104 | "prompt_data": prompt_data 105 | }) 106 | 107 | logging.info(f"检查节点:结束 {'有错误' if not result.judge else ''}") 108 | return { 109 | "current_judge": result.judge, 110 | "judgement_reason": result.reason 111 | } 112 | 113 | def ask_operator(state: State) -> dict[str, Any]: 114 | logging.info("正在与操作员确认...") 115 | print(f"\n警告:检测到以下问题:\n{state.judgement_reason}") 116 | print("\n生成的工作流:") 117 | print(state.messages[-1]) 118 | 119 | while True: 120 | response = input("\n您想要重新生成这个工作流吗?(y/n):").lower() 121 | if response == 'y': 122 | return {"operator_approved": False} 123 | elif response == 'n': 124 | return {"operator_approved": True} 125 | else: 126 | print("无效输入。请输入 y 或 n。") 127 | 128 | def create_workflow_graph(generator: WorkflowGenerator) -> StateGraph: 129 | workflow = StateGraph(State) 130 | 131 | workflow.add_node("workflow_generator", generator.generate_workflow) 132 | workflow.add_node("check", generator.check_workflow) 133 | workflow.add_node("ask_operator", ask_operator) 134 | 135 | workflow.set_entry_point("workflow_generator") 136 | workflow.add_edge("workflow_generator", "check") 137 | 138 | workflow.add_conditional_edges( 139 | "check", 140 | lambda state: state.current_judge, 141 | {True: END, False: "ask_operator"} 142 | ) 143 | 144 | workflow.add_conditional_edges( 145 | "ask_operator", 146 | lambda state: state.operator_approved, 147 | {True: END, False: "workflow_generator"} 148 | ) 149 | 150 | return workflow.compile() 151 | 152 | 153 | def main(): 154 | setup_logging() 155 | 156 | wanted_workflow = """ 157 | 目的:研究并创建一篇关于烹饪食谱的文章 158 | 1. 在互联网上搜索烹饪食谱并获取3个URL 159 | 2. 从这3个URL中获取信息 160 | 3. 将从3个URL获得的信息输入到LLM中,整理烹饪食谱并输出 161 | """ 162 | 163 | generator = WorkflowGenerator() 164 | workflow = create_workflow_graph(generator) 165 | 166 | initial_state = State(query=wanted_workflow) 167 | result = workflow.invoke(initial_state) 168 | 169 | logging.info(f"判断:{result['current_judge']}") 170 | logging.info(f"判断原因:{result['judgement_reason']}") 171 | # 从消息中提取被```yaml和```包围的部分 172 | yaml_content = re.search(r'```yaml\n(.*?)```', result['messages'][-1], re.DOTALL) 173 | if yaml_content: 174 | logging.info(f"结果:\n {yaml_content.group(1)}") 175 | else: 176 | logging.error("未找到YAML内容。") 177 | 178 | if __name__ == "__main__": 179 | main() 180 | -------------------------------------------------------------------------------- /difyDslGenCheck_en.py: -------------------------------------------------------------------------------- 1 | import os 2 | import operator 3 | from typing import Annotated, Any 4 | from pydantic import BaseModel, Field 5 | from langchain_anthropic import ChatAnthropic 6 | from langchain_core.runnables import ConfigurableField 7 | from langchain_core.prompts import ChatPromptTemplate 8 | from langchain_core.output_parsers import StrOutputParser 9 | from langgraph.graph import StateGraph, END 10 | import yaml 11 | import logging 12 | import re 13 | 14 | # Logging configuration 15 | def setup_logging(): 16 | logging.basicConfig( 17 | level=logging.INFO, 18 | format='%(asctime)s - %(levelname)s - %(message)s', 19 | datefmt='%Y-%m-%d %H:%M:%S' 20 | ) 21 | 22 | # State class 23 | class State(BaseModel): 24 | query: str = Field(..., description="Workflow content that the user wants to generate") 25 | messages: Annotated[list[str], operator.add] = Field( 26 | default=[], description="Response history" 27 | ) 28 | current_judge: bool = Field(default=False, description="Quality check result") 29 | judgement_reason: str = Field(default="", description="Quality check judgment reason") 30 | operator_approved: bool = Field(default=False, description="Operator approval status") 31 | 32 | class Judgement(BaseModel): 33 | reason: str = Field(default="", description="Judgment reason") 34 | judge: bool = Field(default=False, description="Judgment result") 35 | 36 | class WorkflowGenerator: 37 | def __init__(self): 38 | self.llm = ChatAnthropic(model="claude-3-5-sonnet-20241022", temperature=0.0) 39 | self.llm = self.llm.configurable_fields(max_tokens=ConfigurableField(id='max_tokens')) 40 | 41 | def load_prompt(self, file_path: str) -> dict: 42 | with open(file_path, 'r', encoding='utf-8') as file: 43 | return yaml.safe_load(file) 44 | 45 | def generate_workflow(self, state: State) -> dict[str, Any]: 46 | logging.info("workflow_generator_node: START") 47 | query = state.query 48 | role = "You are an expert in generating Dify workflows." 49 | role_details = self.load_prompt("workflow_generator_prompt.yml") 50 | 51 | # Create a prompt including the reason if there were issues in the previous check 52 | if state.judgement_reason: 53 | prompt = ChatPromptTemplate.from_template( 54 | """{role_details}{query} 55 | The following issues were detected in the previous generation, please fix them: 56 | {judgement_reason}""".strip() 57 | ) 58 | else: 59 | prompt = ChatPromptTemplate.from_template( 60 | """{role_details}{query}""".strip() 61 | ) 62 | chain = prompt | self.llm.with_config({"max_tokens": 8192}) | StrOutputParser() 63 | answer = self._get_complete_answer(chain, role, role_details, query, state.judgement_reason) 64 | 65 | logging.info("workflow_generator_node: END") 66 | return {"messages": [answer]} 67 | 68 | def _get_complete_answer(self, chain, role, role_details, query, judgement_reason=""): 69 | answer = "" 70 | while True: 71 | try: 72 | current_answer = chain.invoke({ 73 | "role": role, 74 | "role_details": role_details, 75 | "query": query + ("\nExisting answer:" + answer if answer else ""), 76 | "judgement_reason": judgement_reason 77 | }) 78 | answer += current_answer 79 | break 80 | except Exception as e: 81 | if "maximum context length" not in str(e): 82 | raise e 83 | return answer 84 | 85 | def check_workflow(self, state: State) -> dict[str, Any]: 86 | logging.info("check_node: START") 87 | answer = state.messages[-1] 88 | prompt_data = self.load_prompt("workflow_generator_prompt.yml") 89 | 90 | prompt = ChatPromptTemplate.from_template( 91 | """ 92 | Please check if the generated workflow follows the rules specified in the prompt. 93 | Answer 'False' if there are issues, 'True' if there are no issues. 94 | Also, please explain the reason for your judgment. 95 | Prompt: {prompt_data} 96 | Answer: {answer} 97 | """ 98 | ) 99 | 100 | chain = prompt | self.llm.with_structured_output(Judgement) 101 | result: Judgement = chain.invoke({ 102 | "query": state.query, 103 | "answer": answer, 104 | "prompt_data": prompt_data 105 | }) 106 | 107 | logging.info(f"check_node: END {'with error' if not result.judge else ''}") 108 | return { 109 | "current_judge": result.judge, 110 | "judgement_reason": result.reason 111 | } 112 | 113 | def ask_operator(state: State) -> dict[str, Any]: 114 | logging.info("Checking with operator...") 115 | print(f"\nWarning: The following issues were detected:\n{state.judgement_reason}") 116 | print("\nGenerated workflow:") 117 | print(state.messages[-1]) 118 | 119 | while True: 120 | response = input("\nDo you want to regenerate this workflow? (y/n): ").lower() 121 | if response == 'y': 122 | return {"operator_approved": False} 123 | elif response == 'n': 124 | return {"operator_approved": True} 125 | else: 126 | print("Invalid input. Please enter y or n.") 127 | 128 | def create_workflow_graph(generator: WorkflowGenerator) -> StateGraph: 129 | workflow = StateGraph(State) 130 | 131 | workflow.add_node("workflow_generator", generator.generate_workflow) 132 | workflow.add_node("check", generator.check_workflow) 133 | workflow.add_node("ask_operator", ask_operator) 134 | 135 | workflow.set_entry_point("workflow_generator") 136 | workflow.add_edge("workflow_generator", "check") 137 | 138 | workflow.add_conditional_edges( 139 | "check", 140 | lambda state: state.current_judge, 141 | {True: END, False: "ask_operator"} 142 | ) 143 | 144 | workflow.add_conditional_edges( 145 | "ask_operator", 146 | lambda state: state.operator_approved, 147 | {True: END, False: "workflow_generator"} 148 | ) 149 | 150 | return workflow.compile() 151 | 152 | 153 | def main(): 154 | setup_logging() 155 | 156 | wanted_workflow = """ 157 | Purpose: Research and create an article about cooking recipes 158 | 1. Search the internet for cooking recipes and get 3 URLs 159 | 2. Retrieve information from the 3 URLs 160 | 3. Input the information obtained from the 3 URLs into LLM and organize the cooking recipe for output 161 | """ 162 | 163 | generator = WorkflowGenerator() 164 | workflow = create_workflow_graph(generator) 165 | 166 | initial_state = State(query=wanted_workflow) 167 | result = workflow.invoke(initial_state) 168 | 169 | logging.info(f"Judgment: {result['current_judge']}") 170 | logging.info(f"Judgment reason: {result['judgement_reason']}") 171 | # Extract the part enclosed by ```yaml and ``` from the message 172 | yaml_content = re.search(r'```yaml\n(.*?)```', result['messages'][-1], re.DOTALL) 173 | if yaml_content: 174 | logging.info(f"Result: \n {yaml_content.group(1)}") 175 | else: 176 | logging.error("YAML content not found.") 177 | 178 | if __name__ == "__main__": 179 | main() 180 | -------------------------------------------------------------------------------- /dify_chatbot/DifyWorkflowGeneate.yml: -------------------------------------------------------------------------------- 1 | app: 2 | description: Difyのワークフローを生成するプロンプトです。 3 | icon: 🤖 4 | icon_background: '#FFEAD5' 5 | mode: chat 6 | name: Difyワークフロー生成プロンプト 7 | use_icon_as_answer_icon: false 8 | kind: app 9 | model_config: 10 | agent_mode: 11 | enabled: false 12 | max_iteration: 5 13 | strategy: function_call 14 | tools: [] 15 | annotation_reply: 16 | enabled: false 17 | chat_prompt_config: {} 18 | completion_prompt_config: {} 19 | dataset_configs: 20 | datasets: 21 | datasets: [] 22 | reranking_enable: true 23 | retrieval_model: multiple 24 | top_k: 4 25 | dataset_query_variable: '' 26 | external_data_tools: [] 27 | file_upload: 28 | allowed_file_extensions: 29 | - .JPG 30 | - .JPEG 31 | - .PNG 32 | - .GIF 33 | - .WEBP 34 | - .SVG 35 | allowed_file_types: 36 | - image 37 | allowed_file_upload_methods: 38 | - remote_url 39 | - local_file 40 | enabled: false 41 | image: 42 | detail: high 43 | enabled: false 44 | number_limits: 3 45 | transfer_methods: 46 | - remote_url 47 | - local_file 48 | number_limits: 3 49 | model: 50 | completion_params: 51 | stop: [] 52 | mode: chat 53 | name: claude-3-5-sonnet-20241022 54 | provider: anthropic 55 | more_like_this: 56 | enabled: false 57 | opening_statement: '' 58 | pre_prompt: "prompt:\n metadata:\n title: Difyワークフロー生成プロンプト\n version: 1.0.0\n\ 59 | \ description: Difyのワークフローファイルを生成するためのプロンプト定義\n\n\n input_requirements: |\n\ 60 | \ 以下の情報を提供してください:\n 1. ワークフローの目的(例:本の要約生成、商品説明文作成など)\n 2. 入力として必要な情報(例:本のタイトル、商品名と特徴など)\n\ 61 | \ 3. 出力として期待する形式や内容\n 4. 特別な制約条件(文字数制限、トーンの指定など)\n\n\n instructions:\n\ 62 | \ workflow_overview: |\n 提供された要件に基づいて、以下の要素を含むDifyワークフローファイル(YAML形式)を生成します:\n\ 63 | \ - 3つのノード(開始、LLM、終了)で構成される単純なワークフロー\n - ノード間は順次実行されるよう接続\n - 入力から出力までの一連の処理を自動化\n\ 64 | \n\n required_structure:\n app_info:\n - mode: workflowを指定\n \ 65 | \ - name: 目的を表す名前を設定\n - version: 0.1.3を使用\n\n\n workflow_graph:\n\ 66 | \ edges:\n - source: 開始ノードのID(例:'1731228343114')\n \ 67 | \ target: LLMノードのID(例:'1731229438627')\n data:\n sourceType:\ 68 | \ start\n targetType: llm\n - source: LLMノードのID(例:'1731229438627')\n\ 69 | \ target: 終了ノードのID(例:'1731228345560')\n data:\n \ 70 | \ sourceType: llm\n targetType: end\n - source: 質問分類器ノードのID\n\ 71 | \ sourceHandle: '1' # 質問分類1用\n target: ターゲットノードID1\n \ 72 | \ targetHandle: target\n data:\n sourceType:\ 73 | \ question-classifier\n targetType: [ターゲットノードタイプ]\n - source:\ 74 | \ 質問分類器ノードのID\n sourceHandle: '2' # 質問分類2用\n target: ターゲットノードID2\n\ 75 | \ targetHandle: target\n data:\n sourceType:\ 76 | \ question-classifier\n targetType: [ターゲットノードタイプ]\n - source:\ 77 | \ [IF/ELSEノードID]\n target: [ターゲットノードID]\n data:\n \ 78 | \ sourceType: if-else\n targetType: [ターゲットノードタイプ]\n \ 79 | \ sourceHandle: 'true' # IF条件成立時\n - source: [IF/ELSEノードID]\n \ 80 | \ target: [別のターゲットノードID]\n data:\n sourceType:\ 81 | \ if-else\n targetType: [ターゲットノードタイプ]\n sourceHandle:\ 82 | \ 'false' # ELSE条件時\n\n\n nodes:\n start_node:\n -\ 83 | \ id: ユニークなID\n - type: start\n - variables:\n \ 84 | \ # ファイル入力の例\n - type: file\n variable: input_document\n\ 85 | \ label: ドキュメント\n required: true\n \ 86 | \ max_length: 48\n allowed_file_types:\n - document\n\ 87 | \ allowed_file_upload_methods:\n - local_file\n\ 88 | \ - remote_url\n\n\n # 数値入力の例\n - type:\ 89 | \ number\n variable: input_number\n label: 数値\n\ 90 | \ required: true\n min: 0\n max:\ 91 | \ 1000000\n\n\n # 段落入力の例\n - type: paragraph\n \ 92 | \ variable: danraku\n label: 段落\n required:\ 93 | \ true\n max_length: 48\n options: []\n\n\n \ 94 | \ # 短文入力の例\n - type: text-input\n variable:\ 95 | \ tanbun\n label: 短文\n required: true\n \ 96 | \ max_length: 48\n options: []\n\n\n llm_node:\n\ 97 | \ - id: ユニークなID\n - type: llm\n - model:\n \ 98 | \ - provider: openai\n - name: gpt-4o\n -\ 99 | \ mode: chat\n - completion_params:\n - temperature:\ 100 | \ 生成時の温度設定\n - prompt_template:\n - id: ユニークなID(例'prompt1')\n\ 101 | \ role: system\n text: シングートで括ったプロンプトテキスト\n \ 102 | \ - context:\n - enabled: true\n - variable_selector:\ 103 | \ 使用する変数の指定\n - vision:\n - enabled: false\n\n\n \ 104 | \ end_node:\n - id: ユニークなID\n - type: end\n \ 105 | \ - outputs: #出力変数の定義\n - input_data: 入力データ\n - generated_text:\ 106 | \ 生成されたテキスト\n\n\n http_request_node:\n - id: ユニークなID\n \ 107 | \ - type: http-request\n - data:\n - authorization:\n\ 108 | \ config: null\n type: no-auth/basic/bearer\ 109 | \ # 認証タイプを指定\n - body:\n type: json/form-data/x-www-form-urlencoded\n\ 110 | \ data: # JSONの場合の例\n - id: [キーバリューID]\n\ 111 | \ key: [キー名]\n type: text\n \ 112 | \ value: [JSON形式の値]\n - headers: Content-Type:[content-type]\ 113 | \ # 例:application/json\n - method: get/post/put/delete\n \ 114 | \ - url: [APIエンドポイントURL]\n - timeout:\n max_connect_timeout:\ 115 | \ [接続タイムアウト秒数]\n max_read_timeout: [読み取りタイムアウト秒数]\n \ 116 | \ max_write_timeout: [書き込みタイムアウト秒数]\n - title: HTTPリクエスト\n\ 117 | \ - variables: [] # 必要に応じて変数を定義\n\n\n json_parse_node:\n\ 118 | \ - id: ユニークなID\n - type: tool\n - data:\n \ 119 | \ - provider_id: json_process\n - provider_name: json_process\n\ 120 | \ - provider_type: builtin\n - title: JSON Parse\n \ 121 | \ - tool_configurations:\n ensure_ascii: 1\n \ 122 | \ - tool_name: parse\n - tool_parameters:\n \ 123 | \ content:\n type: mixed\n value: '{{#[入力ノードID].[変数名]#}}'\n\ 124 | \ json_filter:\n type: mixed\n \ 125 | \ value: [抽出したいJSONキー]\n\n\n question_classifier_node:\n \ 126 | \ - id: ユニークなID\n - type: question-classifier\n -\ 127 | \ data:\n - title: 質問分類器\n - model:\n \ 128 | \ provider: openai\n name: gpt-4o\n mode:\ 129 | \ chat\n completion_params:\n temperature:\ 130 | \ 0.7\n - query_variable_selector:\n - [入力ノードID]\n\ 131 | \ - [変数名]\n - classes:\n - id:\ 132 | \ [クラスID]\n name: [分類名]\n\n\n knowledge_retrieval_node:\n\ 133 | \ - id: ユニークなID\n - type: knowledge-retrieval\n \ 134 | \ - data:\n - title: 知識取得\n - dataset_ids:\n \ 135 | \ - [データセットID]\n - retrieval_mode: multiple\n \ 136 | \ - multiple_retrieval_config:\n reranking_enable: true\n\ 137 | \ reranking_mode: weighted_score\n top_k: 4\n\ 138 | \ weights:\n vector_setting:\n \ 139 | \ embedding_model_name: text-embedding-3-large\n \ 140 | \ embedding_provider_name: openai\n vector_weight: 1\n\ 141 | \ keyword_setting:\n keyword_weight: 0\n\ 142 | \ - query_variable_selector:\n - [入力ノードID]\n \ 143 | \ - [変数名]\n\n\n code_node:\n - id: ユニークなID\n\ 144 | \ - type: code\n - data:\n - code_language:\ 145 | \ python3\n - code: \"def main(arg1: str) -> dict:\\nreturn {\\n\\\ 146 | \"task_url\\\": \\\"http://example.com/task/\\\"+arg1,\\n}\" # Pythonードを記述しダブルクォートで括る。\n\ 147 | \ - title: Pythonコード実行\n - variables: [] # 必要に応じて変数を定義\n\ 148 | \ - outputs: # 出力変数の定義(必須)\n task_url: # 変数名\n \ 149 | \ children: null\n type: string # 変数の型\n \ 150 | \ - variables: # 入力変数の定義(必須)\n - value_selector: #\ 151 | \ 他のノードからの入力\n - [入力ノードID]\n - [変数名]\n \ 152 | \ variable: arg1 # 関数の引数名\n\n\n if_else_node:\n \ 153 | \ - id: ユニークなID\n - type: if-else\n - data:\n \ 154 | \ title: 条件分岐\n cases:\n - case_id: 'true'\n\ 155 | \ logical_operator: and\n conditions:\n\ 156 | \ - id: 5d3c1fa4-e26c-4f4b-a3a9-d4c32d63d5f8\n \ 157 | \ varType: number\n variable_selector:\n \ 158 | \ - [入力ノードID]\n - [変数名]\n \ 159 | \ comparison_operator: 'contains' # ComparisonOperatorの列挙型に従う\n\ 160 | \ value: '5'\n numberVarType: constant\n\ 161 | \ - id: f764d294-6b89-46a2-9486-8b2c067e58ff\n \ 162 | \ varType: string\n variable_selector:\n \ 163 | \ - [入力ノードID]\n - [変数名]\n \ 164 | \ key: 'subKey'\n comparison_operator:\ 165 | \ 'contains'\n value: 'テスト'\n sub_variable_condition:\n\ 166 | \ case_id: 'sub1'\n logical_operator:\ 167 | \ and\n conditions:\n - id:\ 168 | \ 'sub-condition-1'\n varType: string\n \ 169 | \ comparison_operator: 'start with'\n \ 170 | \ value: 'prefix'\n\n\n variable_aggregator_node:\n \ 171 | \ - id: ユニークなID\n - type: variable-aggregator\n - data:\n\ 172 | \ - title: 変数集約器\n - output_type: string/number/boolean\ 173 | \ # 出力変数の型\n - variables: # 集約する変数のリスト\n\ 174 | \ - - [入力ノードID1]\n - [変数名1]\n -\ 175 | \ - [入力ノードID2]\n - [変数名2]\n\n\n document_extractor_node:\n\ 176 | \ - id: ユニークなID\n - type: document-extractor\n \ 177 | \ - data:\n - title: テキスト抽出ツール\n - is_array_file:\ 178 | \ false\n - variable_selector:\n - [入力ノードID]\n \ 179 | \ - [変数名]\n\n\n template_transform_node:\n - id:\ 180 | \ ユニークなID\n - type: template-transform\n - data:\n \ 181 | \ title: テンプレート変換\n template: テンプレート文字列(Jinja2形式)\n \ 182 | \ variables:\n - value_selector: # 入力変数の指定\n \ 183 | \ - [入力ノードID]\n - [変数名]\n \ 184 | \ variable: [テンプレート内で使用する変数名]\n outputs:\n \ 185 | \ output: # 固定の出力変数名\n type: string # 常にstring型\n\n\n \ 186 | \ answer_node:\n - id: ユニークなID\n - type: answer\n\ 187 | \ - data:\n title: 応答ノード\n answer: 応答テキストまたは変数参照\n\ 188 | \ variables: [] # 必要に応じて変数定義\n\n\n parameter_extractor_node:\n\ 189 | \ - id: ユニークなID(必須)\n - type: parameter-extractor(固定)\n\ 190 | \ - data:\n - title: パラメータ抽出\n - query: #\ 191 | \ 入力変数の指定(必須)\n - [入力ノードID]\n - [変数名]\n \ 192 | \ - model: # モデル設定(必須)\n - provider: プロバイダー名\n \ 193 | \ - name: モデル名\n - mode: chat/completion\n -\ 194 | \ completion_params:\n - temperature: 0.0-1.0\n \ 195 | \ - reasoning_mode: # 推論モード(必須)\n - prompt: プロンプトベース\n \ 196 | \ - function_call: 関数呼び出し\n - parameters: # 抽出パラメータ定義(必須)\n\ 197 | \ - name: パラメータ名\n type: パラメータ型\n \ 198 | \ description: 説明文\n required: true/false\n \ 199 | \ options: # select型の場合の選択肢\n - オプション1\n \ 200 | \ - オプション2\n - instruction: プロンプト文字列\n - memory:\ 201 | \ # メモリ設定(オプション)\n - role_prefix:\n - user: ユーザープレフィックス\n\ 202 | \ - assistant: アシスタントプレフィックス\n - vision: # 画像処理設定(オプション)\n\ 203 | \ - enabled: true/false\n - configs: 画像設定\n\n\n\ 204 | \ youtube_transcript_node:\n - id: ユニークなID\n -\ 205 | \ data:\n type: tool\n title: Free YouTube Transcript\ 206 | \ API\n provider_name: transcript\n provider_id:\ 207 | \ transcript\n provider_type: builtin\n tool_label:\ 208 | \ Free YouTube Transcript API\n tool_name: free_youtube_transcript\n\ 209 | \ tool_configurations:\n cookies: null\n \ 210 | \ format: text\n language: ja\n \ 211 | \ preserve_formatting: 0\n proxy: null\n tool_parameters:\n\ 212 | \ video_id:\n type: mixed\n \ 213 | \ value: YouTubeビデオID or 変数参照\n outputs:\n \ 214 | \ text: # 字幕テキストの出力変数\n type: string\n\n\n jina_reader_node:\n\ 215 | \ - id: ユニークなID\n - type: tool\n - data:\n \ 216 | \ - provider_id: jina\n - provider_name: jina\n \ 217 | \ - provider_type: builtin\n - title: JinaReader\n \ 218 | \ - tool_configurations:\n gather_all_images_at_the_end:\ 219 | \ 0 # 画像収集設定\n gather_all_links_at_the_end: 0 # リンク収集設定\n\ 220 | \ image_caption: 0 # 画像キャプション設定\n \ 221 | \ no_cache: 0 # キャッシュ無効化\n proxy_server:\ 222 | \ null # プロキシサーバー設定\n summary: 0 \ 223 | \ # 要約機能\n target_selector: null # ターゲット要素セレクター\n\ 224 | \ wait_for_selector: null # 待機要素セレクター\n \ 225 | \ - tool_label: JinaReader\n - tool_name: jina_reader\n \ 226 | \ - tool_parameters:\n url:\n type: mixed\n\ 227 | \ value: '{{#[入力ノードID].[変数名]#}}' # URL入力\n\n\n tavily_search_node:\n\ 228 | \ - id: ユニークなID\n - type: tool\n - data:\n \ 229 | \ - provider_id: tavily\n - provider_name: tavily\n \ 230 | \ - provider_type: builtin\n - title: TavilySearch\n \ 231 | \ - tool_configurations:\n exclude_domains: null\ 232 | \ # 除外ドメイン\n include_domains: null # 含めるドメイン\n \ 233 | \ include_answer: null # 回答を含める\n include_images:\ 234 | \ null # 画像を含める\n include_raw_content: null # 生コンテンツを含める\n\ 235 | \ max_results: 3 # 最大結果数\n search_depth:\ 236 | \ basic # 検索深度\n - tool_label: TavilySearch\n \ 237 | \ - tool_name: tavily_search\n - tool_parameters:\n \ 238 | \ query:\n type: mixed\n value: '{{#[入力ノードID].[変数名]#}}'\n\ 239 | \n\n usage_guide: |\n ワークフローの使用方法:\n 1. 開始ノード\n ユースケース:\n\ 240 | \ - ワークフローの開始点として機能\n - ユーザーからの入力を受け付け\n - 入力された情報を変数として保存\n\ 241 | \n\n 構造:\n - id: ユニークなID(必須)\n - type: start(固定)\n \ 242 | \ - variables: 入力変数の配列(必須)\n - type: 変数の型(必須)\n - variable:\ 243 | \ 変数名(必須)\n - label: 表示ラベル(必須)\n - required: 必須入力かどうか(必須)\n\ 244 | \ - その他設定(型に応じて必要)\n\n\n 変数型と固有設定:\n - file(ファイル入力):\n\ 245 | \ - allowed_file_types: 許可するファイルタイプ\n - document: ドキュメントファイル\n\ 246 | \ - image: 画像ファイル\n - audio: 音声ファイル\n - video:\ 247 | \ 動画ファイル\n - allowed_file_upload_methods: アップロード方法\n - local_file:\ 248 | \ ローカルファイル\n - remote_url: リモートURL\n - max_length: 最大ファイル名長\n\ 249 | \ - required: 必須項目かどうか\n - number(数値入力):\n - min:\ 250 | \ 最小値(オプション)\n - max: 最大値(オプション)\n - paragraph(段落テキスト):\n \ 251 | \ - max_length: 最大文字数(オプション)\n - options: 選択肢(オプション)\n \ 252 | \ - text-input(短文テキスト):\n - max_length: 最大文字数(オプション)\n \ 253 | \ - options: 選択肢(オプション)\n\n\n 2. LLMノード\n ユースケース:\n - テキスト生成や応答の作成\n\ 254 | \ - 入力テキストの加工や変換\n - 質問への回答生成\n 構造:\n - id: ユニークなID(必須)\n\ 255 | \ - type: llm(固定)\n - model:(必須)\n - provider: openai(固定)\n\ 256 | \ - name: gpt-4o(固定)\n - mode: chat(固定)\n - completion_params:\n\ 257 | \ - temperature: 0.0-1.0の値(必須)\n - prompt_template:(必須)\n\ 258 | \ - role: system(固定)\n - text: プロンプトテキスト(必須)\n - context:(必須)\n\ 259 | \ - enabled: true(固定)\n - variable_selector: 使用する変数の指定(必須)\n\ 260 | \ - vision:\n - enabled: false(固定)\n 特記事項:\n \ 261 | \ - プロンプトはシングルクォートで括る必要あり\n - システムロールのプロンプトのみ使用可能\n - 変数参照形式:\ 262 | \ {{#ノードID.変数名#}}\n \n 3. 終了ノード\n ユースケース:\n - ワークフローの終了点として機能\n\ 263 | \ - 処理結果の出力を定義\n - 後続システムへのデータ受け渡し\n\n\n 構造:\n \ 264 | \ - id: ユニークなID(必須)\n - type: end(固定)\n - outputs:(必須)\n \ 265 | \ - value_selector:(必須)\n - [ノードID]\n - [変数名]\n\ 266 | \ - variable: 出力変数名(必須)\n\n\n 特記事項:\n - 少なくとも1つの出力変数が必要\n\ 267 | \ - 複数の出力変数を定義可能\n\n\n 4. HTTPリクエストノード\n ユースケース:\n \ 268 | \ - 外部APIとの連携\n - データの送受信\n - Webhook通知の送信\n - 外部サービスとの統合\n\ 269 | \n\n 構造:\n - id: ユニークなID(必須)\n - type: http-request(固定)\n\ 270 | \ - data:(必須)\n - authorization:(必須)\n - config:\ 271 | \ 認証設定(オプション)\n - type: 認証タイプ(必須)\n - no-auth: 認証なし\n\ 272 | \ - basic: Basic認証\n - bearer: Bearer認証\n \ 273 | \ - body:(必須)\n - type: リクエストボディタイプ(必須)\n - json:\ 274 | \ JSON形式\n - form-data: マルチパートフォーム\n - x-www-form-urlencoded:\ 275 | \ URLエンコード形式\n - data: リクエストデータ(必須)\n - headers: ヘッダー情報(必須)\n\ 276 | \ - method: HTTPメソッド(必須)\n - url: エンドポイントURL(必須)\n \ 277 | \ - timeout:(オプション)\n - max_connect_timeout: 接続タイムアウト秒数\n \ 278 | \ - max_read_timeout: 読み取りタイムアウト秒数\n - max_write_timeout: 書き込みタイムアウト秒数\n\ 279 | \ - title: ノードのタイトル(必須)\n - variables: 変数定義(オプション)\n\n\n \ 280 | \ 特記事項:\n HTTPメソッド:\n - GET: リソースの取得\n - クエリパラメータによる検索\n\ 281 | \ - キャッシュ可能\n - POST: データの送信・作成\n - リソースの規成\n \ 282 | \ - 大容量データの送信\n - PUT: リソースの更新・作成\n - 完全な置き換え\n \ 283 | \ - べき等性あり\n - PATCH: リソースの部分更新\n - 一部フィールドの更新\n \ 284 | \ - べき等性なし\n - DELETE: リソースの削除\n - 指定リソースの削除\n -\ 285 | \ HEAD: ヘッダー情報の取得\n - レスポンスボディなし\n\n\n 変数参照:\n - 形式:\ 286 | \ {{#[ノードID].[変数名]#}}\n - 他のノードの出力を参照可能\n - JSONパスによるネストされた値の参照可能\n\ 287 | \n\n タイムアウト設定:\n - 0は無制限を意味する\n - ミリ秒単位で指定可能\n \ 288 | \ - 各フェーズで個別に設定可能\n\n\n 5. JSON Parseノード\n ユースケース:\n - JSONデータの解析\n\ 289 | \ - 特定のキーの抽出\n - APIレスポンスの処理\n - 構造化データの加工\n\n\n \ 290 | \ 構造:\n - id: ユニークなID(必須)\n - type: tool(固定)\n - data:(必須)\n\ 291 | \ - provider_id: json_process(固定)\n - provider_name: json_process(固定)\n\ 292 | \ - provider_type: builtin(固定)\n - title: ノードのタイトル(必須)\n \ 293 | \ - tool_configurations:(必須)\n - ensure_ascii: 1または0(必須)\n\ 294 | \ - tool_name: parse(固定)\n - tool_parameters:(必須)\n \ 295 | \ - content:(必須)\n - type: mixed(固定)\n - value:\ 296 | \ パース対象のJSON(必須)\n - json_filter:(必須)\n - type: mixed(固定)\n\ 297 | \ - value: 抽出キー(必須)\n\n\n 特記事項:\n データ形式:\n \ 298 | \ - content: JSON文字列またはオブジェクト\n - 他のノードの出力を参照可能\n - 変数参照形式:\ 299 | \ {{#[ノードID].[変数名]#}}\n \n 文字エンコード:\n - ensure_ascii:\ 300 | \ \n - 1: ASCII文字のみ使用\n - 0: Unicode文字を許可\n \n \ 301 | \ フィルタリング:\n - 単一キー: \"key\"\n - ネトしたキー: \"key1.key2\"\n\ 302 | \ - 配列インデックス: \"array[0]\"\n - 複数キー: [\"key1\", \"key2\"]\n \ 303 | \ - 条件付き: \"key[?(@.field=='value')]\"\n\n\n 6. 質問分類器ノード\n \ 304 | \ ユースケース:\n - 質問内容の自動分類\n - インテントの判別\n - 応答フローの最適化\n \ 305 | \ - マルチパス処理の制御\n\n\n 構造:\n - id: ユニークなID(必須)\n \ 306 | \ - type: question-classifier(固定)\n - data:(必須)\n - title: ノードのタイトル(必須)\n\ 307 | \ - model:(必須)\n - provider: openai(固定)\n -\ 308 | \ name: gpt-4o(固定)\n - mode: chat(固定)\n - completion_params:(必須)\n\ 309 | \ - temperature: 0.0-1.0の値\n - query_variable_selector:(必須)\n\ 310 | \ - [入力ノードID]\n - [変数名]\n - classes:(必須)\n \ 311 | \ - id: クラスID(必須)\n - name: 分類名(必須)\n\n\n 特記事項:\n\ 312 | \ 分岐パターン:\n 1. 共通LLM使用パターン:\n - クラス1の質問 → 知識取得1 → 共通LLM\ 313 | \ → 終了\n - クラス2の質問 → 知識取得2 → 共通LLM → 終了\n - その他の質問 → 直接終了ノードへ\n\ 314 | \ \n 2. 個別LLM使用パターン:\n - クラス1の質問 → 知識取得1 → LLM1 → 終了1\n\ 315 | \ - クラス2の質問 → 知識取得2 → LLM2 → 終了2\n - その他の質問 → 直接終了ノードへ\n\ 316 | \n\n エッジ接続設定:\n - sourceHandle: 質問分類のID('1', '2'など)\n \ 317 | \ - targetHandle: 'target'を指定\n - sourceType: question-classifier\n \ 318 | \ - targetType: 接続先のノードタイプ\n\n\n 分類結果の利用:\n - 各クラスに応じた適切な知識ベースの選択\n\ 319 | \ - クラスごとに異なるプロンプトの使用\n - 分類結果に基づく条件分岐の実装\n\n\n 7. 知識取得ノード\n\ 320 | \ ユースケース:\n - データセットからの関連情報検索\n - 質問に関連する知識の取得\n \ 321 | \ - コンテキストベースの応答生成\n - 複数ソースからの情報統合\n\n\n 構造:\n - id:\ 322 | \ ユニークなID(必須)\n - type: knowledge-retrieval(固定)\n - data:(必須)\n\ 323 | \ - title: ノードのタイトル(必須)\n - dataset_ids: データセットIDの配列(必須)\n\ 324 | \ - retrieval_mode: multiple(固定)\n - multiple_retrieval_config:(必須)\n\ 325 | \ - reranking_enable: true/false(必須)\n - reranking_mode:\ 326 | \ weighted_score(必須)\n - top_k: 取得件数(必須)\n - weights:(必須)\n\ 327 | \ - vector_setting:(必須)\n - embedding_model_name:\ 328 | \ モデル名(必須)\n - embedding_provider_name: プロバイダー名(須)\n \ 329 | \ - vector_weight: ベクトル重み(必須)\n - keyword_setting:(必須)\n\ 330 | \ - keyword_weight: キーワード重み(必須)\n - query_variable_selector:(必須)\n\ 331 | \ - [入力ノードID]\n - [変数名]\n\n\n 特記事項:\n \ 332 | \ 検索設定:\n - embedding_model_name:\n - text-embedding-3-large:\ 333 | \ 高精度モデル\n - text-embedding-ada-002: 標準モデル\n \n 重み付け:\n\ 334 | \ - vector_weight: 0.0-1.0\n - 1.0: ベクトル検索のみ\n - 0.0:\ 335 | \ キーワード検索のみ\n - keyword_weight: 0.0-1.0\n - 高値: キーワードマッチを重視\n\ 336 | \ - 低値: セマンティック検索を重視\n \n 検索結果:\n - top_k: 取得する結果数\n\ 337 | \ - 推奨値: 3-5\n - 最大値: 10\n - reranking: 検索結果の再ランキング\n\ 338 | \ - weighted_score: スコアによる重み付け\n - 精度と応答時間のバランスを調整可能\n \ 339 | \ \n 8. コードノード\n ユースケース:\n - カスタムロジックの実装\n \ 340 | \ - データの加工・変換\n - 外部システムとの連携\n - 条件分岐の制御\n\n\n \ 341 | \ 構造:\n - id: ユニークなID(必須)\n - type: code(固定)\n - data:(必須)\n\ 342 | \ - code_language: python3(固定)\n - code: Pythonコード(必須、ダブルクォートで括る)\n\ 343 | \ - title: ノードのタイトル(必須)\n - outputs:(必須)\n \ 344 | \ - [変数名]:\n - type: 変数の型(必須)\n - children: null(固定)\n\ 345 | \ - variables:(必須)\n - value_selector:(必須)\n \ 346 | \ - [入力ノードID]\n - [変数名]\n - variable: 関数の引数名(必須)\n\ 347 | \n\n 特記事項:\n - boolean型は利用できません。number型で0/1で代用してください。\n \ 348 | \ 使用可能なライブラリ:\n - 基本ライブラリ:\n - datetime: 日時処理\n \ 349 | \ - math: 数学関数\n - random: 乱数生成\n - re: 正規表現\n \ 350 | \ - string: 文字列操作\n - システム関連:\n - sys: システム操作\n\ 351 | \ - os: OS操作\n - time: 時間処理\n - traceback: エラー追跡\n\ 352 | \ - uuid: 一意識別子生成\n - データ処理:\n - json: JSON処理\n\ 353 | \ - base64: エンコード/デコード\n - collections: コレクション型\n \ 354 | \ - itertools: イテレータ操作\n - 暗号化/ハッシュ:\n - hashlib: ハッシュ関数\n\ 355 | \ - hmac: メッセージ認証\n - binascii: バイナリ/ASCII変換\n \ 356 | \ - 関数操作:\n - functools: 関数ツール\n - operator: 演算子インターフェース\n\ 357 | \n\n 出力変数の型:\n - 基本型:\n - string: 文字列型\n \ 358 | \ - number: 数値型\n - 特殊型:\n - secret: 機密情報型\n \ 359 | \ - object: オブジェクト型\n - file: ファイル型\n - 配列型:\n \ 360 | \ - array: 基本配列型\n - array[string]: 文字列配列\n - array[number]:\ 361 | \ 数値配列\n - array[object]: オブジェクト配列\n - array[file]: ファイル配列\n\ 362 | \ - その他:\n - any: 任意の型\n\n\n コード実装規則:\n \ 363 | \ - main関数として実装(必須)\n - 型アノテーション付与(必須)\n - 戻り値は辞書形式(必須)\n \ 364 | \ - ダブルクォートでコード全体を括る\n - 内部のダブルクォートはエスケープ\n - 改行は\\nで表現\n\ 365 | \ 実装例:\n ```python\n def main(arg1: str) -> dict:\n\ 366 | \ return {\n \"result\": arg1[7:-3],\n \ 367 | \ }\n ```\n\n\n 9. IF/ELSEノード\n ユースケース:\n \ 368 | \ - 条件に基づくフロー制御\n - 複数パスへの分岐処理\n - データ値による処理の振り分け\n \ 369 | \ - 条件付きロジックの実装\n\n\n 構造:\n - id: ユニークなID(必須)\n -\ 370 | \ type: if-else(固定)\n - data:(必須)\n - title: ノードのタイトル(必須)\n\ 371 | \ - cases:(必須)\n - case_id: 条件ID(必須)\n -\ 372 | \ logical_operator: and/or(必須)\n - conditions:(必須)\n \ 373 | \ - id: 条件のID(必須)\n - varType: 変数の型(必須)\n - variable_selector:(必須)\n\ 374 | \ - [入力ノードID]\n - [変数名]\n - comparison_operator:\ 375 | \ 比較演算子(必須)\n - value: 比較値(必須)\n - numberVarType:\ 376 | \ 数値比較タイプ(数値型の場合必須)\n - key: サブ変数のキー(オプション)\n -\ 377 | \ sub_variable_condition: サブ変数の条件(オプション)\n\n\n 特記事項:\n 比較演算子:\n\ 378 | \ - 文字列比較:\n - contains: 文字列に指定値が含まれる\n - not contains:\ 379 | \ 文字列に指定値が含まれない\n - start with: 指定値で始まる\n - end with: 指定値で終わる\n\ 380 | \ - is: 完全一致\n - is not: 完全不一致\n - 数値比較:\n \ 381 | \ - =: 等しい\n - ≠: 等しくない\n - >: より大きい\n \ 382 | \ - <: より小さい\n - ≥: 以上\n - ≤: 以下\n - 存在チェック:\n\ 383 | \ - empty: 空である\n - not empty: 空でない\n - is null:\ 384 | \ null値である\n - is not null: null値でない\n - リスト操作:\n \ 385 | \ - in: リスト内に存在する\n - not in: リスト内に存在しない\n - all of:\ 386 | \ すべての条件を満たす\n - その他:\n - exists: 存在する\n - not\ 387 | \ exists: 存在しない\n\n\n 変数型:\n - number: 数値型\n - numberVarType:\ 388 | \ constant/variable\n - string: 文字列型\n - boolean: 真偽値型\n\n\n\ 389 | \ エッジ接続:\n - sourceHandle: 'true'\n - IF条件成立時の接続\n\ 390 | \ - sourceHandle: 'false'\n - ELSE条件時の接続\n - sourceType:\ 391 | \ if-else\n - targetType: 接続先のノードタイプ\n\n\n 10. Variable Aggregatorノード\n\ 392 | \ ユースケース:\n - 複数のノードからの出力を集約\n - 異なるパスからの結果の統合\n \ 393 | \ - 分岐処理後のデータ統合\n - 複数ソースからのデータマージ\n\n\n 構造:\n \ 394 | \ - id: ユニークなID(必須)\n - type: variable-aggregator(固定)\n -\ 395 | \ data:(必須)\n - title: ノードのタイトル(必須)\n - output_type: 出力変数の型(必須)\n\ 396 | \ - string: 文字列型\n - number: 数値型\n - boolean:\ 397 | \ 真偽値型\n - variables: 集約する変数のリスト(必須)\n - [入力ノードID, 変数名]の配列\n\ 398 | \n\n 特記事項:\n データ集約パターン:\n - IF/ELSE分岐後の統合:\n \ 399 | \ - true分岐からの出力\n - false分岐からの出力\n - 単一の出力ストリームへの統合\n\ 400 | \ \n - 並列処理結果の統合:\n - 複数LLMノードからの応答\n \ 401 | \ - 複数APIコールの結果\n - 異なる処理パスからの出力\n \n 変数の順序:\n \ 402 | \ - リストの順序が出力順序に影響\n - 先に指定した変数が優先\n - 後続の変数は条件付きで使用\n\ 403 | \n\n 型変換ルール:\n - string型への変換:\n - number: 文字列表現に変換\n\ 404 | \ - boolean: \"true\"/\"false\"に変換\n - number型への変換:\n \ 405 | \ - string: 数値表現のみ許可\n - boolean: 1/0に変換\n - boolean型への変換:\n\ 406 | \ - string: \"true\"/\"false\"のみ許可\n - number: 0以外はtrue\n\ 407 | \n\n 11. Document Extractorノード\n ユースケース:\n - ドキュメントからのテキスト抽出\n\ 408 | \ - ファイル内容の解析\n - テキストデータの前処理\n\n\n 構造:\n \ 409 | \ - id: ユニークなID(必須)\n - type: document-extractor(固定)\n - data:\n\ 410 | \ - title: ノードのタイトル(必須)\n - is_array_file: 配列入力かどうか(必須)\n\ 411 | \ - variable_selector: 入力変数の指定(必須)\n - [入力ノードID]\n \ 412 | \ - [変数名]\n\n\n 12. Template Transformノード\n ユースケース:\n\ 413 | \ - テンプレート文字列への変数埋め込み\n - 動的なメッセージ生成\n - 条件付きテキスト生成\n\ 414 | \ - 配列データの文字列化\n\n\n 構造:\n - id: ユニークなID(必須)\n \ 415 | \ - type: template-transform(固定)\n - data:\n title:\ 416 | \ ノードのタイトル(必須)\n template: Jinja2形式のテンプレート(必須)\n variables:\ 417 | \ 入力変数の配列(必須)\n - value_selector: 変数の参照元\n - [入力ノードID]\n\ 418 | \ - [変数名]\n variable: テンプレート内で使用する変数名\n\n\n\ 419 | \ テンプレート構文:\n - 変数参照: \n - 基本形: {{ 変数名 }}\n \ 420 | \ - フィルター使用: {{ 変数名|upper }}\n - 条件分岐:\n ```\n \ 421 | \ {% if 条件 %}\n 条件成立時の文字列\n {% else %}\n \ 422 | \ 条件不成立時の文字列\n {% endif %}\n ```\n - ループ処理:\n\ 423 | \ ```\n {% for item in items %}\n {{ item }}\n\ 424 | \ {% endfor %}\n ```\n\n\n 入力変数の型:\n -\ 425 | \ string: 文字列\n - number: 数値\n - object: オブジェクト\n -\ 426 | \ array: 配列\n - arrayNumber: 数値配列\n - arrayString: 文字列配列\n \ 427 | \ - arrayObject: オブジェクト配列\n\n\n 出力:\n - output: 生成された文字列(string型固定)\n\ 428 | \n\n 13. Answerノード\n ユースケース:\n - ワークフローの応答出力\n \ 429 | \ - LLM出力の表示\n - 変数値の表示\n - 中間結果の確認\n\n\n 構造:\n \ 430 | \ - id: ユニークなID(必須)\n - type: answer(固定)\n - data:\n\ 431 | \ title: ノードのタイトル(必須)\n answer: 応答テキスト(必須)\n \ 432 | \ - 固定テキスト\n - 変数参照: {{#ノードID.変数名#}}\n variables:\ 433 | \ [] # オプション\n\n\n 特記事項:\n - 変数参照:\n - 形式: {{#ノードID.変数名#}}\n\ 434 | \ - 複数の変数を組み合わせ可能\n - システム変数も参照可能\n \n \ 435 | \ - 使用可能な変数型:\n - string: 文字列\n - number: 数値\n \ 436 | \ - object: オブジェクト\n - array: 配列\n - arrayString: 文字列配列\n\ 437 | \ - arrayNumber: 数値配列\n ※ arrayObjectは非対応\n\n\n \ 438 | \ - 接続:\n - 前段: 全てのノードタイプから接続可能\n - 後段: 全てのノードタイプに接続可能\n\ 439 | \ - チャットモードでの特別な動作あり\n\n\n 16. パラメータ抽出ノード\n ユースケース:\n\ 440 | \ - テキストからの構造化データ抽出\n - ユーザー入力の解析\n - 情報の分類と整理\n \ 441 | \ - 条件分岐のための入力解析\n\n\n 構造:\n - id: ユニークなID(必須)\n \ 442 | \ - type: parameter-extractor(固定)\n - data:\n - title:\ 443 | \ ノードのタイトル(必須)\n - query: 入力変数の指定(必須)\n - model: モデル設定(必須)\n\ 444 | \ - reasoning_mode: 推論モード(必須)\n - parameters: パラメータ定義(必須)\n\ 445 | \ - instruction: プロンプト(必須)\n - memory: メモリ設定(オプション)\n \ 446 | \ - vision: 画像処理設定(オプション)\n\n\n パラメータ型:\n - string:\ 447 | \ 文字列型\n - number: 数値型\n - bool: 真偽値型\n - select: 選択型(options必須)\n\ 448 | \ - array[string]: 文字列配列型\n - array[number]: 数値配列型\n \ 449 | \ - array[object]: オブジェクト配列型\n\n\n 推論モード:\n - prompt: \n \ 450 | \ - プロンプトベースの抽出\n - 柔軟な抽出ルール定義可能\n - function_call:\n\ 451 | \ - 関数呼び出しベース\n - より構造化された抽出\n\n\n 出力変数:\n \ 452 | \ - [パラメータ名]: 各パラメータの抽出結果\n - __is_success: 抽出成功フラグ(0/1)\n \ 453 | \ - __reason: エラー理由(エラー時)\n\n\n 特記事項:\n - パラメータ名は一意である必要がある\n\ 454 | \ - 必須パラメータは抽出必須\n - プロンプトは抽出ルールを明確に記述\n - 画像処理は対応モデルのみ使用可能\n\ 455 | \n\n 17. YouTubeトランスクリプトノード\n ユースケース:\n - YouTubeビデオの字幕取得\n\ 456 | \ - 音声コンテンツのテキスト化\n - 多言語コンテンツの翻訳支援\n - 動画内容の分析・要約\n\ 457 | \n\n 構造:\n - id: ユニークなID(必須)\n - data:\n \ 458 | \ type: tool(固定)\n title: Free YouTube Transcript API\n \ 459 | \ provider_name: transcript(固定)\n provider_id: transcript(固定)\n\ 460 | \ provider_type: builtin(固定)\n tool_label: Free YouTube\ 461 | \ Transcript API\n tool_name: free_youtube_transcript(固定)\n \ 462 | \ tool_configurations:\n cookies: null\n \ 463 | \ format: text(固定)\n language: ja # 言語コード\n preserve_formatting:\ 464 | \ 0 # フォーマット保持\n proxy: null\n tool_parameters:\n\ 465 | \ video_id:\n type: mixed(固定)\n \ 466 | \ value: YouTubeビデオID or 変数参照\n outputs:\n text:\ 467 | \ # 字幕テキストの出力変数\n type: string\n\n\n 特記事項:\n \ 468 | \ - video_idは以下の形式で指定可能:\n - 直接指定: 'XLzul_7GPs4'\n -\ 469 | \ 変数参照: '{{#[入力ノードID].[変数名]#}}'\n - language設定:\n - ja: 日本語\n\ 470 | \ - en: 英語\n - preserve_formatting:\n - 0: フォーマット除去(推奨)\n\ 471 | \ - 1: 原文フォーマット保持\n - 出力変数:\n - text: 取得した字幕テキスト(string型)\n\ 472 | \n\n 18. JinaReaderノード\n ユースケース:\n - ウェブページのテキスト抽出\n \ 473 | \ - コンテンツスクレイピング\n - ウェブ記事の要約\n - 画像・リンクの収集\n\n\n \ 474 | \ 構造:\n - id: ユニークなID(必須)\n - type: tool(固定)\n \ 475 | \ - data:\n title: ノードのタイトル(必須)\n provider_name: jina(固定)\n\ 476 | \ provider_id: jina(固定)\n provider_type: builtin(固定)\n\ 477 | \ tool_label: JinaReader(固定)\n tool_name: jina_reader(固定)\n\ 478 | \ tool_configurations:\n gather_all_images_at_the_end:\ 479 | \ 0/1 # 画像収集\n gather_all_links_at_the_end: 0/1 # リンク収集\n \ 480 | \ image_caption: 0/1 # 画像キャプション\n \ 481 | \ no_cache: 0/1 # キャッシュ設定\n proxy_server:\ 482 | \ プロキシURL # プロキシ設定\n summary: 0/1 \ 483 | \ # 要約機能\n target_selector: CSSセレクター # 特定要素の抽出\n \ 484 | \ wait_for_selector: CSSセレクター # 待機要素\n tool_parameters:\n\ 485 | \ url:\n type: mixed(固定)\n value:\ 486 | \ URL文字列または変数参照\n outputs:\n text:\n \ 487 | \ type: string\n\n\n 特記事項:\n - URL入力:\n - 直接指定:\ 488 | \ 'https://example.com'\n - 変数参照: '{{#[入力ノードID].[変数名]#}}'\n \ 489 | \ \n - 設定オプション:\n - gather_all_images_at_the_end: 画像の一括収集\n\ 490 | \ - gather_all_links_at_the_end: リンクの一括収集\n - image_caption:\ 491 | \ 画像キャプションの取得\n - summary: コンテンツの自動要約\n - target_selector:\ 492 | \ 特定のDOM要素の抽出\n \n - プロキシ設定:\n - アクセス制限のあるサイトへの対応\n\ 493 | \ - 地域制限の回避\n - 負荷分散\n\n\n - キャッシュ制御:\n \ 494 | \ - no_cache: 1でキャッシュ無効化\n - 常に最新コンテンツを取得\n\n\n 19. TavilySearchノード\n\ 495 | \ ユースケース:\n - ウェブ検索の実行\n - 情報収集\n - コンテンツ調査\n\ 496 | \ - ドメイン指定検索\n\n\n 構造:\n - id: ユニークなID(必須)\n \ 497 | \ - type: tool(固定)\n - data:\n title: ノードのタイトル(必須)\n\ 498 | \ provider_name: tavily(固定)\n provider_id: tavily(固定)\n\ 499 | \ provider_type: builtin(固定)\n tool_label: TavilySearch(固定)\n\ 500 | \ tool_name: tavily_search(固定)\n tool_configurations:\n\ 501 | \ exclude_domains: 除外ドメインリスト # オプション\n include_domains:\ 502 | \ 含めるドメインリスト # オプション\n include_answer: true/false #\ 503 | \ 回答含める\n include_images: true/false # 画像含める\n \ 504 | \ include_raw_content: true/false # 生コンテンツ\n max_results:\ 505 | \ 検索結果数(1-10) # 必須\n search_depth: basic/advanced \ 506 | \ # 検索深度\n tool_parameters:\n query:\n \ 507 | \ type: mixed(固定)\n value: 検索クエリまたは変数参照\n\n\n \ 508 | \ 特記事項:\n - 検索クエリ:\n - 直接指定: '検索したいキーワード'\n -\ 509 | \ 変数参照: '{{#[入力ノードID].[変数名]#}}'\n \n - 検索深度:\n -\ 510 | \ basic: 基本的な検索(高速)\n - advanced: 詳細な検索(より多くの結果)\n \n \ 511 | \ - ドメイン制御:\n - exclude_domains: 検索から除外するドメイン\n - include_domains:\ 512 | \ 検索対象とするドメイン\n \n - 結果制御:\n - max_results: 取得する検索結果の数\n\ 513 | \ - include_answer: 関連する回答の取得\n - include_images: 関連画像の取得\n\ 514 | \ - include_raw_content: 未加工コンテンツ\n\n\n output_format: |\n \ 515 | \ 生成されるYAMLファイルは以下の形式に従ってください:\n ```yaml\n app:\n mode: workflow\n\ 516 | \ name: [ワークフロー名]\n version: 0.1.3\n\n\n workflow:\n \ 517 | \ graph:\n edges:\n # IF/ELSE分岐のエッジ例\n - source:\ 518 | \ [IF/ELSEノードID]\n target: [ターゲットノードID]\n data:\n \ 519 | \ sourceType: if-else\n targetType: [ターゲットノードタイプ]\n\ 520 | \ sourceHandle: 'true' # IF条件成立時\n - source: [IF/ELSEノードID]\n\ 521 | \ target: [別のターゲットノードID]\n data:\n sourceType:\ 522 | \ if-else\n targetType: [ターゲットノードタイプ]\n sourceHandle:\ 523 | \ 'false' # ELSE条件時\n\n\n nodes:\n - id: [開始ノードID]\n \ 524 | \ data:\n type: start\n title: 開始\n \ 525 | \ variables:\n # ファイル入力の例\n - type:\ 526 | \ file\n variable: input_document\n label:\ 527 | \ ドキュメント\n required: true\n max_length:\ 528 | \ 48\n allowed_file_types:\n - document\n\ 529 | \ allowed_file_upload_methods:\n - local_file\n\ 530 | \ - remote_url\n\n\n # その他の入力タイプ\n \ 531 | \ - type: text-input\n variable: [変数名]\n \ 532 | \ type: string/number\n label: [入力フィールドのラベル]\n\ 533 | \ required: true\n max_length: [最大文字数]\n\ 534 | \n\n - id: [LLMノードID]\n data:\n type: llm\n\ 535 | \ title: LLM\n model:\n provider:\ 536 | \ openai\n name: gpt-4o\n mode: chat\n \ 537 | \ completion_params:\n temperature: 0.7\n \ 538 | \ prompt_template:\n - id: [プロンプトID]\n \ 539 | \ role: system\n text: '[プロンプトテキスト]'\n \ 540 | \ context:\n enabled: true\n variable_selector:\n\ 541 | \ - [開始ノードID]\n - [変数名]\n \ 542 | \ vision:\n enabled: false\n - id: [終了ノードID]\n \ 543 | \ data:\n type: end\n title: 終了\n \ 544 | \ outputs:\n - value_selector:\n \ 545 | \ - [開始ノードID]\n - [変数名]\n variable:\ 546 | \ inputData\n - value_selector:\n - [LLMノードID]\n\ 547 | \ - text\n variable: generatedText\n\n\ 548 | \n - id: [HTTPリクエストノードID]\n data:\n type:\ 549 | \ http-request\n authorization:\n config: null\n\ 550 | \ type: no-auth # または必要な認証タイプ\n body:\n \ 551 | \ type: json\n data:\n - id: [キーバリューID]\n\ 552 | \ key: ''\n type: text\n \ 553 | \ value: |\n {\n \"\ 554 | key1\": \"{{#[開始ノードID].[変数名]#}}\",\n \"key2\": \"値2\"\ 555 | \n }\n headers: Content-Type:application/json\n\ 556 | \ method: post\n url: [APIエンドポイントURL]\n \ 557 | \ timeout:\n max_connect_timeout: 0\n \ 558 | \ max_read_timeout: 0\n max_write_timeout: 0\n \ 559 | \ title: HTTPリクエスト\n variables: []\n\n\n - id: [JSONパースノードID]\n\ 560 | \ data:\n type: tool\n desc: ''\n \ 561 | \ provider_id: json_process\n provider_name: json_process\n\ 562 | \ provider_type: builtin\n selected: false\n \ 563 | \ title: JSON Parse\n tool_configurations:\n \ 564 | \ ensure_ascii: 1\n tool_label: JSON Parse\n \ 565 | \ tool_name: parse\n tool_parameters:\n \ 566 | \ content:\n type: mixed\n value: '{{#[入力ノードID].[変数名]#}}'\n\ 567 | \ json_filter:\n type: mixed\n \ 568 | \ value: [抽出したいJSONキー]\n\n\n - id: [質問分類器ノードID]\n \ 569 | \ data:\n type: question-classifier\n title:\ 570 | \ 質問分類器\n model:\n provider: openai\n \ 571 | \ name: gpt-4o\n mode: chat\n completion_params:\n\ 572 | \ temperature: 0.7\n query_variable_selector:\n\ 573 | \ - [入力ノードID]\n - [変数名]\n classes:\n\ 574 | \ - id: '1'\n name: [分類名1]\n \ 575 | \ - id: '2'\n name: [分類名2]\n\n\n - id: [知識取得ノードID]\n\ 576 | \ data:\n type: knowledge-retrieval\n \ 577 | \ title: 知識取得\n dataset_ids:\n - [データセットID]\n\ 578 | \ retrieval_mode: multiple\n multiple_retrieval_config:\n\ 579 | \ reranking_enable: true\n reranking_mode: weighted_score\n\ 580 | \ top_k: 4\n weights:\n vector_setting:\n\ 581 | \ embedding_model_name: text-embedding-3-large\n \ 582 | \ embedding_provider_name: openai\n vector_weight:\ 583 | \ 1\n keyword_setting:\n keyword_weight:\ 584 | \ 0\n query_variable_selector:\n - [入力ノードID]\n\ 585 | \ - [変数名]\n\n\n - id: [コードノードID]\n data:\n\ 586 | \ type: code\n code_language: python3\n \ 587 | \ code: # Pythonプログラムの文字列\n outputs: # 出力変数の定義(必須)\n \ 588 | \ task_url: # 変数名\n children: null\n \ 589 | \ type: string # 上記で定義された型のいずれかを指定\n variables: \ 590 | \ # 入力変数の定義(必須)\n - value_selector: # 他のノードからの入力\n \ 591 | \ - [入力ノードID]\n - [変数名]\n variable:\ 592 | \ arg1 # 関数の引数名\n\n\n - id: [IF/ELSEノードID]\n data:\n\ 593 | \ type: if-else\n title: 条件分岐\n cases:\n\ 594 | \ - case_id: 'true'\n logical_operator: and\n\ 595 | \ conditions:\n - id: [条件ID]\n \ 596 | \ varType: [number/string/boolean]\n variable_selector:\n\ 597 | \ - [入力ノードID]\n - [変数名]\n \ 598 | \ comparison_operator: [比較演算子]\n value:\ 599 | \ [比較値]\n numberVarType: [constant/variable] # 数値型の場合\n\ 600 | \ - id: [条件ID2]\n varType: [変数型]\n\ 601 | \ key: [サブ変数キー] # オプション\n comparison_operator:\ 602 | \ [比較演算子]\n value: [比較値]\n sub_variable_condition:\ 603 | \ # オプション\n case_id: [サブ条件ID]\n \ 604 | \ logical_operator: and\n conditions:\n \ 605 | \ - id: [サブ条件ID]\n varType: [変数型]\n\ 606 | \ comparison_operator: [比較演算子]\n \ 607 | \ value: [比較値]\n\n\n - id: [Variable Aggregatorノード]\n\ 608 | \ data:\n type: variable-aggregator\n \ 609 | \ title: 変数集約器\n output_type: string # または number/boolean\n\ 610 | \ variables:\n - - [入力ノードID1]\n \ 611 | \ - [変数名1]\n - - [入力ノードID2]\n - [変数名2]\n\ 612 | \n\n - id: [Document ExtractorノードID]\n data:\n \ 613 | \ type: document-extractor\n title: テキスト抽出ツール\n \ 614 | \ is_array_file: false\n variable_selector:\n \ 615 | \ - [入力ノードID]\n - [変数名]\n - id: [テンプレートノードID]\n\ 616 | \ data:\n type: template-transform\n \ 617 | \ title: テンプレート変換\n template: |\n こんにちは、{{ user_name\ 618 | \ }}さん!\n あなたの得点は{{ score }}点です。\n {% if score\ 619 | \ >= 80 %}\n 合格です!おめでとうございます。\n {% else %}\n\ 620 | \ 残念ながら不合格です。\n {% endif %}\n \ 621 | \ variables:\n - value_selector:\n - [入力ノードID]\n\ 622 | \ - user_name\n variable: user_name\n\ 623 | \ - value_selector:\n - [入力ノードID]\n \ 624 | \ - score\n variable: score\n -\ 625 | \ id: [応答ノードID]\n data:\n type: answer\n \ 626 | \ title: 応答出力\n answer: |\n {{#[LLMノードID].text#}}\n\ 627 | \ variables: []\n - id: [パラメータ抽出ノードID]\n \ 628 | \ data:\n type: parameter-extractor\n title: パラメータ抽出\n\ 629 | \ query:\n - [入力ノードID]\n - [変数名]\n\ 630 | \ model:\n provider: [プロバイダー名]\n \ 631 | \ name: [モデル名]\n mode: chat\n completion_params:\n\ 632 | \ temperature: 0.7\n reasoning_mode: prompt\n\ 633 | \ parameters:\n - name: [パラメータ名]\n \ 634 | \ type: string/number/bool/select/array[string]/array[number]/array[object]\n\ 635 | \ description: [説明文]\n required: true/false\n\ 636 | \ options: # select型の場合のみ\n - [オプション1]\n\ 637 | \ - [オプション2]\n instruction: |\n \ 638 | \ [プロンプト文字列]\n memory:\n role_prefix:\n\ 639 | \ user: [ユーザープレフィックス]\n assistant: [アシスタントプレフィックス]\n\ 640 | \ vision:\n enabled: false\n \ 641 | \ configs: {}\n - id: [YouTubeトランスクリプトノードID]\n data:\n\ 642 | \ type: tool\n title: Free YouTube Transcript API\n\ 643 | \ provider_name: transcript\n provider_id: transcript\n\ 644 | \ provider_type: builtin\n tool_label: Free YouTube\ 645 | \ Transcript API\n tool_name: free_youtube_transcript\n \ 646 | \ tool_configurations:\n cookies: null\n \ 647 | \ format: text\n language: ja\n preserve_formatting:\ 648 | \ 0\n proxy: null\n tool_parameters:\n \ 649 | \ video_id:\n type: mixed\n value:\ 650 | \ '{{#[入力ノードID].[変数名]#}}'\n outputs:\n text:\n\ 651 | \ type: string\n - id: [JinaReaderノードID]\n \ 652 | \ data:\n type: tool\n title: JinaReader\n\ 653 | \ provider_name: jina\n provider_id: jina\n \ 654 | \ provider_type: builtin\n tool_label: JinaReader\n\ 655 | \ tool_name: jina_reader\n tool_configurations:\n\ 656 | \ gather_all_images_at_the_end: 0 # 画像収集設定\n \ 657 | \ gather_all_links_at_the_end: 0 # リンク収集設定\n image_caption:\ 658 | \ 0 # 画像キャプション設定\n no_cache: 0 \ 659 | \ # キャッシュ無効化\n proxy_server: null # プロキシサーバー設定\n\ 660 | \ summary: 0 # 要約機能\n \ 661 | \ target_selector: null # ターゲット要素セレクター\n wait_for_selector:\ 662 | \ null # 待機要素セレクター\n tool_parameters:\n \ 663 | \ url:\n type: mixed\n value: '{{#[入力ノードID].[変数名]#}}'\ 664 | \ # URL入力\n outputs:\n text:\n \ 665 | \ type: string\n - id: [TavilySearchノードID]\n data:\n\ 666 | \ type: tool\n title: TavilySearch\n \ 667 | \ provider_name: tavily\n provider_id: tavily\n \ 668 | \ provider_type: builtin\n tool_label: TavilySearch\n \ 669 | \ tool_name: tavily_search\n tool_configurations:\n \ 670 | \ exclude_domains: null # 除外ドメイン\n include_domains:\ 671 | \ null # 含めるドメイン\n include_answer: null # 回答を含める\n\ 672 | \ include_images: null # 画像を含める\n include_raw_content:\ 673 | \ null # 生コンテンツを含める\n max_results: 3 # 最大結果数\n \ 674 | \ search_depth: basic # 検索深度\n tool_parameters:\n\ 675 | \ query:\n type: mixed\n \ 676 | \ value: '{{#[入力ノードID].[変数名]#}}'\n outputs:\n \ 677 | \ text:\n type: string\n ```" 678 | prompt_type: simple 679 | retriever_resource: 680 | enabled: true 681 | sensitive_word_avoidance: 682 | configs: [] 683 | enabled: false 684 | type: '' 685 | speech_to_text: 686 | enabled: false 687 | suggested_questions: [] 688 | suggested_questions_after_answer: 689 | enabled: false 690 | text_to_speech: 691 | enabled: false 692 | language: '' 693 | voice: '' 694 | user_input_form: [] 695 | version: 0.1.3 -------------------------------------------------------------------------------- /example/adoviser_bot.yml: -------------------------------------------------------------------------------- 1 | app: 2 | mode: workflow 3 | name: タスク分析アドバイザー 4 | version: 0.1.3 5 | 6 | workflow: 7 | graph: 8 | edges: 9 | # 開始 → 質問分類器 10 | - source: '1731228343114' 11 | target: '1731228343115' 12 | data: 13 | sourceType: start 14 | targetType: question-classifier 15 | 16 | # 質問分類器 → LLM(プロジェクト管理) 17 | - source: '1731228343115' 18 | sourceHandle: '1' 19 | target: '1731228343116' 20 | targetHandle: target 21 | data: 22 | sourceType: question-classifier 23 | targetType: llm 24 | 25 | # 質問分類器 → LLM(技術開発) 26 | - source: '1731228343115' 27 | sourceHandle: '2' 28 | target: '1731228343117' 29 | targetHandle: target 30 | data: 31 | sourceType: question-classifier 32 | targetType: llm 33 | 34 | # 質問分類器 → LLM(顧客対応) 35 | - source: '1731228343115' 36 | sourceHandle: '3' 37 | target: '1731228343118' 38 | targetHandle: target 39 | data: 40 | sourceType: question-classifier 41 | targetType: llm 42 | 43 | # 各LLM → Variable Aggregator 44 | - source: '1731228343116' 45 | target: '1731228343119' 46 | data: 47 | sourceType: llm 48 | targetType: variable-aggregator 49 | - source: '1731228343117' 50 | target: '1731228343119' 51 | data: 52 | sourceType: llm 53 | targetType: variable-aggregator 54 | - source: '1731228343118' 55 | target: '1731228343119' 56 | data: 57 | sourceType: llm 58 | targetType: variable-aggregator 59 | 60 | # Variable Aggregator → IF/ELSE 61 | - source: '1731228343119' 62 | target: '1731228343120' 63 | data: 64 | sourceType: variable-aggregator 65 | targetType: if-else 66 | 67 | # IF/ELSE → テンプレート(Manager用) 68 | - source: '1731228343120' 69 | target: '1731228343121' 70 | data: 71 | sourceType: if-else 72 | targetType: template-transform 73 | sourceHandle: 'true' 74 | 75 | # IF/ELSE → テンプレート(Staff用) 76 | - source: '1731228343120' 77 | target: '1731228343122' 78 | data: 79 | sourceType: if-else 80 | targetType: template-transform 81 | sourceHandle: 'false' 82 | 83 | # テンプレート → パラメータ抽出(共通) 84 | - source: '1731228343121' 85 | target: '1731228343123' 86 | data: 87 | sourceType: template-transform 88 | targetType: parameter-extractor 89 | - source: '1731228343122' 90 | target: '1731228343123' 91 | data: 92 | sourceType: template-transform 93 | targetType: parameter-extractor 94 | 95 | # パラメータ抽出 → 応答 96 | - source: '1731228343123' 97 | target: '1731228343124' 98 | data: 99 | sourceType: parameter-extractor 100 | targetType: answer 101 | 102 | nodes: 103 | # 開始ノード 104 | - id: '1731228343114' 105 | data: 106 | type: start 107 | title: タスク情報入力 108 | variables: 109 | - type: paragraph 110 | variable: task_content 111 | label: タスク内容 112 | required: true 113 | max_length: 1000 114 | - type: select 115 | variable: position 116 | label: ポジション 117 | required: true 118 | options: 119 | - manager 120 | - staff 121 | 122 | # 質問分類器ノード 123 | - id: '1731228343115' 124 | data: 125 | type: question-classifier 126 | title: タスク分類 127 | model: 128 | provider: openai 129 | name: gpt-4o 130 | mode: chat 131 | completion_params: 132 | temperature: 0.3 133 | query_variable_selector: 134 | - '1731228343114' 135 | - task_content 136 | classes: 137 | - id: '1' 138 | name: プロジェクト管理 139 | - id: '2' 140 | name: 技術開発 141 | - id: '3' 142 | name: 顧客対応 143 | 144 | # LLMノード(プロジェクト管理) 145 | - id: '1731228343116' 146 | data: 147 | type: llm 148 | title: プロジェクト管理アドバイス 149 | model: 150 | provider: openai 151 | name: gpt-4o 152 | mode: chat 153 | completion_params: 154 | temperature: 0.7 155 | prompt_template: 156 | - id: 'prompt1' 157 | role: system 158 | text: 'プロジェクト管理に関する以下のタスクについて、具体的なアドバイスを提供してください:{{#1731228343114.task_content#}}' 159 | context: 160 | enabled: true 161 | variable_selector: 162 | - '1731228343114' 163 | - task_content 164 | vision: 165 | enabled: false 166 | 167 | # LLMノード(技術開発) 168 | - id: '1731228343117' 169 | data: 170 | type: llm 171 | title: 技術開発アドバイス 172 | model: 173 | provider: openai 174 | name: gpt-4o 175 | mode: chat 176 | completion_params: 177 | temperature: 0.7 178 | prompt_template: 179 | - id: 'prompt2' 180 | role: system 181 | text: '技術開発に関する以下のタスクについて、技術的な観点からアドバイスを提供してください:{{#1731228343114.task_content#}}' 182 | context: 183 | enabled: true 184 | variable_selector: 185 | - '1731228343114' 186 | - task_content 187 | vision: 188 | enabled: false 189 | 190 | # LLMノード(顧客対応) 191 | - id: '1731228343118' 192 | data: 193 | type: llm 194 | title: 顧客対応アドバイス 195 | model: 196 | provider: openai 197 | name: gpt-4o 198 | mode: chat 199 | completion_params: 200 | temperature: 0.7 201 | prompt_template: 202 | - id: 'prompt3' 203 | role: system 204 | text: '顧客対応に関する以下のタスクについて、顧客満足度を重視したアドバイスを提供してください:{{#1731228343114.task_content#}}' 205 | context: 206 | enabled: true 207 | variable_selector: 208 | - '1731228343114' 209 | - task_content 210 | vision: 211 | enabled: false 212 | 213 | # Variable Aggregatorノード 214 | - id: '1731228343119' 215 | data: 216 | type: variable-aggregator 217 | title: アドバイス集約 218 | output_type: string 219 | variables: 220 | - - '1731228343116' 221 | - text 222 | - - '1731228343117' 223 | - text 224 | - - '1731228343118' 225 | - text 226 | 227 | # IF/ELSEノード 228 | - id: '1731228343120' 229 | data: 230 | type: if-else 231 | title: ポジション判定 232 | cases: 233 | - case_id: 'true' 234 | logical_operator: and 235 | conditions: 236 | - id: 'cond1' 237 | varType: string 238 | variable_selector: 239 | - '1731228343114' 240 | - position 241 | comparison_operator: is 242 | value: manager 243 | 244 | # テンプレート変換ノード(Manager用) 245 | - id: '1731228343121' 246 | data: 247 | type: template-transform 248 | title: Manager向けフォーマット 249 | template: | 250 | ## マネージャー向けタスクアドバイス 251 | 252 | ### 概要 253 | タスク内容:{{ task_content }} 254 | 255 | ### 詳細アドバイス 256 | {{ advice }} 257 | 258 | ### アクションアイテム 259 | 1. チーム編成の検討 260 | 2. リソース配分の最適化 261 | 3. スケジュール管理 262 | 4. リスク分析 263 | variables: 264 | - value_selector: 265 | - '1731228343114' 266 | - task_content 267 | variable: task_content 268 | - value_selector: 269 | - '1731228343119' 270 | - output 271 | variable: advice 272 | 273 | # テンプレート変換ノード(Staff用) 274 | - id: '1731228343122' 275 | data: 276 | type: template-transform 277 | title: Staff向けフォーマット 278 | template: | 279 | ## スタッフ向けタスクアドバイス 280 | 281 | ### タスク内容 282 | {{ task_content }} 283 | 284 | ### アドバイス要点 285 | {{ advice }} 286 | 287 | ### 次のステップ 288 | 1. 必要なスキル確認 289 | 2. タイムライン作成 290 | 3. 上司への報告準備 291 | variables: 292 | - value_selector: 293 | - '1731228343114' 294 | - task_content 295 | variable: task_content 296 | - value_selector: 297 | - '1731228343119' 298 | - output 299 | variable: advice 300 | 301 | # パラメータ抽出ノード 302 | - id: '1731228343123' 303 | data: 304 | type: parameter-extractor 305 | title: レスポンス解析 306 | query: 307 | - '1731228343121' 308 | - output 309 | model: 310 | provider: openai 311 | name: gpt-4o 312 | mode: chat 313 | completion_params: 314 | temperature: 0.3 315 | reasoning_mode: prompt 316 | parameters: 317 | - name: priority_level 318 | type: select 319 | description: タスクの優先度 320 | required: true 321 | options: 322 | - 高 323 | - 中 324 | - 低 325 | - name: estimated_time 326 | type: string 327 | description: 推定所要時間 328 | required: true 329 | - name: key_points 330 | type: array[string] 331 | description: 主要なポイント 332 | required: true 333 | instruction: | 334 | 提供されたアドバイスから以下の情報を抽出してください: 335 | 1. タスクの優先度 336 | 2. 推定される所要時間 337 | 3. 重要なポイント(箇条書き) 338 | 339 | # 応答ノード 340 | - id: '1731228343124' 341 | data: 342 | type: answer 343 | title: 最終レスポンス 344 | answer: | 345 | {{#1731228343121.output#}} 346 | {{#1731228343122.output#}} 347 | 348 | 追加分析: 349 | 優先度: {{#1731228343123.priority_level#}} 350 | 推定所要時間: {{#1731228343123.estimated_time#}} 351 | 352 | 重要ポイント: 353 | {{#1731228343123.key_points#}} 354 | -------------------------------------------------------------------------------- /example/manual_search.yml: -------------------------------------------------------------------------------- 1 | app: 2 | mode: workflow 3 | name: マニュアル質問応答システム 4 | version: 0.1.3 5 | 6 | workflow: 7 | graph: 8 | edges: 9 | # 開始から質問分類へ 10 | - source: '1731228343114' 11 | target: '1731228344221' 12 | data: 13 | sourceType: start 14 | targetType: question-classifier 15 | 16 | # Docker質問の場合 17 | - source: '1731228344221' 18 | sourceHandle: '1' 19 | target: '1731228345332' 20 | targetHandle: target 21 | data: 22 | sourceType: question-classifier 23 | targetType: knowledge-retrieval 24 | 25 | # Ubuntu質問の場合 26 | - source: '1731228344221' 27 | sourceHandle: '2' 28 | target: '1731228345333' 29 | targetHandle: target 30 | data: 31 | sourceType: question-classifier 32 | targetType: knowledge-retrieval 33 | 34 | # Docker知識取得からLLMへ 35 | - source: '1731228345332' 36 | target: '1731228346443' 37 | data: 38 | sourceType: knowledge-retrieval 39 | targetType: llm 40 | 41 | # Ubuntu知識取得からLLMへ 42 | - source: '1731228345333' 43 | target: '1731228346443' 44 | data: 45 | sourceType: knowledge-retrieval 46 | targetType: llm 47 | 48 | # LLMから終了へ 49 | - source: '1731228346443' 50 | target: '1731228347554' 51 | data: 52 | sourceType: llm 53 | targetType: end 54 | 55 | # 分類不能な質問は直接終了へ 56 | - source: '1731228344221' 57 | target: '1731228347554' 58 | data: 59 | sourceType: question-classifier 60 | targetType: end 61 | 62 | nodes: 63 | # 開始ノード 64 | - id: '1731228343114' 65 | data: 66 | type: start 67 | title: 開始 68 | variables: 69 | - type: text-input 70 | variable: Query 71 | label: 質問内容を入力してください 72 | required: true 73 | max_length: 1000 74 | 75 | # 質問分類器ノード 76 | - id: '1731228344221' 77 | data: 78 | type: question-classifier 79 | title: 質問分類 80 | model: 81 | provider: openai 82 | name: gpt-4o 83 | mode: chat 84 | completion_params: 85 | temperature: 0.7 86 | query_variable_selector: 87 | - '1731228343114' 88 | - Query 89 | classes: 90 | - id: '1' 91 | name: Docker質問 92 | - id: '2' 93 | name: Ubuntu質問 94 | 95 | # Docker用知識取得ノード 96 | - id: '1731228345332' 97 | data: 98 | type: knowledge-retrieval 99 | title: Docker知識取得 100 | dataset_ids: 101 | - 64862693-8529-4627-a20e-35b7dcb883c8 102 | retrieval_mode: multiple 103 | multiple_retrieval_config: 104 | reranking_enable: true 105 | reranking_mode: weighted_score 106 | top_k: 4 107 | weights: 108 | vector_setting: 109 | embedding_model_name: text-embedding-3-large 110 | embedding_provider_name: openai 111 | vector_weight: 1 112 | keyword_setting: 113 | keyword_weight: 0 114 | query_variable_selector: 115 | - '1731228343114' 116 | - Query 117 | 118 | # Ubuntu用知識取得ノード 119 | - id: '1731228345333' 120 | data: 121 | type: knowledge-retrieval 122 | title: Ubuntu知識取得 123 | dataset_ids: 124 | - 84782981-6a4d-4d19-9189-dd72fe435a57 125 | retrieval_mode: multiple 126 | multiple_retrieval_config: 127 | reranking_enable: true 128 | reranking_mode: weighted_score 129 | top_k: 4 130 | weights: 131 | vector_setting: 132 | embedding_model_name: text-embedding-3-large 133 | embedding_provider_name: openai 134 | vector_weight: 1 135 | keyword_setting: 136 | keyword_weight: 0 137 | query_variable_selector: 138 | - '1731228343114' 139 | - Query 140 | 141 | # LLMノード 142 | - id: '1731228346443' 143 | data: 144 | type: llm 145 | title: 回答生成 146 | model: 147 | provider: openai 148 | name: gpt-4o 149 | mode: chat 150 | completion_params: 151 | temperature: 0.7 152 | prompt_template: 153 | - role: system 154 | id: '1731228346443-1' 155 | text: '以下のコンテキストを参考に、ユーザーの質問に対して正確で分かりやすい回答を生成してください。 156 | 回答は以下の形式で作成してください: 157 | 158 | 1. 質問内容の要約 159 | 2. 具体的な回答 160 | 3. (必要に応じて)補足説明や注意点 161 | 162 | 質問: {{#1731228343114.Query#}}' 163 | context: 164 | enabled: true 165 | variable_selector: 166 | - '1731228343114' 167 | - Query 168 | 169 | # 終了ノード 170 | - id: '1731228347554' 171 | data: 172 | type: end 173 | title: 終了 174 | outputs: 175 | - value_selector: 176 | - '1731228343114' 177 | - Query 178 | variable: inputQuery 179 | - value_selector: 180 | - '1731228346443' 181 | - text 182 | variable: generatedAnswer -------------------------------------------------------------------------------- /images/DifyWorkflowGenerator.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tomatio13/DifyWorkFlowGenerator/1acdcae69cbd9c5e44e6df77edd74ffb8976d632/images/DifyWorkflowGenerator.jpg -------------------------------------------------------------------------------- /images/DifyWorkflowGenerator_initial.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tomatio13/DifyWorkFlowGenerator/1acdcae69cbd9c5e44e6df77edd74ffb8976d632/images/DifyWorkflowGenerator_initial.jpg -------------------------------------------------------------------------------- /images/adoviser_bot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tomatio13/DifyWorkFlowGenerator/1acdcae69cbd9c5e44e6df77edd74ffb8976d632/images/adoviser_bot.png -------------------------------------------------------------------------------- /images/manual_search.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tomatio13/DifyWorkFlowGenerator/1acdcae69cbd9c5e44e6df77edd74ffb8976d632/images/manual_search.jpg -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | langchain==0.3.8 2 | langchain-anthropic==0.3.0 3 | langgraph==0.2.53 4 | -------------------------------------------------------------------------------- /workflow_generator_prompt.yml: -------------------------------------------------------------------------------- 1 | prompt: 2 | metadata: 3 | title: Difyワークフロー生成プロンプト 4 | version: 1.0.0 5 | description: Difyのワークフローファイルを生成するためのプロンプト定義 6 | 7 | input_requirements: | 8 | 以下の情報を提供してください: 9 | 1. ワークフローの目的(例:本の要約生成、商品説明文作成など) 10 | 2. 入力として必要な情報(例:本のタイトル、商品名と特徴など) 11 | 3. 出力として期待する形式や内容 12 | 4. 特別な制約条件(文字数制限、トーンの指定など) 13 | 14 | instructions: 15 | workflow_overview: | 16 | 提供された要件に基づいて、以下の要素を含むDifyワークフローファイル(YAML形式)を生成します: 17 | - ノード(開始、LLM、終了)で構成されるワークフロー 18 | - ノード間は順次実行されるよう接続(但し、指定された場合は並列実行も可能) 19 | - 入力から出力までの一連の処理を自動化 20 | 21 | required_structure: 22 | app_info: 23 | - mode: workflowを指定 24 | - name: 目的を表す名前を設定 25 | - version: 0.1.3を使用 26 | 27 | workflow_graph: 28 | edges: 29 | - source: 開始ノードのID(例:'1731228343114') 30 | target: LLMノードのID(例:'1731229438627') 31 | data: 32 | sourceType: start 33 | targetType: llm 34 | - source: LLMノードのID(例:'1731229438627') 35 | target: 終了ノードのID(例:'1731228345560') 36 | data: 37 | sourceType: llm 38 | targetType: end 39 | - source: 質問分類器ノードのID 40 | sourceHandle: '1' # 質問分類1用 41 | target: ターゲットノードID1 42 | targetHandle: target 43 | data: 44 | sourceType: question-classifier 45 | targetType: [ターゲットノードタイプ] 46 | - source: 質問分類器ノードのID 47 | sourceHandle: '2' # 質問分類2用 48 | target: ターゲットノードID2 49 | targetHandle: target 50 | data: 51 | sourceType: question-classifier 52 | targetType: [ターゲットノードタイプ] 53 | - source: [IF/ELSEノードID] 54 | target: [ターゲットノードID] 55 | data: 56 | sourceType: if-else 57 | targetType: [ターゲットノードタイプ] 58 | sourceHandle: 'true' # IF条件成立時 59 | - source: [IF/ELSEノードID] 60 | target: [別のターゲットノードID] 61 | data: 62 | sourceType: if-else 63 | targetType: [ターゲットノードタイプ] 64 | sourceHandle: 'false' # ELSE条件時 65 | - source: [ツールノードID] 66 | target: [ターゲットノードID] 67 | data: 68 | sourceType: tool 69 | targetType: [ターゲットノードタイプ] 70 | 71 | nodes: 72 | start_node: 73 | - id: ユニークなID 74 | - type: start 75 | - variables: 76 | # ファイル入力の例 77 | - type: file 78 | variable: input_document 79 | label: ドキュメント 80 | required: true 81 | max_length: 48 82 | allowed_file_types: 83 | - document 84 | allowed_file_upload_methods: 85 | - local_file 86 | - remote_url 87 | 88 | # 数値入力の例 89 | - type: number 90 | variable: input_number 91 | label: 数値 92 | required: true 93 | min: 0 94 | max: 1000000 95 | 96 | # 段落入力の例 97 | - type: paragraph 98 | variable: danraku 99 | label: 段落 100 | required: true 101 | max_length: 48 102 | options: [] 103 | 104 | # 短文入力の例 105 | - type: text-input 106 | variable: tanbun 107 | label: 短文 108 | required: true 109 | max_length: 48 110 | options: [] 111 | 112 | llm_node: 113 | - id: ユニークなID 114 | - type: llm 115 | - model: 116 | - provider: openai 117 | - name: gpt-4o 118 | - mode: chat 119 | - completion_params: 120 | - temperature: 生成時の温度設定 121 | - prompt_template: 122 | - id: ユニークなID(例'prompt1') 123 | role: system 124 | text: シングートで括ったプロンプトテキスト 125 | - context: 126 | - enabled: true 127 | - variable_selector: 使用する変数の指定 128 | - vision: 129 | - enabled: false 130 | 131 | end_node: 132 | - id: ユニークなID 133 | - type: end 134 | - outputs: #出力変数の定義 135 | - input_data: 入力データ 136 | - generated_text: 生成されたテキスト 137 | 138 | http_request_node: 139 | - id: ユニークなID 140 | - type: http-request 141 | - data: 142 | - authorization: 143 | config: null 144 | type: no-auth/basic/bearer # 認証タイプを指定 145 | - body: 146 | type: json/form-data/x-www-form-urlencoded 147 | data: # JSONの場合の例 148 | - id: [キーバリューID] 149 | key: [キー名] 150 | type: text 151 | value: [JSON形式の値] 152 | - headers: Content-Type:[content-type] # 例:application/json 153 | - method: get/post/put/delete 154 | - url: [APIエンドポイントURL] 155 | - timeout: 156 | max_connect_timeout: [接続タイムアウト秒数] 157 | max_read_timeout: [読み取りタイムアウト秒数] 158 | max_write_timeout: [書き込みタイムアウト秒数] 159 | - title: HTTPリクエスト 160 | - variables: [] # 必要に応じて変数を定義 161 | 162 | json_parse_node: 163 | - id: ユニークなID 164 | - type: tool 165 | - data: 166 | - provider_id: json_process 167 | - provider_name: json_process 168 | - provider_type: builtin 169 | - title: JSON Parse 170 | - tool_configurations: 171 | ensure_ascii: 1 172 | - tool_name: parse 173 | - tool_parameters: 174 | content: 175 | type: mixed 176 | value: '{{#[入力ノードID].[変数名]#}}' 177 | json_filter: 178 | type: mixed 179 | value: [抽出したいJSONキー] 180 | 181 | question_classifier_node: 182 | - id: ユニークなID 183 | - type: question-classifier 184 | - data: 185 | - title: 質問分類器 186 | - model: 187 | provider: openai 188 | name: gpt-4o 189 | mode: chat 190 | completion_params: 191 | temperature: 0.7 192 | - query_variable_selector: 193 | - [入力ノードID] 194 | - [変数名] 195 | - classes: 196 | - id: [クラスID] 197 | name: [分類名] 198 | 199 | knowledge_retrieval_node: 200 | - id: ユニークなID 201 | - type: knowledge-retrieval 202 | - data: 203 | - title: 知識取得 204 | - dataset_ids: 205 | - [データセットID] 206 | - retrieval_mode: multiple 207 | - multiple_retrieval_config: 208 | reranking_enable: true 209 | reranking_mode: weighted_score 210 | top_k: 4 211 | weights: 212 | vector_setting: 213 | embedding_model_name: text-embedding-3-large 214 | embedding_provider_name: openai 215 | vector_weight: 1 216 | keyword_setting: 217 | keyword_weight: 0 218 | - query_variable_selector: 219 | - [入力ノードID] 220 | - [変数名] 221 | 222 | code_node: 223 | - id: ユニークなID 224 | - type: code 225 | - data: 226 | - code_language: python3 227 | - code: "def main(arg1: str) -> dict:\nreturn {\n\"task_url\": \"http://example.com/task/\"+arg1,\n}" # Pythonードを記述しダブルクォートで括る。 228 | - title: Pythonコード実行 229 | - variables: [] # 必要に応じて変数を定義 230 | - outputs: # 出力変数の定義(必須) 231 | task_url: # 変数名 232 | children: null 233 | type: string # 変数の型 234 | - variables: # 入力変数の定義(必須) 235 | - value_selector: # 他のノードからの入力 236 | - [入力ノードID] 237 | - [変数名] 238 | variable: arg1 # 関数の引数名 239 | 240 | if_else_node: 241 | - id: ユニークなID 242 | - type: if-else 243 | - data: 244 | title: 条件分岐 245 | cases: 246 | - case_id: 'true' 247 | logical_operator: and 248 | conditions: 249 | - id: 5d3c1fa4-e26c-4f4b-a3a9-d4c32d63d5f8 250 | varType: number 251 | variable_selector: 252 | - [入力ノードID] 253 | - [変数名] 254 | comparison_operator: 'contains' # ComparisonOperatorの列挙型に従う 255 | value: '5' 256 | numberVarType: constant 257 | - id: f764d294-6b89-46a2-9486-8b2c067e58ff 258 | varType: string 259 | variable_selector: 260 | - [入力ノードID] 261 | - [変数名] 262 | key: 'subKey' 263 | comparison_operator: 'contains' 264 | value: 'テスト' 265 | sub_variable_condition: 266 | case_id: 'sub1' 267 | logical_operator: and 268 | conditions: 269 | - id: 'sub-condition-1' 270 | varType: string 271 | comparison_operator: 'start with' 272 | value: 'prefix' 273 | 274 | variable_aggregator_node: 275 | - id: ユニークなID 276 | - type: variable-aggregator 277 | - data: 278 | - title: 変数集約器 279 | - output_type: string/number/boolean # 出力変数の型 280 | - variables: # 集約する変数のリスト 281 | - - [入力ノードID1] 282 | - [変数名1] 283 | - - [入力ノードID2] 284 | - [変数名2] 285 | 286 | document_extractor_node: 287 | - id: ユニークなID 288 | - type: document-extractor 289 | - data: 290 | - title: テキスト抽出ツール 291 | - is_array_file: false 292 | - variable_selector: 293 | - [入力ノードID] 294 | - [変数名] 295 | 296 | template_transform_node: 297 | - id: ユニークなID 298 | - type: template-transform 299 | - data: 300 | title: テンプレート変換 301 | template: テンプレート文字列(Jinja2形式) 302 | variables: 303 | - value_selector: # 入力変数の指定 304 | - [入力ノードID] 305 | - [変数名] 306 | variable: [テンプレート内で使用する変数名] 307 | outputs: 308 | output: # 固定の出力変数名 309 | type: string # 常にstring型 310 | 311 | answer_node: 312 | - id: ユニークなID 313 | - type: answer 314 | - data: 315 | title: 応答ノード 316 | answer: 応答テキストまたは変数参照 317 | variables: [] # 必要に応じて変数定義 318 | 319 | parameter_extractor_node: 320 | - id: ユニークなID(必須) 321 | - type: parameter-extractor(固定) 322 | - data: 323 | - title: パラメータ抽出 324 | - query: # 入力変数の指定(必須) 325 | - [入力ノードID] 326 | - [変数名] 327 | - model: # モデル設定(必須) 328 | - provider: プロバイダー名 329 | - name: モデル名 330 | - mode: chat/completion 331 | - completion_params: 332 | - temperature: 0.0-1.0 333 | - reasoning_mode: # 推論モード(必須) 334 | - prompt: プロンプトベース 335 | - function_call: 関数呼び出し 336 | - parameters: # 抽出パラメータ定義(必須) 337 | - name: パラメータ名 338 | type: パラメータ型 339 | description: 説明文 340 | required: true/false 341 | options: # select型の場合の選択肢 342 | - オプション1 343 | - オプション2 344 | - instruction: プロンプト文字列 345 | - memory: # メモリ設定(オプション) 346 | - role_prefix: 347 | - user: ユーザープレフィックス 348 | - assistant: アシスタントプレフィックス 349 | - vision: # 画像処理設定(オプション) 350 | - enabled: true/false 351 | - configs: 画像設定 352 | 353 | youtube_transcript_node: 354 | - id: ユニークなID 355 | - data: 356 | type: tool 357 | title: Free YouTube Transcript API 358 | provider_name: transcript 359 | provider_id: transcript 360 | provider_type: builtin 361 | tool_label: Free YouTube Transcript API 362 | tool_name: free_youtube_transcript 363 | tool_configurations: 364 | cookies: null 365 | format: text 366 | language: ja 367 | preserve_formatting: 0 368 | proxy: null 369 | tool_parameters: 370 | video_id: 371 | type: mixed 372 | value: YouTubeビデオID or 変数参照 373 | outputs: 374 | text: # 字幕テキストの出力変数 375 | type: string 376 | 377 | jina_reader_node: 378 | - id: ユニークなID 379 | - type: tool 380 | - data: 381 | - provider_id: jina 382 | - provider_name: jina 383 | - provider_type: builtin 384 | - title: JinaReader 385 | - tool_configurations: 386 | gather_all_images_at_the_end: 0 # 画像収集設定 387 | gather_all_links_at_the_end: 0 # リンク収集設定 388 | image_caption: 0 # 画像キャプション設定 389 | no_cache: 0 # キャッシュ無効化 390 | proxy_server: null # プロキシサーバー設定 391 | summary: 0 # 要約機能 392 | target_selector: null # ターゲット要素セレクター 393 | wait_for_selector: null # 待機要素セレクター 394 | - tool_label: JinaReader 395 | - tool_name: jina_reader 396 | - tool_parameters: 397 | url: 398 | type: mixed 399 | value: '{{#[入力ノードID].[変数名]#}}' # URL入力 400 | 401 | tavily_search_node: 402 | - id: ユニークなID 403 | - type: tool 404 | - data: 405 | - provider_id: tavily 406 | - provider_name: tavily 407 | - provider_type: builtin 408 | - title: TavilySearch 409 | - tool_configurations: 410 | exclude_domains: null # 除外ドメイン 411 | include_domains: null # 含めるドメイン 412 | include_answer: null # 回答を含める 413 | include_images: null # 画像を含める 414 | include_raw_content: null # 生コンテンツを含める 415 | max_results: 3 # 最大結果数 416 | search_depth: basic # 検索深度 417 | - tool_label: TavilySearch 418 | - tool_name: tavily_search 419 | - tool_parameters: 420 | query: 421 | type: mixed 422 | value: '{{#[入力ノードID].[変数名]#}}' 423 | 424 | usage_guide: | 425 | 共通事項: 426 | - ノードIDはユニークなIDである必要があります。 427 | - ノードIDは1700000000000から始まる必要があります。 428 | - ノードIDは1700000000000から1799999999999までの範囲である必要があります。 429 | 430 | ワークフローの使用方法: 431 | 1. 開始ノード 432 | ユースケース: 433 | - ワークフローの開始点として機能 434 | - ユーザーからの入力を受け付け 435 | - 入力された情報を変数として保存 436 | 437 | 構造: 438 | - id: ユニークなID(必須) 439 | - type: start(固定) 440 | - variables: 入力変数の配列(必須) 441 | - type: 変数の型(必須) 442 | - variable: 変数名(必須) 443 | - label: 表示ラベル(必須) 444 | - required: 必須入力かどうか(必須) 445 | - その他設定(型に応じて必要) 446 | 447 | 変数型と固有設定: 448 | - file(ファイル入力): 449 | - allowed_file_types: 許可するファイルタイプ 450 | - document: ドキュメントファイル 451 | - image: 画像ファイル 452 | - audio: 音声ファイル 453 | - video: 動画ファイル 454 | - allowed_file_upload_methods: アップロード方法 455 | - local_file: ローカルファイル 456 | - remote_url: リモートURL 457 | - max_length: 最大ファイル名長 458 | - required: 必須項目かどうか 459 | - number(数値入力): 460 | - min: 最小値(オプション) 461 | - max: 最大値(オプション) 462 | - paragraph(段落テキスト): 463 | - max_length: 最大文字数(オプション) 464 | - options: 選択肢(オプション) 465 | - text-input(短文テキスト): 466 | - max_length: 最大文字数(オプション) 467 | - options: 選択肢(オプション) 468 | 469 | 2. LLMノード 470 | ユースケース: 471 | - テキスト生成や応答の作成 472 | - 入力テキストの加工や変換 473 | - 質問への回答生成 474 | 構造: 475 | - id: ユニークなID(必須) 476 | - type: llm(固定) 477 | - model:(必須) 478 | - provider: openai(固定) 479 | - name: gpt-4o(固定) 480 | - mode: chat(固定) 481 | - completion_params: 482 | - temperature: 0.0-1.0の値(必須) 483 | - prompt_template:(必須) 484 | - role: system(固定) 485 | - text: プロンプトテキスト(必須) 486 | - context:(必須) 487 | - enabled: true(固定) 488 | - variable_selector: 使用する変数の指定(必須) 489 | - vision: 490 | - enabled: false(固定) 491 | 特記事項: 492 | - プロンプトはシングルクォートで括る必要あり 493 | - システムロールのプロンプトのみ使用可能 494 | - 変数参照形式: {{#ノードID.変数名#}} 495 | - contextのvariable_selectorで指定した変数は、prompt_templateのtextでも使用して下さい。 496 | 497 | 3. 終了ノード 498 | ユースケース: 499 | - ワークフローの終了点として機能 500 | - 処理結果の出力を定義 501 | - 後続システムへのデータ受け渡し 502 | 503 | 構造: 504 | - id: ユニークなID(必須) 505 | - type: end(固定) 506 | - outputs:(必須) 507 | - value_selector:(必須) 508 | - [ノードID] 509 | - [変数名] 510 | - variable: 出力変数名(必須) 511 | 512 | 特記事項: 513 | - 少なくとも1つの出力変数が必要 514 | - 複数の出力変数を定義可能 515 | 516 | 4. HTTPリクエストノード 517 | ユースケース: 518 | - 外部APIとの連携 519 | - データの送受信 520 | - Webhook通知の送信 521 | - 外部サービスとの統合 522 | 523 | 構造: 524 | - id: ユニークなID(必須) 525 | - type: http-request(固定) 526 | - data:(必須) 527 | - authorization:(必須) 528 | - config: 認証設定(オプション) 529 | - type: 認証タイプ(必須) 530 | - no-auth: 認証なし 531 | - basic: Basic認証 532 | - bearer: Bearer認証 533 | - body:(必須) 534 | - type: リクエストボディタイプ(必須) 535 | - json: JSON形式 536 | - form-data: マルチパートフォーム 537 | - x-www-form-urlencoded: URLエンコード形式 538 | - data: リクエストデータ(必須) 539 | - headers: ヘッダー情報(必須) 540 | - method: HTTPメソッド(必須) 541 | - url: エンドポイントURL(必須) 542 | - timeout:(オプション) 543 | - max_connect_timeout: 接続タイムアウト秒数 544 | - max_read_timeout: 読み取りタイムアウト秒数 545 | - max_write_timeout: 書き込みタイムアウト秒数 546 | - title: ノードのタイトル(必須) 547 | - variables: 変数定義(オプション) 548 | 549 | 特記事項: 550 | HTTPメソッド: 551 | - GET: リソースの取得 552 | - クエリパラメータによる検索 553 | - キャッシュ可能 554 | - POST: データの送信・作成 555 | - リソースの規成 556 | - 大容量データの送信 557 | - PUT: リソースの更新・作成 558 | - 完全な置き換え 559 | - べき等性あり 560 | - PATCH: リソースの部分更新 561 | - 一部フィールドの更新 562 | - べき等性なし 563 | - DELETE: リソースの削除 564 | - 指定リソースの削除 565 | - HEAD: ヘッダー情報の取得 566 | - レスポンスボディなし 567 | 568 | 変数参照: 569 | - 形式: {{#[ノードID].[変数名]#}} 570 | - 他のノードの出力を参照可能 571 | - JSONパスによるネストされた値の参照可能 572 | 573 | タイムアウト設定: 574 | - 0は無制限を意味する 575 | - ミリ秒単位で指定可能 576 | - 各フェーズで個別に設定可能 577 | 578 | 5. JSON Parseノード 579 | ユースケース: 580 | - JSONデータの解析 581 | - 特定のキーの抽出 582 | - APIレスポンスの処理 583 | - 構造化データの加工 584 | 585 | 構造: 586 | - id: ユニークなID(必須) 587 | - type: tool(固定) 588 | - data:(必須) 589 | - provider_id: json_process(固定) 590 | - provider_name: json_process(固定) 591 | - provider_type: builtin(固定) 592 | - title: ノードのタイトル(必須) 593 | - tool_configurations:(必須) 594 | - ensure_ascii: 1または0(必須) 595 | - tool_name: parse(固定) 596 | - tool_parameters:(必須) 597 | - content:(必須) 598 | - type: mixed(固定) 599 | - value: パース対象のJSON(必須) 600 | - json_filter:(必須) 601 | - type: mixed(固定) 602 | - value: 抽出キー(必須) 603 | 604 | 特記事項: 605 | データ形式: 606 | - content: JSON文字列またはオブジェクト 607 | - 他のノードの出力を参照可能 608 | - 変数参照形式: {{#[ノードID].[変数名]#}} 609 | 610 | 文字エンコード: 611 | - ensure_ascii: 612 | - 1: ASCII文字のみ使用 613 | - 0: Unicode文字を許可 614 | 615 | フィルタリング: 616 | - 単一キー: "key" 617 | - ネトしたキー: "key1.key2" 618 | - 配列インデックス: "array[0]" 619 | - 複数キー: ["key1", "key2"] 620 | - 条件付き: "key[?(@.field=='value')]" 621 | 622 | 6. 質問分類器ノード 623 | ユースケース: 624 | - 質問内容の自動分類 625 | - インテントの判別 626 | - 応答フローの最適化 627 | - マルチパス処理の制御 628 | 629 | 構造: 630 | - id: ユニークなID(必須) 631 | - type: question-classifier(固定) 632 | - data:(必須) 633 | - title: ノードのタイトル(必須) 634 | - model:(必須) 635 | - provider: openai(固定) 636 | - name: gpt-4o(固定) 637 | - mode: chat(固定) 638 | - completion_params:(必須) 639 | - temperature: 0.0-1.0の値 640 | - query_variable_selector:(必須) 641 | - [入力ノードID] 642 | - [変数名] 643 | - classes:(必須) 644 | - id: クラスID(必須) 645 | - name: 分類名(必須) 646 | 647 | 特記事項: 648 | 分岐パターン: 649 | 1. 共通LLM使用パターン: 650 | - クラス1の質問 → 知識取得1 → 共通LLM → 終了 651 | - クラス2の質問 → 知識取得2 → 共通LLM → 終了 652 | - その他の質問 → 直接終了ノードへ 653 | 654 | 2. 個別LLM使用パターン: 655 | - クラス1の質問 → 知識取得1 → LLM1 → 終了1 656 | - クラス2の質問 → 知識取得2 → LLM2 → 終了2 657 | - その他の質問 → 直接終了ノードへ 658 | 659 | エッジ接続設定: 660 | - sourceHandle: 質問分類のID('1', '2'など) 661 | - targetHandle: 'target'を指定 662 | - sourceType: question-classifier 663 | - targetType: 接続先のノードタイプ 664 | 665 | 分類結果の利用: 666 | - 各クラスに応じた適切な知識ベースの選択 667 | - クラスごとに異なるプロンプトの使用 668 | - 分類結果に基づく条件分岐の実装 669 | 670 | 7. 知識取得ノード 671 | ユースケース: 672 | - データセットからの関連情報検索 673 | - 質問に関連する知識の取得 674 | - コンテキストベースの応答生成 675 | - 複数ソースからの情報統合 676 | 677 | 構造: 678 | - id: ユニークなID(必須) 679 | - type: knowledge-retrieval(固定) 680 | - data:(必須) 681 | - title: ノードのタイトル(必須) 682 | - dataset_ids: データセットIDの配列(必須) 683 | - retrieval_mode: multiple(固定) 684 | - multiple_retrieval_config:(必須) 685 | - reranking_enable: true/false(必須) 686 | - reranking_mode: weighted_score(必須) 687 | - top_k: 取得件数(必須) 688 | - weights:(必須) 689 | - vector_setting:(必須) 690 | - embedding_model_name: モデル名(必須) 691 | - embedding_provider_name: プロバイダー名(須) 692 | - vector_weight: ベクトル重み(必須) 693 | - keyword_setting:(必須) 694 | - keyword_weight: キーワード重み(必須) 695 | - query_variable_selector:(必須) 696 | - [入力ノードID] 697 | - [変数名] 698 | 699 | 特記事項: 700 | 検索設定: 701 | - embedding_model_name: 702 | - text-embedding-3-large: 高精度モデル 703 | - text-embedding-ada-002: 標準モデル 704 | 705 | 重み付け: 706 | - vector_weight: 0.0-1.0 707 | - 1.0: ベクトル検索のみ 708 | - 0.0: キーワード検索のみ 709 | - keyword_weight: 0.0-1.0 710 | - 高値: キーワードマッチを重視 711 | - 低値: セマンティック検索を重視 712 | 713 | 検索結果: 714 | - top_k: 取得する結果数 715 | - 推奨値: 3-5 716 | - 最大値: 10 717 | - reranking: 検索結果の再ランキング 718 | - weighted_score: スコアによる重み付け 719 | - 精度と応答時間のバランスを調整可能 720 | 721 | 8. コードノード 722 | ユースケース: 723 | - カスタムロジックの実装 724 | - データの加工・変換 725 | - 外部システムとの連携 726 | - 条件分岐の制御 727 | 728 | 構造: 729 | - id: ユニークなID(必須) 730 | - type: code(固定) 731 | - data:(必須) 732 | - code_language: python3(固定) 733 | - code: Pythonコード(必須、ダブルクォートで括る) 734 | - title: ノードのタイトル(必須) 735 | - outputs:(必須) 736 | - [変数名]: 737 | - type: 変数の型(必須) 738 | - children: null(固定) 739 | - variables:(必須) 740 | - value_selector:(必須) 741 | - [入力ノードID] 742 | - [変数名] 743 | - variable: 関数の引数名(必須) 744 | 745 | 特記事項: 746 | - boolean型は利用できません。number型で0/1で代用してください。 747 | 使用可能なライブラリ: 748 | - 基本ライブラリ: 749 | - datetime: 日時処理 750 | - math: 数学関数 751 | - random: 乱数生成 752 | - re: 正規表現 753 | - string: 文字列操作 754 | - システム関連: 755 | - sys: システム操作 756 | - os: OS操作 757 | - time: 時間処理 758 | - traceback: エラー追跡 759 | - uuid: 一意識別子生成 760 | - データ処理: 761 | - json: JSON処理 762 | - base64: エンコード/デコード 763 | - collections: コレクション型 764 | - itertools: イテレータ操作 765 | - 暗号化/ハッシュ: 766 | - hashlib: ハッシュ関数 767 | - hmac: メッセージ認証 768 | - binascii: バイナリ/ASCII変換 769 | - 関数操作: 770 | - functools: 関数ツール 771 | - operator: 演算子インターフェース 772 | 773 | 出力変数の型: 774 | - 基本型: 775 | - string: 文字列型 776 | - number: 数値型 777 | - 特殊型: 778 | - secret: 機密情報型 779 | - object: オブジェクト型 780 | - file: ファイル型 781 | - 配列型: 782 | - array: 基本配列型 783 | - array[string]: 文字列配列 784 | - array[number]: 数値配列 785 | - array[object]: オブジェクト配列 786 | - array[file]: ファイル配列 787 | - その他: 788 | - any: 任意の型 789 | 790 | コード実装規則: 791 | - main関数として実装(必須) 792 | - 型アノテーション付与(必須) 793 | - 戻り値は辞書形式(必須) 794 | - ダブルクォートでコード全体を括る 795 | - 内部のダブルクォートはエスケープ 796 | - 改行は\nで表現 797 | 実装例: 798 | ```python 799 | def main(arg1: str) -> dict: 800 | return { 801 | "result": arg1[7:-3], 802 | } 803 | ``` 804 | 805 | 9. IF/ELSEノード 806 | ユースケース: 807 | - 条件に基づくフロー制御 808 | - 複数パスへの分岐処理 809 | - データ値による処理の振り分け 810 | - 条件付きロジックの実装 811 | 812 | 構造: 813 | - id: ユニークなID(必須) 814 | - type: if-else(固定) 815 | - data:(必須) 816 | - title: ノードのタイトル(必須) 817 | - cases:(必須) 818 | - case_id: 条件ID(必須) 819 | - logical_operator: and/or(必須) 820 | - conditions:(必須) 821 | - id: 条件のID(必須) 822 | - varType: 変数の型(必須) 823 | - variable_selector:(必須) 824 | - [入力ノードID] 825 | - [変数名] 826 | - comparison_operator: 比較演算子(必須) 827 | - value: 比較値(必須) 828 | - numberVarType: 数値比較タイプ(数値型の場合必須) 829 | - key: サブ変数のキー(オプション) 830 | - sub_variable_condition: サブ変数の条件(オプション) 831 | 832 | 特記事項: 833 | 比較演算子: 834 | - 文字列比較: 835 | - contains: 文字列に指定値が含まれる 836 | - not contains: 文字列に指定値が含まれない 837 | - start with: 指定値で始まる 838 | - end with: 指定値で終わる 839 | - is: 完全一致 840 | - is not: 完全不一致 841 | - 数値比較: 842 | - =: 等しい 843 | - ≠: 等しくない 844 | - >: より大きい 845 | - <: より小さい 846 | - ≥: 以上 847 | - ≤: 以下 848 | - 存在チェック: 849 | - empty: 空である 850 | - not empty: 空でない 851 | - is null: null値である 852 | - is not null: null値でない 853 | - リスト操作: 854 | - in: リスト内に存在する 855 | - not in: リスト内に存在しない 856 | - all of: すべての条件を満たす 857 | - その他: 858 | - exists: 存在する 859 | - not exists: 存在しない 860 | 861 | 変数型: 862 | - number: 数値型 863 | - numberVarType: constant/variable 864 | - string: 文字列型 865 | - boolean: 真偽値型 866 | 867 | エッジ接続: 868 | - sourceHandle: 'true' 869 | - IF条件成立時の接続 870 | - sourceHandle: 'false' 871 | - ELSE条件時の接続 872 | - sourceType: if-else 873 | - targetType: 接続先のノードタイプ 874 | 875 | 10. Variable Aggregatorノード 876 | ユースケース: 877 | - 複数のノードからの出力を集約 878 | - 異なるパスからの結果の統合 879 | - 分岐処理後のデータ統合 880 | - 複数ソースからのデータマージ 881 | 882 | 構造: 883 | - id: ユニークなID(必須) 884 | - type: variable-aggregator(固定) 885 | - data:(必須) 886 | - title: ノードのタイトル(必須) 887 | - output_type: 出力変数の型(必須) 888 | - string: 文字列型 889 | - number: 数値型 890 | - boolean: 真偽値型 891 | - variables: 集約する変数のリスト(必須) 892 | - [入力ノードID, 変数名]の配列 893 | 894 | 特記事項: 895 | データ集約パターン: 896 | - IF/ELSE分岐後の統合: 897 | - true分岐からの出力 898 | - false分岐からの出力 899 | - 単一の出力ストリームへの統合 900 | 901 | - 並列処理結果の統合: 902 | - 複数LLMノードからの応答 903 | - 複数APIコールの結果 904 | - 異なる処理パスからの出力 905 | 906 | 変数の順序: 907 | - リストの順序が出力順序に影響 908 | - 先に指定した変数が優先 909 | - 後続の変数は条件付きで使用 910 | 911 | 型変換ルール: 912 | - string型への変換: 913 | - number: 文字列表現に変換 914 | - boolean: "true"/"false"に変換 915 | - number型への変換: 916 | - string: 数値表現のみ許可 917 | - boolean: 1/0に変換 918 | - boolean型への変換: 919 | - string: "true"/"false"のみ許可 920 | - number: 0以外はtrue 921 | 922 | 11. Document Extractorノード 923 | ユースケース: 924 | - ドキュメントからのテキスト抽出 925 | - ファイル内容の解析 926 | - テキストデータの前処理 927 | 928 | 構造: 929 | - id: ユニークなID(必須) 930 | - type: document-extractor(固定) 931 | - data: 932 | - title: ノードのタイトル(必須) 933 | - is_array_file: 配列入力かどうか(必須) 934 | - variable_selector: 入力変数の指定(必須) 935 | - [入力ノードID] 936 | - [変数名] 937 | 938 | 12. Template Transformノード 939 | ユースケース: 940 | - テンプレート文字列への変数埋め込み 941 | - 動的なメッセージ生成 942 | - 条件付きテキスト生成 943 | - 配列データの文字列化 944 | 945 | 構造: 946 | - id: ユニークなID(必須) 947 | - type: template-transform(固定) 948 | - data: 949 | title: ノードのタイトル(必須) 950 | template: Jinja2形式のテンプレート(必須) 951 | variables: 入力変数の配列(必須) 952 | - value_selector: 変数の参照元 953 | - [入力ノードID] 954 | - [変数名] 955 | variable: テンプレート内で使用する変数名 956 | 957 | テンプレート構文: 958 | - 変数参照: 959 | - 基本形: {{ 変数名 }} 960 | - フィルター使用: {{ 変数名|upper }} 961 | - 条件分岐: 962 | ``` 963 | {% if 条件 %} 964 | 条件成立時の文字列 965 | {% else %} 966 | 条件不成立時の文字列 967 | {% endif %} 968 | ``` 969 | - ループ処理: 970 | ``` 971 | {% for item in items %} 972 | {{ item }} 973 | {% endfor %} 974 | ``` 975 | 976 | 入力変数の型: 977 | - string: 文字列 978 | - number: 数値 979 | - object: オブジェクト 980 | - array: 配列 981 | - arrayNumber: 数値配列 982 | - arrayString: 文字列配列 983 | - arrayObject: オブジェクト配列 984 | 985 | 出力: 986 | - output: 生成された文字列(string型固定) 987 | 988 | 13. Answerノード 989 | ユースケース: 990 | - ワークフローの応答出力 991 | - LLM出力の表示 992 | - 変数値の表示 993 | - 中間結果の確認 994 | 995 | 構造: 996 | - id: ユニークなID(必須) 997 | - type: answer(固定) 998 | - data: 999 | title: ノードのタイトル(必須) 1000 | answer: 応答テキスト(必須) 1001 | - 固定テキスト 1002 | - 変数参照: {{#ノードID.変数名#}} 1003 | variables: [] # オプション 1004 | 1005 | 特記事項: 1006 | - 変数参照: 1007 | - 形式: {{#ノードID.変数名#}} 1008 | - 複数の変数を組み合わせ可能 1009 | - システム変数も参照可能 1010 | 1011 | - 使用可能な変数型: 1012 | - string: 文字列 1013 | - number: 数値 1014 | - object: オブジェクト 1015 | - array: 配列 1016 | - arrayString: 文字列配列 1017 | - arrayNumber: 数値配列 1018 | ※ arrayObjectは非対応 1019 | 1020 | - 接続: 1021 | - 前段: 全てのノードタイプから接続可能 1022 | - 後段: 全てのノードタイプに接続可能 1023 | - チャットモードでの特別な動作あり 1024 | 1025 | 16. パラメータ抽出ノード 1026 | ユースケース: 1027 | - テキストからの構造化データ抽出 1028 | - ユーザー入力の解析 1029 | - 情報の分類と整理 1030 | - 条件分岐のための入力解析 1031 | 1032 | 構造: 1033 | - id: ユニークなID(必須) 1034 | - type: parameter-extractor(固定) 1035 | - data: 1036 | - title: ノードのタイトル(必須) 1037 | - query: 入力変数の指定(必須) 1038 | - model: モデル設定(必須) 1039 | - reasoning_mode: 推論モード(必須) 1040 | - parameters: パラメータ定義(必須) 1041 | - instruction: プロンプト(必須) 1042 | - memory: メモリ設定(オプション) 1043 | - vision: 画像処理設定(オプション) 1044 | 1045 | パラメータ型: 1046 | - string: 文字列型 1047 | - number: 数値型 1048 | - bool: 真偽値型 1049 | - select: 選択型(options必須) 1050 | - array[string]: 文字列配列型 1051 | - array[number]: 数値配列型 1052 | - array[object]: オブジェクト配列型 1053 | 1054 | 推論モード: 1055 | - prompt: 1056 | - プロンプトベースの抽出 1057 | - 柔軟な抽出ルール定義可能 1058 | - function_call: 1059 | - 関数呼び出しベース 1060 | - より構造化された抽出 1061 | 1062 | 出力変数: 1063 | - [パラメータ名]: 各パラメータの抽出結果 1064 | - __is_success: 抽出成功フラグ(0/1) 1065 | - __reason: エラー理由(エラー時) 1066 | 1067 | 特記事項: 1068 | - パラメータ名は一意である必要がある 1069 | - 必須パラメータは抽出必須 1070 | - プロンプトは抽出ルールを明確に記述 1071 | - 画像処理は対応モデルのみ使用可能 1072 | 1073 | 17. YouTubeトランスクリプトノード 1074 | ユースケース: 1075 | - YouTubeビデオの字幕取得 1076 | - 音声コンテンツのテキスト化 1077 | - 多言語コンテンツの翻訳支援 1078 | - 動画内容の分析・要約 1079 | 1080 | 構造: 1081 | - id: ユニークなID(必須) 1082 | - data: 1083 | type: tool(固定) 1084 | title: Free YouTube Transcript API 1085 | provider_name: transcript(固定) 1086 | provider_id: transcript(固定) 1087 | provider_type: builtin(固定) 1088 | tool_label: Free YouTube Transcript API 1089 | tool_name: free_youtube_transcript(固定) 1090 | tool_configurations: 1091 | cookies: null 1092 | format: text(固定) 1093 | language: ja # 言語コード 1094 | preserve_formatting: 0 # フォーマット保持 1095 | proxy: null 1096 | tool_parameters: 1097 | video_id: 1098 | type: mixed(固定) 1099 | value: YouTubeビデオID or 変数参照 1100 | outputs: 1101 | text: # 字幕テキストの出力変数 1102 | type: string 1103 | 1104 | 特記事項: 1105 | - video_idは以下の形式で指定可能: 1106 | - 直接指定: 'XLzul_7GPs4' 1107 | - 変数参照: '{{#[入力ノードID].[変数名]#}}' 1108 | - language設定: 1109 | - ja: 日本語 1110 | - en: 英語 1111 | - preserve_formatting: 1112 | - 0: フォーマット除去(推奨) 1113 | - 1: 原文フォーマット保持 1114 | - 出力変数: 1115 | - text: 取得した字幕テキスト(string型) 1116 | 1117 | 18. JinaReaderノード 1118 | ユースケース: 1119 | - ウェブページのテキスト抽出 1120 | - コンテンツスクレイピング 1121 | - ウェブ記事の要約 1122 | - 画像・リンクの収集 1123 | 1124 | 構造: 1125 | - id: ユニークなID(必須) 1126 | - type: tool(固定) 1127 | - data: 1128 | title: ノードのタイトル(必須) 1129 | provider_name: jina(固定) 1130 | provider_id: jina(固定) 1131 | provider_type: builtin(固定) 1132 | tool_label: JinaReader(固定) 1133 | tool_name: jina_reader(固定) 1134 | tool_configurations: 1135 | gather_all_images_at_the_end: 0/1 # 画像収集 1136 | gather_all_links_at_the_end: 0/1 # リンク収集 1137 | image_caption: 0/1 # 画像キャプション 1138 | no_cache: 0/1 # キャッシュ設定 1139 | proxy_server: プロキシURL # プロキシ設定 1140 | summary: 0/1 # 要約機能 1141 | target_selector: CSSセレクター # 特定要素の抽出 1142 | wait_for_selector: CSSセレクター # 待機要素 1143 | tool_parameters: 1144 | url: 1145 | type: mixed(固定) 1146 | value: URL文字列または変数参照 1147 | outputs: 1148 | text: 1149 | type: string 1150 | 1151 | 特記事項: 1152 | - URL入力: 1153 | - 直接指定: 'https://example.com' 1154 | - 変数参照: '{{#[入力ノードID].[変数名]#}}' 1155 | 1156 | - 設定オプション: 1157 | - gather_all_images_at_the_end: 画像の一括収集 1158 | - gather_all_links_at_the_end: リンクの一括収集 1159 | - image_caption: 画像キャプションの取得 1160 | - summary: コンテンツの自動要約 1161 | - target_selector: 特定のDOM要素の抽出 1162 | 1163 | - プロキシ設定: 1164 | - アクセス制限のあるサイトへの対応 1165 | - 地域制限の回避 1166 | - 負荷分散 1167 | 1168 | - キャッシュ制御: 1169 | - no_cache: 1でキャッシュ無効化 1170 | - 常に最新コンテンツを取得 1171 | 1172 | 19. TavilySearchノード 1173 | ユースケース: 1174 | - ウェブ検索の実行 1175 | - 情報収集 1176 | - コンテンツ調査 1177 | - ドメイン指定検索 1178 | 1179 | 構造: 1180 | - id: ユニークなID(必須) 1181 | - type: tool(固定) 1182 | - data: 1183 | title: ノードのタイトル(必須) 1184 | provider_name: tavily(固定) 1185 | provider_id: tavily(固定) 1186 | provider_type: builtin(固定) 1187 | tool_label: TavilySearch(固定) 1188 | tool_name: tavily_search(固定) 1189 | tool_configurations: 1190 | exclude_domains: 除外ドメインリスト # オプション 1191 | include_domains: 含めるドメインリスト # オプション 1192 | include_answer: true/false # 回答含める 1193 | include_images: true/false # 画像含める 1194 | include_raw_content: true/false # 生コンテンツ 1195 | max_results: 検索結果数(1-10) # 必須 1196 | search_depth: basic/advanced # 検索深度 1197 | tool_parameters: 1198 | query: 1199 | type: mixed(固定) 1200 | value: 検索クエリまたは変数参照 1201 | 1202 | 特記事項: 1203 | - 検索クエリ: 1204 | - 直接指定: '検索したいキーワード' 1205 | - 変数参照: '{{#[入力ノードID].[変数名]#}}' 1206 | 1207 | - 検索深度: 1208 | - basic: 基本的な検索(高速) 1209 | - advanced: 詳細な検索(より多くの結果) 1210 | 1211 | - ドメイン制御: 1212 | - exclude_domains: 検索から除外するドメイン 1213 | - include_domains: 検索対象とするドメイン 1214 | 1215 | - 結果制御: 1216 | - max_results: 取得する検索結果の数 1217 | - include_answer: 関連する回答の取得 1218 | - include_images: 関連画像の取得 1219 | - include_raw_content: 未加工コンテンツ 1220 | - 次のノードへの接続: 1221 | - 検索結果からURLを取得するには、パラメータ抽出ノードを使用 1222 | 1223 | output_format: | 1224 | 生成されるYAMLファイルは以下の形式に従ってください: 1225 | ```yaml 1226 | app: 1227 | mode: workflow 1228 | name: [ワークフロー名] 1229 | version: 0.1.3 1230 | 1231 | workflow: 1232 | graph: 1233 | edges: 1234 | # IF/ELSE分岐のエッジ例 1235 | - source: [IF/ELSEノードID] 1236 | target: [ターゲットノードID] 1237 | data: 1238 | sourceType: if-else 1239 | targetType: [ターゲットノードタイプ] 1240 | sourceHandle: 'true' # IF条件成立時 1241 | - source: [IF/ELSEノードID] 1242 | target: [別のターゲットノードID] 1243 | data: 1244 | sourceType: if-else 1245 | targetType: [ターゲットノードタイプ] 1246 | sourceHandle: 'false' # ELSE条件時 1247 | 1248 | nodes: 1249 | - id: [開始ノードID] 1250 | data: 1251 | type: start 1252 | title: 開始 1253 | variables: 1254 | # ファイル入力の例 1255 | - type: file 1256 | variable: input_document 1257 | label: ドキュメント 1258 | required: true 1259 | max_length: 48 1260 | allowed_file_types: 1261 | - document 1262 | allowed_file_upload_methods: 1263 | - local_file 1264 | - remote_url 1265 | 1266 | # その他の入力タイプ 1267 | - type: text-input 1268 | variable: [変数名] 1269 | type: string/number 1270 | label: [入力フィールドのラベル] 1271 | required: true 1272 | max_length: [最大文字数] 1273 | 1274 | - id: [LLMノードID] 1275 | data: 1276 | type: llm 1277 | title: LLM 1278 | model: 1279 | provider: openai 1280 | name: gpt-4o 1281 | mode: chat 1282 | completion_params: 1283 | temperature: 0.7 1284 | prompt_template: 1285 | - id: [プロンプトID] 1286 | role: system 1287 | text: '[プロンプトテキスト]' 1288 | context: 1289 | enabled: true 1290 | variable_selector: 1291 | - [開始ノードID] 1292 | - [変数名] 1293 | vision: 1294 | enabled: false 1295 | - id: [終了ノードID] 1296 | data: 1297 | type: end 1298 | title: 終了 1299 | outputs: 1300 | - value_selector: 1301 | - [開始ノードID] 1302 | - [変数名] 1303 | variable: inputData 1304 | - value_selector: 1305 | - [LLMノードID] 1306 | - text 1307 | variable: generatedText 1308 | 1309 | - id: [HTTPリクエストノードID] 1310 | data: 1311 | type: http-request 1312 | authorization: 1313 | config: null 1314 | type: no-auth # または必要な認証タイプ 1315 | body: 1316 | type: json 1317 | data: 1318 | - id: [キーバリューID] 1319 | key: '' 1320 | type: text 1321 | value: | 1322 | { 1323 | "key1": "{{#[開始ノードID].[変数名]#}}", 1324 | "key2": "値2" 1325 | } 1326 | headers: Content-Type:application/json 1327 | method: post 1328 | url: [APIエンドポイントURL] 1329 | timeout: 1330 | max_connect_timeout: 0 1331 | max_read_timeout: 0 1332 | max_write_timeout: 0 1333 | title: HTTPリクエスト 1334 | variables: [] 1335 | 1336 | - id: [JSONパースノードID] 1337 | data: 1338 | type: tool 1339 | desc: '' 1340 | provider_id: json_process 1341 | provider_name: json_process 1342 | provider_type: builtin 1343 | selected: false 1344 | title: JSON Parse 1345 | tool_configurations: 1346 | ensure_ascii: 1 1347 | tool_label: JSON Parse 1348 | tool_name: parse 1349 | tool_parameters: 1350 | content: 1351 | type: mixed 1352 | value: '{{#[入力ノードID].[変数名]#}}' 1353 | json_filter: 1354 | type: mixed 1355 | value: [抽出したいJSONキー] 1356 | 1357 | - id: [質問分類器ノードID] 1358 | data: 1359 | type: question-classifier 1360 | title: 質問分類器 1361 | model: 1362 | provider: openai 1363 | name: gpt-4o 1364 | mode: chat 1365 | completion_params: 1366 | temperature: 0.7 1367 | query_variable_selector: 1368 | - [入力ノードID] 1369 | - [変数名] 1370 | classes: 1371 | - id: '1' 1372 | name: [分類名1] 1373 | - id: '2' 1374 | name: [分類名2] 1375 | 1376 | - id: [知識取得ノードID] 1377 | data: 1378 | type: knowledge-retrieval 1379 | title: 知識取得 1380 | dataset_ids: 1381 | - [データセットID] 1382 | retrieval_mode: multiple 1383 | multiple_retrieval_config: 1384 | reranking_enable: true 1385 | reranking_mode: weighted_score 1386 | top_k: 4 1387 | weights: 1388 | vector_setting: 1389 | embedding_model_name: text-embedding-3-large 1390 | embedding_provider_name: openai 1391 | vector_weight: 1 1392 | keyword_setting: 1393 | keyword_weight: 0 1394 | query_variable_selector: 1395 | - [入力ノードID] 1396 | - [変数名] 1397 | 1398 | - id: [コードノードID] 1399 | data: 1400 | type: code 1401 | code_language: python3 1402 | code: # Pythonプログラムの文字列 1403 | outputs: # 出力変数の定義(必須) 1404 | task_url: # 変数名 1405 | children: null 1406 | type: string # 上記で定義された型のいずれかを指定 1407 | variables: # 入力変数の定義(必須) 1408 | - value_selector: # 他のノードからの入力 1409 | - [入力ノードID] 1410 | - [変数名] 1411 | variable: arg1 # 関数の引数名 1412 | 1413 | - id: [IF/ELSEノードID] 1414 | data: 1415 | type: if-else 1416 | title: 条件分岐 1417 | cases: 1418 | - case_id: 'true' 1419 | logical_operator: and 1420 | conditions: 1421 | - id: [条件ID] 1422 | varType: [number/string/boolean] 1423 | variable_selector: 1424 | - [入力ノードID] 1425 | - [変数名] 1426 | comparison_operator: [比較演算子] 1427 | value: [比較値] 1428 | numberVarType: [constant/variable] # 数値型の場合 1429 | - id: [条件ID2] 1430 | varType: [変数型] 1431 | key: [サブ変数キー] # オプション 1432 | comparison_operator: [比較演算子] 1433 | value: [比較値] 1434 | sub_variable_condition: # オプション 1435 | case_id: [サブ条件ID] 1436 | logical_operator: and 1437 | conditions: 1438 | - id: [サブ条件ID] 1439 | varType: [変数型] 1440 | comparison_operator: [比較演算子] 1441 | value: [比較値] 1442 | 1443 | - id: [Variable Aggregatorノード] 1444 | data: 1445 | type: variable-aggregator 1446 | title: 変数集約器 1447 | output_type: string # または number/boolean 1448 | variables: 1449 | - - [入力ノードID1] 1450 | - [変数名1] 1451 | - - [入力ノードID2] 1452 | - [変数名2] 1453 | 1454 | - id: [Document ExtractorノードID] 1455 | data: 1456 | type: document-extractor 1457 | title: テキスト抽出ツール 1458 | is_array_file: false 1459 | variable_selector: 1460 | - [入力ノードID] 1461 | - [変数名] 1462 | - id: [テンプレートノードID] 1463 | data: 1464 | type: template-transform 1465 | title: テンプレート変換 1466 | template: | 1467 | こんにちは、{{ user_name }}さん! 1468 | あなたの得点は{{ score }}点です。 1469 | {% if score >= 80 %} 1470 | 合格です!おめでとうございます。 1471 | {% else %} 1472 | 残念ながら不合格です。 1473 | {% endif %} 1474 | variables: 1475 | - value_selector: 1476 | - [入力ノードID] 1477 | - user_name 1478 | variable: user_name 1479 | - value_selector: 1480 | - [入力ノードID] 1481 | - score 1482 | variable: score 1483 | - id: [応答ノードID] 1484 | data: 1485 | type: answer 1486 | title: 応答出力 1487 | answer: | 1488 | {{#[LLMノードID].text#}} 1489 | variables: [] 1490 | - id: [パラメータ抽出ノードID] 1491 | data: 1492 | type: parameter-extractor 1493 | title: パラメータ抽出 1494 | query: 1495 | - [入力ノードID] 1496 | - [変数名] 1497 | model: 1498 | provider: [プロバイダー名] 1499 | name: [モデル名] 1500 | mode: chat 1501 | completion_params: 1502 | temperature: 0.7 1503 | reasoning_mode: prompt 1504 | parameters: 1505 | - name: [パラメータ名] 1506 | type: string/number/bool/select/array[string]/array[number]/array[object] 1507 | description: [説明文] 1508 | required: true/false 1509 | options: # select型の場合のみ 1510 | - [オプション1] 1511 | - [オプション2] 1512 | instruction: | 1513 | [プロンプト文字列] 1514 | memory: 1515 | role_prefix: 1516 | user: [ユーザープレフィックス] 1517 | assistant: [アシスタントプレフィックス] 1518 | vision: 1519 | enabled: false 1520 | configs: {} 1521 | - id: [YouTubeトランスクリプトノードID] 1522 | data: 1523 | type: tool 1524 | title: Free YouTube Transcript API 1525 | provider_name: transcript 1526 | provider_id: transcript 1527 | provider_type: builtin 1528 | tool_label: Free YouTube Transcript API 1529 | tool_name: free_youtube_transcript 1530 | tool_configurations: 1531 | cookies: null 1532 | format: text 1533 | language: ja 1534 | preserve_formatting: 0 1535 | proxy: null 1536 | tool_parameters: 1537 | video_id: 1538 | type: mixed 1539 | value: '{{#[入力ノードID].[変数名]#}}' 1540 | outputs: 1541 | text: 1542 | type: string 1543 | - id: [JinaReaderノードID] 1544 | data: 1545 | type: tool 1546 | title: JinaReader 1547 | provider_name: jina 1548 | provider_id: jina 1549 | provider_type: builtin 1550 | tool_label: JinaReader 1551 | tool_name: jina_reader 1552 | tool_configurations: 1553 | gather_all_images_at_the_end: 0 # 画像収集設定 1554 | gather_all_links_at_the_end: 0 # リンク収集設定 1555 | image_caption: 0 # 画像キャプション設定 1556 | no_cache: 0 # キャッシュ無効化 1557 | proxy_server: null # プロキシサーバー設定 1558 | summary: 0 # 要約機能 1559 | target_selector: null # ターゲット要素セレクター 1560 | wait_for_selector: null # 待機要素セレクター 1561 | tool_parameters: 1562 | url: 1563 | type: mixed 1564 | value: '{{#[入力ノードID].[変数名]#}}' # URL入力 1565 | outputs: 1566 | text: 1567 | type: string 1568 | - id: [TavilySearchノードID] 1569 | data: 1570 | type: tool 1571 | title: TavilySearch 1572 | provider_name: tavily 1573 | provider_id: tavily 1574 | provider_type: builtin 1575 | tool_label: TavilySearch 1576 | tool_name: tavily_search 1577 | tool_configurations: 1578 | exclude_domains: null # 除外ドメイン 1579 | include_domains: null # 含めるドメイン 1580 | include_answer: null # 回答を含める 1581 | include_images: null # 画像を含める 1582 | include_raw_content: null # 生コンテンツを含める 1583 | max_results: 3 # 最大結果数 1584 | search_depth: basic # 検索深度 1585 | tool_parameters: 1586 | query: 1587 | type: mixed 1588 | value: '{{#[入力ノードID].[変数名]#}}' 1589 | outputs: 1590 | text: 1591 | type: string 1592 | ``` --------------------------------------------------------------------------------