Skip to main content

🛠️ 开发

编写自定义工具包

工具包在单个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):
"""初始化工具。"""
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]

类型提示

每个工具都必须具有参数的类型提示。类型也可以是嵌套的,例如queries_and_docs: list[tuple[str, int]]。这些类型提示用于生成发送到模型的JSON架构。没有类型提示的工具将工作,但一致性会大大降低。

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

Valves和UserValves用于指定工具的可自定义设置,您可以在专门的Valves & UserValves页面上阅读更多内容。

可选参数

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

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

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

事件发射器

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

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

如果模型似乎无法调用工具,请确保它已启用(通过模型页面或聊天输入字段旁边的+号)。您还可以将模型页面的高级参数部分的函数调用参数从默认转换为原生

状态

这用于在执行步骤时向消息添加状态。这些可以在工具的任何阶段完成。这些状态出现在消息内容正上方。这些对于延迟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": "此消息将被追加到聊天中。"},
# 注意对于消息类型,我们不必设置完成条件
}
)
示例
async def test_function(
self, prompt: str, __user__: dict, __event_emitter__=None
) -> str:
"""
这是一个演示

:param test: 这是一个测试参数
"""

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

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

return f"告诉用户: {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="测试"
)

def __init__(self):
self.citation = False

async def test_function(
self, prompt: str, __user__: dict, __event_emitter__=None
) -> str:
"""
这是一个只创建引用的演示

:param test: 这是一个测试参数
"""

await __event_emitter__(
{
"type": "citation",
"data": {
"document": ["此消息将作为引用追加到聊天中,点击时显示"],
"metadata": [
{
"date_accessed": datetime.now().isoformat(),
"source": title,
}
],
"source": {"name": "内容标题", "url": "http://link-to-citation"},
},
}
)

外部包

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

请记住,由于pip在与Open WebUI相同的进程中使用,UI在安装期间将完全无响应。

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

示例
"""
title: myToolName
author: myName
funding_url: [这里的任何链接都将显示在`心形`按钮后面,供用户表示对您的支持]
version: 1.0.0
# 版本显示在UI中,帮助用户跟踪更新。
license: GPLv3
description: [推荐]
requirements: package1>=2.7.0,package2,package3
"""