🚰 管道函数:创建自定义"代理/模型"
欢迎来到在Open WebUI中创建管道的指南!将管道视为向Open WebUI添加新模型的方式。在本文档中,我们将分解什么是管道、它如何工作,以及如何创建自己的管道来为Open WebUI模型添加自定义逻辑和处理。我们将使用清晰的比喻并详细介绍每个细节,确保您有全面的理解。
管道简介
将Open WebUI想象为一个管道系统,数据通过管道和阀门流动。在这个类比中:
- 管道就像插件,让您引入新的数据流动路径,允许您注入自定义逻辑和处理。
- 阀门是管道的可配置部分,控制数据如何通过它流动。
通过创建管道,您本质上是在Open WebUI框架内制作具有您想要的特定行为的自定义模型。
理解管道结构
让我们从管道的基本框架版本开始理解其结构:
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
类是您定义自定义逻辑的地方。 - 目的:作为您插件的蓝图,确定它在Open WebUI中的行为方式。
阀门:配置您的管道
- 定义:
Valves
是Pipe
内的嵌套类,继承自BaseModel
。 - 目的:它包含在使用管道时持续存在的配置选项(参数)。
- 示例:在上面的代码中,
MODEL_ID
是一个配置选项,默认为空字符串。
比喻:将阀门视为真实管道系统上控制水流的旋钮。在您的管道中,阀门允许用户调整影响数据流动和处理方式的设置。
__init__
方法
- 定义:
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
函数。这种结构确保清晰和一致性。
使用管道创建多个模型
如果您想让您的管道在Open WebUI中创建多个模型怎么办?您可以通过在Pipe
类内定义pipes
函数或变量来实现这一点。这种设置,非正式地称为歧管,允许您的管道代表多个模型。
以下是您可以做到的方法:
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代理管道
让我们深入一个实际示例,我们将创建一个将请求代理到OpenAI API的管道。这个管道将从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"错误:{e}"
详细分解
阀门配置
NAME_PREFIX
:- 为在Open WebUI中显示的模型名称添加前缀。
- 默认:
"OPENAI/"
。
OPENAI_API_BASE_URL
:- 指定OpenAI API的基础URL。
- 默认:
"https://api.openai.com/v1"
。
OPENAI_API_KEY
:- 您的OpenAI API密钥用于身份验证。
- 默认:
""
(空字符串;必须提供)。