首页
/ Langflow 开发实战指南:从 AGENTS.md 看 Langflow 仓库的构建、架构与组件开发规范

Langflow 开发实战指南:从 AGENTS.md 看 Langflow 仓库的构建、架构与组件开发规范

2026-09-04 21:08:46作者:蔡怀权

Langflow 是一个用于构建和部署 AI Agent 与工作流的可视化开发平台,仓库采用 Python/FastAPI 后端 + React/TypeScript 前端 + 轻量级执行器 CLI(lfx)的 Monorepo 组织方式。本篇基于仓库根目录的 AGENTS.md 逐节展开,并结合当前仓库中的 MakefileMakefile.frontend 与各子包源码,讲清楚如何在本地完成 Langflow 的初始化、热重载开发、代码质量检查、测试与数据库迁移,以及其 Monorepo 包结构、RBAC 授权层与自定义组件的完整开发规范——读完即可在源码级上参与 Langflow 的开发。

一、环境前置要求

AGENTS.md 在 “Prerequisites” 一节中明确了本地开发所需工具链:

工具 版本要求
Python 3.10 – 3.14
uv >= 0.4(Python 包管理器)
Node.js >= 20.19.0(推荐 v22.12 LTS)
npm v10.9+
make 用于构建协调

这些要求在当前仓库中均可得到印证:根 pyproject.toml 声明 requires-python = ">=3.10,<3.15",当前版本为 1.12.0src/frontend/package.jsonengines.node>=20.19.0,React 依赖为 ^19.2.1Makefilecheck_tools 目标会在 make init 前校验 uvnpm 是否已安装,不满足则直接中止。

注意:AGENTS.md 中列出的命令(如 make initmake run_climake unit_testsmake alembic-revision 等)均已在 MakefileMakefile.frontend 中确认存在。其中 make backend 依赖 setup_envinstall_backend,最终通过 uv run uvicorn --factory langflow.main:create_app 启动;make run_cli / make run_clic 则是先构建前端静态产物再执行 uv run langflow run

二、常用命令速查

2.1 开发环境初始化与一键运行

make init              # 安装全部依赖 + pre-commit hooks
make run_cli           # 构建并运行 Langflow(http://localhost:7860)
make run_clic          # 清理前端构建缓存后重新构建并运行(前端出现异常时使用)

对照 Makefile 源码可以看到各目标的实际行为:

  • init:先执行 check_tools 校验工具链,然后 install_backenduv sync --frozen --extra "postgresql")、install_frontend,最后 uvx pre-commit install 安装 git 钩子;
  • run_cli:复用已有前端构建缓存,依次执行 install_frontendinstall_backendbuild_frontend,最后以 --host 0.0.0.0 --port 7860(默认值来自 Makefile 顶部变量 port ?= 7860)启动;
  • run_clic:与 run_cli 的差异在于前置了 clean_frontend_build 目标——它会清空 src/frontend/buildsrc/backend/base/langflow/frontend 两处构建产物,保证前端资源是全新构建的,适合前端资源加载异常时排查问题。

2.2 开发模式(热重载)

make backend           # FastAPI 运行在 7860 端口(终端 1)
make frontend          # Vite 开发服务器运行在 3000 端口(终端 2)

make backend 实际执行的是 uvicorn --factory langflow.main:create_app --reload(当 workers=1 时自动加 --reload),入口为 src/backend/base/langflow/main.py 中的 create_app 工厂函数;make frontend 定义在 Makefile.frontend 中,先 install_frontend 再启动 Vite dev server。

组件开发时建议开启动态加载,以支持修改组件代码后免重启生效:

LFX_DEV=1 make backend                    # 动态加载所有组件模块
LFX_DEV=mistral,openai make backend       # 只动态加载指定模块

LFX_DEV 的解析逻辑位于 lfx 包:src/lfx/src/lfx/interface/components.py 中的解析函数说明,开发模式必须显式通过该环境变量开启,布尔模式(1/true/yes)动态加载全部模块,逗号分隔列表则只加载对应模块。

2.3 代码质量

make format_backend    # 格式化 Python(ruff)—— 务必先于 lint 执行
make format_frontend   # 格式化 TypeScript(biome)
make format            # 前后端一起格式化
make lint              # 后端 lint / 类型检查

Makefileformat_backend 的具体动作是 uv run ruff check . --fix + uv run ruff format .。需要说明的是,当前 Makefile 中的 lint 目标实际输出为 "No type checker configured. See PR #12448 for context.",即本仓库当前阶段不再配置 mypy 类型检查,前端检查则可用 make format_frontend_checknpx @biomejs/biome check)。另外 Makefile 还提供 codespell / fix_codespell 拼写检查目标,可作为提交前的补充检查。

2.4 测试命令

make unit_tests                        # 后端单元测试(pytest 并行)
make unit_tests async=false            # 顺序执行
uv run pytest path/to/test.py          # 单个测试文件
uv run pytest path/to/test.py::test_name   # 单个测试用例

make test_frontend                     # 前端 Jest 单元测试
make tests_frontend                    # 前端 Playwright e2e 测试

make unit_testsMakefile 中默认追加 --instafail -n auto 实现 xdist 并行,并带 --durations-path--splitting-algorithm least_duration 做耗时统计与测试分割;同时默认 -m 'not api_key_required' 跳过需要外部 API Key 的测试。前端两条命令分别对应 Makefile.frontend 中的 test_frontend(Jest)与 tests_frontend(Playwright),配置见 src/frontend/jest.config.jssrc/frontend/playwright.config.ts。此外 Makefile 还有 integration_testsintegration_tests_api_keystemplate_testslfx_tests 等更细粒度的目标,可在需要时选用。

2.5 数据库迁移(Alembic)

make alembic-revision message="Description"  # 创建迁移
make alembic-upgrade                         # 应用迁移
make alembic-downgrade                       # 回滚一个版本

这些目标都会进入 src/backend/base/langflow 目录执行 uv run alembic ...,其中 alembic-revision 使用 --autogenerate -m 自动根据 SQLAlchemy 模型差异生成迁移脚本,迁移版本文件位于 src/backend/base/langflow/alembic/versions/。Makefile 中还提供了 alembic-currentalembic-historyalembic-checkalembic-stamp 等辅助目标,方便排查迁移状态。数据库模型与迁移管理位于服务层 src/backend/base/langflow/services/database/ 下。

三、Monorepo 架构:目录结构与包依赖关系

AGENTS.md 给出的仓库结构如下:

src/
├── backend/
│   ├── base/langflow/     # 核心后端包(langflow-base)
│   │   ├── api/           # FastAPI 路由(v1/、v2/)
│   │   ├── components/    # 内置 Langflow 组件
│   │   ├── services/      # 服务层(auth、database、cache 等)
│   │   ├── graph/         # 流程图执行引擎
│   │   └── custom/        # 自定义组件框架
│   └── tests/             # 后端测试
├── frontend/              # React/TypeScript UI
│   └── src/
│       ├── components/    # UI 组件
│       ├── stores/        # Zustand 状态管理
│       └── icons/         # 组件图标
├── langflow-core/         # 可独立使用、不绑定任何 provider 的发行版
├── bundles/               # 精选 provider 集成
└── lfx/                   # 轻量执行器与共享基础原语

在当前仓库中可核对到的对应物:src/backend/base/langflow/ 下确有 api/services/graph/custom/ 目录;src/bundles/ 下是各 provider 的 bundle(openaianthropicgoogleollamalfx-bundles 等);src/lfx/ 是 lfx 子包(其 pyproject.toml 当前版本同为 1.12.0);前端位于 src/frontend/

关键包与依赖方向

  • langflow:面向最终用户的完整包,依赖 langflow-core 与精选 provider bundle;
  • langflow-core:服务完备、不捆绑 provider 的发行版,拥有 langflow CLI;
  • langflow-base:模块化应用平台(API、服务层、图执行引擎),通过 extras 追加服务集成;
  • lfx:共享执行原语与独立 CLI(lfx servelfx run)。

对外的依赖方向为 langflow → langflow-core → langflow-base → lfxsrc/bundles/ 下的 provider 包只会被完整的 langflow 发行版引入。根 pyproject.toml 中可见该结构的实际体现:主包依赖 langflow-base~=1.12.0,并声明了一组带版本区间的 lfx-* 策展 bundle 依赖(仓库注释说明:精确 pin 保留在 uv.lock 与发布构建清单中,主依赖只写有界区间以避免给下游带来解析冲突)。

服务层(Service Layer)

后端服务集中在 src/backend/base/langflow/services/ 下,AGENTS.md 列出的核心子域为:

  • auth/ —— 认证;
  • authorization/ —— 授权(RBAC)插件层;
  • database/ —— SQLAlchemy 模型与迁移;
  • cache/ —— 缓存层;
  • storage/ —— 文件存储;
  • tracing/ —— 可观测性集成。

从当前目录结构看,services/ 下还包含 session/rate_limit/jobs/checkpoint/memory_base/ 等更多子域,服务按“一域一目录”的方式组织。

四、RBAC 授权层:接口、默认值与执行模型

AGENTS.md 用较大篇幅描述了 Langflow 的授权(Authorization)设计,这是理解其多用户权限体系的关键。核心要点是:授权是与认证分离的可插拔层

4.1 OSS 提供的部分

  • 接口:BaseAuthorizationService 定义在 lfx 包中;
  • 直通实现:LangflowAuthorizationService(pass-through stub);
  • 数据库 schema:authz_* 管理表与 casbin_rule 规则表;
  • 路由守卫:route guards。

插件通过 lfx.toml 中的 lfx.services 入口点 authorization_service 注册(与 SSO 的 auth_service 同一套模式)。注册后的插件读取 authz_* 管理表,并把编译后的规则写入 casbin_rule

默认关闭LANGFLOW_AUTHZ_ENABLED=false。若开启但只注册了 OSS stub,所有检查都返回 allow——stub 是 no-op,路由保持连通,审计日志(audit rows)依然会写入。真正的 allow/deny 必须注册授权插件才能实现。该开关在源码中可见于 src/backend/base/langflow/services/authorization/service.py

4.2 路由守卫(Route Guards)

守卫实现位于 langflow.services.authorization.guards(旧路径 langflow.services.authorization.utils 为向后兼容做了再导出)。当前仓库 src/backend/base/langflow/services/authorization/guards.py 中确认存在这些守卫函数:

  • ensure_flow_permission(user, FlowAction.*, flow_id=..., flow_user_id=..., workspace_id=..., folder_id=...) —— 单流程的 CRUD + 执行;
  • ensure_deployment_permission(user, DeploymentAction.*, deployment_id=..., deployment_user_id=..., workspace_id=..., project_id=...)
  • ensure_project_permission(user, ProjectAction.*, project_id=..., project_user_id=..., workspace_id=...)
  • ensure_knowledge_base_permission(user, KnowledgeBaseAction.*, kb_name=..., kb_user_id=...)
  • ensure_variable_permission(user, VariableAction.*, variable_id=..., variable_user_id=...)
  • ensure_file_permission(user, FileAction.*, file_id=..., file_user_id=...)
  • ensure_share_permission(user, ShareAction.*, share_id=..., share_user_id=...)
  • filter_visible_resources(user, resource_type=..., candidates=..., act=...) —— 列表端点过滤,在 OSS 中是安全 no-op。

4.3 权限执行请求元组

执行权限时的请求形状为 (subject, domain, object, action)

  • subject = user:{uuid}
  • domain = project:{uuid}workspace:{uuid}*(由 _resolve_flow_domain 解析;更具体的 domain 优先,project 级授权可直接匹配,workspace 级授权则通过插件侧角色继承向下流动);
  • object = flow:{uuid} / deployment:{uuid} / project:{uuid} / flow:* 等;
  • action = read / write / create / delete / execute / deploy

4.4 共享感知读取(Phase 3)

路由读取助手(_read_flowget_flow_by_id_or_endpoint_nameget_deploymentprojects.py 中的 project 读取、v2 文件读取器、variable.py 的 PATCH/DELETE)会根据 BaseAuthorizationService.supports_cross_user_fetch() 分支处理:

  • OSS 直通实现返回 False,因此保留原有的 owner 作用域查询——即使打开 LANGFLOW_AUTHZ_ENABLED=true 而没有注册插件,也不会意外放宽可见范围;
  • 插件侧设置 SUPPORTS_CROSS_USER_FETCH=True 后,资源只凭 id 即可加载,由 ensure_*_permission 决定访问结果;路由处理器可通过 langflow.services.authorization.fetch.deny_to_404 把插件拒绝的 HTTPException(403) 转换为 HTTPException(404),以保护 UUID 隐私。

4.5 Share CRUD 与审计 API

  • Share CRUD(Phase 3)/api/v1/authz/shares 提供对 authz_share 行的 POST / GET / PATCH / DELETE。处理器强制执行 OSS 下限——只有资源属主或超级用户可以管理该资源的分享行,直通实现无法让非属主创建 share 行。每次写入都会触发 BaseAuthorizationService.invalidate_user / invalidate_all,让已注册的 enforcer 可以丢弃缓存策略;审计记录通过 audit_decisionshare:create / share:update / share:delete 动作写入。
  • 审计查询 API(Phase 4)GET /api/v1/authz/audit(仅超级用户)提供 authz_audit_log 的分页、可过滤视图,支持 user_idresource_typeresource_idactionresultsinceuntil 过滤,单页上限 200 条。
  • 默认角色目录(Phase 4):统一的 foundations 迁移 7c8d9e0f1a2b_authz_foundations 播种了三个内置 is_system=True 角色(viewer / developer / admin),权限 slug 形如 "{resource}:{action}"。OSS 本身不解释这些角色——它们存在是为了让注册插件的策略同步拥有一个稳定的引导来源。

五、组件(Component)开发规范

AGENTS.md 指出组件位于 src/backend/base/langflow/components/,新增组件的步骤为:

  1. 创建继承自 Component 的组件类;
  2. 定义 display_namedescriptioniconinputsoutputs
  3. 按字母序添加到 __init__.py
  4. 使用 LFX_DEV=1 make backend 热重载验证。

重要约束:修改组件的类名属于破坏性变更,任何时候都不应这样做。类名是已保存 flow 中匹配组件的标识符,也用于 UI 中标记需要更新的组件;重命名会直接破坏使用该组件的既有 flow。

文档给出的标准组件结构示例(注意:文档示例基于早期 import 路径;当前仓库中组件框架位于 src/backend/base/langflow/custom/,且内置组件已按 provider 拆分到 src/bundles/ 下的 bundle 包中,新增内置组件时请以仓库内现有组件代码的实际 import 为准):

from langflow.custom import Component
from langflow.io import MessageTextInput, Output

class MyComponent(Component):
    display_name = "My Component"
    description = "What it does"
    icon = "component-icon"  # Lucide 图标名或自定义图标

    inputs = [
        MessageTextInput(name="input_value", display_name="Input"),
    ]
    outputs = [
        Output(display_name="Output", name="output", method="process"),
    ]

    def process(self) -> Message:
        # 组件逻辑
        return Message(text=self.input_value)

组件测试

组件测试放在 src/backend/tests/unit/components/(当前仓库该目录存在,含 conftest.pybundles/ 等子目录)。使用两个基类:

  • ComponentTestBaseWithClient —— 需要 API 访问的组件;
  • ComponentTestBaseWithoutClient —— 纯逻辑组件。

必需的 fixtures:component_classdefault_kwargsfile_names_mapping。仓库还提供了 make check_components_frozen 对应的检查脚本 scripts/ci/check_components_frozen.py 与冻结目录清单 scripts/ci/frozen_component_dirs.txt,用于在 CI 中约束组件目录的稳定性——这从侧面印证了“类名与组件目录是对外契约”这一规范。

六、前端开发要点

AGENTS.md 对前端的约定:

  • React 19 + TypeScript + Vite;
  • Zustand 管理状态;
  • @xyflow/react 做图(流程画布)可视化;
  • Tailwind CSS 负责样式。

以上均可在 src/frontend/package.jsonsrc/frontend/vite.config.mts 中得到印证。

自定义图标

  1. src/frontend/src/icons/YourIcon/ 下创建 SVG 组件;
  2. 使用 forwardRef 导出,并支持 isDark prop;
  3. lazyIconImports.ts 中注册;
  4. 在 Python 组件中设置 icon = "YourIcon"

七、测试注意事项与 Graph 测试模式

AGENTS.md 列出的测试注意事项(与当前仓库的 Makefile 目标一致):

  • @pytest.mark.api_key_required —— 需要外部 API Key 的测试(make unit_tests 默认跳过);
  • @pytest.mark.no_blockbuster —— 跳过 blockbuster 插件;
  • 数据库测试可能在批量执行时失败、单独执行时通过;
  • pre-commit 钩子要求使用 uv run git commit
  • 运行 Python 命令时始终使用 uv run
  • 在子包内(如 langflow-baselfx)运行测试前,先同步该子包的 dev 依赖组:uv sync --group dev --package langflow-base。默认的 uv sync 只解析顶层 workspace,可能漏装 dev-only 的测试依赖(例如 fakeredis)。

Graph 测试标准模式

正规的 Graph 测试遵循四步:

  1. 用已连接的组件构建图;
  2. 通过 .set() 调用连接各组件;
  3. 调用 async_start 并迭代结果;
  4. 校验结果。

测试最佳实践

  • 尽量避免在测试中使用 mock;
  • 优先使用真实集成,测试更可靠。

八、版本管理

make patch v=1.5.0  # 跨所有包更新版本

AGENTS.md 说明该命令会更新 pyproject.tomlsrc/backend/base/pyproject.tomlsrc/frontend/package.json。对照 Makefilepatch 目标的完整实现,其实际动作远不止三处:它还会同步 src/lfx/pyproject.toml 版本、组件索引 src/lfx/src/lfx/_assets/component_index.json 的版本字段、src/sdk/pyproject.toml 与 lfx 对 langflow-sdk 的依赖下限、src/bundles/* 各 bundle 的 lfx pin(通过 scripts/ci/sync_bundle_lfx_pin.py),随后执行 uv syncnpm install 并行刷新锁文件,并逐条 grep 校验上述文件确实被修改、修改后的依赖约束(如 langflow-base~=X.Y.0 的兼容下限、lfx~=X.Y.Z 精确对齐)符合预期——任何一步校验失败都会中止。因此发布新版本时应以该目标的最终输出为准,而不是手工改版本号。

九、Pre-commit 工作流与 PR 规范

Pre-commit 钩子在 git commit 时自动运行 ruff 与 biome,因此不需要手动格式化。当改动较多时,为避免额外的提交轮次,AGENTS.md 建议:

  1. 暂存前运行一次 make format_backend,提前修掉大部分 ruff 问题;
  2. 使用 uv run git commituv run 确保 pre-commit 找到正确的 Python);
  3. 若改动了后端代码,本地先跑 make unit_tests,反馈快于 CI。

Pull Request 指南:

  • 遵循语义化提交规范(conventional commits);
  • 引用所修复的 issue(如 Fixes #1234);
  • 提交前确保所有测试通过。

十、文档站点本地运行

Langflow 的文档使用 Docusaurus,位于 docs/ 目录:

cd docs
yarn install
yarn start        # 开发服务器运行在 3000 端口(3000 被占用时会提示改用 3001)

文档源码为 docs/docs/ 下的 .mdx 文件(Get-Started、Agents、Components、Deployment、Develop、Lfx、Tutorials 等栏目),版本化历史文档在 docs/versioned_docs/

小结

AGENTS.md 是面向 AI 编码助手与人类贡献者的仓库操作手册:它把“装环境 → 起服务 → 改代码 → 跑测试 → 提交 → 发版”这条链路的关键命令、目录职责与硬性约束(尤其是组件类名不可重命名、uv run 使用惯例、RBAC 默认关闭且插件可插拔)压缩成了一页速查。配合 MakefileMakefile.frontend 与各子包源码阅读,可以完整理解 Langflow 从 Monorepo 组织、包依赖分层到权限模型的设计思路,并据此安全地参与后端组件、前端 UI 与 lfx 执行器的开发。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.12 K
2.72 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
527
590
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
904
1.82 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
854
1.34 K
docsdocs
暂无描述
Markdown
889
5.78 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.52 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.33 K
1.45 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
980
502
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
540
384