跳到主要内容

⚙️ 工具

什么是工具?

工具是在请求时提供给大型语言模型(LLM)的 Python 脚本。这些工具使 LLM 能够执行各种操作并获取额外的信息。通常来说,您选择的 LLM 需要支持函数调用才能可靠地使用这些工具。

工具为聊天提供了多种应用场景,包括网络搜索、网页抓取以及在聊天中与 API 进行交互。

许多工具可以在 社区网站 上找到,并且可以轻松导入到您的 Open WebUI 实例中。

如何使用工具?

安装完成后,您可以通过将工具分配给任何支持函数调用的 LLM 来使用它们,然后启用这些工具。要为模型分配工具,您需要导航到工作区 => 模型。在这里,您可以选择希望启用工具的模型。

点击铅笔图标以编辑模型设置后,向下滚动到工具部分并勾选您想要启用的工具。完成后,请务必点击保存。

现在,为模型启用了工具后,您可以在与 LLM 聊天时点击“+”图标来使用各种工具。请注意,启用一个工具并不意味着它会被强制使用,而是表示 LLM 将获得调用该工具的选项。

最后,我们在社区网站上提供了一个过滤功能,允许 LLM 自动选择工具,而无需您在“+”图标菜单中手动启用:自动工具过滤器

请注意:当使用自动工具过滤器时,您仍然需要按照上述步骤为每个模型启用工具。

如何安装工具

工具的导入过程非常简单。您有两种选择:

下载并手动导入

访问社区网站:OpenWebUI 工具

  1. 点击您想导入的工具
  2. 点击页面右上角的蓝色“获取”按钮
  3. 点击“下载 JSON 导出”
  4. 您现在可以通过导航到工作区 => 工具并点击“导入工具”来上传工具到 OpenWebUI

通过 OpenWebUI URL 导入

  1. 访问社区网站:OpenWebUI 工具
  2. 点击您想导入的工具
  3. 点击页面右上角的蓝色“获取”按钮
  4. 输入您的 OpenWebUI 实例的 IP 地址并点击“导入到 WebUI”,这将自动打开您的实例并允许您导入工具。

注意:您可以安装自己的工具以及其他未在社区网站上列出的工具,使用手动导入方法。请不要导入您不了解或不信任来源的工具。运行未知代码始终存在风险。

工具能做些什么?

工具通过提供广泛的功能,使得互动对话有了多种用途,例如:

  • 网络搜索:进行实时网络搜索以获取最新信息。
  • 图像生成:根据用户提示生成图像。
  • 外部语音合成:在聊天中通过 API 请求集成外部语音合成服务 ElevenLabs 并生成基于 LLM 输出的音频。

编写自定义工具包

工具包在一个单独的 Python 文件中定义,文件顶部有包含元数据的文档字符串和一个 Tools 类。

示例顶层文档字符串

"""
标题: 字符串反转
作者: 您的名字
作者网址: https://website.com
Git 仓库地址: https://github.com/username/string-reverse.git
描述: 此工具计算字符串的逆序
所需 OpenWebUI 版本: 0.4.0
依赖项: langchain-openai, langgraph, ollama, langchain_ollama
版本: 0.4.0
许可证: MIT
"""

Tools 类

工具必须作为名为 Tools 的类中的方法定义,可选的子类包括 ValvesUserValves,例如:

class Tools:
def __init__(self):
"""初始化工具。"""
self.valves = self.Valves()
    class Valves(BaseModel):
api_key: str = Field("", description="在此填写您的 API 密钥")
    def reverse_string(self, string: str) -> str:
"""
反转输入字符串。
:param string: 要反转的字符串
"""
# 示例阀门用法
if self.valves.api_key != "42":
return "错误的 API 密钥"
return string[::-1]

类型提示

每个工具都必须为其参数添加类型提示。从 OpenWebUI 0.4.3 版本开始,类型提示也可以嵌套,如 queries_and_docs: list[tuple[str, int]]。这些类型提示用于生成发送给模型的 JSON 模式。没有类型提示的工具一致性较差。

阀门和用户阀门 - (可选,但强烈建议)

阀门和用户阀门允许用户提供动态细节,如 API 密钥或配置选项。这些将在 GUI 菜单中创建可填充字段或布尔开关。

阀门仅由管理员配置,而用户阀门则可以由任何用户配置。

示例
    # 定义阀门
class Valves(BaseModel):
priority: int = Field(
default=0, description="过滤操作的优先级级别。"
)
test_valve: int = Field(
default=4, description="控制数值的阀门"
)
pass

# 定义用户阀门
class UserValves(BaseModel):
test_user_valve: bool = Field(
default=False, description="控制 True/False(开/关)切换的用户阀门"
)
pass

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

可选参数

以下是您的工具可以依赖的一些可选参数:

  • __event_emitter__: 发送事件(参见以下部分)
  • __event_call__: 与事件发射器相同,但可用于用户交互
  • __user__: 包含用户信息的字典
  • __metadata__: 包含聊天元数据的字典
  • __messages__: 之前的聊天消息列表
  • __files__: 附加的文件
  • __model__: 模型名称

事件发射器

事件发射器用于向聊天界面添加额外信息。类似于过滤出口,事件发射器能够向聊天中追加内容。不同的是,过滤出口不能移除信息。此外,发射器可以在工具的任何阶段激活。

有两种不同类型的事件发射器:

状态

这种类型用于在执行步骤时向消息添加状态。这些状态可以在工具的任何阶段显示。状态会出现在消息内容的上方,对于那些延迟 LLM 响应或处理大量信息的工具非常有用。这样可以让用户实时了解正在处理的内容。

await __event_emitter__(
{
"type": "status", # 设置类型
"data": {"description": "显示在聊天中的消息", "done": False, "hidden": False},
# 注意 done 是 False,表示我们仍在发射状态
}
)
示例
async def test_function(
self, prompt: str, __user__: dict, __event_emitter__=None
) -> str:
"""
这是一个演示
:param test: 这是一个测试参数
"""

await __event_emitter__(
{
"type": "status", # 设置类型
"data": {"description": "显示在聊天中的消息", "done": False},
# 注意 done 是 False,表示我们仍在发射状态
}
)

# 执行其他逻辑
await __event_emitter__(
{
"type": "status",
"data": {"description": "完成任务的消息", "done": True, "hidden": False},
# 注意 done 是 True,表示我们已完成发射状态
# 如果希望在消息返回后隐藏状态,可以将 "hidden" 设为 True
}
)

except Exception as e:
await __event_emitter__(
{
"type": "status",
"data": {"description": f"发生错误: {e}", "done": True},
}
)

return f"告知用户: {e}"

消息

这种类型用于在工具的任何阶段向 LLM 追加消息。这意味着您可以在 LLM 响应之前、之后或期间追加消息、嵌入图像甚至渲染网页。

await __event_emitter__(
{
"type": "message", # 设置类型
"data": {"content": "此消息将被追加到聊天中。"},
# 注意,对于消息类型,我们不需要设置 done 条件
}
)
示例
async def test_function(
self, prompt: str, __user__: dict, __event_emitter__=None
) -> str:
"""
这是一个演示
:param test: 这是一个测试参数
"""

await __event_emitter__(
{
"type": "message", # 设置类型
"data": {"content": "此消息将被追加到聊天中。"},
# 注意,对于消息类型,我们不需要设置 done 条件
}
)

except Exception as e:
await __event_emitter__(
{
"type": "status",
"data": {"description": f"发生错误: {e}", "done": True},
}
)

return f"告知用户: {e}"