🪄 篩選功能:修改輸入與輸出
歡迎來到 Open WebUI 關於篩選功能的詳盡指南!篩選器是一種靈活且功能強大的插件系統,可用於在數據發送到大型語言模型 (LLM) 前(輸入)或從LLM返回後(輸出)進行修改。無論是調整輸入以獲得更好的上下文,還是清理輸出以提高清晰度,篩選功能都能滿足您的需求。
本指南將詳細介紹篩選器的定義、運作方式、結構,以及您需要了解的一切以打造強大且易於使用的篩選器。我們現在就開始吧,別擔心——我會使用比喻、範例和提示來讓一切一目了然!🌟
🌊 在 Open WebUI 中,什麼是篩選器?
想像一下 Open WebUI 是一條通過管道流動的水流:
- 用戶輸入和LLM輸出是流水。
- 篩選器是水處理階段,它在水到達最終目的地之前進行清理、修改和調整。
篩選器位於數據流的中間——就像檢查站——您可以在這裡決定需要調整什麼。
以下是篩選器的作用簡要概述:
- 修改用戶輸入(入口函數):在數據到達AI模型之前,調整輸入數據。在這裡,您可以提高清晰度、增加上下文、淨化文本或重新格式化消息以符合特定要求。
- 攔截模型輸出(流函數):在模型生成過程中捕獲並調整AI的響應。這對於實時修改非常有用,比如過濾敏感信息或格式化輸出以提高可讀性。
- 修改模型輸出(出口函數):在AI的響應處理完成後,展示給用戶之前進行調整。這有助於改進、記錄或調整數據,以提高用戶體驗。
**關鍵概念:**篩選器不是獨立的模型,而是改進或轉換在模型之間傳遞的數據的工具。
篩選器就像AI工作流程中的翻譯或編輯器:您可以攔截並更改對話內容,而不會中斷流程。
🗺️ 篩選功能的結構:骨架
讓我們從篩選功能的最簡單表示開始。即使某些部分初看上去感覺很技術化,也別擔心——我們將逐步分解!
🦴 篩選器的基本骨架
from pydantic import BaseModel
from typing import Optional
class Filter:
# 閥門:篩選器的配置選項
class Valves(BaseModel):
pass
def __init__(self):
# 初始化閥門(篩選器的可選配置)
self.valves = self.Valves()
def inlet(self, body: dict) -> dict:
# 這裡是您操作用戶輸入的地方。
print(f"inlet called: {body}")
return body
def stream(self, event: dict) -> dict:
# 這裡是您修改模型輸出數據流的部分。
print(f"stream event: {event}")
return event
def outlet(self, body: dict) -> None:
# 這裡是您操作模型輸出的地方。
print(f"outlet called: {body}")
🆕 🧲 開關篩選器範例:增加互動性和圖示(Open WebUI 0.6.10 的新功能)
篩選器可以做的不僅僅是修改文本——它們還可以在用戶界面中顯示切換選項及自定義圖示。例如,您可能想創建一個可以通過用戶界面按鈕開啟/關閉的篩選器,並在 Open WebUI 的訊息輸入界面中顯示特殊的圖示。
以下是如何創建此類開關篩選器:
from pydantic import BaseModel, Field
from typing import Optional
class Filter:
class Valves(BaseModel):
pass
def __init__(self):
self.valves = self.Valves()
self.toggle = True # 重要:這會在 Open WebUI 創建一個切換UI界面
# 提示:使用 SVG Data URI!
self.icon = """data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9Im5vbmUiIHZpZXdCb3g9IjAgMCAyNCAyNCIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZT0iY3VycmVudENvbG9yIiBjbGFzcz0ic2l6ZS02Ij4KICA8cGF0aCBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGQ9Ik0xMiAxOHYtNS4yNW0wIDBhNi4wMSA2LjAxIDAgMCAwIDEuNS0uMTg5bS0xLjUuMTg5YTYuMDEgNi4wMSAwIDAgMS0xLjUtLjE4OW0zLjc1IDcuNDc4YTEyLjA2IDEyLjA2IDAgMCAxLTQuNSAwbTMuNzUgMi4zODNhMTQuNDA2IDE0LjQwNiAwIDAgMS0zIDBNMTQuMjUgMTh2LS4xOTJjMC0uOTgzLjY1OC0xLjgyMyAxLjUwOC0yLjMxNmE3LjUgNy41IDAgMSAwLTcuNTE3IDBjLjg1LjQ5MyAxLjUwOSAxLjMzMyAxLjUwOSAyLjMxNlYxOCIgLz4KPC9zdmc+Cg=="""
pass
async def inlet(
self, body: dict, __event_emitter__, __user__: Optional[dict] = None
) -> dict:
await __event_emitter__(
{
"type": "status",
"data": {
"description": "已切換!",
"done": True
"hidden": False,
},
}
)
return body
🖼️ 發生了什麼事?
- toggle = True 會在 Open WebUI 中建立一個開關式的使用者界面——使用者可以即時手動開啟或關閉這個過濾器。
- icon(使用資料 URI 格式)會顯示為過濾器名稱旁邊的一個小圖示。只要是 Data URI 編碼的 SVG 都可以使用!
inlet
函數 使用特別的__event_emitter__
參數將反饋/狀態廣播到界面,例如一個小的通知告知 "已切換!"
你可以用這些機制讓你的過濾器在 Open WebUI 的插件生態系統中變得更具動態性、互動性以及視覺獨特性。
🎯 核心元件解析
1️⃣ Valves
類別(可選設定)
將 Valves 想像成你的過濾器的旋鈕和滑塊。如果你希望使用者能設置以調整過濾器的行為,可以在這裡定義這些選項。
class Valves(BaseModel):
OPTION_NAME: str = "預設值"
例如:
如果你設計了能將回應轉換為大寫的過濾器,你可以允許使用者通過 TRANSFORM_UPPERCASE: bool = True/False
這樣的選項來配置是否將輸出完全轉換為大寫。
2️⃣ inlet
函數(輸入預處理)
inlet
函數就像是 在烹煮食物前的準備工作。想像你是位廚師:在材料進入食譜(在這裡是 LLM)之前,你可能會洗菜、切洋蔥、或者調味。不經過這個步驟,你的成品可能會缺乏風味、有髒的食材、或者不夠一致。
在 Open WebUI 的世界中,inlet
函數會在 使用者輸入 傳送到模型前完成重要的準備工作,確保輸入被清理、具備上下文並對 AI 更友好。
📥 輸入:
body
:來自 Open WebUI 遞交到模型的原始輸入,一般是一個聊天完成請求(通常是一個字典,包含會話消息、模型設定以及其他元數據)。這些就是你的食譜材料。
🚀 你的任務:
修改並返回 body
。被修改後的 body
就是 LLM 處理的對象,因此你可以利用這個機會增加明確性、結構性和上下文。
🍳 為什麼使用 inlet
?
-
新增上下文:自動為使用者輸入附加重要的信息,尤其是當文字模糊或不完整時。例如,你可以加上 "你是一個友好的助手" 或 "幫助這位使用者排查一個軟體錯誤。"
-
格式化數據:如果輸入需要特定格式,例如 JSON 或 Markdown,你可以在發送到模型之前轉換它。
-
輸入清理:移除不需要的字符,刪除可能有害或混淆的符號(如多餘的空白或表情符號),或者替代敏感信息。
-
精簡使用者輸入:如果模型的輸出能在額外指導下改善,可以使用
inlet
自動添加清晰的指示!
💡 使用範例:基於食物準備的案例
🥗 範例 1:添加系統上下文
假設 LLM 是一位廚師負責準備義大利美食,但使用 者並未提到 "這是為了義大利烹飪"。你可以確保信息的清晰性,在傳送數據到模型前添加這個上下文。
def inlet(self, body: dict, __user__: Optional[dict] = None) -> dict:
# 添加系統消息為會話設置義大利上下文
context_message = {
"role": "system",
"content": "你正幫助使用者準備義大利美食。"
}
# 將上下文插入到聊天記錄的開頭
body.setdefault("messages", []).insert(0, context_message)
return body
📖 會發生什麼?
- 任何使用者輸入如 "有哪些好的晚餐建議?" 現在都將帶有義大利風格主題,因為我們設置了系統上下文!麵條可能會出現作為答案,但芝士蛋糕就不太可能。