Communitygithub.com

gdevenyi/openwebui-tool-skill

用於編寫與驗證 Open WebUI Python 工具的 Agent 技能

openwebui-tool-skill 是什麼?

此技能專門協助開發者建立與驗證 Open WebUI 的 Python 工具。Open WebUI 的工具本質上是一個單一的 Python 檔案,其中的 `Tools` 類別中的每個公開方法都會成為可供模型呼叫的函式;而每個方法的 docstring 則作為該函式的描述與參數說明,直接影響模型的呼叫行為。技能詳細說明了工具檔案的必備結構——包括 YAML frontmatter、`Valves` 設定類別、`__init__` 初始化方式以及非同步方法定義——並強調了許多容易被忽略的關鍵規則,例如:docstring 第一行必須是 `"""`、輔助方法需以底線前綴隱藏、僅支援 reST 風格的參數文件、和每個注入的 `__dunder__` 參數必須有預設值。此外,技能還提供了標準的驗證腳本 `scripts/check_tool.py` 來模擬伺服器的載入與規格生成流程,確保工具表面(tool surface)僅包含開發者預期被模型呼叫的函式。此技能主要針對 Open WebUI 平台,並適用於任何需要與該平台互動的 AI 代理或開發環境。

相容平台~Claude Code~Codex CLI~Cursor
npx skills add gdevenyi/openwebui-tool-skill

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

Open WebUI Python 工具

一個工具就是一個 Python 檔案。Open WebUI 會 exec 該檔案,實例化 Tools(),並將每個公開方法轉換為模型可呼叫的函式。這組公開方法就是工具的表面 (surface)——你忘了加上 _ 前綴的輔助函式,就會變成模型可以呼叫的函式。

Docstring 不是註解。它的第一個區塊會變成傳送給模型的函式描述,而每一行 :param name: 則會變成參數描述。Docstring 就是提示詞。

檔案範例

"""
title: Package Lookup
author: you
description: Look up a package on PyPI
requirements: httpx
version: 0.1.0
licence: MIT
"""

import json
from typing import Any, Callable, Optional

import httpx
from pydantic import BaseModel, Field


class Tools:
    class Valves(BaseModel):
        base_url: str = Field(
            default="https://pypi.org/pypi",
            description="PyPI JSON API 根路徑",
        )

    class UserValves(BaseModel):
        include_yanked: bool = Field(default=False, description="包含已棄用的發行版")

    def __init__(self):
        self.valves = self.Valves()

    async def get_package(
        self,
        name: str,
        version: Optional[str] = None,
        __user__: Optional[dict] = None,
        __event_emitter__: Optional[Callable[[dict], Any]] = None,
    ) -> str:
        """
        查詢 PyPI 上的 Python 套件並回傳其後設資料。

        :param name: 套件名稱,例如 `httpx`
        :param version: 特定版本;省略則取得最新版本
        :return: 包含摘要、最新版本、首頁與授權的 JSON
        """
        if __event_emitter__:
            await __event_emitter__(
                {"type": "status", "data": {"description": f"正在擷取 {name}...", "done": False}}
            )

        try:
            data = await self._fetch(name, version)
        except httpx.HTTPStatusError as e:
            return f"PyPI 針對套件 '{name}' 回傳了狀態碼 {e.response.status_code}。"
        except Exception as e:
            return f"無法連線至 PyPI:{e}"

        info = data.get("info", {})
        return json.dumps(
            {"name": info.get("name"), "version": info.get("version"), "summary": info.get("summary")},
            ensure_ascii=False,
        )

    async def _fetch(self, name: str, version: Optional[str]) -> dict:
        path = f"{name}/{version}/json" if version else f"{name}/json"
        async with httpx.AsyncClient(timeout=15) as client:
            response = await client.get(f"{self.valves.base_url}/{path}")
            response.raise_for_status()
            return response.json()

那個檔案會為模型產生完全符合以下的規格——檔案中的其他任何內容都無法被觸及:

{"name": "get_package",
 "description": "查詢 PyPI 上的 Python 套件並回傳其後設資料。",
 "parameters": {"type": "object", "required": ["name"], "properties": {
   "name": {"type": "string", "description": "套件名稱,例如 `httpx`"},
   "version": {"type": "string", "description": "特定版本;省略則取得最新版本"}}}}

骨架無法呈現的規則

  • 第 1 行必須剛好是 """。 註解、匯入陳述或空行都會讓整個 frontmatter 變得不可見——此時 requirements 永遠不會被安裝,而且靜默失敗。
  • 使用前導 _ 讓輔助函式遠離表面。 其他所有 Tools 上的公開內容——包括任何繼承而來的——都是模型可以呼叫的函式。
  • 僅使用 reST 風格的 docstring。 :param name: text 才能傳遞給模型;Google 風格的 Args: 區塊則完全無效。
  • 對每個模型可見的參數加上型別提示。 型別提示會產生 JSON Schema。型別提示必須在匯入時就能解析;無法解析的標註會直接導致工具儲存失敗。
  • 為每個注入的 __dunder__ 參數提供預設值。 Open WebUI 只在有該參數的地方才提供值,而模型永遠看不到它們——它們會從 schema 中被移除。
  • __init__ 不接受任何引數,並設定 self.valves = self.Valves()。 沒有這行程式碼,管理員設定的 valve 值就會被丟棄。
  • 每個方法都必須是 async def。 同步方法會在事件迴圈中內聯執行,並阻塞伺服器;請透過 await asyncio.to_thread(...) 將阻塞性工作推出去。
  • 回傳一個字串(dict 或 list 會自動幫你轉成 JSON)。回傳一個可讀的錯誤訊息,而不是拋出例外——拋出的例外會以其原始的 str() 形式傳遞給模型。
  • 進度透過 status 事件傳遞;答案透過回傳值傳遞。 四個內容事件(message, chat:message, chat:message:delta, replace)在原生模式(唯一支援的模式)下會被完成快照覆寫。

驗證

python scripts/check_tool.py mytool.py

該腳本僅使用標準函式庫,但它會執行工具檔案,因此工具自身的匯入必須能成功解析——對於上面的檔案,請使用 uv run --with httpx --with pydantic python scripts/check_tool.py mytool.py。

它會複製伺服器的載入與規格生成流程。兩個條件都必須成立:程式能正常退出,並且在印出的工具表面中的每個名稱都是你預期模型呼叫的。

然後將檔案貼到 Workspace > Tools。工具 ID 是在那裡設定的,而不是在檔案中,且必須是小寫的 Python 識別字。

參考資料

請參閱 references/REFERENCE.md 以取得完整的注入參數列表、事件發射器目錄(status, citation, notification, confirmation, input, 檔案)、閥值輸入類型(密碼、下拉選單、多選、動態選項)、回傳檔案或內嵌 HTML,以及那些不再有任何作用的繼承旗標。

相關技能