Communitygithub.com

gdevenyi/openwebui-tool-skill

编写和验证 Open WebUI Python 工具的技能

openwebui-tool-skill 是什么?

该技能指导开发者创建和验证 Open WebUI 的 Python 工具。每个工具是一个 Python 文件,Open WebUI 会执行该文件,实例化 Tools() 类,并将其所有公共方法暴露给模型调用。开发者必须严格遵循特定规则:文件第一行必须是三个双引号,保持辅助函数以下划线开头以避免暴露,仅使用 reST 风格的文档字符串,并为每个面向模型的参数添加类型提示。工具支持状态事件推送进度,最终返回字符串结果。此外,还提供了一个检查脚本 scripts/check_tool.py,用于验证工具文件的表面接口和语法正确性。该技能适用于任何支持 Open WebUI 工具的平台,通过本地脚本在开发过程中快速验证,确保工具在上传前无误。

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

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

Open WebUI Python 工具

工具是一个 Python 文件。Open WebUI 会 exec 这个文件,实例化 Tools(),并将每个公共方法转化为模型可以调用的函数。这组公共方法就是工具的表面——你忘记加 _ 前缀的辅助函数,就是模型会调用的函数。

文档字符串不是注释。它的第一个块成为发送给模型的函数描述,每一行 :param name: 成为参数描述。文档字符串就是提示词。

文件

"""
title: 包查询
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="是否包含已废弃的发布版本")

    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": "特定版本;省略则获取最新发布"}}}}

框架无法展示的规则

  • 第一行必须是三个双引号 """。 注释、导入或空行在上面会使整个前置元数据不可见——requirements 永远不会安装,静默失败。
  • 用前导 _ 保持辅助函数不出现在表面上。 Tools 上的其他所有公共内容——包括继承来的——都是模型可调用的函数。
  • 仅使用 reST 风格文档字符串。 :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、文件)、valve 输入类型(password、select、multiselect、dynamic options)、返回文件或嵌入 HTML,以及不再起作用的继承标志。

相关技能