背景
之前由于想学习AI Agent相关的知识,安装了LangFlow。自己尝试运行了一下LangFlow设定好的工作流。今天试着自己搭建了一个简单的工作流。不涉及调用AI模型。就是一个简单的复读机功能,用户输入啥,工作流就返回啥。虽说简单,但也能帮助理解LangFlow工作流的搭建。过程中也遇到了一些问题,在此记录一下。
我用两种方式实现了复读机工作流的搭建。
-
使用LangFlow自带的组件
-
自定义组件
工作流搭建
实现思路
首先,要搭建一个复读机功能的工作流,只需要实现将输入原原本本地输出就行了。
结合LangFlow的组件,我们可以使用Chat Input 组件读取输入,然后使用Chat Output组件将输入的内容直接输出。
按照上面的思路,搭建出来的工作流看起来应该像下面这样

思路验证
按照上面的工作流运行,我没有得到自己期望的结果。运行之后,我在对话界面输入内容,没有任何反馈。

为什么会出现上面这样的问题呢?Chat Input 组件输入内容,Chat Output组件输出内容。应该没错呀。
问题分析
通过查询相关资料,发现Chat Output 组件不能直接接收Chat Input组件的输出。通过LangFlow的界面,可以分别看到这两个组件的输出类型和能够接收的输入类型。查看方法如下

Chat Input组件的输出类型如下
python
outputs = [
Output(display_name="Message", name="message", method="message_response"),
]
async def message_response(self) -> Message:
background_color = self.background_color
text_color = self.text_color
icon = self.chat_icon
message = await Message.create(
text=self.input_value,
sender=self.sender,
sender_name=self.sender_name,
session_id=self.session_id,
files=self.files,
properties={
"background_color": background_color,
"text_color": text_color,
"icon": icon,
},
)
if self.session_id and isinstance(message, Message) and self.should_store_message:
stored_message = await self.send_message(
message,
)
self.message.value = stored_message
message = stored_message
self.status = message
return message
Chat Output组件的输入类型如下
python
inputs = [
HandleInput(
name="input_value",
display_name="Text",
info="Message to be passed as output.",
input_types=["Data", "DataFrame", "Message"],
required=True,
),
BoolInput(
name="should_store_message",
display_name="Store Messages",
info="Store the message in the history.",
value=True,
advanced=True,
),
DropdownInput(
name="sender",
display_name="Sender Type",
options=[MESSAGE_SENDER_AI, MESSAGE_SENDER_USER],
value=MESSAGE_SENDER_AI,
advanced=True,
info="Type of sender.",
),
MessageTextInput(
name="sender_name",
display_name="Sender Name",
info="Name of the sender.",
value=MESSAGE_SENDER_NAME_AI,
advanced=True,
),
MessageTextInput(
name="session_id",
display_name="Session ID",
info="The session ID of the chat. If empty, the current session ID parameter will be used.",
advanced=True,
),
MessageTextInput(
name="data_template",
display_name="Data Template",
value="{text}",
advanced=True,
info="Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.",
),
MessageTextInput(
name="background_color",
display_name="Background Color",
info="The background color of the icon.",
advanced=True,
),
MessageTextInput(
name="chat_icon",
display_name="Icon",
info="The icon of the message.",
advanced=True,
),
MessageTextInput(
name="text_color",
display_name="Text Color",
info="The text color of the name",
advanced=True,
),
BoolInput(
name="clean_data",
display_name="Basic Clean Data",
value=True,
info="Whether to clean the data",
advanced=True,
),
]
通过对比可以发现,Chat Input 组件最终输出的是Message 类型,而Chat Output组件不能接收这个类型。
要解决这个问题,需要在Chat Input 组件和Chat Output 组件之间再新增一个数据转换组件,这个组件接收Message 类型,将接收的数据转换为Data 类型输出,作为Chat Output类型的输入。
有了解决方案,下面便开始搭建工作流。
实现方案
在具体实现的过程中,发现有两种方法都可以达到目的,一是我发现LangFlow有一个自带的Beta版的消息转换组件Message to Data,使用这个组件可以实现数据类型转换。二是可以自定义一个组件,实现数据类型的转换。
下面介绍分别用两种方法实现复读机的工作流。
LangFlow自带组件转换
这种方法很简单,只需要将Message to Data组件添加到工作流即可。该组件在LangFlow组件面板的Processing类下。如下图所示:

添加该组件之后的完整工作流如下:

向上面这样配置好工作流之后,就可以了。运行效果如下:

自定义组件转换
自定义组件进行数据的转换,操作步骤如下:
- 在工作面板左下角,有一个New Custom Component 菜单,点击该菜单,会在工作流设计面板中创建一个名为Custom Component的组件。

- 点击该组件左上角的Code,进入代码编写的界面。


- 在代码编辑界面编写类型转换的处理逻辑,编写好之后保存即可。完整的代码如下:
python
from loguru import logger
from langflow.custom import Component
from langflow.io import MessageTextInput, Output
from langflow.schema import Data
from langflow.schema.message import Message
class MessageToChatMessage(Component):
display_name = "复读机"
description = "将ChatInput组件的消息转换为Data对象"
icon = "message-square-share"
name = "MessageToChatMessage"
inputs = [
MessageInput(
name="input_value",
display_name="Input Value",
info="This is a custom component Input",
),
]
outputs = [
Output(display_name="Output", name="output", method="build_output"),
]
def build_output(self) -> Data:
if isinstance(self.input_value,Message):
# 将输入转换为Data
return Data (data=self.input_value.data)
msg = "Error converting Message to Data: Input must be a Message object"
logger.opt(exception=True).debug(msg)
self.status = msg
return Data(data={"error": msg})
配置完成后的工作流如下:

PS:组件的现实标题可以自己配置。
运行效果如下图所示:

至此,便实现了一个简单的复读机工作流。