首页
/ Langflow OpenAI Compatible 扩展 Bundle:把任意 OpenAI 兼容端点变成一等模型供应商

Langflow OpenAI Compatible 扩展 Bundle:把任意 OpenAI 兼容端点变成一等模型供应商

2026-09-06 14:08:22作者:温玫谨Lighthearted

本文基于仓库中的 lfx-openai-compatible 扩展文档 展开,介绍 Langflow 的 OpenAI Compatible Extension Bundle 如何将 OpenRouter、Together AI、Groq、Fireworks AI 以及自托管 vLLM/TGI/LM Studio 等任意 OpenAI 兼容端点,注册为 Langflow 统一模型选择器中的一等模型供应商。读完本文,你将理解该 Bundle 的 provider 注册机制(extension.jsonproviders[] 块)、/v1/models 实时模型发现与凭据校验的底层实现、SSRF 安全防护策略,以及完整的安装、配置与开发流程。

一、它是什么:一个"无组件"的 Provider 型扩展 Bundle

Langflow 的扩展 Bundle 通常以"组件"(Component)为载体提供功能,但 lfx-openai-compatible 是另一种形态——Provider 型 Bundle:它不携带任何组件,而是通过 extension.json 清单中的 providers[] 块,向 Langflow 的统一模型系统(unified model system)注入一个名为 OpenAI Compatible 的模型供应商。该供应商会出现在 Langflow 的模型选择器中,与内置供应商并列。

任何遵循 OpenAI HTTP API 形态的服务端点都可以通过它接入,README 给出的常见端点如下:

Provider Base URL
OpenRouter https://openrouter.ai/api/v1
Together AI https://api.together.xyz/v1
Groq https://api.groq.com/openai/v1
Fireworks AI https://api.fireworks.ai/inference/v1
自托管 vLLM / TGI / LM Studio http://localhost:8000/v1

从源码结构看,该供应商复用了 ChatOpenAI / OpenAIEmbeddings 这两个 langchain-openai 类,并实时从端点的 /v1/models 路由发现模型。因此同一个模型会同时出现在 Language Model(语言模型)和 Embedding Model(嵌入模型)两类上下文中。整个实现不修改任何 Langflow 核心文件。

二、extension.json 清单:provider 注册的完整契约

extension.json 是整个 Bundle 的注册契约。它声明了 Bundle 元信息与唯一的 provider 条目,关键字段如下:

  • id / versionlfx-openai-compatible,版本 0.1.1lfx.compat 声明兼容 lfx 主版本 ["1"]
  • nameOpenAI Compatible,即注册进统一模型系统后显示的供应商名,图标为 Plugmax_tokens_field_namemax_tokens

2.1 用户可配置变量(variables)

metadata.variables 定义了两个字段,也就是用户在 Model Providers 面板中看到的两个输入项:

variable_name variable_key required is_secret langchain_param
Base URL OPENAI_COMPATIBLE_BASE_URL base_url
API Key OPENAI_COMPATIBLE_API_KEY api_key

两个变量都带 component_metadata:当用户在组件字段中内联覆盖时,分别映射到 openai_compatible_base_urlapi_key 字段(advanced: true),且均可回退到同名环境变量。API Key 标记为 is_secret: true,表示存储与展示时按密钥处理。

2.2 模型类与嵌入类映射

清单同时指定了语言模型与嵌入模型的具体实现类:

"model_class": {
  "module": "langchain_openai",
  "attr": "ChatOpenAI"
},
"embedding": {
  "class_name": "OpenAIEmbeddings",
  "module": "langchain_openai",
  "attr": "OpenAIEmbeddings",
  "param_mapping": {
    "model": "model",
    "api_base": "base_url",
    "dimensions": "dimensions",
    "chunk_size": "chunk_size",
    "request_timeout": "timeout",
    "max_retries": "max_retries",
    ...
  }
}

即:聊天模型用 ChatOpenAI(参数经 mapping.model_param: "model" 传入),嵌入模型用 OpenAIEmbeddings,并把用户配置的 Base URL 注入到 api_base 参数、其余参数(dimensionschunk_sizetimeout 等)逐项透传。

2.3 实时发现与校验钩子

"api_key_required": false,
"live": true,
"live_discovery": "lfx_openai_compatible.discovery:fetch_live_openai_compatible_models",
"validator": "lfx_openai_compatible.discovery:validate_openai_compatible_credentials"
  • api_key_required: false:本地无鉴权服务可不填 API Key;
  • live: true + live_discovery:以点分路径引用发现函数,由 lfx 的 provider registry 延迟导入并调用;
  • validator:同样以点分路径引用凭据校验函数,在用户保存配置时被 registry 调用。

这一"点分路径 + 延迟调用"的设计使得 Bundle 的导入开销极低:只有当供应商实际被使用时,discovery 模块 才会被导入。该注册机制在 lfx 侧的实现入口位于 provider_registry(其中 live_discovery_for / validator_for 负责按点分路径解析并缓存这两个可调用对象)。

三、实时模型发现与凭据校验的源码解析

discovery.py 提供两个可调用对象,是理解该 Bundle 行为的核心。

3.1 Base URL 归一化

def _models_url(base_url: str) -> str:
    """Return the ``/v1/models`` URL, tolerating a base that already ends in /v1."""
    base_url = base_url.rstrip("/")
    return f"{base_url}/models" if base_url.endswith("/v1") else f"{base_url}/v1/models"

该函数容忍用户 Base URL 末尾已带 /v1 的情况,避免拼出 .../v1/v1/models单元测试 中的参数化用例验证了四种输入:http://localhost:8000.../v1/modelshttp://localhost:8000/v1.../v1/models(不重复);http://localhost:8000/.../v1/modelshttps://api.groq.com/openai/v1.../v1/models

3.2 实时发现:fetch_live_openai_compatible_models

该函数(discovery.py#L45)的行为要点:

  1. 读取用户配置:通过 get_provider_variable_value(user_id, ...)OPENAI_COMPATIBLE_BASE_URL;若未配置,直接返回空列表。API Key 读取被 try/except 包裹——API Key 查询失败不会阻断发现,而是退化为匿名探测(对应测试 test_fetch_swallows_api_key_lookup_error)。
  2. SSRF 安全 GET:使用 ssrf_safe_httpx_get 发起请求,参数为 timeout=5 秒、follow_redirects=False。该工具函数会先对 URL 做 connector SSRF 校验与 DNS 固定(DNS pinning),防止 DNS rebinding;不跟随重定向则天然阻断"先 302 到内网元数据地址"一类的攻击(测试 test_fetch_does_not_follow_redirects 用指向 169.254.169.254 的 302 响应验证了这一点)。
  3. 双格式解析_parse_model_names 兼容 OpenAI 标准 {"data": [{"id": ...}]} 结构与纯列表两种响应体(部分自建服务直接返回列表),结果按名称排序。
  4. 打标签:每个模型经 create_model_metadata 打上 provider="OpenAI Compatible"icon="Plug"model_typellmembeddings)标签;/v1/models 不区分聊天与嵌入模型,所以端点上每个模型都会被返回并打上请求方的 model_type——统一目录按类型各取一次,因此同一模型同时进入 Language Model 与 Embedding Model 选择器。tool_calling 仅在 llm 上下文中为真,前 MIN_DEFAULT_MODELS 个模型标记为默认项。
  5. 永不抛错:任何传输或解析错误都降级为"无实时模型"(返回空列表并记 debug 日志),保证一个配置错误的端点不会拖垮整个模型目录。

3.3 凭据校验:validate_openai_compatible_credentials

该函数(discovery.py#L87)在用户保存供应商配置时做主动探测,与发现函数形成互补:发现路径"静默降级",校验路径"显式报错"。它同样请求 /v1/models(携带可选的 Authorization: Bearer <key>),并将各类失败翻译成可操作的 ValueError

  • 缺少 Base URL → Invalid OpenAI-compatible base URL
  • HTTP 401/403 → Authentication failed for the OpenAI-compatible endpoint. Check OPENAI_COMPATIBLE_API_KEY.
  • 连接失败(httpx.ConnectError)→ 提示确认服务已启动且 URL 正确;
  • 超时 → 明确的 timeout 提示;
  • 其他 HTTP 状态错误 → 附带具体状态码与完整 models_url,提示检查 Base URL 是否指向 OpenAI 兼容 API。

四、配置、安装与本地端点注意事项

4.1 配置方式

Settings → Model Providers → OpenAI Compatible 面板中设置端点,或通过环境变量:

字段 环境变量 必填 说明
Base URL OPENAI_COMPATIBLE_BASE_URL OpenAI 兼容端点的 Base URL,如 https://openrouter.ai/api/v1http://localhost:8000/v1
API Key OPENAI_COMPATIBLE_API_KEY Bearer token;本地无鉴权服务可留空

完整的 UI 操作流程见仓库文档 OpenAI Compatible 组件文档:点击头像 → Settings → Model Providers → 选择 OpenAI Compatible → 填写 Base URL 与 API Key → 点击 Save。保存时 Langflow 会调用上面第 3.3 节的校验函数探测 /v1/models,发现的模型随即出现在 Language ModelsEmbedding Models 分组中;启用所需模型后,即可在任何 Language Model、Embedding Model 或 Agent 字段中选择 OpenAI Compatible 及具体模型。

4.2 单端点限制与并发方案

该供应商一次只持有一个端点。如需同时接入第二个自定义端点,README 建议组合使用内置 OpenAI 供应商的 Base URL 覆盖能力,或 vLLM 供应商 Bundle(lfx-vllm)。

4.3 本地/内网端点的 SSRF 防护

Langflow 默认开启 SSRF 防护,回环与私有地址(localhost127.0.0.1::1 等)会被阻断。在保存 http://localhost:8000/v1 之类的 Base URL 之前,需要将该主机加入白名单:

export LANGFLOW_SSRF_ALLOWED_HOSTS=localhost

也可以白名单化 IP 或 CIDR 段,如 127.0.0.110.0.0.0/8。从测试用例看(test_fetch_allows_literal_loopback_by_default / test_fetch_blocks_literal_loopback_when_connector_policy_opts_out),字面回环地址是否放行受 LANGFLOW_SSRF_PROTECTION_ENABLEDLANGFLOW_CONNECTOR_SSRF_VALIDATION_ENABLEDLANGFLOW_CONNECTOR_SSRF_ALLOW_LOOPBACK 这组环境变量控制——默认允许字面回环,但策略显式关闭时直接拦截,且不会发出任何网络请求。

4.4 安装

pip install lfx-openai-compatible

该 Bundle 通过 langflow.extensions entry-point 自动注册;安装后重启 Langflow 服务,即可在任意 Language Model 或 Embedding Model 字段中选中 OpenAI Compatible。另外,据 官方文档 说明,该供应商也随 uv pip install langflow 自动安装,无需单独安装。

五、包结构与开发流程

5.1 打包约定

pyproject.toml 中的关键设计:

  • 依赖极简:仅 lfx>=1.12.0.dev0,<2.0.0httpx>=0.24.0,<1.0.0。注释说明 ChatOpenAI / OpenAIEmbeddings 由 lfx 提供并延迟解析,Bundle 本身不直接导入它们,因此不必重复声明 langchain-openai 依赖;httpx 支撑 SSRF 安全、DNS 固定的实时发现与凭据校验探测。

  • entry-point 注册

    [project.entry-points."langflow.extensions"]
    lfx-openai-compatible = "lfx_openai_compatible"
    

    运行时 Langflow loader 通过该入口发现 extension.json(manifest-shipping 分布通过 importlib.metadata.files(dist) 定位清单;editable 安装则回退到该 entry-point)。

  • wheel 内容extension.jsondiscovery.py 都放在 src/lfx_openai_compatible 包内,确保 registry 能按点分路径导入发现/校验函数。

5.2 本地开发

cd src/bundles/openai-compatible
pip install -e .
lfx extension validate src/lfx_openai_compatible

lfx extension validate 用于校验清单合法性;该 lfx 版本下限(1.11 起提供 provider-registry 接缝)由 scripts/ci/sync_bundle_lfx_pin.pymake patch 时同步。

5.3 测试覆盖

测试文件 覆盖三类关键行为,可作为二次开发时的验收清单:

  • 端到端注册test_bundle_registers_provider_end_to_end):通过 load_extension 加载后断言 provider_registry.is_registered("OpenAI Compatible")、无组件(result.components == [])、API Key 可选、live 发现与校验函数均已解析,且该供应商出现在 get_live_only_providers() 中——即未配置时也会进入 Model Providers 对话框供用户配置;
  • 发现函数:空 Base URL、OpenAI dict / 纯列表两种负载、/v1 去重、Bearer 头转发、无 Key 时不发 Authorization 头、连接错误与坏负载的静默降级、embedding 上下文的 tool_calling=False 标记;
  • 校验函数:缺 URL、401/403、500、连接错误、超时各自的错误信息,以及 SSRF 回环策略与重定向阻断。

六、适用前提与小结

该 Bundle 的适用前提:lfx 1.11+(provider-registry 接缝所在的版本线)、Python >=3.10,<3.15;端点必须遵循 OpenAI HTTP API 形态(至少提供 /v1/models 列表接口)。其设计要点可以概括为:以 extension.jsonproviders[] 块声明式注册供应商,复用 ChatOpenAI/OpenAIEmbeddings 保证行为一致性,用点分路径延迟注入实时发现与校验钩子,并以"发现静默降级 + 校验显式报错 + SSRF 安全请求"三件套兼顾易用性与安全性。对需要在 Langflow 中接入 OpenRouter、Groq 等第三方聚合端点或自托管推理服务的场景,这就是无需改动任何核心代码的标准接入路径。

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