Langflow 组件开发指南:深入理解输入输出系统
本文基于 Langflow 1.6.9 源码分析,详细讲解组件开发中的输入输出类型系统,帮助你快速掌握自定义组件开发。
前言
最近在研究 Langflow 这个可视化 AI 工作流平台时,发现官方文档对组件开发的输入输出系统介绍比较零散。作为一个基于图形执行模型的框架,Langflow 的核心就是组件(Component)之间的数据流转。每个组件通过输入(Input)接收数据,处理后再通过输出(Output)传递给下一个组件。
如果你打算开发自己的 Langflow 组件,理解这套输入输出系统是必不可少的一步。下面我把研究源码时整理的内容分享出来。
一、系统架构
1.1 核心文件结构
先看下源码中输入输出相关的文件位置:
src/base/langflow/
├── inputs/
│ ├── inputs.py # 所有输入类型的实现
│ ├── input_mixin.py # Mixin 基础类
│ └── validators.py # 验证器
├── template/field/
│ └── base.py # Input 和 Output 基础类
└── schema/
├── data.py # Data 数据模型
└── message.py # Message 消息模型
1.2 字段类型枚举
Langflow 通过 FieldTypes 枚举定义了所有支持的字段类型:
class FieldTypes(str, Enum):
TEXT = "str" # 文本
INTEGER = "int" # 整数
PASSWORD = "str" # 密码
FLOAT = "float" # 浮点数
BOOLEAN = "bool" # 布尔值
DICT = "dict" # 字典
NESTED_DICT = "NestedDict" # 嵌套字典
SORTABLE_LIST = "sortableList"
CONNECTION = "connect" # 连接
AUTH = "auth"
FILE = "file"
PROMPT = "prompt"
CODE = "code"
TABLE = "table"
LINK = "link"
SLIDER = "slider"
TAB = "tab"
QUERY = "query"
TOOLS = "tools"
MCP = "mcp"
1.3 Mixin 设计模式
Langflow 采用了 Mixin 模式来组合不同功能,这种方式比传统继承更灵活。比如 StrInput 的继承链:
class StrInput(BaseInputMixin, ListableInputMixin,
DatabaseLoadMixin, MetadataTraceMixin, ToolModeMixin):
field_type: SerializableFieldTypes = FieldTypes.TEXT
| Mixin | 功能 |
|---|---|
| BaseInputMixin | 基础输入功能 |
| ListableInputMixin | 支持列表模式 |
| MultilineMixin | 多行文本 |
| RangeMixin | 数字范围控制 |
| DropDownMixin | 下拉选择 |
| FileMixin | 文件上传 |
二、输入类型详解
2.1 基本数据类型
StrInput - 文本输入
最基础的文本输入:
from langflow.io import StrInput
StrInput(
name="text_input",
display_name="文本输入",
value="默认值",
required=True,
info="请输入文本内容"
)
IntInput / FloatInput - 数字输入
from langflow.io import IntInput, FloatInput
# 整数输入,自动转换浮点数为整数
IntInput(
name="count",
display_name="数量",
value=10,
required=True
)
# 浮点数输入
FloatInput(
name="temperature",
display_name="温度",
value=0.7,
info="控制生成随机性,范围 0-1"
)
BoolInput - 布尔输入
支持的字符串转换挺实用的:
from langflow.io import BoolInput
BoolInput(
name="enabled",
display_name="启用",
value=True
)
# 以下字符串都会被转换为 True:
# "True", "true", "1", "yes"
# 同理,"False", "false", "0", "no" → False
2.2 文本相关输入
MessageTextInput - 消息文本
这是最常用的文本输入类型,支持多种数据源:
from langflow.io import MessageTextInput
MessageTextInput(
name="prompt",
display_name="提示词",
value="",
info="输入提示词内容"
)
它会自动处理以下输入类型:
- Message 对象 → 提取 text 属性
- Data 对象 → 提取 text_key 对应的值
- 字符串 → 直接使用
MultilineInput - 多行文本
适合长内容输入:
from langflow.io import MultilineInput
MultilineInput(
name="content",
display_name="内容",
value=""
)
SecretStrInput - 密码输入
用于 API Key 等敏感信息:
from langflow.io import SecretStrInput
SecretStrInput(
name="api_key",
display_name="API Key",
load_from_db=True # 支持从数据库加载
)
2.3 选择类型
DropdownInput - 下拉选择
基础用法:
from langflow.io import DropdownInput
DropdownInput(
name="model",
display_name="模型",
options=["gpt-4", "gpt-3.5-turbo", "claude-3"],
value="gpt-4"
)
高级用法(带刷新和自定义输入):
DropdownInput(
name="model",
display_name="模型",
options=["gpt-4", "gpt-3.5-turbo"],
combobox=True, # 允许自定义输入
real_time_refresh=True, # 实时刷新选项
refresh_button=True
)
MultiselectInput - 多选
from langflow.io import MultiselectInput
MultiselectInput(
name="tags",
display_name="标签",
options=["python", "javascript", "java"],
value=["python"]
)
SortableListInput - 可排序列表
这个类型支持带图标的选项:
from langflow.io import SortableListInput
SortableListInput(
name="operations",
display_name="操作",
options=[
{"name": "Filter", "icon": "filter"},
{"name": "Sort", "icon": "sort"}
],
limit=1,
real_time_refresh=True
)
2.4 数据结构类型
TableInput - 表格数据
这个输入类型很智能,会自动转换多种格式:
from langflow.io import TableInput
TableInput(
name="data",
display_name="数据"
)
支持自动转换:
- 单个字典 → 单行列表
- Data 对象 → 列表
- pandas DataFrame → 字典列表
DictInput / NestedDictInput
from langflow.io import DictInput, NestedDictInput
# 普通字典
DictInput(
name="config",
display_name="配置",
value={"key": "value"}
)
# 嵌套字典
NestedDictInput(
name="nested_config",
display_name="嵌套配置",
value={"level1": {"level2": "value"}}
)
2.5 连接类型
这些类型用于连接其他组件的输出:
from langflow.io import DataInput, DataFrameInput, HandleInput
# Data 对象连接
DataInput(
name="data",
display_name="数据"
)
# DataFrame 连接
DataFrameInput(
name="df",
display_name="DataFrame"
)
# 通用连接
HandleInput(
name="data",
display_name="数据",
input_types=["Data"] # 指定接受的类型
)
2.6 特殊类型
from langflow.io import CodeInput, PromptInput, SliderInput, QueryInput
# 代码输入
CodeInput(name="code", display_name="代码")
# 提示词输入
PromptInput(name="system_prompt", display_name="系统提示词")
# 滑块
SliderInput(name="value", display_name="值", value=50)
# 查询输入
QueryInput(name="search_query", display_name="搜索", separator=",")
2.7 输入类型速查表
| 类名 | 用途 | 列表支持 |
|---|---|---|
| StrInput | 通用文本 | ✓ |
| MessageTextInput | Message 文本 | ✓ |
| MultilineInput | 长文本 | ✓ |
| SecretStrInput | 密码 | ✗ |
| IntInput | 整数 | ✓ |
| FloatInput | 浮点数 | ✓ |
| BoolInput | 布尔值 | ✓ |
| DropdownInput | 下拉选择 | ✗ |
| MultiselectInput | 多选 | ✓ |
| TableInput | 表格数据 | ✓ |
| FileInput | 文件上传 | ✓ |
| DataInput | Data 连接 | ✓ |
| DataFrameInput | DataFrame 连接 | ✓ |
三、输出类型
3.1 Output 基础类
from langflow.io import Output
Output(
name="result",
display_name="结果",
method="process" # 对应组件方法
)
核心属性:
name: 字段名称display_name: 显示名称method: 对应的组件方法名types: 支持的输出类型列表(多类型输出时使用)value: 运行时的输出值
3.2 输出方式
方式一:方法输出
最常用:
class MyComponent(Component):
outputs = [
Output(name="result", display_name="结果", method="process"),
]
def process(self) -> str:
return self.input_value.upper()
方式二:多类型输出
Output(
name="data",
display_name="数据",
method="get_data",
types=["Data", "Message", "str"],
selected="Data"
)
3.3 常见返回类型
from langflow.schema.data import Data
from langflow.schema.message import Message
from langflow.schema.dataframe import DataFrame
import pandas as pd
# 返回字符串
def get_text(self) -> str:
return "Hello"
# 返回 Data
def get_data(self) -> Data:
return Data(data={"key": "value"}, text_key="key")
# 返回 Data 列表
def get_list(self) -> list[Data]:
return [Data(data={"id": i}) for i in range(3)]
# 返回 DataFrame
def get_dataframe(self) -> DataFrame:
df = pd.DataFrame({"col1": [1, 2, 3]})
return DataFrame(df)
# 返回 Message
def get_message(self) -> Message:
return Message(text="Hello", type="text")
四、实战案例
4.1 简单文本处理组件
from langflow.custom.custom_component.component import Component
from langflow.io import MessageTextInput, Output
from langflow.schema.message import Message
class TextProcessorComponent(Component):
display_name = "文本处理器"
description = "将输入的文本转换为大写"
icon = "type"
name = "TextProcessor"
inputs = [
MessageTextInput(
name="text",
display_name="输入文本",
value="",
required=True,
info="输入要处理的文本"
),
]
outputs = [
Output(name="result", display_name="处理结果", method="process"),
]
def process(self) -> Message:
processed_text = self.text.upper()
return Message(text=processed_text)
4.2 JSON 加载组件(实际源码)
这是 Langflow 源码中的实际案例,展示了文件处理和错误修复:
import json
from pathlib import Path
from json_repair import repair_json
from langflow.custom.custom_component.component import Component
from langflow.io import FileInput, MessageTextInput, MultilineInput, Output
from langflow.schema.data import Data
class JSONToDataComponent(Component):
display_name = "Load JSON"
description = "Convert JSON to Data object"
icon = "braces"
name = "JSONtoData"
inputs = [
FileInput(name="json_file", display_name="JSON File", file_types=["json"]),
MessageTextInput(name="json_path", display_name="JSON File Path"),
MultilineInput(name="json_string", display_name="JSON String"),
]
outputs = [
Output(name="data", display_name="Data", method="convert_json_to_data"),
]
def convert_json_to_data(self) -> Data | list[Data]:
# 确保只有一个输入
if sum(bool(field) for field in [self.json_file, self.json_path, self.json_string]) != 1:
raise ValueError("Please provide exactly one input")
# 加载数据
if self.json_file:
json_data = Path(self.resolve_path(self.json_file)).read_text(encoding="utf-8")
elif self.json_path:
json_data = Path(self.json_path).read_text(encoding="utf-8")
else:
json_data = self.json_string
# 解析 JSON(带自动修复)
try:
parsed_data = json.loads(json_data)
except json.JSONDecodeError:
repaired_json_string = repair_json(json_data)
parsed_data = json.loads(repaired_json_string)
# 转换为 Data 对象
if isinstance(parsed_data, list):
return [Data(data=item) for item in parsed_data]
return Data(data=parsed_data)
4.3 动态表单组件
这个案例展示如何根据选择动态显示不同输入:
from langflow.custom.custom_component.component import Component
from langflow.io import (
DataFrameInput, DropdownInput, StrInput, Output
)
from langflow.schema.dataframe import DataFrame
class DynamicComponent(Component):
display_name = "动态表单"
name = "DynamicComponent"
inputs = [
DropdownInput(
name="mode",
display_name="模式",
options=["简单", "高级"]
),
StrInput(
name="simple_param",
display_name="简单参数",
dynamic=True
),
StrInput(
name="advanced_param",
display_name="高级参数",
dynamic=True,
show=False # 初始隐藏
),
]
outputs = [
Output(name="output", display_name="输出", method="process"),
]
def update_build_config(self, build_config, field_value, field_name=None):
"""根据选择动态更新配置"""
if field_name == "mode":
if field_value == "高级":
build_config["simple_param"]["show"] = False
build_config["advanced_param"]["show"] = True
else:
build_config["simple_param"]["show"] = True
build_config["advanced_param"]["show"] = False
return build_config
def process(self) -> str:
if self.mode == "高级":
return f"高级模式: {self.advanced_param}"
return f"简单模式: {self.simple_param}"
五、高级技巧
5.1 列表输入
所有输入类型都支持列表模式:
StrInput(
name="tags",
display_name="标签",
is_list=True,
value=["tag1", "tag2"]
)
5.2 状态管理
使用 self.status 反馈执行状态:
def process(self):
try:
result = self.do_something()
self.status = "处理成功"
return result
except Exception as e:
self.status = f"处理失败: {str(e)}"
raise
5.3 输入验证
自定义验证逻辑:
from pydantic import field_validator
class ValidatedInput(StrInput):
@field_validator("value")
@classmethod
def validate_value(cls, v: Any, info):
if v and len(v) < 3:
raise ValueError("输入至少需要 3 个字符")
return v
5.4 组件继承模板
from langflow.custom.custom_component.component import Component
from langflow.io import Output, MessageTextInput
from langflow.schema.message import Message
class MyComponent(Component):
"""组件开发模板"""
# 组件元数据
display_name = "组件显示名称"
description = "组件功能描述"
icon = "icon-name" # lucide-react 图标名
name = "MyComponent"
# 输入定义
inputs = [
MessageTextInput(
name="input_name",
display_name="输入显示名",
value="默认值",
required=True,
info="帮助提示文本"
),
]
# 输出定义
outputs = [
Output(
name="output_name",
display_name="输出显示名",
method="method_name"
),
]
def method_name(self) -> ReturnType:
"""处理逻辑"""
# 访问输入: self.input_name
# 设置状态: self.status = "状态消息"
return result
六、总结
Langflow 的输入输出系统设计得相当灵活,核心要点:
- Mixin 模式:通过组合不同 Mixin 实现功能复用
- 类型安全:基于 Pydantic 的强类型验证
- 自动转换:输入输出支持多种格式的自动转换
- 动态配置:支持根据用户选择动态显示/隐藏字段
- 状态反馈:通过
self.status提供执行状态反馈
快速参考
| 需求 | 使用类型 |
|---|---|
| 文本输入 | StrInput, MessageTextInput |
| 长文本 | MultilineInput |
| 密码 | SecretStrInput |
| 数字 | IntInput, FloatInput |
| 开关 | BoolInput |
| 选择 | DropdownInput, MultiselectInput |
| 文件 | FileInput |
| 数据连接 | DataInput, DataFrameInput |
| 表格数据 | TableInput |
| 输出 | Output |
开发建议
- 始终提供清晰的
display_name和info - 使用
required标记必填项 - 合理使用
advanced隐藏复杂参数 - 使用
self.status反馈处理状态 - 添加适当的错误处理
- 使用类型提示提高代码可读性
相关资源
- Langflow 官方文档: docs.langflow.org
- Langflow GitHub: github.com/langflow-ai…
- 源码位置:
src/base/langflow/inputs/和src/base/langflow/template/field/