🛠️ 开发
编写自定义 Toolkit
Toolkit 在单个 Python 文件中定义,包含顶层 docstring(带有元数据)和一个 Tools
类。
顶层 Docstring 示例
"""
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 必须定义在一个名为 Tools
的类中的方法(methods)中,可以包含可选的子类 Valves
和 UserValves
,例如
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]
类型提示 (Type Hints)
每个工具都必须为参数提供类型提示。类型可以是嵌套的,例如 queries_and_docs: list[tuple[str, int]]
。这些类型提示用于生成发送给模型的 JSON schema。没有类型提示的工具在一致性方面会差很多。
Valves 和 UserValves - (可选,但强烈建议)
Valves 和 UserValves 用于指定 Tool 的可定制设置,你可以在专门的 Valves 与 UserValves 页面阅读更多内容。
可选参数
以下是你的工具可以依赖的可选参数列表
__event_emitter__
: 发送事件(参见下一节)__event_call__
: 与事件发送器相同,但可用于用户交互__user__
: 包含用户信息的字典。它还包含__user__["valves"]
中的UserValves
对象。__metadata__
: 包含聊天元数据的字典__messages__
: 之前消息的列表__files__
: 附件文件__model__
: 包含模型信息的字典
只需将它们作为参数添加到你的 Tool 类中的任何方法中,就像上面示例中的 __user__
一样。
事件发送器 (Event Emitters)
事件发送器用于向聊天界面添加额外信息。与 Filter Outlets 类似,事件发送器能够向聊天追加内容。与 Filter Outlets 不同的是,它们不能移除信息。此外,发送器可以在 Tool 执行期间的任何阶段激活。
事件发送器有两种不同类型
如果模型似乎无法调用工具,请确保它已启用(可以通过模型页面或聊天输入字段旁边的 +
号进行)。你还可以将模型页面的 Advanced Params
部分的 Function Calling
参数从 Default
切换为 Native
。
状态
这用于在消息执行步骤时添加状态。这些可以在 Tool 执行期间的任何阶段完成。这些状态出现在消息内容的上方。这对于延迟 LLM 响应或处理大量信息的 Tools 非常有用。这使你能够实时告知用户正在处理的内容。
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}"
消息
此类型用于在 Tool 执行期间的任何阶段向 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"},
},
}
)
外部包
在 Tools 定义的元数据中,你可以指定自定义包。当你点击 Save
时,该行将被解析,并且会一次性对所有 requirements 运行 pip install
。
请注意,由于 pip 在与 Open WebUI 相同的进程中使用,因此在安装过程中 UI 将完全无响应。
未采取任何措施来处理与 Open WebUI requirements 的包冲突。这意味着如果你不小心,指定 requirements 可能会破坏 Open WebUI。你或许可以通过将 open-webui
本身指定为 requirement 来解决此问题。
示例
"""
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
"""