🚰 Pipe 函数:创建自定义“代理/模型”
欢迎阅读 Open WebUI Pipes 创建指南!你可以将 Pipes 想象成向 Open WebUI 添加新模型的一种方式。在本文档中,我们将详细介绍什么是 Pipe、它是如何工作的,以及如何创建自己的 Pipe 来为 Open WebUI 模型添加自定义逻辑和处理。我们将使用清晰的比喻并深入每一个细节,以确保你有一个全面的理解。
Pipe 简介
想象 Open WebUI 是一个供水系统,数据在管道和阀门中流动。在这个类比中:
- Pipes (管道) 就像插件,让你引入新的数据流动路径,允许你注入自定义逻辑和处理。
- Valves (配置阀门) 是管道中可配置的部分,用于控制数据如何流过它。
通过创建一个 Pipe,你实际上是在 Open WebUI 框架内构建一个具有特定行为的自定义模型。
理解 Pipe 结构
让我们从一个基本的 Pipe 骨架开始,以了解其结构:
from pydantic import BaseModel, Field
class Pipe:
class Valves(BaseModel):
MODEL_ID: str = Field(default="")
def __init__(self):
self.valves = self.Valves()
def pipe(self, body: dict):
# 逻辑写在这里
print(self.valves, body) # 这将打印配置选项和输入的 body
return "Hello, World!"
Pipe 类
- 定义:
Pipe类是你定义自定义逻辑的地方。 - 用途:作为插件的蓝图,决定它在 Open WebUI 中的行为方式。
Valves:配置你的 Pipe
- 定义:
Valves是Pipe内部的一个嵌套类,继承自BaseModel。 - 用途:它包含在 Pipe 使用过程中持久化的配置选项(参数)。
- 示例:在上面的代码中,
MODEL_ID是一个默认值为空字符串的配置选项。
比喻:将 Valves 想象成现实世界管道系统上的旋钮,用于控制水流。在你的 Pipe 中,Valves 允许用户调整影响数据流动和处理方式的设置。
__init__ 方法
- 定义:
Pipe类的构造方法。 - 用途:初始化 Pipe 的状态并设置任何必要的组件。
- 最佳实践:保持简单;主要在这里初始化
self.valves。
def __init__(self):
self.valves = self.Valves()
pipe 函数
- 定义:核心函数,你的自定义逻辑所在之处。
- 参数:
body:包含输入数据的字典。
- 用途:使用自定义逻辑处理输入数据并返回结果。
def pipe(self, body: dict):
# 逻辑写在这里
print(self.valves, body) # 这将打印配置选项和输入的 body
return "Hello, World!"
注意:始终将 Valves 放在 Pipe 类的顶部,然后是 __init__,最后是 pipe 函数。这种结构确保了清晰度和一致性。
使用 Pipes 创建多个模型
如果 你想让你的 Pipe 在 Open WebUI 中创建多个模型怎么办?你可以通过在 Pipe 类中定义一个 pipes 函数或变量来实现。这种设置非正式地被称为 manifold (歧管),允许你的 Pipe 代表多个模型。
以下是实现方法:
from pydantic import BaseModel, Field
class Pipe:
class Valves(BaseModel):
MODEL_ID: str = Field(default="")
def __init__(self):
self.valves = self.Valves()
def pipes(self):
return [
{"id": "model_id_1", "name": "model_1"},
{"id": "model_id_2", "name": "model_2"},
{"id": "model_id_3", "name": "model_3"},
]
def pipe(self, body: dict):
# 逻辑写在这里
print(self.valves, body) # 打印配置选项和输入的 body
model = body.get("model", "")
return f"{model}: Hello, World!"
解释
-
pipes函数:- 返回一个字典列表。
- 每个字典代表一个具有唯一
id和name键的模型。 - 这些模型将分别显示在 Open WebUI 模型选择器中。
-
更新后的
pipe函数:- 根据选择的模型处理输入。
- 在本例中,它在返回的字符串中包含了模型名称。
示例:OpenAI 代理 Pipe (Proxy Pipe)
让我们深入研究一个实际示例,我们将创建一个将请求代理到 OpenAI API 的 Pipe。此 Pipe 将从 OpenAI 获取可用模型,并允许用户通过 Open WebUI 与它们进行交互。
from pydantic import BaseModel, Field
import requests
class Pipe:
class Valves(BaseModel):
NAME_PREFIX: str = Field(
default="OPENAI/",
description="添加到模型名称前的前缀。",
)
OPENAI_API_BASE_URL: str = Field(
default="https://api.openai.com/v1",
description="访问 OpenAI API 端点的基础 URL。",
)
OPENAI_API_KEY: str = Field(
default="",
description="用于验证 OpenAI API 请求的 API 密钥。",
)
def __init__(self):
self.valves = self.Valves()
def pipes(self):
if self.valves.OPENAI_API_KEY:
try:
headers = {
"Authorization": f"Bearer {self.valves.OPENAI_API_KEY}",
"Content-Type": "application/json",
}
r = requests.get(
f"{self.valves.OPENAI_API_BASE_URL}/models", headers=headers
)
models = r.json()
return [
{
"id": model["id"],
"name": f'{self.valves.NAME_PREFIX}{model.get("name", model["id"])}',
}
for model in models["data"]
if "gpt" in model["id"]
]
except Exception as e:
return [
{
"id": "error",
"name": "获取模型出错。请检查您的 API 密钥。",
},
]
else:
return [
{
"id": "error",
"name": "未提供 API 密钥。",
},
]
def pipe(self, body: dict, __user__: dict):
print(f"pipe:{__name__}")
headers = {
"Authorization": f"Bearer {self.valves.OPENAI_API_KEY}",
"Content-Type": "application/json",
}
# 从模型名称中提取模型 id
model_id = body["model"][body["model"].find(".") + 1 :]
# 更新 body 中的模型 id
payload = {**body, "model": model_id}
try:
r = requests.post(
url=f"{self.valves.OPENAI_API_BASE_URL}/chat/completions",
json=payload,
headers=headers,
stream=True,
)
r.raise_for_status()
if body.get("stream", False):
return r.iter_lines()
else:
return r.json()
except Exception as e:
return f"Error: {e}"
详细解析
Valves 配置
NAME_PREFIX:- 为 Open WebUI 中显示的模型名称添加前缀。
- 默认值:
"OPENAI/"。
OPENAI_API_BASE_URL:- 指定 OpenAI API 的基础 URL。
- 默认值:
"https://api.openai.com/v1"。
OPENAI_API_KEY:- 你的 OpenAI API 密钥,用于身份验证。
- 默认值:
""(空字符串;必须提供)。
pipes 函数
-
用途:获取可用的 OpenAI 模型并使其在 Open WebUI 中可访问。
-
过程:
- 检查 API 密钥:确保提供了 API 密钥。
- 获取模型:向 OpenAI API 发送 GET 请求以检索可用模型。
- 过滤模型:返回
id中包含"gpt"的模型。 - 错误处理:如果出现问题,返回错误消息。
-
返回格式:包含每个模型
id和name的字典列表。
pipe 函数
-
用途:处理对所选 OpenAI 模型的请求并返回响应。
-
参数:
body:包含请求数据。__user__:包含用户信息(在本例中未使用,但对于身份验证或日志记录很有用)。
-
过程:
- 准备请求头:设置包含 API 密钥和内容类型的请求头。
- 提取模型 ID:从所选模型名称中提取实际的模型 ID。
- 准备 Payload:使用正确的模型 ID 更新 body。
- 发起 API 请求