一、Dify 简介
Dify 是一个开源的 AI 应用开发平台,旨在帮助开发者快速构建和部署基于大语言模型(LLM)的应用。它提供了可视化的界面和丰富的工具,简化了 AI 应用的开发流程。
Dify 内置知识库管理功能,支持上传文档并自动处理为可检索的知识片段,方便构建基于知识的问答系统。
Dify 适用于构建智能客服、内容生成、数据分析报告等多种 AI 应用场景,特别适合企业和个人开发者快速实现 AI 创意。
开源特性使得 Dify 可以免费使用和自定义修改,社区持续提供更新和支持,降低了 AI 应用开发的门槛。
二、准备工作
- 获取 API 密钥
- 登录 Dify 平台控制台
- 在「API 密钥」模块创建新的密钥
- 搭建 Java 环境
- JDK 1.8 及以上
- 新建一个 Spring Boot 项目,导入相关的依赖文件,完整的依赖文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>AiDify</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.0.RELEASE</version>
<relativePath/>
</parent>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.36</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>2.0.58</version>
</dependency>
</dependencies>
</project>
三、实现过程
1. Controller 层代码
import com.wang.entity.MessageVO;
import com.wang.entity.StreamResponse;
import com.wang.service.DifyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
@RestController
@RequestMapping("/api")
public class DifyController {
@Value("${dify.api.key}")
private String difyKey;
@Autowired
private DifyService difyService;
@PostMapping(value = "/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<StreamResponse> difyStream(@RequestBody MessageVO vo) {
return difyService.streamingMessage(vo.getQuery(), 0L, difyKey)
.onErrorResume(throwable -> {
StreamResponse errorResponse = new StreamResponse();
errorResponse.setAnswer("Stream processing error: " + throwable.getMessage());
return Flux.just(errorResponse);
});
}
}
2. Service 层代码
import com.wang.entity.StreamResponse;
import reactor.core.publisher.Flux;
public interface DifyService {
Flux<StreamResponse> streamingMessage(String query, Long userId, String apiKey);
}
import com.alibaba.fastjson.JSON;
import com.wang.entity.DifyRequestBody;
import com.wang.entity.StreamResponse;
import com.wang.service.DifyService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Flux;
import java.util.HashMap;
@Service
@RequiredArgsConstructor
public class DifyServiceImpl implements DifyService {
@Value("${dify.api.url}")
private String url;
private final WebClient webClient;
/**
* @param query 查询文本
* @param userId 用户 id
* @param apiKey apiKey
* @return Flux 响应流
*/
public Flux<StreamResponse> streamingMessage(String query, Long userId, String apiKey) {
// 1.设置请求体
DifyRequestBody body = new DifyRequestBody();
body.setInputs(new HashMap<>());
body.setQuery(query);
body.setResponseMode("streaming");
body.setConversationId("");
body.setUser(userId.toString());
// 2.使用 webclient 发送 post 请求
return webClient.post()
.uri(url)
.headers(httpHeaders -> {
httpHeaders.setContentType(MediaType.APPLICATION_JSON);
httpHeaders.setBearerAuth(apiKey);
})
.bodyValue(JSON.toJSONString(body))
.retrieve()
.bodyToFlux(StreamResponse.class);
}
}
3. 实体类代码
import lombok.Data;
import java.io.Serializable;
import java.util.Map;
/**
* Dify 请求体.
*/
@Data
public class DifyRequestBody implements Serializable {
/**
* 用户输入/提问内容.
*/
private String query;
/**
* 允许传入 App 定义的各变量值.
*/
private Map<String, String> inputs;
/**
* 响应模式,streaming 流式,blocking 阻塞.
*/
private String responseMode;
/**
* 用户标识.
*/
private String user;
/**
* 会话 id.
*/
private String conversationId;
}
@Data
public class StreamResponse implements Serializable {
String event;
String id;
String taskId;
String messageId;
String answer;
Long createdAt;
String conversationId;
}
@Data
public class MessageVO {
private String query;
}
4. Config 代码
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.function.client.WebClient;
@Configuration
public class WebClientConfig {
@Bean
public WebClient.Builder webClientBuilder() {
return WebClient.builder();
}
@Bean
public WebClient webClient(WebClient.Builder builder) {
return builder.build();
}
}
5. 配置文件
spring:
application:
name: app
server:
port: 8080
dify:
api:
url: 你自己的 url
key: app-你自己的密钥
四、常见问题排查
- 401 未授权错误
- 检查 API 密钥是否正确
- 确认请求头 Authorization 格式正确
- 500 服务器错误
- 检查请求参数格式是否是 json 格式
{
"query": "你好"
}

