扩展 Dify 内置工具集,打造自己独有的 AI Agent 工作站


Dify 提供了很多的内置工具,让我们在创建 Agent 的时候可以做更多的事情。 看着琳琅满目的工具,我们是不是也想接入自己独特的工具呢?

扩展 Dify 内置工具集,打造自己独有的 AI Agent 工作站

今天演示下如何构建自己的工具并添加到 Dify 内置工具集里面。

扩展 Dify 内置工具集,打造自己独有的 AI Agent 工作站

运行 Dify

如何运行 Dify(源码和容器运行)我这里就不赘述了,大家可以参考前面这两篇文章:

  • • Dify + FastAPI 创建自定义工具

  • • Dify+谷歌翻译 使用中文提示词实现本地文生图

扩展工具

厂商(供应商)和工具

首先我们了解下 Dify 内置工具的两个概念:厂商 和 工具

你要扩展工具的话,首先要注册一个厂商,一个厂商下面可以有多个工具,在你选择工具的时候,工具会按照厂商分组。

扩展 Dify 内置工具集,打造自己独有的 AI Agent 工作站

扩展方式

扩展 Dify 工具和厂商分了两部分:

  • • 使用 yaml 文件描述其参数的功能

  • • 使用 python 文件编写厂商注册函数和工具实现

不如定义了两个工具,最终的目录结构大概是这样:

├── _assets
│   └── icon.svg
├── shuyi.py
├── shuyi.yaml
└── tools
    ├── shuyi_excel.py
    ├── shuyi_excel.yaml
    ├── shuyi_test.py
    └── shuyi_test.yaml

定义厂商

厂商定义 yaml

这个 yaml 将包含工具供应商的信息,包括供应商名称、图标、作者等详细信息,以帮助前端灵活展示。

在 core/tools/provider/builtin 目录下创建一个文件夹,比如 shuyi,然后软件 shuyi.yaml

在文件里面增加关于工具的描述、以及展示的图标。

identity:
  author: Shuyi
  name: shuyi
  label:
    en_US: Shuyi
    zh_Hans: 数翼
    pt_BR: Shuyi
  description:
    en_US: Shuyi tools
    zh_Hans: 数翼自定义工具集
    pt_BR: Shuyi tools
  icon: icon.svg
  tags:
    - search
    - productivity

授权定义

如果工具需要授权,那么我们还需要定义授权参数

授权一般都是填写这个工具的密钥(API Key),比如谷歌搜索、DALL-E 绘画,通过授权可以完成工具的安全调用。

如果配置了授权在工具详情就会出现一个授权按钮:

扩展 Dify 内置工具集,打造自己独有的 AI Agent 工作站

点击可以看到授权参数的填写:

扩展 Dify 内置工具集,打造自己独有的 AI Agent 工作站

我们自定义工具增加两个授权参数:

  • • 服务器地址:我们自己部署服务的地址

  • • API Key:用于验证调用的合法性

定义授权参数 shuyi_api_key 和 shuyi_api_url,表单类型分别是secret-inputtext-input。Yaml 增加如下内容:

credentials_for_provider:
  shuyi_api_key:
    type: secret-input
    required: true
    default: "123456"
    label:
      en_US: Shuyi API key
      zh_Hans: Shuyi API key
      pt_BR: Shuyi API key
    placeholder:
      en_US: Please input your Shuyi API key
      zh_Hans: 请输入你的 Shuyi API key
      pt_BR: Please input your Shuyi API key
    help:
      en_US: Get your Shuyi API key from Shuyi
      zh_Hans:  Shuyi 获取您的 Shuyi API key
      pt_BR: Get your Shuyi API key from Shuyi
    url: https://blog.tupu.work/

  shuyi_api_url:
    type: text-input
    required: true
    default: http://localhost:8000
    label:
      en_US: Shuyi API url
      zh_Hans: Shuyi API 地址
      pt_BR: Shuyi API url
    placeholder:
      en_US: Please input your Shuyi API url
      zh_Hans: 请输入你的 Shuyi API 服务地址
      pt_BR: Please input your Shuyi API url
    help:
      en_US: Get your Shuyi API url from Shuyi
      zh_Hans:  Shuyi 获取您的 Shuyi API url
      pt_BR: Get your Shuyi API url from Shuyi
    url: https://blog.tupu.work/

这时候我们就可以看到工具的授权参数了:

扩展 Dify 内置工具集,打造自己独有的 AI Agent 工作站

点击可以看到授权表单:

扩展 Dify 内置工具集,打造自己独有的 AI Agent 工作站

是否必须授权和调用外部服务

自定义工具当然不是必须需要授权或者调用服务的。

你可以把所有逻辑都在你的工具代码里面实现,这样比较简单,但是也有一些弊端:

  • • 工具代码过于复杂,耦合性过高,也不利于测试

  • • 插件依赖等问题可能和 Dify 冲突,升级安装也不好保证

  • • 在 Dify 中计算不方便分布式扩容

如果我们的工具功能比较简单,可以不用认证这些的,就比如 JSON 相关的工具:

扩展 Dify 内置工具集,打造自己独有的 AI Agent 工作站

如果要实现的工具功能复杂,还是建议单独写一个服务,让 Dify 来调用。

工具实现

工具实现也是分为定义文件 Yaml 和功能实现类两部分。

我们再 shuyi/tools 目录下创建 shuyi_test.yaml 文件如下,内容主要就是工具描述、以及参数两部分。

identity:
  name: shuyi_test
  author: Shuyi
  label:
    en_US: ShuyiTest
    zh_Hans: 数翼工具测试
    pt_BR: ShuyiTest
description:
  human:
    en_US: A tool for testing Dify message type and input parameters.Input should be a search query.
    zh_Hans: 用于测试Dify消息类型和输入参数的工具。
    pt_BR: A tool for testing Dify message type and input parameters.Input should be a search query.
  llm: A tool for testing Dify message type and input parameters.Input should be a search query.
parameters:
  - name: query
    type: string
    required: true
    label:
      en_US: Query string
      zh_Hans: 查询语句
      pt_BR: Query string
    human_description:
      en_US: used for searching
      zh_Hans: 用于搜索内容
      pt_BR: used for searching
    llm_description: key words for searching
    form: llm

Dify 支持的参数有四种类型:

  • • string

  • • number

  • • boolean

  • • select

这块儿我们不在赘述,需要的话可以参考官方文档[2]

值得注意的是 form 这个参数, form 表示表单类型,目前支持llmform两种类型,分别对应 Agent 自行推理和前端填写。

Agent 自行推理的意思就是有 LLM 确定字段的值。

工具的实现类 shuyi_test.py 最简单的莫过于直接返回一个固定的消息。

from typing import AnyUnion

from core.tools.entities.tool_entities import ToolInvokeMessage
from core.tools.tool.builtin_tool import BuiltinTool

class ShuyiTestTool(BuiltinTool):
    def _invoke(self,
                user_id: str,
                tool_parameters: dict[strAny],
                
) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]:
        return self.create_link_message('hello')

当然现实中肯定不会这么简单,我们一般要获取插件认证的参数:

api_url = self.runtime.credentials['shuyi_api_url'],
params = {
    "api_key": self.runtime.credentials['shuyi_api_key'],
    "type": tool_parameters['type'],
    "query": tool_parameters['query'],
}

调用外部服务:

response = requests.get(url=api_url, params=params)

解析调用结果的服务返回一般逻辑比较复杂,我们可以使用一个单独的函数实现:

def _parse_response(self, response: dict) -> dict:
    result = {}
    # logics
    return result

然后返回:

response.raise_for_status()
valuable_res = self._parse_response(response.json())
return self.create_json_message(valuable_res)

我写了这样一个模板,大家可以基于这个模板来创建自己的工具

from typing import AnyUnion

import requests

from core.tools.entities.tool_entities import ToolInvokeMessage
from core.tools.tool.builtin_tool import BuiltinTool

class ShuyiTestTool(BuiltinTool):

    def _parse_response(self, response: dict) -> dict:
        result = {}
        # logics
        return result

    def _invoke(self,
                user_id: str,
                tool_parameters: dict[strAny],
                
) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]:
        api_url = self.runtime.credentials['shuyi_api_url'],
        params = {
            "api_key": self.runtime.credentials['shuyi_api_key'],
            "type": tool_parameters['type'],
            "query": tool_parameters['query'],
        }
        response = requests.get(url=api_url, params=params)
        response.raise_for_status()
        valuable_res = self._parse_response(response.json())
        return self.create_json_message(valuable_res)

消息类型

Dify 提供了几种消息类型[3], 在我看来都是文本(Markdown)类型的封装,下面是对应的封装方法:

  • • 图片:create_image_message(self, image: str, save_as: str = '')

  • • 链接:create_link_message(self, link: str, save_as: str = '')

  • • 文本:create_text_message(self, text: str, save_as: str = '')

  • • Blob: create_blob_message(self, blob: bytes, meta: dict = None, save_as: str = '')

  • • JSON: create_json_message(self, object: dict)

当然,也支持返回多个消息,用数组表示即可。

文本

文本类型其实是 Markdown 。

我们创建一个包含图片、列表、标题的 Markdown 消息:

return self.create_text_message(
                """### User message
%s
### 生成式 AI 应用创新引擎
开源的 LLM 应用开发平台,轻松构建和运营生成式 AI 原生应用。
- 生成式 AI
- 应用开发框架



#### RAG Pipeline
"""
 % params['query'])

效果如下:

扩展 Dify 内置工具集,打造自己独有的 AI Agent 工作站

图片消息

图片消息需要传递一个 地址:

image_path = 'https://buffer.com/cdn-cgi/image/w=1000,fit=contain,q=90,f=auto/library/content/images/size/w1200/2023/10/free-images.jpg'
return self.create_image_message(image_path)

效果如下:

扩展 Dify 内置工具集,打造自己独有的 AI Agent 工作站

Blob 消息

文档上说 Blob 消息可以返回文件的原始数据,如图片、音频、视频、PPT、Word、Excel 等。

但是实际测试下来效果不太对。

with open(file_path, 'rb'as mp4:
    byte_arr = mp4.read()

return self.create_blob_message(
    blob=byte_arr,
    meta={
        # 'mime_type': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
        'mime_type''video/mp4',
        'file_name''xxx.mp4',},
    save_as=self.VARIABLE_KEY.IMAGE.value
)

效果并没有显示出文件内容,或者下载链接:

扩展 Dify 内置工具集,打造自己独有的 AI Agent 工作站

经过尝试,如果想要返回文档,发现只有使用 Markdown 来实现一个下载超链接。

[something.xlsx](https://yourhost/xxx.xlsx

链接消息

连接类型的消息只需要出入一个地址,

return self.create_link_message(link)

返回的内容就是:Link: 后面跟上你的链接:

扩展 Dify 内置工具集,打造自己独有的 AI Agent 工作站

多条消息

Dify 还支持多条消息的返回,使用数组即可:

messages = [
    self.create_text_message("""### User message ...""" % params['query']),
    self.create_json_message({'result''success''text''This is a message'}),
    self.create_image_message(image_path),
    self.create_link_message(link),
    ...
]

效果也是多条消息的拼接:

扩展 Dify 内置工具集,打造自己独有的 AI Agent 工作站

使用工具

当我们编写好工具类,重启服务就可以使用刚刚创建的工具类了。

添加节点的时候找到并选择自己的工具:

扩展 Dify 内置工具集,打造自己独有的 AI Agent 工作站

就可以和 Dify 提供的默认工具一样用了。

扩展 Dify 内置工具集,打造自己独有的 AI Agent 工作站

总结

相比于在 UI 上创建基于 OpenAPI 的自定义工具,通过代码来扩展供应商和工具集更使能方便我们完成 工具的积累和传播,在使用上也有更大的可能性。

通过扩展工具,基于 Dify 打造自己独特的 AI 工作站,同时还可以复用自己之前的工具积累,而不仅仅是通用的 AI Agent 工作站。

Agent智能体新闻资讯

Dify + FastAPI 创建自定义工具

2025-5-2 19:38:36

Agent智能体新闻资讯

Llama + Dify,在你的电脑搭建一套AI工作流

2025-5-2 21:47:47

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
购物车
优惠劵
搜索