最近使用WSL2 做了dify的本地化部署。试着使用工作流的方式实现一个工作流来通过和大模型对话完成对本地资源的访问。
预配置
WSL2的本地部署
1 2
| wsl --list wsl --install
|
部署完成后,配置安装apt源 ,Docker源(镜像有问题可以查询之前的文章),Git配置,以及 一些基本的命令行工具
Dify 本地部署
Github 上 https://github.com/langgenius/dify 有部署教程,
1 2 3 4
| cd dify cd docker cp .env.example .env docker compose up -d
|
安装完毕后 访问本地的http://localhost/install 进行管理员配置
至此我们获得了一个部署在本地windows子系统上的dify环境
设计

目标是通过和大模型对话,识别其中的关键词来完成和自定义插件中的功能的映射关系。向本地的HTTP服务器发送对应请求。完成功能的执行
一些未来可行的扩展项
- 更好的服务通信方式。wsl2 子系统可以直接对挂载到该系统的windows系统上的文件进行操作。所以存在更快捷方法调用本地资源。但是这可能需要dify提供更丰富的调用方式或者在docker层面上进行一些功能定制,当前只是一个可行性尝试。所以使用了 http的调用-响应模式
- 注册, 提供一个通用的PC平台应用发现服务。而不是通过将所有的可执行程序注册为Dify的自定义插件功能。这样更加灵活
- 本地的部署+自然语言的请求+插件自定义功能的解耦 目前来看相对还是比较安全。如果需要实现远程的请求调用可能需要更加安全的信息传输方式
- 在本地添加应用程序和文件资源的调用记录。
Dify的自定义插件
脚手架工具初始化
官方文档
https://docs.dify.ai/zh-hans/plugins/quick-start/develop-plugins/initialize-development-tools
下载 Dify的插件脚手架工具 https://github.com/langgenius/dify-plugin-daemon/tags
以tools 类型为例 初始化 插件项目目录
1
| dify-plugin-windows-amd64 plugin init
|

name 创建 插件名
author 插件作者
description 插件功能描述
语言 : python
工具 : tools (自定义tools 类型插件

一些权限的设置
最终我们得到的是一个这样的工程
以下是一些比较重要的文件
1 2 3 4 5 6 7 8 9 10
| - _assets - provider - someplugin.py - someplugin.yaml - tools - somefunction.py - somefunction.yaml - main.py - manifest.yaml
|
插件功能定义
插件通过调用的是_invoke方法来执行对应的功能
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| from collections.abc import Generator from typing import Any
import requests
from dify_plugin import Tool from dify_plugin.entities.tool import ToolInvokeMessage
BASE_URL ="<http://localhost:8080>"
class DestopHTool(Tool):
def _invoke(self, tool_parameters: dict[str, Any]) -> Generator[ToolInvokeMessage]: method = tool_parameters.get("method","") result = "" if method == "desktop_get" : result = requests.get(BASE_URL).text yield self.create_text_message(f'调用了{method},返回{result}')
|
这里给出了一个简单的http请求调用,使用request模拟http get 请求。并返回接收到的消息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| identity: name: desktop_get author: codfish label: en_US: destop_get zh_Hans: destop_get pt_BR: destop_get description: human: en_US: a interface design for destop_application_oprating zh_Hans: a interface design for destop_application_oprating pt_BR: a interface design for destop_application_oprating llm: a interface design for destop_application_oprating parameters: - name: url type: string required: true label: en_US: Query string zh_Hans: 查询语句 pt_BR: Query string human_description: en_US: a interface design for destop_application_oprating zh_Hans: a interface design for destop_application_oprating pt_BR: a interface design for destop_application_oprating llm_description: a interface design for destop_application_oprating form: llm extra: python: source: tools/desktop_get.py
|
每个tools 插件允许添加多个方法,每个方法需要定义自己的模块文件(.py)和资源描述文件(.yaml)
其结构为
1 2 3 4 5 6
| tools\\ - somefunction1.py - somefunction1.yaml - somefunction2.py - somefunction2.yaml ...
|
插件调试
通过修改工作目录中的.env.example 为.env
1 2 3 4
| INSTALL_METHOD=remote REMOTE_INSTALL_HOST=debug.dify.ai REMOTE_INSTALL_PORT=5003 REMOTE_INSTALL_KEY=some_install_key
|
将dify插件页的调试信息填充到.env中,本地执行main方法,插件会被加载到dify的插件列表中

创建CHAT任务流

创建大模型组件,并填入模型,国内推荐使用硅基流动。
在大模型组件中填入模型,填入系统提示词,核心目的是预期输出合理且可控,不要有多余的输出,测试的系统提示词如下(并不能很好的获取到目标方法名,需要后期再调试)
1 2 3 4 5 6 7 8
| 你是一位专业的桌面助理
当用户发送查询桌面的请求时,你可以根据对话信息检查是否返回一个调用方法
发起桌面请求 = destop_get
不需要 直接回答用户请求,只需要返回一个具体的执行方法
|
在后续添加自定义组件作为节点, 接收大模型的返回作为输入的参数,进行后续执行

一个基础的工作链条 启动大模型→发起请求→ 根据请求给出需要执行的方法→传递给插件执行方法→返回执行结果
大模型正确识别方法名,插件解析方法,执行对应方法。向本地启动的服务器发送请求。得到响应返回结果到对话框
