Communitygithub.com

Open WebUI Pythonツールスキル

Open WebUI用のPythonツールを作成・検証するためのエージェントスキルです。

Open WebUI Pythonツールスキル とは?

このスキルは、Open WebUIプラットフォームで動作するPythonツールを記述・検証するための包括的なガイドです。基本的なルールとして、ツールは1つのPythonファイルで構成され、Open WebUIがファイルをexecしてTools()クラスをインスタンス化し、すべての公開メソッドをモデルが呼び出せる関数として公開します。docstringは単なるコメントではなく、関数の説明やパラメータ記述としてモデルに直接渡されるプロンプトとして機能します。具体的な実装例としてPyPIパッケージ検索ツールが提供されており、`requirements`による依存関係の指定、`Valves`による設定値の管理、`__event_emitter__`による進捗報告など、Open WebUI固有の機能を活用する方法が示されています。また、`scripts/check_tool.py`による検証スクリプトを使ったテスト方法や、アンダースコア接頭辞による公開面の制御、reST形式のdocstringの強制、型ヒントの必要性など、実際の開発で陥りがちな落とし穴を避けるための重要なルールも詳細に解説されています。

対応~Claude Code~Codex CLI~Cursor
npx skills add gdevenyi/openwebui-tool-skill

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

Open WebUI Pythonツール

ツールは1つのPythonファイルです。Open WebUIはファイルをexecし、Tools()をインスタンス化して、すべての公開メソッドをモデルが呼び出せる関数に変換します。この公開メソッドの集合がツールの表面(surface)です——_を接頭辞として付け忘れたヘルパーは、モデルが呼び出す関数になってしまいます。

docstringは単なるコメントではありません。最初のブロックがモデルに送られる関数説明となり、各:param name:行がパラメータ説明になります。docstringこそがプロンプトです。

ファイル

"""
title: Package Lookup
author: you
description: 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="yankedリリースを含める")

    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行目は正確に"""であること。 コメントやインポート、空行が上にあるとフロントマター全体が見えなくなり——requirementsがインストールされず、警告も出ません。
  • ヘルパーは先頭に_を付けて公開面に出さない。 Tools上のその他すべての公開要素(継承されたものも含む)は、モデルが呼び出せる関数となります。
  • reST形式のdocstringのみ使用可能。 :param name: テキストはモデルに届きますが、GoogleスタイルのArgs:ブロックは何も届きません。
  • モデル向けの全パラメータに型ヒントを付ける。 型ヒントからJSONスキーマが生成されます。型ヒントはインポート時に解決可能でなければならず、解決できないアノテーションはツールの保存に失敗します。
  • 注入される__dunder__パラメータにはすべてデフォルト値を設定する。 Open WebUIは利用可能な場合のみこれらを提供し、モデルからは見えません——スキーマからは除去されます。
  • __init__は引数を取らず、self.valves = self.Valves()を設定する。 この行がないと、管理者が設定したバルブ値は無視されます。
  • すべてのメソッドはasync defで定義する。 同期メソッドはイベントループ上でインライン実行され、サーバーをブロックします。ブロッキング処理はawait asyncio.to_thread(...)に委譲してください。
  • 文字列を返す(dictやlistは自動的にJSONダンプされます)。例外を発生させるのではなく、読みやすいエラーメッセージを返してください——発生した例外はそのままstr()でモデルに届きます。
  • 進捗はstatusイベントで、回答は戻り値で伝える。 4つのコンテンツイベント(message、chat:message、chat:message:delta、replace)は、ネイティブモード(唯一サポートされるモード)では補完スナップショットによって上書きされます。

検証

python scripts/check_tool.py mytool.py

このスクリプトはstdlibのみに依存しますが、ツールファイルを実行するため、ツール自身のインポートが解決可能である必要があります——上記のファイルの場合はuv run --with httpx --with pydantic python scripts/check_tool.py mytool.pyとします。

このスクリプトはサーバーの読み込みと仕様生成を再現します。2つの条件が成立する必要があります:スクリプトが正常に終了すること、そして表示されるツールの公開面のすべての名前が、モデルに呼び出させる意図を持ったものであること。

その後、ファイルをWorkspace > Toolsに貼り付けます。ツールIDはファイル内ではなくそこで設定され、小文字のPython識別子でなければなりません。

リファレンス

完全な注入パラメータ一覧、イベントエミッターカタログ(status、citation、notification、confirmation、input、ファイル)、バルブの入力タイプ(パスワード、セレクト、マルチセレクト、動的オプション)、ファイルや埋め込みHTMLの返却方法、および使用されなくなった継承フラグについては、references/REFERENCE.mdを参照してください。

関連スキル