在 AI 应用开发平台中,工具(Tool)系统是连接大语言模型与外部世界的桥梁,它使 AI 能够执行各种实际任务,如搜索信息、生成图片、处理数据等。本文将深入解析 Dify 工具系统的核心架构设计,帮助理解其工作原理并进行扩展开发。
1、工具系统概述
Dify 工具系统是一个模块化、可扩展的框架,用于在 Agent 助手和工作流中实现各种功能。该系统的设计理念是实现前后端解耦,使开发者能够在不修改前端逻辑的情况下定义和展示自己的工具,从而实现 Dify 能力的水平扩展。
目前,Dify 工具系统支持两种类型的工具:
- 内置工具(Built-in Tools):在产品内部实现,硬编码用于 Agent 和工作流。
- API 工具(Api-Based Tools):利用第三方 API 实现,无需编码即可集成,只需在前端提供 OpenAPI、Swagger 或 OpenAI-plugin 格式的接口定义。
2、核心架构设计
2.1 整体架构
Dify 工具系统采用了分层架构设计,主要包括管理层、提供者层和工具层三个层次。
2.2 核心组件
2.2.1 工具管理器(ToolManager)
ToolManager
是工具系统的核心管理类,负责管理所有工具提供者和工具实例。它提供了获取工具提供者、工具实例和工具运行时的方法,是工具系统的入口点。
主要功能:
- 加载和管理内置工具提供者
- 获取特定工具提供者和工具实例
- 为 Agent 和工作流创建工具运行时
2.2.2 工具提供者控制器(ToolProviderController)
ToolProviderController
是工具提供者的抽象基类,定义了工具提供者的接口。每个工具提供者都需要实现这个接口,以提供工具列表、获取特定工具、验证凭据等功能。
主要子类:
BuiltinToolProviderController
:内置工具提供者控制器ApiToolProviderController
:API 工具提供者控制器
2.2.3 工具(Tool)
Tool
是工具的抽象基类,定义了工具的接口。每个工具都需要实现这个接口,以提供工具的调用、参数验证等功能。
主要子类:
BuiltinTool
:内置工具ApiTool
:API 工具
2.3 数据结构
3、工具接入方式
3.1 快速接入
快速接入适用于简单工具的开发,通过配置驱动的方式快速实现工具功能。以 Google 搜索工具为例,快速接入需要完成以下步骤:
3.1.1 准备工具供应商 YAML
identity:
author:Dify
name:google
label:
en_US:Google
zh_Hans:Google
description:
en_US:Google
zh_Hans:Google
icon:icon.svg
tags:
-search
3.1.2 准备供应商凭据
credentials_for_provider:
serpapi_api_key:
type:secret-input
required:true
label:
en_US:SerpApiAPIkey
zh_Hans:SerpApiAPIkey
placeholder:
en_US:PleaseinputyourSerpApiAPIkey
zh_Hans:请输入你的SerpApiAPIkey
help:
en_US:GetyourSerpApiAPIkeyfromSerpApi
zh_Hans:从SerpApi获取您的SerpApiAPIkey
url:https://serpapi.com/manage-api-key
3.1.3 准备工具 YAML
identity:
name:google_search
author:Dify
label:
en_US:GoogleSearch
zh_Hans:谷歌搜索
description:
human:
en_US:AtoolforperformingaGoogleSERPsearchandextractingsnippetsandwebpages.
zh_Hans:一个用于执行GoogleSERP搜索并提取片段和网页的工具。
llm:AtoolforperformingaGoogleSERPsearchandextractingsnippetsandwebpages.
parameters:
-name:query
type:string
required:true
label:
en_US:Querystring
zh_Hans:查询语句
human_description:
en_US:usedforsearching
zh_Hans:用于搜索网页内容
llm_description:keywordsforsearching
form:llm
-name:result_type
type:select
required:true
options:
-value:text
label:
en_US:text
zh_Hans:文本
-value:link
label:
en_US:link
zh_Hans:链接
default:link
label:
en_US:Resulttype
zh_Hans:结果类型
human_description:
en_US:usedforselectingtheresulttype,textorlink
zh_Hans:用于选择结果类型,使用文本还是链接进行展示
form:form
3.1.4 准备工具代码
from core.tools.tool.builtin_tool import BuiltinTool
from core.tools.entities.tool_entities import ToolInvokeMessage
from typing import Any, Dict, List, Union
class GoogleSearchTool(BuiltinTool):
def _invoke(self,
user_id: str,
tool_parameters: Dict[str, Any],
) -> Union[ToolInvokeMessage, List[ToolInvokeMessage]]:
"""
invoke tools
"""
query = tool_parameters['query']
result_type = tool_parameters['result_type']
api_key = self.runtime.credentials['serpapi_api_key']
result = SerpAPI(api_key).run(query, result_type=result_type)
if result_type == 'text':
return self.create_text_message(text=result)
return self.create_link_message(link=result)
3.1.5 准备供应商代码
from core.tools.provider.builtin_tool_provider import BuiltinToolProviderController
from core.tools.errors import ToolProviderCredentialValidationError
from core.tools.provider.builtin.google.tools.google_search import GoogleSearchTool
from typing import Any, Dict
class GoogleProvider(BuiltinToolProviderController):
def _validate_credentials(self, credentials: Dict[str, Any]) -> None:
try:
GoogleSearchTool().fork_tool_runtime(
meta={
"credentials": credentials,
}
).invoke(
user_id='',
tool_parameters={
"query": "test",
"result_type": "link"
},
)
except Exception as e:
raise ToolProviderCredentialValidationError(str(e))
3.2 高级接入
高级接入适用于复杂工具的开发,支持多种消息类型、变量池和工具链的构建。
3.2.1 多种消息类型
Dify 工具系统支持多种消息类型,包括文本、图片、链接、文件 BLOB 和 JSON。
示例代码:
# 返回文本消息
self.create_text_message(text="Hello, world!")
# 返回图片消息
self.create_image_message(image="https://example.com/image.png")
# 返回链接消息
self.create_link_message(link="https://example.com")
# 返回文件 BLOB 消息
self.create_blob_message(blob=binary_data, meta={"mime_type": "image/png"})
# 返回 JSON 消息
self.create_json_message(object={"key": "value"})
3.2.2 变量池机制
变量池是工具系统中的一个重要组件,用于在工具之间共享数据。它允许一个工具生成的数据被另一个工具使用,从而构建复杂的工具链。
示例代码(DallE3 生成图片并保存到变量池):
# 将图片保存到变量池
self.create_blob_message(
blob=b64decode(image.b64_json),
meta={"mime_type": "image/png"},
save_as=self.VARIABLE_KEY.IMAGE.value
)
示例代码(Vectorizer.AI 从变量池获取图片):
# 从变量池获取图片
image_binary = self.get_variable_file(self.VARIABLE_KEY.IMAGE)
if not image_binary:
return self.create_text_message("Image not found")
# 处理图片
response = post(
"https://vectorizer.ai/api/v1/vectorize",
files={"image": image_binary},
data={"mode": "test"},
auth=(api_key_name, api_key_value),
timeout=30
)
3.2.3 动态参数生成
工具可以根据当前变量池中的数据动态生成参数列表,使 LLM 能够根据实际情况选择合适的参数。
def get_runtime_parameters(self) -> List[ToolParameter]:
"""
override the runtime parameters
"""
return [
ToolParameter.get_simple_instance(
name="image_id",
llm_description="the image id that you want to vectorize",
type=ToolParameter.ToolParameterType.SELECT,
required=True,
options=[i.name for i in self.list_default_image_variables()]
)
]
3.2.4 工具可用性控制
工具可以根据当前变量池中的数据决定自己是否可用,避免在不适合的情况下被调用。
def is_tool_available(self) -> bool:
# 只有当变量池中有图片时,工具才可用
return len(self.list_default_image_variables()) > 0
4、工具系统工作流程
4.1 工具调用过程
- 用户发送请求到 Agent 或工作流
- Agent 或工作流通过 ToolManager 获取工具运行时
- ToolManager 获取工具提供者和工具实例
- ToolManager 创建工具运行时,包括加载凭据和变量池
- Agent 或工作流调用工具
- 工具执行逻辑,可能会保存结果到变量池
- 工具返回结果给 Agent 或工作流
- Agent 或工作流返回响应给用户
4.2 变量池使用过程
- 工具 A 执行逻辑,生成结果
- 工具 A 将结果保存到变量池
- 工具 B 从变量池获取工具 A 的结果
- 工具 B 使用工具 A 的结果执行自己的逻辑
5、总结
Dify 的工具架构设计充分考虑了灵活性和可扩展性,通过配置驱动开发、变量池机制、动态参数生成和工具可用性控制等技术,使开发者能够快速构建从简单到复杂的各类工具。特别是变量池机制,为构建复杂工具链提供了强大支持,使得多个工具可以协同工作,完成更复杂的任务。
如何学习大模型 AI ?
由于新岗位的生产效率,要优于被取代岗位的生产效率,所以实际上整个社会的生产效率是提升的。
但是具体到个人,只能说是:
“最先掌握AI的人,将会比较晚掌握AI的人有竞争优势”。
这句话,放在计算机、互联网、移动互联网的开局时期,都是一样的道理。
我在一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。
我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在人工智能学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。但苦于知识传播途径有限,很多互联网行业朋友无法获得正确的资料得到学习提升,故此将并将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。
这份完整版的大模型 AI 学习资料已经上传优快云,朋友们如果需要可以微信扫描下方优快云官方认证二维码免费领取【保证100%免费
】
第一阶段(10天):初阶应用
该阶段让大家对大模型 AI有一个最前沿的认识,对大模型 AI 的理解超过 95% 的人,可以在相关讨论时发表高级、不跟风、又接地气的见解,别人只会和 AI 聊天,而你能调教 AI,并能用代码将大模型和业务衔接。
- 大模型 AI 能干什么?
- 大模型是怎样获得「智能」的?
- 用好 AI 的核心心法
- 大模型应用业务架构
- 大模型应用技术架构
- 代码示例:向 GPT-3.5 灌入新知识
- 提示工程的意义和核心思想
- Prompt 典型构成
- 指令调优方法论
- 思维链和思维树
- Prompt 攻击和防范
- …
第二阶段(30天):高阶应用
该阶段我们正式进入大模型 AI 进阶实战学习,学会构造私有知识库,扩展 AI 的能力。快速开发一个完整的基于 agent 对话机器人。掌握功能最强的大模型开发框架,抓住最新的技术进展,适合 Python 和 JavaScript 程序员。
- 为什么要做 RAG
- 搭建一个简单的 ChatPDF
- 检索的基础概念
- 什么是向量表示(Embeddings)
- 向量数据库与向量检索
- 基于向量检索的 RAG
- 搭建 RAG 系统的扩展知识
- 混合检索与 RAG-Fusion 简介
- 向量模型本地部署
- …
第三阶段(30天):模型训练
恭喜你,如果学到这里,你基本可以找到一份大模型 AI相关的工作,自己也能训练 GPT 了!通过微调,训练自己的垂直大模型,能独立训练开源多模态大模型,掌握更多技术方案。
到此为止,大概2个月的时间。你已经成为了一名“AI小子”。那么你还想往下探索吗?
- 为什么要做 RAG
- 什么是模型
- 什么是模型训练
- 求解器 & 损失函数简介
- 小实验2:手写一个简单的神经网络并训练它
- 什么是训练/预训练/微调/轻量化微调
- Transformer结构简介
- 轻量化微调
- 实验数据集的构建
- …
第四阶段(20天):商业闭环
对全球大模型从性能、吞吐量、成本等方面有一定的认知,可以在云端和本地等多种环境下部署大模型,找到适合自己的项目/创业方向,做一名被 AI 武装的产品经理。
- 硬件选型
- 带你了解全球大模型
- 使用国产大模型服务
- 搭建 OpenAI 代理
- 热身:基于阿里云 PAI 部署 Stable Diffusion
- 在本地计算机运行大模型
- 大模型的私有化部署
- 基于 vLLM 部署大模型
- 案例:如何优雅地在阿里云私有部署开源大模型
- 部署一套开源 LLM 项目
- 内容安全
- 互联网信息服务算法备案
- …
学习是一个过程,只要学习就会有挑战。天道酬勤,你越努力,就会成为越优秀的自己。
如果你能在15天内完成所有的任务,那你堪称天才。然而,如果你能完成 60-70% 的内容,你就已经开始具备成为一名大模型 AI 的正确特征了。