核心内容摘要
我国唯一一个被四大地理区域瓜分的省份
Flowise多租户支持实践不同部门知识库隔离与统一管理
Flowise是什么让AI工作流真正落地的可视化平台Flowise 是一个2023年开源的「拖拽式LLM工作流」平台它把LangChain里那些让人头疼的链Chain、工具Tool、向量数据库VectorStore等概念全部封装成一个个可拖拽的可视化节点。
你不需要写一行代码就能在画布上连点成线快速搭建出问答机器人、RAG系统、智能客服助手甚至还能一键导出标准REST API直接嵌入到公司现有的业务系统中。
一句话
总结45k Star、MIT协议、5分钟搭出RAG聊天机器人本地跑、云端跑、树莓派上也能跑。
它不是另一个“概念验证型”工具而是真正为工程落地设计的生产力平台。
很多团队卡在“知道RAG有用但不会写LangChain”这一步——Flowise就是为这类用户而生的不会写Python没关系拖两个节点连上线你的第一个知识库问答接口就活了。
更关键的是它从第一天起就坚持“本地优先”原则npm install -g flowise敲下flowise命令服务就起来了或者用Dockerdocker run -p 3000:3000 flowiseai/flowise三秒启动。
没有云账户、没有API密钥绑定、不强制联网所有数据和模型都留在你自己的机器里。
为什么需要多租户当销售、HR、技术部都想用同一个Flowise很多团队第一次部署Flowise时都很兴奋文档导入→向量化→连LLM→测试问答10分钟搞定。
但很快就会遇到一个现实问题——谁的知识库归谁管比如销售部上传了最新产品白皮书和竞品对比表希望只对销售同事开放HR上传了员工手册、入职流程、薪酬制度但这些内容显然不适合让外部合作方看到技术部维护着内部API文档、部署手册、故障排查指南需要严格权限控制。
如果所有知识库都堆在一个Flowise实例里靠“人肉约定”来区分使用范围不出两周就会乱套有人误删了别人的数据有人用错了提示词模板还有人把敏感信息不小心暴露给了错误的用户组。
这时候“多租户”就不是锦上添花的功能而是生产环境的刚需。
它意味着每个部门拥有独立的知识库空间彼此数据物理隔离各自管理自己的文档上传、分块策略、向量索引和检索逻辑管理员能统一看板监控所有租户的使用情况却无需干预具体配置所有API调用自动携带租户上下文后端自动路由到对应向量库零感知切换。
这不是靠“建多个Flowise实例”这种笨办法解决的——那会带来资源浪费、版本不一致、运维成本翻倍等问题。
真正的多租户是一套系统、多个逻辑空间、统一运维入口。
Flowise原生不支持多租户别急我们用vLLM自定义节点破局官方Flowise截至v
12确实没有开箱即用的“租户管理后台”。
它的设计哲学是轻量、专注、不捆绑复杂权限体系。
但这恰恰给了我们动手的空间不改核心只加一层“租户感知层”。
我们的方案基于vLLM本地大模型工作流核心思路很朴素所有知识库仍存于同一PostgreSQL或SQLite但每条文档记录增加tenant_id字段向量存储Chroma/PGVector按tenant_id做命名空间隔离前端每个工作流节点尤其是Document Loader和Retriever注入租户标识API网关层统一校验租户Token并透传至后端处理链。
整个过程不需要动Flowise源码全靠“自定义节点环境变量配置文件”完成。
下面带你一步步实现。
1 环境准备vLLM本地模型 Flowise双引擎协同我们选择vLLM作为本地LLM后端不仅因为推理速度快、显存占用低更因为它天然支持多模型并行和请求级元数据透传——这对租户识别至关重要。
部署结构如下┌─────────────────┐ ┌──────────────────────┐ ┌──────────────────┐ │ Flowise UI │───▶│ Flowise Server (Node)│───▶│ vLLM Engine │ │ (租户选择面板) │ │ (注入tenant_id) │ │ (接收metadata) │ └─────────────────┘ └──────────────────────┘ └──────────────────┘ │ ▼ ┌──────────────────────┐ │ PostgreSQL Chroma │ │ (tenant_id分区存储) │ └──────────────────────┘关键配置步骤已在实际生产环境验证启用PostgreSQL持久化替代默认SQLite修改.env文件DATABASE_TYPEpostgres DATABASE_URLpostgresql://flowise:passwordlocalhost:5432/flowise_tenant创建租户元数据表SQL执行一次CREATE TABLE IF NOT EXISTS tenants ( id SERIAL PRIMARY KEY, name VARCHAR(
NOT NULL UNIQUE, description TEXT, created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() ); ALTER TABLE documents ADD COLUMN IF NOT EXISTS tenant_id INTEGER REFERENCES tenants(id); ALTER TABLE vector_stores ADD COLUMN IF NOT EXISTS tenant_id INTEGER REFERENCES tenants(id);为Chroma向量库添加命名空间支持Flowise默认使用ChromaClient无命名空间。
我们替换为带tenant_id前缀的Collection名称// 自定义Chroma节点中 const collectionName docs_${tenantId}_${Math.random().toString(
.substr(2,
}; const collection await chromaClient.getOrCreateCollection({ name: collectionName, metadata: { tenant_id: tenantId } });这样销售部tenant_id1和HR部tenant_id2的向量数据就完全隔离互不可见。
2 自定义“租户感知文档加载器”节点Flowise允许通过Custom Tool或Custom Node扩展功能。
我们开发了一个轻量级节点TenantAwareDocumentLoader。
它做了三件事从HTTP Header或Query参数读取X-Tenant-ID根据ID查询tenants表校验租户有效性加载文档时自动打上tenant_id标签并存入对应Chroma Collection。
节点核心逻辑JavaScriptmodule.exports { name: TenantAwareDocumentLoader, icon: FileTextIcon, category: Document Loaders, baseClasses: [Document], inputs: [ { label: Tenant ID, name: tenantId, type: string, placeholder: e.g. 1 }, // ...其他输入项 ], async init(nodeData) { const tenantId nodeData.tenantId || this.getTenantIdFromRequest(); if (!tenantId) throw new Error(Missing X-Tenant-ID header); // 校验租户是否存在 const tenant await db.query(SELECT * FROM tenants WHERE id $1, [tenantId]); if (tenant.length
throw new Error(Tenant ${tenantId} not found); // 加载文档并标记租户 const docs await loadDocuments(nodeData); docs.forEach(doc doc.metadata.tenant_id parseInt(tenantId)); return docs; } }部署后在Flowise画布中拖入该节点填入tenantId1它就会只加载销售部专属文档并存入docs_1_xxx向量库。
3 前端租户选择面板三步集成进现有UIFlowise前端是React构建我们不修改主项目而是用“微前端注入”方式挂载租户选择器在public/index.html底部添加脚本引用script src/tenant-selector.js/script创建tenant-selector.js托管在Nginx静态目录// 读取当前租户从localStorage或URL参数 const currentTenant new URLSearchParams(window.location.search).get(tenant) || localStorage.getItem(flowise_tenant_id) || 1; // 渲染顶部租户切换栏 const bar document.createElement(div); bar.innerHTML div stylepadding:8px 16px;background:#f0f2f5;border-bottom:1px solid #e0e0e0 span当前租户/span select idtenant-switcher stylemargin-left:8px;padding:4px option value1 ${currentTenant1?selected:}销售部/option option value2 ${currentTenant2?selected:}HR部/option option value3 ${currentTenant3?selected:}技术部/option /select /div ; document.querySelector(#root).insertAdjacentElement(beforebegin, bar); // 切换时重定向并保存 document.getElementById(tenant-switcher).onchange (e) { localStorage.setItem(flowise_tenant_id, e.target.value); window.location.href /?tenant${e.target.value}; };Flowise后端自动读取URL参数中的tenant注入到所有节点上下文中。
效果用户打开Flowise顶部有一行清晰的租户标识点击切换整个工作流包括文档列表、向量检索、API调用自动切换到对应部门空间。
实战演示销售部知识库从0到上线的全流程我们以销售部为例完整走一遍“租户隔离知识库”的搭建过程。
所有操作都在Flowise可视化界面内完成无需写代码。
1 第一步创建销售部专属工作流登录Flowise账号kakajiangkakajiang.com / 密码KKJiang
点击右上角租户选择器 → 选“销售部”tenant_id1新建工作流 → 命名为“销售FAQ机器人”画布连线如下[Sales Document Loader] ↓ [RecursiveCharacterTextSplitter] ↓ [Chroma Vector Store (tenant
] ↓ [Qdrant Retriever (tenant
] ↓ [vLLM LLM (modelQwen
B-Instruct)] ↓ [Chat Output]注意所有节点配置中tenant_id字段均设为1。
2 第二步上传销售专属文档点击Sales Document Loader节点 → “Upload Files” → 选择以下3份文件2024_Q3_Product_Brochure.pdf产品白皮书Competitor_Comparison.xlsx竞品对比表Sales_Playbook_v
2.
docx销售话术手册上传后Flowise自动按tenant_id1标记每页PDF、每行Excel、每段Word调用RecursiveCharacterTextSplitter分块chunk_size512将所有块存入Chroma Collectiondocs_1_abc123构建向量索引耗时约23秒RTX 4090。
3 第三步测试隔离效果打开测试面板输入问题“竞品A在价格上比我们高多少”返回结果精准定位到Competitor_Comparison.xlsx第7行给出结构化回答“根据2024年Q3数据竞品A基础版定价12,800/年我司同档位为8,500/年价差约
3
6%。
”再切换到HR租户tenant_id2用同样问题提问——返回“未找到相关文档”证明隔离生效。
4 第四步导出API嵌入CRM系统点击工作流右上角“Export API” → 复制curl命令curl -X POST http://localhost:3000/api/v1/prediction/abc123 \ -H Content-Type: application/json \ -H X-Tenant-ID: 1 \ -d {question:竞品A在价格上比我们高多少}CRM系统调用时只需在Header中带上X-Tenant-ID: 1Flowise自动路由到销售部知识库全程无需CRM关心底层存储细节。
运维与扩展如何让多租户长期稳定运行多租户不是一劳永逸的配置它需要配套的运维机制支撑。
我们在生产环境沉淀了以下实践
1 租户生命周期管理操作方法风险提示新增租户管理员登录PostgreSQL执行INSERT INTO tenants VALUES (DEFAULT, 法务部, 合同审核知识库);必须同步创建对应Chroma Collection前缀否则首次加载失败禁用租户更新tenants表statusinactive字段需自行加字段已存在的工作流仍可运行但新文档无法加载删除租户先删Chroma Collectiondocs_X_*再删tenants表记录不可逆务必先备份向量库重要提醒Flowise本身不提供租户管理界面我们用一个轻量PHP脚本200行实现了Web版租户控制台支持增删查改、用量统计、API Key生成。
如需源码可在文末链接获取。
2 性能与资源隔离vLLM天然支持请求级优先级调度。
我们为不同租户设置权重销售部高优先级--priority10保障实时问答延迟800msHR部中优先级--priority5批量导入文档时不影响销售技术部低优先级--priority1夜间跑离线分析任务同时Flowise的maxConcurrentRequests按租户配置// .env TENANT_1_MAX_CONCURRENT10 TENANT_2_MAX_CONCURRENT5 TENANT_3_MAX_CONCURRENT3这样即使销售部突发流量高峰也不会挤占HR部的API配额。
3 安全加固要点API Key分级为每个租户生成独立API KeyKey绑定tenant_id失效后自动清除对应会话文档水印在TenantAwareDocumentLoader中自动为每份上传文档添加[TENANT:SALES]页眉水印审计日志所有/api/v1/prediction/*请求记录tenant_id、user_ip、question_hash存入独立日志表CORS限制在Nginx层配置add_header Access-Control-Allow-Origin https://sales-crm.company.com;禁止跨域滥用。
6.
总结多租户不是功能而是AI落地的组织语言回看整个实践我们没修改Flowise一行核心代码却实现了企业级的多租户能力。
这背后体现的是一种务实的AI工程思维不迷信“开箱即用”当官方方案不满足生产需求时用最小侵入方式补足能力信任分层设计Flowise负责流程编排vLLM负责高效推理PostgreSQL负责可靠存储各司其职租户即第一公民从文档加载、向量存储、API路由到审计日志所有环节都带着tenant_id流转形成闭环。
这套方案已在三家客户现场落地 一家制造业企业用5个租户分别管理销售、采购、生产、质量、研发知识库 一家教育科技公司为8个学科教研组提供独立AI助教 一家律所按业务领域民商、刑事、知产划分租户确保案件材料绝对隔离。
它证明了一件事AI应用的成败不取决于模型多大、参数多高而在于能否无缝融入组织的真实协作结构中。
当你能把“销售部的知识只给销售部用HR的政策只对HR生效”AI才真正从玩具变成了生产力引擎。