ð° ãã€ã颿°: ã«ã¹ã¿ã ããšãŒãžã§ã³ã/ã¢ãã«ããäœæãã
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) # ããã«ããèšå®ãªãã·ã§ã³ãšå
¥åããã£ãåºåãããŸã
return "ããã«ã¡ã¯ãäžçïŒ"
Pipeã¯ã©ã¹â
- å®çŸ©:
Pipe
ã¯ã©ã¹ã¯ã«ã¹ã¿ã ããžãã¯ãå®çŸ©ããå Žæã§ãã - ç®ç: ãã©ã°ã€ã³ã®èšèšå³ãšããŠæ©èœããOpen WebUIå ã§ã®æåãæ±ºå®ããŸãã
Valves: ãã€ãã®èšå®â
- å®çŸ©:
Valves
ã¯Pipe
å ã®ãã¹ããããã¯ã©ã¹ã§ãBaseModel
ãç¶æ¿ããŠããŸãã - ç®ç: ãã€ãã®äœ¿çšäžã«æ ç¶ããèšå®ãªãã·ã§ã³ïŒãã©ã¡ãŒã¿ïŒãå«ã¿ãŸãã
- äŸ: äžèšã®ã³ãŒãã§ã¯ã
MODEL_ID
ã¯ããã©ã«ãå€ã空æååã®èšå®ãªãã·ã§ã³ã§ãã
æ¯å©: Valvesã¯çŸå®äžçã®é 管ã·ã¹ãã ã«ãããæ°Žã®æµããå¶åŸ¡ããããã®ãããªãã®ã§ããPipeå ã§ã¯ValvesãããŒã¿ã®æµããšåŠçã«åœ±é¿ãäžããèšå®ã調æŽã§ããããã«ããŸãã
__init__
ã¡ãœããâ
- å®çŸ©:
Pipe
ã¯ã©ã¹ã®ã³ã³ã¹ãã©ã¯ã¿ã¡ãœããã§ãã - ç®ç: ãã€ãã®ç¶æ ãåæåããå¿ èŠãªã³ã³ããŒãã³ããèšå®ããŸãã
- ãã¹ããã©ã¯ãã£ã¹: ã·ã³ãã«ã«ä¿ã¡ãäž»ã«
self.valves
ã®åæåã®ã¿è¡ããŸãã
def __init__(self):
self.valves = self.Valves()
pipe
颿°â
- å®çŸ©: ã«ã¹ã¿ã ããžãã¯ãååšããã³ã¢é¢æ°ã§ãã
- ãã©ã¡ãŒã¿:
body
: å ¥åããŒã¿ãå«ãèŸæžã
- ç®ç: ã«ã¹ã¿ã ããžãã¯ã䜿çšããŠå ¥åããŒã¿ãåŠçããçµæãè¿ããŸãã
def pipe(self, body: dict):
# ããžãã¯ãããã«å
¥ã
print(self.valves, body) # èšå®ãªãã·ã§ã³ãšå
¥åããã£ãåºåããŸã
return "ããã«ã¡ã¯ãäžçïŒ"
泚æ: 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) # èšå®ãªãã·ã§ã³ãšå
¥åããã£ãåºåããŸã
model = body.get("model", "")
return f"{model}: ããã«ã¡ã¯ãäžçïŒ"
解説â
-
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}"
詳现ãªåæâ
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ãæœåºããŸãã
- ãã€ããŒãã®æºå: æ£ããã¢ãã«IDã䜿çšããŠbodyãæŽæ°ããŸãã
- APIãªã¯ãšã¹ãã®éä¿¡: OpenAI APIã®ãã£ããå®äºãšã³ããã€ã³ãã«POSTãªã¯ãšã¹ããéä¿¡ããŸãã
- ã¹ããªãŒãã³ã°ã®åŠç:
stream
ãTrue
ã®å Žåãè¡ã®ã€ãã©ãã«ãè¿ããŸãã - ãšã©ãŒãã³ããªã³ã°: äŸå€ããã£ããããŠãšã©ãŒã¡ãã»ãŒãžãè¿ããŸãã
Proxy Pipeã®æ¡åŒµâ
AnthropicãPerplexityãªã©ã®è¿œå ã®ãµãŒãã¹ãããã€ããŒããµããŒãããããã«ããã®Proxy Pipeãä¿®æ£ã§ããŸããããã«ã¯APIãšã³ããã€ã³ããããããpipes
ããã³pipe
颿°å
ã®ããžãã¯èª¿æŽãå«ãŸããŸãã
å éšOpen WebUI颿°ã®äœ¿çšâ
ææãPipeå
ã§Open WebUIã®å
éšé¢æ°ãå©çšãããå ŽåããããŸãããããã®é¢æ°ã¯open_webui
ããã±ãŒãžããçŽæ¥ã€ã³ããŒãããããšãã§ããŸãããã ããæé©åã®ããã«å
éšé¢æ°ã¯å€æŽãããå¯èœæ§ãäœãã§ãããå¿
ãææ°ã®ããã¥ã¡ã³ããåç
§ããŠãã ããã
以äžã®ããã«ããŠå éšOpen WebUI颿°ã䜿çšã§ããŸã:
from pydantic import BaseModel, Field
from fastapi import Request
from open_webui.models.users import Users
from open_webui.utils.chat import generate_chat_completion
class Pipe:
def __init__(self):
pass
async def pipe(
self,
body: dict,
__user__: dict,
__request__: Request,
) -> str:
# æŽæ°ããã眲åã§çµ±äžããããšã³ããã€ã³ãã䜿çšãã
user = Users.get_user_by_id(__user__["id"])
body["model"] = "llama3.2:latest"
return await generate_chat_completion(__request__, body, user)