Langflow 开发实战指南:从 AGENTS.md 看 Langflow 仓库的构建、架构与组件开发规范
Langflow 是一个用于构建和部署 AI Agent 与工作流的可视化开发平台,仓库采用 Python/FastAPI 后端 + React/TypeScript 前端 + 轻量级执行器 CLI(lfx)的 Monorepo 组织方式。本篇基于仓库根目录的 AGENTS.md 逐节展开,并结合当前仓库中的 Makefile、Makefile.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.0;src/frontend/package.json 中 engines.node 为 >=20.19.0,React 依赖为 ^19.2.1;Makefile 的 check_tools 目标会在 make init 前校验 uv 与 npm 是否已安装,不满足则直接中止。
注意:AGENTS.md 中列出的命令(如
make init、make run_cli、make unit_tests、make alembic-revision等)均已在 Makefile 与 Makefile.frontend 中确认存在。其中make backend依赖setup_env与install_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_backend(uv sync --frozen --extra "postgresql")、install_frontend,最后uvx pre-commit install安装 git 钩子;run_cli:复用已有前端构建缓存,依次执行install_frontend、install_backend、build_frontend,最后以--host 0.0.0.0 --port 7860(默认值来自 Makefile 顶部变量port ?= 7860)启动;run_clic:与run_cli的差异在于前置了clean_frontend_build目标——它会清空src/frontend/build与src/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 / 类型检查
Makefile 中 format_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_check(npx @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_tests 在 Makefile 中默认追加 --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.js 与 src/frontend/playwright.config.ts。此外 Makefile 还有 integration_tests、integration_tests_api_keys、template_tests、lfx_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-current、alembic-history、alembic-check、alembic-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(openai、anthropic、google、ollama、lfx-bundles 等);src/lfx/ 是 lfx 子包(其 pyproject.toml 当前版本同为 1.12.0);前端位于 src/frontend/。
关键包与依赖方向
- langflow:面向最终用户的完整包,依赖
langflow-core与精选 provider bundle; - langflow-core:服务完备、不捆绑 provider 的发行版,拥有
langflowCLI; - langflow-base:模块化应用平台(API、服务层、图执行引擎),通过 extras 追加服务集成;
- lfx:共享执行原语与独立 CLI(
lfx serve、lfx run)。
对外的依赖方向为 langflow → langflow-core → langflow-base → lfx;src/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_flow、get_flow_by_id_or_endpoint_name、get_deployment、projects.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_decision以share:create/share:update/share:delete动作写入。 - 审计查询 API(Phase 4):
GET /api/v1/authz/audit(仅超级用户)提供authz_audit_log的分页、可过滤视图,支持user_id、resource_type、resource_id、action、result、since、until过滤,单页上限 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/,新增组件的步骤为:
- 创建继承自
Component的组件类; - 定义
display_name、description、icon、inputs、outputs; - 按字母序添加到
__init__.py; - 使用
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.py、bundles/ 等子目录)。使用两个基类:
ComponentTestBaseWithClient—— 需要 API 访问的组件;ComponentTestBaseWithoutClient—— 纯逻辑组件。
必需的 fixtures:component_class、default_kwargs、file_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.json 与 src/frontend/vite.config.mts 中得到印证。
自定义图标
- 在
src/frontend/src/icons/YourIcon/下创建 SVG 组件; - 使用
forwardRef导出,并支持isDarkprop; - 在
lazyIconImports.ts中注册; - 在 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-base、lfx)运行测试前,先同步该子包的 dev 依赖组:uv sync --group dev --package langflow-base。默认的uv sync只解析顶层 workspace,可能漏装 dev-only 的测试依赖(例如fakeredis)。
Graph 测试标准模式
正规的 Graph 测试遵循四步:
- 用已连接的组件构建图;
- 通过
.set()调用连接各组件; - 调用
async_start并迭代结果; - 校验结果。
测试最佳实践
- 尽量避免在测试中使用 mock;
- 优先使用真实集成,测试更可靠。
八、版本管理
make patch v=1.5.0 # 跨所有包更新版本
AGENTS.md 说明该命令会更新 pyproject.toml、src/backend/base/pyproject.toml、src/frontend/package.json。对照 Makefile 中 patch 目标的完整实现,其实际动作远不止三处:它还会同步 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 sync 与 npm install 并行刷新锁文件,并逐条 grep 校验上述文件确实被修改、修改后的依赖约束(如 langflow-base~=X.Y.0 的兼容下限、lfx~=X.Y.Z 精确对齐)符合预期——任何一步校验失败都会中止。因此发布新版本时应以该目标的最终输出为准,而不是手工改版本号。
九、Pre-commit 工作流与 PR 规范
Pre-commit 钩子在 git commit 时自动运行 ruff 与 biome,因此不需要手动格式化。当改动较多时,为避免额外的提交轮次,AGENTS.md 建议:
- 暂存前运行一次
make format_backend,提前修掉大部分 ruff 问题; - 使用
uv run git commit(uv run确保 pre-commit 找到正确的 Python); - 若改动了后端代码,本地先跑
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 默认关闭且插件可插拔)压缩成了一页速查。配合 Makefile、Makefile.frontend 与各子包源码阅读,可以完整理解 Langflow 从 Monorepo 组织、包依赖分层到权限模型的设计思路,并据此安全地参与后端组件、前端 UI 与 lfx 执行器的开发。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0622
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00