Skip to main content

⚙️ 工具

什么是工具?

工具是在请求时提供给 LLM 的 Python 脚本。工具使 LLM 能够执行操作并获取额外的上下文信息作为结果。通常情况下,您选择的 LLM 需要支持函数调用(function calling)功能才能可靠地使用工具。

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

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

如何使用工具?

完成安装后,您可以将工具分配给任何支持函数调用的 LLM,并启用该工具来使用它。要将工具分配给模型,请导航到 Workspace => Models。在这里,您可以选择想要启用工具的模型。

点击编辑图标(铅笔图标)来修改模型设置后,向下滚动到工具部分,勾选您希望启用的工具。完成后请务必点击保存。

工具启用后,您可以在与 LLM 对话时点击添加工具按钮("+"图标)来使用各种工具。请注意,启用工具并不意味着它会被强制使用,而是意味着 LLM 将有选项可以调用这个工具。

此外,我们在社区网站上提供了一个自动工具过滤器功能,让 LLM 能够自动选择工具,而无需您在添加工具菜单中手动启用:https://openwebui.com/f/hub/autotool_filter/

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

如何安装工具

工具的导入过程非常简单,您可以选择以下两种方式之一:

下载并手动导入

访问社区网站:https://openwebui.com/tools/

  1. 选择您要导入的工具
  2. 点击页面右上角的"Get"按钮
  3. 点击"Download as JSON export"
  4. 导航至 Workspace => Tools,点击"Import Tools"将工具导入到 Open WebUI 中

通过 Open WebUI URL 导入

  1. 访问社区网站:https://openwebui.com/tools/
  2. 选择您要导入的工具
  3. 点击页面右上角的"Get"按钮
  4. 输入您的 Open WebUI 实例 IP 地址,点击"Import to WebUI",系统将自动打开您的实例并引导您完成工具导入

安全提示:您可以使用手动导入方法来安装自定义工具或未在社区网站上登记的其他工具。请务必谨慎,不要导入来源不明或不可信的工具。执行未知代码可能会带来安全风险。

工具能做什么?

工具为交互式对话提供了丰富的功能支持,例如:

  • 网络搜索:执行实时网络搜索,获取最新信息
  • 图像生成:根据用户提示词生成图像
  • 外部语音合成:通过 API 调用集成 ElevenLabs 外部语音合成服务,将 LLM 输出转换为音频

编写自定义工具包

工具包需要在单个 Python 文件中定义,该文件需包含带有元数据的顶级文档字符串(docstring)和一个 Tools 类。

顶级文档字符串示例

"""
title: String Inverse
author: Your Name
author_url: https://website.com
git_url: https://github.com/username/string-reverse.git
description: This tool calculates the inverse of a string
required_open_webui_version: 0.4.0
requirements: langchain-openai, langgraph, ollama, langchain_ollama
version: 0.4.0
licence: 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: 要反转的字符串
"""
# valves 使用示例
if self.valves.api_key != "42":
return "API 密钥错误"
return string[::-1]

Type Hints

每个工具必须具有类型提示(type hints),以便于生成 JSON 模式(JSON schema)。没有类型提示的工具将无法可靠地工作。

Valves 和 UserValves - (可选,但强烈建议)

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

Valves 只能由管理员配置,而 UserValves 可以由任何用户配置。

示例
# Define and Valves
class Valves(BaseModel):
priority: int = Field(
default=0, description="Priority level for the filter operations."
)
test_valve: int = Field(
default=4, description="A valve controlling a numberical value"
)
pass

# Define any UserValves
class UserValves(BaseModel):
test_user_valve: bool = Field(
default=False, description="A user valve controlling a True/False (on/off) switch"
)
pass

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

Optional Arguments

以下是工具可以依赖的选项列表:

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

Event Emitters

事件发射器用于向聊天界面添加额外信息。与过滤器出口不同,事件发射器可以附加内容到聊天中。与过滤器出口不同,它们不能剥离信息。此外,它们可以在工具的任何阶段激活。

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

Status

此类型用于在消息进行步骤时添加状态。这些可以在工具的任何阶段完成。这些状态出现在消息内容上方。这些对于延迟 LLM 响应或处理大量信息的工具非常有用。这允许您实时通知用户正在处理的内容。

await __event_emitter__(
{
"type": "status", # We set the type here
"data": {"description": "Message that shows up in the chat", "done": False, "hidden": False},
# Note done is False here indicating we are still emitting statuses
}
)
示例
async def test_function(
self, prompt: str, __user__: dict, __event_emitter__=None
) -> str:
"""
This is a demo

:param test: this is a test parameter
"""

await __event_emitter__(
{
"type": "status", # We set the type here
"data": {"description": "Message that shows up in the chat", "done": False},
# Note done is False here indicating we are still emitting statuses
}
)

# Do some other logic here
await __event_emitter__(
{
"type": "status",
"data": {"description": "Completed a task message", "done": True, "hidden": False},
# Note done is True here indicating we are done emitting statuses
# You can also set "hidden": True if you want to remove the status once the message is returned
}
)

except Exception as e:
await __event_emitter__(
{
"type": "status",
"data": {"description": f"An error occured: {e}", "done": True},
}
)

return f"Tell the user: {e}"

Message

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

await __event_emitter__(
{
"type": "message", # We set the type here
"data": {"content": "This message will be appended to the chat."},
# Note that with message types we do NOT have to set a done condition
}
)
示例
async def test_function(
self, prompt: str, __user__: dict, __event_emitter__=None
) -> str:
"""
This is a demo

:param test: this is a test parameter
"""

await __event_emitter__(
{
"type": "message", # We set the type here
"data": {"content": "This message will be appended to the chat."},
# Note that with message types we do NOT have to set a done condition
}
)

except Exception as e:
await __event_emitter__(
{
"type": "status",
"data": {"description": f"An error occured: {e}", "done": True},
}
)

return f"Tell the user: {e}"

Citations

此类型用于在聊天中提供引用或参考。您可以使用它来指定内容、来源和任何相关元数据。以下是如何发出引用事件的示例:

await __event_emitter__(
{
"type": "citation",
"data": {
"document": [content],
"metadata": [
{
"date_accessed": datetime.now().isoformat(),
"source": title,
}
],
"source": {"name": title, "url": url},
},
}
)

如果您发送多个引用,您可以迭代引用并多次调用发射器。在实现自定义引用时,请确保在 Tools__init__ 方法中设置 self.citation = False。否则,内置引用将覆盖您推送的引用。例如:

def __init__(self):
self.citation = False

警告:如果您设置 self.citation = True,这将替换您推送的自定义引用,并完全管理您自己的引用参考。

示例
class Tools:
class UserValves(BaseModel):
test: bool = Field(
default=True, description="test"
)

def __init__(self):
self.citation = False

async def test_function(
self, prompt: str, __user__: dict, __event_emitter__=None
) -> str:
"""
This is a demo that just creates a citation

:param test: this is a test parameter
"""

await __event_emitter__(
{
"type": "citation",
"data": {
"document": ["This message will be appended to the chat as a citation when clicked into"],
"metadata": [
{
"date_accessed": datetime.now().isoformat(),
"source": title,
}
],
"source": {"name": "Title of the content"", "url": "http://link-to-citation"},
},
}
)