跳到主要内容

🛠️ 开发

编写自定义工具包

工具包在一个单独的 Python 文件中定义,包含一个带有元数据的顶级文档字符串和一个 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):
"""Initialize the Tool."""
self.valves = self.Valves()

class Valves(BaseModel):
api_key: str = Field("", description="Your API key here")

def reverse_string(self, string: str) -> str:
"""
Reverses the input string.
:param string: The string to reverse
"""
# example usage of valves
if self.valves.api_key != "42":
return "Wrong API key"
return string[::-1]

类型提示

每个工具都必须为参数提供类型提示。类型也可以嵌套,例如 queries_and_docs: list[tuple[str, int]]。这些类型提示用于生成发送到模型的 JSON 模式。没有类型提示的工具在一致性方面会差很多。

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

Valves 和 UserValves 用于指定工具的可自定义设置,您可以在专门的 Valves & UserValves 页面上了解更多信息。

可选参数

以下是您的工具可以依赖的可选参数列表

  • __event_emitter__: 发出事件(参见下一节)
  • __event_call__: 与事件发射器相同,但可用于用户交互
  • __user__: 一个包含用户信息字典。它还包含 UserValves 对象在 __user__["valves"] 中。
  • __metadata__: 包含聊天元数据的字典
  • __messages__: 以前消息的列表
  • __files__: 附件
  • __model__: 包含模型信息的字典

只需将它们作为参数添加到工具类的任何方法中,就像上面示例中的 __user__ 一样。

事件发射器

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

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

如果模型似乎无法调用该工具,请确保它已启用(通过“模型”页面或通过聊天输入字段旁边的 + 号)。您还可以将“模型”页面“高级参数”部分中的 Function Calling 参数从 Default 更改为 Native

状态

这用于在消息执行步骤时为其添加状态。这些可以在工具执行的任何阶段完成。这些状态显示在消息内容的正上方。这对于延迟 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}"

消息

此类型用于在工具的任何阶段向 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}"

引用

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

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"},
},
}
)

外部包

在工具定义元数据中,您可以指定自定义包。当您点击 Save 时,该行将被解析,并且 pip install 将一次性运行所有要求。

请记住,由于 pip 与 Open WebUI 在同一进程中使用,因此在安装过程中 UI 将完全无响应。

目前没有采取措施来处理与 Open WebUI 要求的包冲突。这意味着如果不小心,指定要求可能会破坏 Open WebUI。您可以通过将 open-webui 本身指定为要求来解决此问题。

示例
"""
title: myToolName
author: myName
funding_url: [any link here will be shown behind a `Heart` button for users to show their support to you]
version: 1.0.0
# the version is displayed in the UI to help users keep track of updates.
license: GPLv3
description: [recommended]
requirements: package1>=2.7.0,package2,package3
"""