【LLM】Dify 搭建 AI 法律法规助手
好久没更新了,最近有工作需求需要用 DeepSeek 搭建一个用来做文档法律合规审查的 AI 助手,正好需要用到知识库,想了想最后还是放弃了原有的 Open-WebUI 方案,直接转为用 Dify 实现。因为需要在内网中部署所以也是踩了一些坑,写个文章顺带记录一下。
搭建环境
由于需要在内网环境部署,整个过程需要离线进行。Dify 的部署依赖于 Docker 和 Docker Compose,因此首先要确保服务器上已经离线安装好了这两个工具。
Docker 的离线安装
本人使用的是 Ubuntu 22.04,因此本文只介绍 Ubuntu 22.04 中 Docker 的离线安装方法。整个过程分为两步:首先在有网络的机器上准备离线安装包,然后将安装包拷贝到目标服务器上进行安装。
一、 在有网络的机器上准备离线包
更新软件包列表并安装依赖
sudo apt update sudo apt-get install -y ca-certificates curl
添加 Docker 的官方 GPG 密钥
sudo install -m 0755 -d /etc/apt/keyrings sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc sudo chmod a+r /etc/apt/keyrings/docker.asc
设置 Docker 的 APT 仓库
echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \ $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \ sudo tee /etc/apt/sources.list.d/docker.list > /dev/null sudo apt-get update
下载 Docker 及其依赖的离线包
首先,创建一个专门用于存放离线包的目录:
然后,使用 `apt` 命令下载所有依赖文件:mkdir ~/docker-offline-packages cd ~/docker-offline-packages
apt-get download $(apt-cache depends --recurse --no-recommends --no-suggests --no-conflicts --no-breaks --no-replaces --no-enhances docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin | grep "^\w")
二、 在离线服务器上安装 Docker
拷贝离线包
将整个
docker-offline-packages
文件夹通过 U 盘或其他方式拷贝到离线服务器上。安装 Docker
在离线服务器上,进入
docker-offline-packages
目录,然后使用dpkg
命令进行安装:cd ~/docker-offline-packages sudo dpkg -i *.deb
验证安装
运行以下命令查看 Docker 是否安装成功:
sudo docker --version
Dify 离线安装
Dify 的离线安装过程主要分为两步:首先在有网络的机器上准备好 Dify 的源代码和所需的 Docker 镜像,然后将这些文件拷贝到目标离线服务器上进行部署。
一、 在有网络的机器上准备资源
下载 Dify 源代码
# 克隆 Dify 仓库 git clone https://github.com/langgenius/dify.git # 进入 dify 目录并切换到最新的稳定 release 版本 cd dify git checkout $(git describe --tags `git rev-list --tags --max-count=1`)
提示: 切换到最新的稳定 release 版本比直接使用
main
分支更可靠,可以避免遇到一些意想不到的 bug。打包 Dify 所需的 Docker 镜像
Dify 依赖多个 Docker 容器来运行。我们可以利用
docker-compose.yml
文件来自动拉取并打包所有必需的镜像。执行完毕后,你会在 `dify/docker` 目录下得到一个 `dify-images.tar` 文件,同时 `dify` 整个文件夹也需要被打包。# 进入 Dify 的 Docker 配置目录 cd docker # 1. 提取所有镜像名称 # 这条命令会解析 docker-compose.yml 文件,找到所有服务的 image 定义,并提取出镜像名和标签 docker compose config | grep "image:" | awk '{print $2}' > image-list.txt # 2. 拉取所有镜像 # 使用 xargs 配合 docker pull 命令,批量拉取 image-list.txt 中列出的所有镜像 cat image-list.txt | xargs -I {} sudo docker pull {} # 3. 将所有镜像打包成一个 tar 文件 # 这样就可以方便地将所有镜像一次性迁移到离线服务器 sudo docker save -o dify-images.tar $(cat image-list.txt | tr '\n' ' ')
二、 在离线服务器上部署 Dify
拷贝资源
将准备好的
dify
整个项目文件夹和dify-images.tar
文件通过 U 盘或其他方式拷贝到离线服务器上。加载 Docker 镜像
在离线服务器上,使用
docker load
命令加载镜像包:sudo docker load -i dify-images.tar
启动 Dify 服务
进入
dify/docker
目录,直接使用 Docker Compose 启动所有服务:cd /path/to/your/dify/docker sudo docker compose up -d
验证安装
等待几分钟让所有服务完全启动后,可以通过
docker ps
命令查看所有 Dify 相关的容器是否都处于Up
状态。如果一切正常,你就可以通过http://<服务器IP>:80
访问 Dify 的 Web 界面了。
Dify 插件离线安装
Dify 的插件生态为其增添了强大的扩展能力,但在离线环境下安装插件则需要一些额外的步骤。
离线安装的挑战
官方的插件包 .difypkg
本质上是一个 zip 压缩文件,其中包含了插件的元数据和代码。然而,这个包并不包含插件运行所需的所有 Python 依赖。当你在 Dify 中上传并安装一个插件时,Dify 会尝试连接到 pypi.org
来下载这些依赖项。在严格的离线环境中,这个过程自然会失败,导致插件无法使用。
解决方案:重新打包插件
为了解决这个问题,我们需要在有网络的机器上,将插件及其所有依赖项预先下载并打包到一个新的、完全离线的 .difypkg
文件中。
根据这篇文章:Dify 实战:纯内网dify插件离线安装解决 找到了一个非常实用的工具:dify-plugin-repackaging。这个脚本可以自动化地完成以下工作:
- 解压原始的
.difypkg
文件。 - 分析
requirements.txt
文件,找出所有 Python 依赖。 - 从 PyPI 下载这些依赖包。
- 将插件代码和所有依赖包重新打包成一个全新的、可离线安装的
.difypkg
文件。
我 Fork 并修改了原仓库的代码,使其更便于批量处理多个插件。我的版本可以在这里找到:lebenito030/dify-plugin-repackaging。
操作步骤
整个过程同样分为“在线准备”和“离线安装”两步。
在线准备
克隆我修改后的仓库:
git clone https://github.com/lebenito030/dify-plugin-repackaging.git cd dify-plugin-repackaging
- 将你从 Dify 商店或其他地方下载的、需要离线安装的
.difypkg
插件包全部放入_temp
文件夹中。 运行打包脚本:
脚本会自动遍历 `_temp` 文件夹中的所有插件包,并生成新的离线包存放在 `_output` 文件夹中。./plugin_repackaging.sh local _temp
离线安装
- 登录 Dify 的 Web 界面。
- 进入
插件
->安装插件
->本地插件
。 - 直接上传重新打包的
(.difypkg)
文件,Dify 会自动安装。
ps:目前发现的问题有,有一部分插件是要求网络连接的,这些插件就无法安装,或者比如一些插件启动的时候要连接网络,会导致 Dify 的其他插件需要等待一段时间才能启动成功。
创建 AI 应用
1. 准备法律法规数据
搭建一个法律法规助手,高质量、全面的知识库是核心。我的数据来源是国家法律法规数据库。
为了方便地从该数据库获取数据,我使用了 LawRefBook/Laws 这个开源项目。该项目提供了一系列脚本,可以自动化地爬取和整理法律法规条文。
然而,在实际使用中,我发现有些部门规章或地方性法规是以 .doc
格式提供的,而原项目默认只处理 .html
和 .docx
。为了能够全面地将这些法规纳入知识库,我对原仓库的代码进行了修改,增加了对 .doc
文件的解析和支持。
并且,为了提高后续知识库父子分段的效果,我在章节的结尾和小节的结尾都添加了 *章节结束*
和 *小节结束*
标记。用于在知识库建立的时候,将这些标记作为分段依据。
我的修改版本可以在这里找到:lebenito030/Laws。当 scripts/request.py
中的 req.request.params
参数为空值时,脚本将下载全部当前有效的法律法规并保存到 Laws/__cache__/out
文件夹下。
通过运行修改后的脚本,爬取到的所有法律法规文件(包括 .doc
格式)将统一转换为纯文本(.md
)格式。这样做的好处是:
- 格式统一:便于 Dify 的知识库进行索引和处理。
- 内容纯净:去除了复杂的格式,只保留核心的文本内容,可以提高检索的准确性。
- 切分优化:Dify 在处理长文本时会自动进行切分,纯文本格式能让切分效果更好,避免因格式混乱导致语义被割裂。
完成数据准备后,就可以将这些 .md
文件批量上传到 Dify 中创建的知识库里了。
2. 搭建知识库
Dify 中创建知识库可以选择父子分段的方式,我们的数据通过脚本已经预处理生成了两级标记:*章节结束*
和 *小节结束*
,因此这里只需要像下图一样填入对应的分段标识符就行。Rerank 设置使用推荐的混合检索。

创建知识库
此时知识库会在后台处理文本,不过这里我推荐一次性少传入太多文本,不然可能会出现错误,比如一直卡在索引中。
3. 编排 Chatflow
回到 Dify 的工作室页面,点击左上角的创建空白应用,这里我使用的是创建 Chatflow 应用。

创建应用
创建完成后会自动进入应用的页面,应该是一个能够直接对话的 LLM 应用,如下图:

应用页面
接下来按照以下步骤操作:
- 在开始和 LLM 之间加入知识检索节点
- 知识检索节点中添加创建的法律法规知识库
- LLM 节点设置上下文为知识检索
- 在系统提示词中加入上下文内容
这个时候就创建完成了,你可以通过发布应用然后使用 Dify 提供的应用页面来直接访问。
这里我提问:未成年人标准是什么。AI 助手回答如下图:

AI 助手回答
我使用的提示词:
# 角色
你是一个严谨、专业的法律知识问答助手,具备两种工作模式。
# 任务
你的任务是根据用户提出的问题 `{{#sys.query#}}`,优先在下面提供的法律知识库 `{{#context#}}` 中寻找最相关的条款和信息。
- 如果 `{{#context#}}` 中包含能回答问题的信息,则生成一份基于知识库的、清晰准确的回答(**模式A**)。
- 如果 `{{#context#}}` 为空或不包含能回答问题的信息,则利用你自己的通用法律知识库生成一份参考性回答,并明确告知用户该信息并非来自其提供的知识库(**模式B**)。
# 工作流程
1. **分析问题**: 仔细理解用户问题 `{{#sys.query#}}` 的核心诉求。
2. **检索与判断**: 分析 `{{#context#}}` 的内容。
* **如果 `{{#context#}}` 提供了相关信息**:则遵循“**核心规则A**”,并使用“**输出格式A**”生成回答。
* **如果 `{{#context#}}` 未提供相关信息**:则遵循“**核心规则B**”,并使用“**输出格式B**”生成回答。
# 核心规则
### 核心规则A (当在知识库中找到信息时)
- **绝对封闭**: 你的回答必须**完全且仅限于** `{{#context#}}` 中提供的信息。严禁使用任何你自己的内部知识或进行任何形式的推测。
- **引用原文**: 在解释时,必须明确引用 `{{#context#}}` 中的相关法律条款原文,并注明来源。
- **忠实原文**: 你的解释不能曲解或过度引申 `{{#context#}}` 中原文的含义。
### 核心规则B (当在知识库中未找到信息时)
- **明确声明来源**: 你必须在回答的**最开始**就清晰地告知用户,提供的信息来源于你的通用知识库,而非其指定的知识库。
- **提供通用知识**: 基于你的通用法律知识,为 `{{#sys.query#}}` 提供一个有帮助但非决定性的、一般性的解答。
- **强调局限性**: 你的回答应侧重于一般性原则和概念,并主动说明缺少具体法律依据。
# 输出格式
### 输出格式A (基于知识库的回答)
请严格按照以下Markdown格式输出你的回答:
**1. 核心结论**
[在这里用一两句话直接回答用户的核心问题]
**2. 相关法条引用**
> [在这里完整引用`{{#context#}}`中最相关的一条或多条法律条款原文]
> 来源:[如果知识库中有来源信息,请填写,如《xxx法》第xx条]
**3. 详细解读**
[在这里基于引用的法条,对用户的具体问题进行详细解释和分析]
---
**免责声明**: 本回答仅基于您提供的知识库生成,不构成任何形式的法律意见或建议。在做出任何决策之前,请务必咨询具备执业资格的专业律师。
### 输出格式B (基于AI通用知识的回答)
请严格按照以下Markdown格式输出你的回答:
⚠️ **重要提示:在您提供的知识库中未能找到与您问题“{{#sys.query#}}”直接相关的信息。**
以下回答是基于我的通用知识库生成的,**并非法律意见,知识库准确性可能有偏差,仅供您参考**。
**1. 一般性解答**
[在这里根据通用的法律原则,对用户的问题提供一个概括性的解释。你需要明确指出这只是一个普遍情况下的理解]
**2. 关键考虑因素**
[在这里列出一些处理此类问题时通常需要考虑的通用因素,例如:证据的重要性、诉讼时效、可能的法律程序等。这有助于引导用户思考,但不是提供解决方案]
---
**强烈建议**: 法律问题高度复杂,且每个案件的具体情况都有极大差异。为了保障您的合法权益,我们**强烈建议**您携带所有相关文件,向具备执业资格的专业律师进行详细咨询,以获得针对您个人情况的正式法律建议。
注意:本文部分内容在 AI (Gemini 2.5 Pro) 的辅助下编写完成,旨在确保语言流畅与结构清晰。如有任何疑问,欢迎评论交流。