# 工作流节点

# 开始

"开始" 节点是每个工作流应用(Chatflow / Workflow)必备的预设节点,为后续工作流节点以及应用的正常流转提供必要的初始信息,例如应用使用者所输入的内容、以及上传的文件等。

# 配置节点

在开始节点的设置页,你可以看到两部分设置,分别是 "输入字段" 和预设的系统变量

# 输入字段

输入字段功能由应用开发者设置,通常用于让应用使用者主动补全更多信息。例如在周报应用中要求使用者按照格式预先提供更多背景信息,如姓名、工作日期区间、工作详情等。这些前置信息将有助于 LLM 生成质量更高的答复。

支持以下六种类型输入变量,所有变量均可设置为必填项:

  • 文本:短文本,由应用使用者自行填写内容,最大长度 256 字符。
  • 段落:长文本,允许应用使用者输入较长字符。
  • 下拉选项:由应用开发者固定选项,应用使用者仅能选择预设选项,无法自行填写内容。
  • 数字:仅允许用户输入数字。
  • 单文件:允许应用使用者单独上传文件,支持文档类型文件、图片、音频、视频和其它文件类型。支持通过本地上传文件或粘贴文件 URL。详细用法请参考文件上传。
  • 文件列表:允许应用使用者批量上传文件,支持文档类型文件、图片、音频、视频和其它文件类型。支持通过本地上传文件或粘贴文件 URL。详细用法请参考文件上传。

配置完成后,用户在使用应用前将按照输入项指引,向 LLM 提供必要信息。更多的信息将有助于 LLM 提升问答效率。

# 系统变量

系统变量指的是在 Chatflow / Workflow 应用内预设的系统级参数,可以被应用内的其它节点全局读取。通常用于进阶开发场景,例如搭建多轮次对话应用、收集应用日志与监控、记录不同应用和用户的使用行为等。

Workflow

Workflow 类型应用提供以下系统变量:

变量名称 数据类型 说明 备注
sys.files [LEGACY] Array[File] 文件参数,存储用户初始使用应用时上传的图片 图片上传功能需在应用编排页右上角的 "功能" 处开启
sys.user_id String 用户 ID,每个用户在使用工作流应用时,系统会自动向用户分配唯一标识符,用以区分不同的对话用户
sys.app_id String 应用 ID,系统会向每个 Workflow 应用分配一个唯一的标识符,用以区分不同的应用,并通过此参数记录当前应用的基本信息 面向具备开发能力的用户,通过此参数区分并定位不同的 Workflow 应用
sys.workflow_id String Workflow ID,用于记录当前 Workflow 应用内所包含的所有节点信息 面向具备开发能力的用户,可以通过此参数追踪并记录 Workflow 内的包含节点信息
sys.workflow_run_id String Workflow 应用运行 ID,用于记录 Workflow 应用中的运行情况 面向具备开发能力的用户,可以通过此参数追踪应用的历次运行情况

Chatflow

Chatflow 类型应用提供以下系统变量:

变量名称 数据类型 说明 备注
sys.query String 用户在对话框中初始输入的内容
sys.files Array[File] 用户在对话框内上传的文件 文件上传功能需在应用编排页右上角的 "功能" 处开启
sys.dialogue_count Number 用户在与 Chatflow 类型应用交互时的对话轮数。每轮对话后自动计数增加 1,可以和 if-else 节点搭配出丰富的分支逻辑。例如到第 X 轮对话时,回顾历史对话并给出分析
sys.conversation_id String 对话框交互会话的唯一标识符,将所有相关的消息分组到同一个对话中,确保 LLM 针对同一个主题和上下文持续对话
sys.user_id String 分配给每个应用用户的唯一标识符,用以区分不同的对话用户
sys.app_id String 应用 ID,系统会向每个 Workflow 应用分配一个唯一的标识符,用以区分不同的应用,并通过此参数记录当前应用的基本信息 面向具备开发能力的用户,通过此参数区分并定位不同的 Workflow 应用
sys.workflow_id String Workflow ID,用于记录当前 Workflow 应用内所包含的所有节点信息 面向具备开发能力的用户,可以通过此参数追踪并记录 Workflow 内的包含节点信息
sys.workflow_run_id String Workflow 应用运行 ID,用于记录 Workflow 应用中的运行情况 面向具备开发能力的用户,可以通过此参数追踪应用的历次运行情况

# LLM

# 定义

调用大语言模型(LLM)的能力,处理用户在 "开始" 节点中输入的信息(自然语言、上传的文件或图片),给出有效的回应信息。


# 应用场景

LLM 节点是 Chatflow/Workflow 的核心节点。该节点能够利用大语言模型的对话/生成/分类/处理等能力,根据给定的提示词处理广泛的任务类型,并能够在工作流的不同环节使用。

  • 意图识别,在客服对话情景中,对用户问题进行意图识别和分类,导向下游不同的流程。
  • 文本生成,在文章生成情景中,作为内容生成的节点,根据主题、关键词生成符合的文本内容。
  • 内容分类,在邮件批处理情景中,对邮件的类型进行自动化分类,如咨询/投诉/垃圾邮件。
  • 文本转换,在文本翻译情景中,将用户提供的文本内容翻译成指定语言。
  • 代码生成,在辅助编程情景中,根据用户的要求生成指定的业务代码,编写测试用例。
  • RAG,在知识库问答情景中,将检索到的相关知识和用户问题重新组织回复问题。
  • 图片理解,使用 vision 能力的多模态模型,能对图像内的信息进行理解和问答。

选择合适的模型,编写提示词,你可以在 Chatflow/Workflow 中构建出强大、可靠的解决方案。


# 配置示例

在应用编辑页中,点击鼠标右键或轻点上一节点末尾的 + 号,添加节点并选择 LLM。

LLM 节点配置-选择模型

配置步骤:

  1. 选择模型,平台提供了全球主流模型的支持,包括 OpenAI 的 GPT 系列、Anthropic 的 Claude 系列、Google 的 Gemini 系列等,选择一个模型取决于其推理能力、成本、响应速度、上下文窗口等因素,你需要根据场景需求和任务类型选择合适的模型。
  2. 配置模型参数,模型参数用于控制模型的生成结果,例如温度、TopP,最大标记、回复格式等。
  3. 填写上下文(可选),上下文可以理解为向 LLM 提供的背景信息,常用于填写知识检索的输出变量。
  4. 编写提示词,LLM 节点提供了一个易用的提示词编排页面,选择聊天模型或补全模型,会显示不同的提示词编排结构。如果选择聊天模型(Chat model),你可以自定义系统提示词(SYSTEM)/用户(USER)/ 助手(ASSISTANT)三部分内容。

如果在编写系统提示词(SYSTEM)时没有好的思路,也可以使用提示生成器功能,借助 AI 能力快速生成适合实际业务场景的提示词。

在提示词编辑器中,你可以通过输入 "/" 呼出 变量插入菜单,将 特殊变量块 或者 上游节点变量 插入到提示词中作为上下文内容。

  1. 高级设置,可以开关记忆功能并设置记忆窗口、开关 Vision 功能或者使用 Jinja-2 模板语言来进行更复杂的提示词等。

# 特殊变量说明

上下文变量

上下文变量是一种特殊变量类型,用于向 LLM 提供背景信息,常用于在知识检索场景下使用。详细说明请参考知识检索节点。

文件变量

部分 LLMs(例如 Claude 4 Sonnet (opens new window))已支持直接处理并分析文件内容,因此系统提示词已允许输入文件变量。为了避免潜在异常,应用开发者在使用该文件变量前需前往 LLM 官网确认 LLM 支持何种文件类型。

模型参数

模型的参数会影响模型的输出效果。不同模型的参数会有所区别。

主要的参数名词解释如下:

  • 温度: 通常是0-1的一个值,控制随机性。温度越接近0,结果越确定和重复,温度越接近1,结果越随机。
  • Top P: 控制结果的多样性。模型根据概率从候选词中选择,确保累积概率不超过预设的阈值P。
  • 存在惩罚: 用于减少重复生成同一实体或信息,通过对已经生成的内容施加惩罚,使模型倾向于生成新的或不同的内容。参数值增加时,对于已经生成过的内容,模型在后续生成中被施加更大的惩罚,生成重复内容的可能性越低。
  • 频率惩罚: 对过于频繁出现的词或短语施加惩罚,通过降低这些词的生成概率。随着参数值的增加,对频繁出现的词或短语施加更大的惩罚。较高的参数值会减少这些词的出现频率,从而增加文本的词汇多样性。

# 高级功能

记忆: 开启记忆后问题分类器的每次输入将包含对话中的聊天历史,以帮助 LLM 理解上文,提高对话交互中的问题理解能力。

记忆窗口: 记忆窗口关闭时,系统会根据模型上下文窗口动态过滤聊天历史的传递数量;打开时用户可以精确控制聊天历史的传递数量(对数)。

对话角色名设置: 由于模型在训练阶段的差异,不同模型对于角色名的指令遵循程度不同,如 Human/Assistant,Human/AI,人类/助手等等。为适配多模型的提示响应效果,系统提供了对话角色名的设置,修改对话角色名将会修改会话历史的角色前缀。

Jinja-2 模板: LLM 的提示词编辑器内支持 Jinja-2 模板语言,允许你借助 Jinja2 这一强大的 Python 模板语言,实现轻量级数据转换和逻辑处理,参考官方文档 (opens new window)

错误重试:针对节点发生的部分异常情况,通常情况下再次重试运行节点即可解决。开启错误重试功能后,节点将在发生错误的时候按照预设策略进行自动重试。你可以调整最大重试次数和每次重试间隔以设置重试策略。

  • 最大重试次数为 10 次
  • 最大重试间隔时间为 5000 ms

异常处理:提供多样化的节点错误处理策略,能够在当前节点发生错误时抛出故障信息而不中断主流程;或通过备用路径继续完成任务。

# 文档提取器

# 定义

LLM 自身无法直接读取或解释文档的内容。因此需要将用户上传的文档,通过文档提取器节点解析并读取文档文件中的信息,转化文本之后再将内容传给 LLM 以实现对于文件内容的处理。

# 应用场景

  • 构建能够与文件进行互动的 LLM 应用,例如 ChatPDF 或 ChatWord;
  • 分析并检查用户上传的文件内容;

# 节点功能

文档提取器节点可以理解为一个信息处理中心,通过识别并读取输入变量中的文件,提取信息后并转化为 string 类型输出变量,供下游节点调用。

文档提取器节点结构分为输入变量、输出变量。

# 输入变量

文档提取器仅接受以下数据结构的变量:

  • File,单独一个文件
  • Array[File],多个文件

文档提取器仅能够提取文档类型文件中的信息,例如 TXT、Markdown、PDF、HTML、DOCX 格式文件的内容,无法处理图片、音频、视频等格式文件。

# 输出变量

输出变量固定命名为 text。输出的变量类型取决于输入变量:

  • 输入变量为 File,输出变量为 string
  • 输入变量为 Array[File],输出变量为 array[string]

# 配置示例

在一个典型的文件交互问答场景中,文档提取器可以作为 LLM 节点的前置步骤,提取应用的文件信息并传递至下游的 LLM 节点,回答用户关于文件的问题。

本章节将通过一个典型的 ChatPDF 示例工作流模板,介绍文档提取器节点的使用方法。

配置流程:

  1. 为应用开启文件上传功能。在"开始"节点中添加单文件变量并命名为 pdf
  2. 添加文档提取节点,并在输入变量内选中 pdf 变量。
  3. 添加 LLM 节点,在系统提示词内选中文档提取器节点的输出变量。LLM 可以通过该输出变量读取文件中的内容。

4. 配置结束节点,在结束节点中选择 LLM 节点的输出变量。

配置完成后,应用将具备文件上传功能,使用者可以上传 PDF 文件并展开对话。

# 变量聚合

# 定义

将多路分支的变量聚合为一个变量,以实现下游节点统一配置。

变量聚合节点是工作流程中的一个关键节点,它负责整合不同分支的输出结果,确保无论哪个分支被执行,其结果都能通过一个统一的变量来引用和访问。这在多分支的情况下非常有用,可将不同分支下相同作用的变量映射为一个输出变量,避免下游节点重复定义。


# 场景

通过变量聚合,可以将诸如问题分类或条件分支等多路输出聚合为单路,供流程下游的节点使用和操作,简化了数据流的管理。

问题分类后的多路聚合

未添加变量聚合,分类1 和 分类 2 分支经不同的知识库检索后需要重复定义下游的 LLM 和直接回复节点。

添加变量聚合,可以将两个知识检索节点的输出聚合为一个变量。

IF/ELSE 条件分支后的多路聚合

# 格式要求

变量聚合器支持聚合多种数据类型,包括字符串(String)、数字(Number)、文件(File)对象(Object)以及数组(Array

变量聚合器只能聚合同一种数据类型的变量。若第一个添加至变量聚合节点内的变量数据格式为 String,后续连线时会自动过滤可添加变量为 String 类型。

聚合分组

开启聚合分组后,变量聚合器可以聚合多组变量,各组内聚合时要求同一种数据类型。

# 变量赋值

# 定义

变量赋值节点用于向可写入变量进行变量赋值,已支持以下可写入变量:

  • 会话变量
  • 循环变量

用法:通过变量赋值节点,你可以将工作流内的变量赋值到会话变量中用于临时存储,并可以在后续对话中持续引用。

会话变量示例


# 使用场景示例

通过变量赋值节点,你可以将会话过程中的上下文、上传至对话框的文件(即将上线)、用户所输入的偏好信息等写入至会话变量,并在后续对话中引用已存储的信息导向不同的处理流程或者进行回复。

场景 1

自动判断提取并存储对话中的信息,在会话内通过会话变量数组记录用户输入的重要信息,并在后续对话中让 LLM 基于会话变量中存储的历史信息进行个性化回复。

示例:开始对话后,LLM 会自动判断用户输入是否包含需要记住的事实、偏好或历史记录。如果有,LLM 会先提取并存储这些信息,然后再用这些信息作为上下文来回答。如果没有新的信息需要保存,LLM 会直接使用自身的相关记忆知识来回答问题。

自动判断提取并存储对话中的信息

配置流程:

  1. 设置会话变量:首先设置一个会话变量数组 memories,类型为 array[object],用于存储用户的事实、偏好和历史记录。
  2. 判断和提取记忆
    • 添加一个条件判断节点,使用 LLM 来判断用户输入是否包含需要记住的新信息。
    • 如果有新信息,走上分支,使用 LLM 节点提取这些信息。
    • 如果没有新信息,走下分支,直接使用现有记忆回答。
  3. 变量赋值/写入
    • 在上分支中,使用变量赋值节点,将提取出的新信息追加(append)到 memories 数组中。
    • 使用转义功能将 LLM 输出的文本字符串转换为适合存储在 array[object] 中的格式。
  4. 变量读取和使用
    • 在后续的 LLM 节点中,将 memories 数组中的内容转换为字符串,并插入到 LLM 的提示词 Prompts 中作为上下文。
    • LLM 使用这些历史信息来生成个性化回复。

图中的 code 节点代码如下:

  1. 将字符串转义为 object
import json

def main(arg1: str) -> object:
    try:
        # Parse the input JSON string
        input_data = json.loads(arg1)
        
        # Extract the memory object
        memory = input_data.get("memory", {})
        
        # Construct the return object
        result = {
            "facts": memory.get("facts", []),
            "preferences": memory.get("preferences", []),
            "memories": memory.get("memories", [])
        }
        
        return {
            "mem": result
        }
    except json.JSONDecodeError:
        return {
            "result": "Error: Invalid JSON string"
        }
    except Exception as e:
        return {
            "result": f"Error: {str(e)}"
        }
  1. 将 object 转义为字符串
import json

def main(arg1: list) -> str:
    try:
        # Assume arg1[0] is the dictionary we need to process
        context = arg1[0] if arg1 else {}
        
        # Construct the memory object
        memory = {"memory": context}
        
        # Convert the object to a JSON string
        json_str = json.dumps(memory, ensure_ascii=False, indent=2)
        
        # Wrap the JSON string in <answer> tags
        result = f"<answer>{json_str}</answer>"
        
        return {
            "result": result
        }
    except Exception as e:
        return {
            "result": f"<answer>Error: {str(e)}</answer>"
        }

场景 2

记录用户的初始偏好信息,在会话内记住用户输入的语言偏好,在后续对话中持续使用该语言类型进行回复。

示例:用户在对话开始前,在 language 输入框内指定了 "中文",该语言将会被写入会话变量,LLM 在后续进行答复时会参考会话变量中的信息,在后续对话中持续使用"中文"进行回复。

记录用户的初始偏好信息

配置流程:

设置会话变量:首先设置一个会话变量 language,在会话流程开始时添加一个条件判断节点,用来判断 language 变量的值是否为空。

变量写入/赋值:首轮对话开始时,若 language 变量值为空,则使用 LLM 节点来提取用户输入的语言,再通过变量赋值节点将该语言类型写入到会话变量 language 中。

变量读取:在后续对话轮次中 language 变量已存储用户语言偏好。在后续对话中,LLM 节点通过引用 language 变量,使用用户的偏好语言类型进行回复。

场景 3

辅助 Checklist 检查,在会话内通过会话变量记录用户的输入项,更新 Checklist 中的内容,并在后续对话中检查遗漏项。

示例:开始对话后,LLM 会要求用户在对话框内输入 Checklist 所涉及的事项,用户一旦提及了 Checklist 中的内容,将会更新并存储至会话变量内。LLM 会在每轮对话后提醒用户继续补充遗漏项。

辅助 Checklist 检查

配置流程:

  • 设置会话变量: 首先设置一个会话变量 ai_checklist,在 LLM 内引用该变量作为上下文进行检查。
  • 变量赋值/写入: 每一轮对话时,在 LLM 节点内检查 ai_checklist 内的值并比对用户输入,若用户提供了新的信息,则更新 Checklist 并将输出内容通过变量赋值节点写入到 ai_checklist 内。
  • 变量读取: 每一轮对话读取 ai_cheklist 内的值并比对用户输入直至所有 checklist 完成。

# 使用变量赋值节点

点击节点右侧 + 号,选择"变量赋值"节点,填写"赋值的变量"和"设置变量"。

变量赋值节点设置

设置变量:

赋值的变量:选择被赋值变量,即指定需要被赋值的目标会话变量。

设置变量:选择需要赋值的变量,即指定需要被转换的源变量。

以上图赋值逻辑为例:将上一个节点的文本输出项 Language Recognition/text 赋值到会话变量 language 内。

# 指定变量的写入模式

目标变量的数据类型将影响变量的写入模式。以下是不同变量间的写入模式:

  1. 目标变量的数据类型为 String
  • 覆盖,将源变量直接覆盖至目标变量
  • 清空,清空所选中变量中的内容
  • 设置,手动指定一个值,无需设置源变量
  1. 目标变量的数据类型为 Number
  • 覆盖,将源变量直接覆盖至目标变量
  • 清空,清空所选中变量中的内容
  • 设置,手动指定一个值,无需设置源变量
  • 数字处理,对目标变量进行加减乘除操作
  1. 目标变量的数据类型为 Object
  • 覆盖,将源变量的内容直接覆盖至目标变量
  • 清空,清空所选中变量中的内容
  • 设置,手动指定一个值,无需设置源变量
  1. 目标变量的数据类型为 Array
  • 覆盖,将源变量的内容直接覆盖至目标变量
  • 清空,清空所选中变量中的内容
  • 追加,在目标的数组变量中添加一个新的元素
  • 扩展,在目标的数组变量中添加新的数组,即一次性添加多个元素
  • 移除,从数组中移除元素,可选择从头部移除(First)或尾部移除(Last),默认为“头部移除”

# 迭代

# 定义

对数组中的元素依次执行相同的操作步骤,直至输出所有结果,可以理解为任务批处理器。迭代节点通常配合数组变量使用。

例如在长文翻译迭代节点内,如果将所有内容输入至 LLM 节点,有可能会达到单次对话限制。上游节点可以先将长文拆分为了多个片段,配合迭代节点对各个片段执行批量翻译,以避免达到 LLM 单次对话的消息限制。


# 功能简介

使用迭代的条件是确保输入值已格式化为列表对象;迭代节点将依次处理迭代开始节点数组变量内的所有元素,每个元素遵循相同的处理步骤,每轮处理被称为一个迭代,最终输出处理结果。

迭代节点的结构通常包含输入变量迭代工作流输出变量三个功能单元。

输入变量: 仅接受 Array 数组变量类型数据。

迭代工作流: 你可以在迭代节点中使用多个工作流节点,编排不同的任务步骤。

输出变量: 仅支持输出数组变量 Array[List]

迭代节点原理图

# 场景

# 示例1:长文章迭代生成器

长故事生成器

  1. 开始节点 内添加输入故事标题、大纲变量,提示用户手动输入初始信息
  2. 使用 LLM 节点 基于用户输入的故事标题和大纲,让 LLM 开始编写内容
  3. 使用 参数提取节点 将 LLM 输出的完整内容转换成数组格式
  4. 通过 迭代节点 包裹的 LLM 节点 循环多次生成各章节内容
  5. 直接回复 节点添加在迭代节点内部,实现在每轮迭代生成之后流式输出

具体配置步骤

  1. 开始节点 配置故事标题(title)和大纲(outline);

开始节点配置

  1. 选择 LLM 节点 基于用户输入的故事标题和大纲,让 LLM 开始编写文本;

模板节点

  1. 选择 参数提取节点,将故事文本转换成为数组(Array)结构。提取参数为 sections ,参数类型为 Array[Object]

参数提取

  1. 将数组格式的故事大纲作为迭代节点的输入,在迭代节点内部使用 LLM 节点 进行处理

配置迭代节点

在 LLM 节点内配置输入变量 GenerateOverallOutline/outputIteration/item

配置 LLM 节点

迭代的内置变量:items[object]index[number]

  • items[object] 代表以每轮迭代的输入条目;
  • index[number] 代表当前迭代的轮次;
  1. 在迭代节点内部配置 直接回复节点 ,可以实现在每轮迭代生成之后流式输出。

配置 Answer 节点

  1. 完整调试和预览

按故事章节多轮迭代生成

# 示例 2:长文章迭代生成器(另一种编排方式)

  • 开始节点 内输入故事标题和大纲
  • 使用 LLM 节点 生成文章小标题,以及小标题对应的内容
  • 使用 代码节点 将完整内容转换成数组格式
  • 通过 迭代节点 包裹的 LLM 节点 循环多次生成各章节内容
  • 使用 模板转换 节点将迭代节点输出的字符串数组转换为字符串
  • 在最后添加 直接回复节点 将转换后的字符串直接输出

# 高级功能

并行模式

迭代节点支持并行模式,开启后将有效提升迭代节点的整体运行效率。

下图是迭代节点开启或关闭并行模式的运行效果对比。

顺序与并行执行原理图

并行模式下的最高并行轮数为 10,这意味着单位时间内最多可以同时运行 10 个任务。如果需要处理超过 10 个任务,前 10 个元素将率先同时运行,前排任务处理完成后将继续处理剩余任务。

开启并行模式后,不再建议在迭代节点内放置直接回答、变量赋值和工具节点。此举可能会造成异常情况。

  • 错误响应方法

迭代节点通常需要处理大量任务,有时会在处理某个元素时发生错误。为了避免某个元素异常而中断所有任务,你可以在错误响应方法中设置异常的应对方法:

  • 错误时终止。如果发现异常输出,终止迭代节点,输出错误信息。
  • 忽略错误并继续。忽略异常信息,继续处理剩余元素。输出的信息中包含正确信息,异常信息为空值。
  • 移除错误输出。忽略异常信息,继续处理剩余元素。输出的信息中仅包含正确信息。

迭代节点的输入变量与输出变量相对应。例如输入变量为 [1,2,3] ,则输出变量同样为 [result-1, result-2, result-3]。

如果选择了忽略错误并继续, 异常情况的输出值为 null 值,例如 [result-1, null, result-3];

如果选择了移除错误输出, 将不会输出异常变量,例如 [result-1, result-3]。

# 循环

# 简介

循环(Loop)节点用于执行依赖前一轮结果的重复任务,直到满足退出条件或达到最大循环次数。

# 循环节点与迭代节点有什么区别?

循环节点和迭代节点在任务处理上的定位不同:

类型 特点 适用场景
循环(Loop) 轮次之间存在依赖关系的优化型任务。即任务的每一轮执行都依赖上一轮的结果。 需要前一轮的计算结果。
迭代(Iteration) 轮次之间无依赖关系的批处理任务。即每一轮任务可以独立运行,无需依赖前一轮。 每轮独立执行。

# 如何配置循环节点?

循环节点包含以下三个关键配置项和一个子节点:

配置项/子节点 作用 示例
循环终止条件(Loop Termination Condition) 设置循环何时停止。 例:当变量 x < 50 时,停止循环。
最大循环次数(Maximum Loop Count) 限制最多执行的轮次,避免无限循环。 例:最多执行 10 轮,不管是否满足退出条件。
循环变量(Loop Variables) 用于在循环的不同轮次间传递数据,并在循环结束后继续供下游节点使用。 例:变量 x < 50 在每轮循环中递增 1,循环体内部可以基于 x < 50 进行计算,循环结束后,x < 50 的最终值可用于后续流程。
退出循环节点(Exit Loop) 当循环体内运行到此节点后,循环终止。 例:最多执行 10 轮,不管是否满足退出条件。

退出循环节点循环终止条件 均可作为循环的终止触发点,满足任意一个条件时,循环都会提前退出。 如果未配置任何退出条件,则循环将持续运行(相当于 while (true)),直到达到 最大循环次数

# 示例一:如何使用循环节点?

需求:生成 1-100 的随机数,直到随机数小于 50 时停止。

实现步骤

  1. 循环 节点中,配置 循环终止条件,为 模板转换 节点输出 done

  2. 使用 代码执行 节点生成 1-100 的随机数。

  3. 使用 条件分支 节点判断随机数是否大于 50

  • 如果大于或等于 50,输出 当前数字 并继续循环,生成新的随机数。

  • 如果小于 50,输出 最终输出数字,并经由 模板转换 节点输出 done,结束循环。

  1. 循环将在随机数小于 50 时自动停止。

Basic loop workflow

Steps

# 代码执行

# 介绍

代码节点支持运行 Python / NodeJS 代码以在工作流程中执行数据转换。它可以简化你的工作流程,适用于Arithmetic、JSON transform、文本处理等情景。

该节点极大地增强了开发人员的灵活性,使他们能够在工作流程中嵌入自定义的 Python 或 Javascript 脚本,并以预设节点无法达到的方式操作变量。通过配置选项,你可以指明所需的输入和输出变量,并撰写相应的执行代码:

# 配置

如果你需要在代码节点中使用其他节点的变量,你需要在输入变量中定义变量名,并引用这些变量。

# 使用场景

使用代码节点,你可以完成以下常见的操作:

# 结构化数据处理

在工作流中,经常要面对非结构化的数据处理,如 JSON 字符串的解析、提取、转换等。最典型的例子就是 HTTP 节点的数据处理,在常见的 API 返回结构中,数据可能会被嵌套在多层 JSON 对象中,而我们需要提取其中的某些字段。代码节点可以帮助你完成这些操作,下面是一个简单的例子,它从 HTTP 节点返回的 JSON 字符串中提取了data.name字段:

def main(http_response: str) -> dict:
    import json
    data = json.loads(http_response)
    return {
        # 注意在输出变量中声明result
        'result': data['data']['name'] 
    }

# 数学计算

当工作流中需要进行一些复杂的数学计算时,也可以使用代码节点。例如,计算一个复杂的数学公式,或者对数据进行一些统计分析。下面是一个简单的例子,它计算了一个数组的平方差:

def main(x: list) -> dict:
    return {
        # 注意在输出变量中声明result
        'result' : sum([(i - sum(x) / len(x)) ** 2 for i in x]) / len(x)
    }

# 拼接数据

有时,也许你需要拼接多个数据源,如多个知识检索、数据搜索、API调用等,代码节点可以帮助你将这些数据源整合在一起。下面是一个简单的例子,它将两个知识库的数据合并在一起:

def main(knowledge1: list, knowledge2: list) -> dict:
    return {
        # 注意在输出变量中声明result
        'result': knowledge1 + knowledge2
    }

# 输出文件(图片、视频、音频)

如何需要在代码中返回图片、视频、音频,请参考下面使用方式:

import base64
def main(abc: str) -> dict:
    #  需要将图片二进制数据编码为base64格式
    image_base64 = base64.b64encode(image_bytes).decode('utf-8')
    return {
        # 如果是单个图片,注意在输出变量类型中声明为file
        'image_1': image_base64
        # 如何是一个图片list,注意在输出变量类型中声明为Array[File]
        'image_list': [image_base64]
    }

⚠️ 注意:输出文件时,必须用base64编码二进制内容,无需添加类型头,变量名必须包含imagevideo或者audio字样,用于表示这是什么类型的文件

# 高级功能

错误重试

针对节点发生的部分异常情况,通常情况下再次重试运行节点即可解决。开启错误重试功能后,节点将在发生错误的时候按照预设策略进行自动重试。你可以调整最大重试次数和每次重试间隔以设置重试策略。

  • 最大重试次数为 10 次
  • 最大重试间隔时间为 5000 ms

异常处理

代码节点处理信息时有可能会遇到代码执行异常的情况。应用开发者可以参考以下步骤配置异常分支,在节点出现异常时启用应对方案,而避免中断整个流程。

  1. 在代码节点启用 “异常处理”
  2. 选择异常处理方案并进行配置

Code Error handling

# 模板转换

# 定义

允许借助 Jinja2 的 Python 模板语言灵活地进行数据转换、文本处理等。

# 什么是 Jinja?

Jinja (opens new window) 是一个快速、表达力强、可扩展的模板引擎。

# 场景

模板节点允许你借助 Jinja2 这一强大的 Python 模板语言,在工作流内实现轻量、灵活的数据转换,适用于文本处理、JSON 转换等情景。例如灵活地格式化并合并来自前面步骤的变量,创建出单一的文本输出。这非常适合于将多个数据源的信息汇总成一个特定格式,满足后续步骤的需求。

示例1: 将多个输入(文章标题、介绍、内容)拼接为完整文本

拼接文本

示例2: 将知识检索节点获取的信息及其相关的元数据,整理成一个结构化的 Markdown 格式

{% for item in chunks %}
### Chunk {{ loop.index }}. 
### Similarity: {{ item.metadata.score | default('N/A') }}

#### {{ item.title }}

##### Content
{{ item.content | replace('\n', '\n\n') }}

---
{% endfor %}

知识检索节点输出转换为 Markdown

你可以参考 Jinja 的官方文档 (opens new window),创建更为复杂的模板来执行各种任务。

示例 3: 支持渲染 HTML 的表单

<form data-format="json"> // Default to text
  <label for="username">Username:</label>
  <input type="text" name="username" />
  <label for="password">Password:</label>
  <input type="password" name="password" />
  <label for="content">Content:</label>
  <textarea name="content"></textarea>
  <label for="date">Date:</label>
  <input type="date" name="date" />
  <label for="time">Time:</label>
  <input type="time" name="time" />
  <label for="datetime">Datetime:</label>
  <input type="datetime" name="datetime" />
  <label for="select">Select:</label>
  <input type="select" name="select" data-options='["hello","world"]'/>
  <input type="checkbox" name="check" data-tip="By checking this means you agreed"/>
  <button data-size="small" data-variant="primary">Login</button>
</form>

# 列表操作

文件列表变量支持同时上传文档文件、图片、音频与视频文件等多种文件。应用使用者在上传文件时,所有文件都存储在同一个 Array[File] 数组类型变量内,不利于后续单独处理文件。 列表操作节点可以在数组变量内提取单独的元素,便于后续节点处理。

Array数据类型意味着该变量的实际值可能为 [1.mp3, 2.png, 3.doc],大语言模型(LLM)仅支持读取图片文件或文本内容等单一值作为输入变量,无法直接读取数组变量,通常需要配合列表操作节点一起使用。

# 节点功能

列表操作节点可以对文件的格式类型、文件名、大小等属性进行过滤与提取,将不同格式的文件传递给对应的处理节点,以实现对不同文件处理流的精确控制。

例如在一个应用中,允许用户同时上传文档文件和图片文件两种不同类型的文件。需要使用列表操作节点进行分拣,将不同的文件类型交由不同流程处理。

分流不同的文件类型

列表操作节点一般用于提取数组变量中的信息,通过设置条件将其转化为能够被下游节点所接受的变量类型。它的结构分为输入变量过滤条件排序(可选)取前 N 项(可选)输出变量

列表操作节点

# 输入变量

列表操作节点仅接受以下数据结构变量:

  • Array[string]
  • Array[number]
  • Array[file]

# 过滤条件

处理输入变量中的数组,添加过滤条件。从数组中分拣所有满足条件的数组变量,可以理解为对变量的属性进行过滤。

举例:文件中可能包含多重维度的属性,例如文件名、文件类型、文件大小等属性。过滤条件允许设置筛选条件,选择并提取数组变量中的特定文件。

支持提取以下变量:

  • type 文件类别,包含图片,文档,音频和视频类型

  • size 文件大小

  • name 文件名

  • url 指的是应用使用者通过 URL 上传的文件,可填写完整 URL 进行筛选

  • extension 文件拓展名

  • mime_type

    MIME 类型 (opens new window)是用来标识文件内容类型的标准化字符串。示例: "text/html" 表示 HTML 文档。

  • transfer_method

    文件上传方式,分为本地上传或通过 URL 上传

# 排序

提供对于输入变量中数组的排序能力,支持根据文件属性进行排序。

  • 升序排列

    默认排序选项,按照从小到大排序。对于字母和文本,按字母表顺序排列(A - Z)

  • 降序排列

    由大到小排序,对于字母和文本,按字母表倒序排列(Z - A)

该选项常用于配合输出变量中的 first_record 及 last_record 使用。

# 取前 N 项

可以在 1-20 中选值,用途是为了选中数组变量的前 n 项。

# 输出变量

满足各项过滤条件的数组元素。过滤条件、排序和限制可以单独开启。如果同时开启,则返回符合所有条件的数组元素。

  • Result,过滤结果,数据类型为数组变量。若数组中仅包含 1 个文件,则输出变量仅包含 1 个数组元素;
  • first_record,筛选完的数组的首元素,即 result[0];
  • last_record,筛选完的数组的尾元素,即 result[array.length-1]。

# 配置案例

在文件交互问答场景中,应用使用者可能会同时上传文档文件或图片文件。LLM 仅支持识别图片文件的能力,不支持读取文档文件。此时需要用到列表操作节点预处理文件变量的数组,将不同的文件类型并发送至对应的处理节点。编排步骤如下:

  1. 开启Features功能,并在文件类型中勾选 "图片" + "文档文件" 类型。
  2. 添加两个列表操作节点,在 "过滤" 条件中分别设置提取图片与文档变量。
  3. 提取文档文件变量,传递至 "文档提取器" 节点;提取图片文件变量,传递至 "LLM" 节点。
  4. 在末尾添加 "直接回复" 节点,填写 LLM 节点的输出变量。

应用使用者同时上传文档文件和图片后,文档文件自动分流至文档提取器节点,图片文件自动分流至 LLM 节点以实现对于混合文件的共同处理。

# HTTP请求

# 快速配置参数

直接点击节点配置页面右上角的 导入cURL,直接导入你的cURL请求即可自动配置完成

小提示

如需访问海外需翻墙的API,可打开代理设置,启动代理即可

# 请求后处理

用途:从请求结果中,提取特定字段值,方便直接返回使用,省去二次解析。要求请求结果为json结构。

用法:
使用JSONPath表达式来指定值,假如HTTP返回值为:

{
    "users": [
        {"name": "Alice", "address": {"city": "Guangzhou"}},
        {"name": "Bob", "address": {"city": "Shanghai"}}
    ],
    "city": "test"
}

如果我们需要提取全部city,可以编写表达式为:

$..city

其实际会返回输出:["Guangzhou", "Shanghai", "test"]
如果我们仅需user下面的city,可以编写如下:

$..address.city

其实际会返回输出:["Guangzhou", "Shanghai"]
更多写法,可以直接搜JSONPath表达式语法,在线测试网页可点击这里:JSON Path在线测试 (opens new window)

需要指定值类型,目前支持(需要更多请找管理员提需):

  • string
  • number
  • object
  • image@base64

多个时可用逗号间隔