Deepseek 集成 Dify 应用开发平台实现Rag(知识检索)
Dify 是一款开源的大语言模型(LLM) 应用开发平台。它融合了后端即服务(Backend as Service)和 LLMOps 的理念,使开发者可以快速搭建生产级的生成式 AI 应用。即使你是非技术人员,也能参与到 AI 应用的定义和数据运营过程中。由于 Dify 内置了构建 LLM 应用所需的关键技术栈,包括对数百个模型的支持、直观的 Prompt 编排界面、高质量的 RAG 引擎、稳健的
Deepseek 集成 Dify 应用开发平台实现Rag(知识检索)
介绍
Dify 是一款开源的大语言模型(LLM) 应用开发平台。它融合了后端即服务(Backend as Service)和 LLMOps 的理念,使开发者可以快速搭建生产级的生成式 AI 应用。即使你是非技术人员,也能参与到 AI 应用的定义和数据运营过程中。
由于 Dify 内置了构建 LLM 应用所需的关键技术栈,包括对数百个模型的支持、直观的 Prompt 编排界面、高质量的 RAG 引擎、稳健的 Agent 框架、灵活的流程编排,并同时提供了一套易用的界面和 API。这为开发者节省了许多重复造轮子的时间,使其可以专注在创新和业务需求上。
快速开始(Docker)
克隆 Dify 代码仓库
# 如果没有安装git 可以使用yum install git
git clone https://github.com/langgenius/dify.git
启动 Dify
-
进入 Dify 源代码的 Docker 目录
cd dify/docker
-
复制环境配置文件
cp .env.example .env
-
启动 Docker 容器
根据你系统上的 Docker Compose 版本,选择合适的命令来启动容器。你可以通过
$ docker compose version
命令检查版本,详细说明请参考 :- 如果版本是 Docker Compose V2,使用以下命令:
最新
docker compose up -d
- 如果版本是 Docker Compose V1,使用以下命令:
docker-compose up -d
- 如果版本是 Docker Compose V2,使用以下命令:
运行命令后,你应该会看到类似以下的输出,显示所有容器的状态和端口映射:
[+] Running 11/11
✔ Network docker_ssrf_proxy_network Created 0.1s
✔ Network docker_default Created 0.0s
✔ Container docker-redis-1 Started 2.4s
✔ Container docker-ssrf_proxy-1 Started 2.8s
✔ Container docker-sandbox-1 Started 2.7s
✔ Container docker-web-1 Started 2.7s
✔ Container docker-weaviate-1 Started 2.4s
✔ Container docker-db-1 Started 2.7s
✔ Container docker-api-1 Started 6.5s
✔ Container docker-worker-1 Started 6.4s
✔ Container docker-nginx-1 Started 7.1s
最后检查是否所有容器都正常运行:
docker compose ps
在这个输出中,你应该可以看到包括 3 个业务服务 api / worker / web
,以及 6 个基础组件 weaviate / db / redis / nginx / ssrf_proxy / sandbox
。
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
docker-api-1 langgenius/dify-api:0.6.13 "/bin/bash /entrypoi…" api About a minute ago Up About a minute 5001/tcp
docker-db-1 postgres:15-alpine "docker-entrypoint.s…" db About a minute ago Up About a minute (healthy) 5432/tcp
docker-nginx-1 nginx:latest "sh -c 'cp /docker-e…" nginx About a minute ago Up About a minute 0.0.0.0:80->80/tcp, :::80->80/tcp, 0.0.0.0:443->443/tcp, :::443->443/tcp
docker-redis-1 redis:6-alpine "docker-entrypoint.s…" redis About a minute ago Up About a minute (healthy) 6379/tcp
docker-sandbox-1 langgenius/dify-sandbox:0.2.1 "/main" sandbox About a minute ago Up About a minute
docker-ssrf_proxy-1 ubuntu/squid:latest "sh -c 'cp /docker-e…" ssrf_proxy About a minute ago Up About a minute 3128/tcp
docker-weaviate-1 semitechnologies/weaviate:1.19.0 "/bin/weaviate --hos…" weaviate About a minute ago Up About a minute
docker-web-1 langgenius/dify-web:0.6.13 "/bin/sh ./entrypoin…" web About a minute ago Up About a minute 3000/tcp
docker-worker-1 langgenius/dify-api:0.6.13 "/bin/bash /entrypoi…" worker About a minute ago Up About a minute 5001/tcp
通过这些步骤,你应该可以成功在本地安装 Dify。
更新 Dify
进入 dify 源代码的 docker 目录,按顺序执行以下命令:
cd dify/docker
docker compose down
git pull origin main
docker compose pull
docker compose up -d
同步环境变量配置 (重要!)
-
如果
.env.example
文件有更新,请务必同步修改你本地的.env
文件。 -
检查
.env
文件中的所有配置项,确保它们与你的实际运行环境相匹配。你可能需要将.env.example
中的新变量添加到.env
文件中,并更新已更改的任何值。
访问 Dify 控制台
你可以先前往管理员初始化页面设置设置管理员账户:
# 本地环境
http://localhost/install
# 服务器环境
http://your_server_ip/install
Dify 主页面:
# 本地环境
http://localhost
# 服务器环境
http://your_server_ip
将 DeepSeek 接入至 Dify
点击 Dify 平台右上角头像 → 设置 → 模型供应商,选择 Ollama,轻点“添加模型”。
::: tip 如果无法添加时, 可能为监听不到ollama(因为跨docker问题)
# 在Linux宿主机上执行, 然后再次添加模型
export OLLAMA_HOST=0.0.0.0:11434
:::
Java 调用 Dify API (集成Rag)
创建工作流
在 Dify 控制台的「工作室」-> 创建「工作流」-> 输入应用名称 -> 确定。
编排工作流
如下图所示, 先在开始时加入输入自定义字段如content
, 然后加入 知识检索 、 大语言模型(LLM) 和节点, 最后在结束节点输出自定义字段如result
的值为LLM/text String
即LLM的输出值。
开始
知识检索
大语言模型(LLM)
结束
这样我们就可以通过输入content
来获取LLM的输出值result
。
点击运行进行测试, 通过后点击发布, 即可完成工作流的创建。
访问API
在工作流左侧菜单点击访问API, 点击API密钥生成一个密钥, 然后在Java代码中调用Dify API即可。
根据文档可知基础路径为http://YOUR_API_IP:PORT/v1
请求路径为http://YOUR_API_IP:PORT/v1/workflows/run
::: code-group
## user (string) Required 用户标识,用于定义终端用户的身份,方便检索、统计。 由开发者定义规则,需保证用户标识在应用内唯一。
curl -X POST "http://YOUR_IP:PORT/v1/workflows/run" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"inputs": {"content": "命名风格"},
"response_mode": "blocking",
"user": "user123"
}'
{
"task_id": "45ddbcdb-6563-470f-91dc-50d1b8238a04",
"workflow_run_id": "2e437682-6a76-4b67-b4bb-8dd0f005afc9",
"data": {
"id": "2e437682-6a76-4b67-b4bb-8dd0f005afc9",
"workflow_id": "f5a03303-778c-4f0d-a7dd-6197a02b8d1c",
"status": "succeeded",
"outputs": {
"result": "<think>\n好,我现在需要按照用户的要求来生成关于“命名风格”的参考信息。让我先仔细看看用户提供的例子。\n\n用户给了一个《Java 开发手册(黄山版)》中的编程规范部分,特别是第(一)点的“编号规定”。里面列出了严格的命名规则,比如不能使用下划线或美元符号开头或结尾,且不能混合拼音和英文,同时不能直接用中文名称。还有一些例子,比如命名字段时需要使用`is_xxx`的格式,并且POJO类中的布尔类型变量不能加前缀`is_`。\n\n我需要将这些规则整合成一个明确、简洁的列表,作为参考信息的一部分。首先,我要确保每个规则都清晰地表达出来,避免模糊不清的情况。\n\n接下来,我会逐一分析每一个规定:\n\n1. **所有编程相关的命名均不能以下划线或美元符号开始,也不能以下划线或美元符号结束**:这意味着不能在字段名中使用`_`或 `$`。比如 `_name`、$\\Object$ 等都是不允许的。\n\n2. **所有编程相关的命名严禁使用拼音与英文混合的方式,更不允许直接使用中文的方式**:这意味着字段名必须只用一个语言的拼写,不能混译。例如 `ali` 是可以的,但 `Ali` 就不行,或者像 `alibaba` 也是一个合法名称,而不是将其翻译成英文。\n\n3. **正例和反例都要包含在内**:比如正确的命名方式包括国际通用名称如 `taobao`、`kaikeba` 等,而国际通用的英文名称如 `hangzhou` 和 `zihuang` 也是允许的。同时,像 `myapp` 这样的纯中文名称是不允许的。\n\n4. **“正确的英文拼写和语法可以让阅读者易于理解,避免歧义”**:这一点很重要,因为它强调了在命名时应遵循清晰、准确的格式,以便读者能够轻松理解和阅读代码。\n\n5. **任何字段如果为非负数,必须使用 `unsigned tinyint`**:这意味着字段名中不能包含数字,但可以是 `unsigned` 之类的单词开头。例如 `is_deleted` 是正确的,而 `36` 这样的数字则是不允许的。\n\n6. **根据国家法律、网络运行状态、网络安全事件、个人敏感信息操作等相关记录,留存的日志不小于六个月,并且进行网络多机备份**:这是一个安全规范,但不是关于命名风格的内容,所以暂时不需要将其加入到这里的列表中。\n\n7. **应用中的扩展日志(如打点、临时监控、访问日志等)命名方式**:这部分提到日志的命名规则,包括分段的名称。例如 `appName_logType_logName.loglogType` 和 `logName`。这些规则在实际开发中非常有用,可以帮助管理日志文件,并且有助于归类查找。\n\n8. **“为了达到代码自解释的目标,任何自定义编程元素在命名时,使用完整的单词组合来表达”**:这意味着自定义元素的命名不能只是简单的缩写或前缀,必须是一个完整的单词组合。例如 `AtomicReferenceFieldUpdater`。\n\n9. **“推荐在常量与变量命名时,表示类型的名词放在词尾,以提升辨识度”**:这一点强调了变量名的结构,通常会将类型部分放在后面。例如 `startTime / workQueue / nameList / TERMINATED_THREAD_COUNT`。\n\n10. **“如果模块、接口、类、方法使用了设计模式,在命名时要体现出具体模式”**:这说明在模块、接口、类、方法名中加入设计模式的元素,有助于更清晰地表达这些部分。例如 `AtomicReferenceFieldUpdater` 是一种设计模式。\n\n现在,我需要把这些规则整理成一个结构化的列表,确保每个点都准确无误,并且用简练的语言表达出来。可能还需要考虑是否有重复或可以优化的地方,但根据用户提供的示例,看起来已经足够详细和全面了。\n\n最后,我会将这些规则整合成一段清晰的文字,作为《Java 开发手册》中的“编号规定(编程相关部分)”的第(一)点,确保每个条款都准确无误,并且符合用户提供的示例格式。\n</think>\n\n以下是根据用户的参考信息生成的“命名风格”部分:\n\n### 编程相关的命名规则(编程相关部分)\n\n1. **字段名不能以下划线或美元符号开始或结束** \n - 例如:`_name / __name / $Object / name_ / name$ / Object`。\n\n2. **字段名严禁使用拼音与英文混合的方式,更不允许直接使用中文方式** \n - 正例:正确的拼写如 `ali / alibaba / taobao / kaikeba / aliyun / youku / hangzhou`。\n - 反例:直接用中文名称如 `myapp`。\n\n3. **任何字段必须使用 `is_xxx` 的格式命名,且 POJO 类中的布尔变量不能加前缀** \n - 正例:字段名如 `is_deleted` 是正确的,而 `36` 无效。\n - 反例:纯中文字段如 `myapp` 不允许。\n\n4. **日志命名规则** \n - 日志文件长度至少六个月,并进行网络多机备份。 \n - 按照段落形式命名,例如 `appName_logType_logName.loglogType` 和 `logName`。\n\n5. **自定义编程元素命名方式** \n - 使用完整的单词组合表达设计模式,如 `AtomicReferenceFieldUpdater`。\n\n6. **常量与变量命名规则** \n - 表示类型的名词放在词尾以提升辨识度,例如 `startTime / workQueue / nameList / TERMINATED_THREAD_COUNT`。\n \n7. **设计模式在模块、接口、类、方法中的应用** \n - 根据设计模式命名模块、接口或字段名,如 `AtomicReferenceFieldUpdater` 用于类。\n\n这些规则确保了命名的清晰、准确和符合规范,有助于代码的可解释性和维护。"
},
"error": null,
"elapsed_time": 199.95265221502632,
"total_tokens": 1983,
"total_steps": 4,
"created_at": 1743954879,
"finished_at": 1743955079
}
}
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import java.util.UUID;
public class DifyWorkflowClient {
public static void main(String[] args) {
// Dify API 配置参数
String apiKey = "YOUR_API_KEY"; // 替换为真实API密钥(从Dify工作流获取)
String workflowUrl = "http://YOUR_API_IP:PORT/v1/workflows/run";
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
HttpPost post = new HttpPost(workflowUrl);
// 构建请求体(根据工作流输入参数调整)
JSONObject requestBody = new JSONObject();
JSONObject inputs = new JSONObject();
inputs.put("content", "Hello, world!"); // 对应工作流输入字段
requestBody.put("inputs", inputs);
requestBody.put("response_mode", "blocking"); // streaming 流式模式(推荐)。基于 SSE(Server-Sent Events)实现类似打字机输出方式的流式返回。blocking 阻塞模式,等待执行完毕后返回结果。(请求若流程较长可能会被中断)。 由于 Cloudflare 限制,请求会在 100 秒超时无返回后中断。
requestBody.put("user", UUID.randomUUID().toString().replace("-", "")); // 用于定义终端用户的身份, 每个会话建议唯一
post.setEntity(new StringEntity(requestBody.toJSONString()));
post.setHeader("Content-Type", "application/json");
post.setHeader("Authorization", "Bearer " + apiKey); // 关键鉴权头
// 执行请求
HttpResponse response = httpClient.execute(post);
String result = EntityUtils.toString(response.getEntity());
// System.out.println("Dify API 原始响应:\n" + result);
// 解析响应
JSONObject jsonResponse = JSON.parseObject(result);
// 提取输出结果(根据工作流输出配置调整路径)
JSONObject data = jsonResponse.getJSONObject("data");
if (data != null) {
JSONObject outputs = data.getJSONObject("outputs");
if (outputs != null) {
String answer = outputs.getString("result"); // 假设输出字段为result
// 清理标签(根据实际需求调整)
String cleaned = answer.replaceAll("\\u003c/?.*?\\u003e", "").trim();
System.out.println("最终结果: " + cleaned);
} else {
System.out.println("响应中缺失 outputs 字段");
}
} else {
System.out.println("请求失败,错误信息: " + jsonResponse.getString("message"));
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
:::
更多推荐
所有评论(0)