Spre deosebire de Tools, pe care le apelează modelul, Functions schimbă comportamentul Open WebUI. Tipul se deduce din numele clasei de la nivelul superior al fișierului: Pipe, Filter, Action sau Event. Se creează sau se importă în Admin Panel > Functions, doar de administratori; codul este salvat în baza de date, încărcat la rulare și executat pe server. Setările configurabile stau în clasa Valves.
Pipe apare în selector ca un model nou: metoda pipe(body) tratează cererea (un furnizor cu API propriu, un agent, un router). Dacă definește și pipes(), care întoarce o listă de {"id": ..., "name": ...}, un singur Pipe expune mai multe modele (un „manifold”). Filter are inlet() înainte de model, request() pentru fiecare apel de model, stream() pentru fragmentele transmise în flux și outlet() după răspuns; poate fi global sau atașat anumitor modele, iar cu self.toggle = True utilizatorul îl pornește per chat. Action adaugă un buton în bara mesajului, cu metoda action(). Event (din v0.10.0) primește în event() evenimente de sistem, de exemplu înregistrarea unui utilizator sau ștergerea unui chat.
Backend-ul este asincron, iar codul sincron al pluginurilor rulează într-un pool de fire, deci și lucrările lungi pot rula în proces. Pentru GPU, dependențe grele sau izolare, documentația recomandă un serviciu extern expus ca server OpenAPI sau MCP. Vechiul server separat Pipelines face lucruri asemănătoare, dar README-ul lui recomandă Functions pentru furnizori și filtre obișnuite. O Function are acces la tot serverul: importă doar cod citit și înțeles.
Concepte cheie și caracteristici
| Concept / Parametru | Descriere practică |
|---|---|
class Pipe / pipe(body) |
Model nou în selector; întoarce un text sau un flux de text. |
pipes() |
Listă de modele expuse de același Pipe (manifold). |
class Filter / inlet(body) |
Modifică cererea înainte de model (context, anonimizare, limite). |
request(body) |
Rulează la fiecare apel de model, inclusiv la cele dintre apelurile de unelte; trebuie scris idempotent. |
stream(event) / outlet(body) |
Interceptează fragmentele transmise în flux, respectiv răspunsul complet. |
self.toggle = True |
Filtrul devine comutabil de utilizator în chat. |
Valves.priority |
Filtrele se sortează după această valoare; la Action, o valoare mai mică pune butonul mai în față. |
class Action / action(body) |
Buton pe mesaj; poate folosi __event_emitter__ și __event_call__ pentru stări și dialoguri. |
class Event / event() |
Reacționează la evenimentele de sistem; poate înregistra endpointuri proprii. |
Global |
Din lista Functions, un filtru sau o acțiune pot fi activate pentru toate modelele. |
Exemple practice și scenarii reale
Exemplul 1: Filter care adaugă o instrucțiune de sistem
Verifică dacă instrucțiunea există deja, ca să nu o adauge de două ori. Testat local cu pydantic, în afara Open WebUI.
from pydantic import BaseModel, Field
class Filter:
class Valves(BaseModel):
priority: int = Field(default=0)
instructiune: str = Field(default="Răspunde în limba română.")
def __init__(self):
self.valves = self.Valves()
async def inlet(self, body: dict) -> dict:
mesaje = body.setdefault("messages", [])
deja = any(
m.get("role") == "system" and self.valves.instructiune in str(m.get("content", ""))
for m in mesaje
)
if not deja:
mesaje.insert(0, {"role": "system", "content": self.valves.instructiune})
return body
Exemplul 2: Pipe cu mai multe modele (manifold)
Structura din ghidul oficial pentru Pipe; fiecare intrare din pipes() apare separat în selector, iar body["model"] spune care a fost ales.
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": "rapid", "name": "Asistent rapid"},
{"id": "detaliat", "name": "Asistent detaliat"},
]
async def pipe(self, body: dict):
model = body.get("model", "")
return f"{model}: răspuns generat de Pipe"
Exemplul 3: Action care afișează o stare și o notificare
from pydantic import BaseModel
class Action:
class Valves(BaseModel):
priority: int = 0
def __init__(self):
self.valves = self.Valves()
async def action(self, body: dict, __event_emitter__=None):
await __event_emitter__({"type": "status", "data": {"description": "Se procesează...", "done": False}})
await __event_emitter__({"type": "notification", "data": {"type": "info", "content": "Gata"}})
await __event_emitter__({"type": "status", "data": {"description": "Terminat", "done": True}})
Greșeli frecvente și capcane
- Scrii un Pipe când ai nevoie ca modelul să apeleze o funcție. Un Pipe înlocuiește modelul; pentru o funcție apelată de model se scrie un Tool.
- Instalezi un filtru și nu îl activezi global sau pe niciun model: nu rulează nicăieri.
- Scrii
request()neidempotent (de exemplu inserezi mereu un mesaj de sistem). Rulează la fiecare apel de model, deci un răspuns cu trei apeluri de unelte primește instrucțiunea de patru ori.
Întrebări & Exemple practice:
Functions: Pipe, Filter, Action și EventAi o întrebare despre Functions: Pipe, Filter, Action și Event sau ai descoperit un truc, prompt sau fragment de cod util? Distribuie-l cu ceilalți membri ai comunității!
Fii primul care pune o întrebare sau distribuie un fragment de cod / prompt!
Nu au fost adăugate încă întrebări sau resurse pentru această pagină. Dacă ai testat un prompt sau ai un snippet util, adaugă-l mai jos pentru comunitate.