java对接Dify的聊天助手API(实战篇)

482 阅读3分钟

前面的博客有讲到如何部署Dify以及简单使用,为了迎合企业级需求,快速搭建AI应用。

image.png

此次演示采用RuoYI-Vue-Plus框架,后续会出具体使用教程!

步骤一:启动Dify 进入Dify的docker目录,cmd回车,执行如下命令

docker compose up -d

image.png

注:需要提前启动docker,目前使用的Docker Desktop

image.png

浏览器访问界面:localhost:80

image.png

步骤二:搭建聊天助手

image.png

中间步骤省略,可参考之前的教程

image.png

步骤三:发布并测试

image.png

此次演示为"发送对话消息"的API

image.png

获取秘钥

image.png

postman接口测试

image.png

需要请求体信息,具体参照接口文档

image.png

测试效果

image.png

返回信息

image.png

扩展:清除控制台信息

image.png

至此,对接流程已通,需要进行编码环节啦

步骤四:编写java代码

image.png

目前idea版本2024.2,已成功破解,需要资料的可以加入技术群获取

application.yml

# 聊天助手 
chatAssist: 
    authorization: Bearer 你的秘钥 
    url: 你的dify服务地址

ChatAssistController

@RestController
@RequestMapping("/chat")
@Slf4j
public class ChatAssistController {
    @Autowired
    private ChatAssistService chatAssistService;

    /**
     * 聊天对话
     *
     * @param chatMessageDto
     * @return
     */
    @PostMapping("/messages")
    public SseEmitter sendChatMessage(@RequestBody ChatMessageDto chatMessageDto) {
        return chatAssistService.sendChatMessage(chatMessageDto);
    }
}

ChatAssistService

public interface ChatAssistService {
    /**
     * 聊天对话
     *
     * @param chatMessageDto
     * @return
     */
    public SseEmitter sendChatMessage(@RequestBody ChatMessageDto chatMessageDto);
}

ChatAssistServiceImpl

@Service
@Slf4j
public class ChatAssistServiceImpl implements ChatAssistService {
    @Autowired
    private DifyConfig difyConfig;

    @Autowired
    private RestTemplate restTemplate;

    /**
     * 聊天对话
     *
     * @param chatMessageDto
     * @return
     */
    @Override
    public SseEmitter sendChatMessage(ChatMessageDto chatMessageDto) {
        // 创建 SSE Emitter,设置超时时间(例如 5 分钟)
        SseEmitter emitter = new SseEmitter(300_000L);

        // 使用线程池处理异步任务
        ExecutorService executor = Executors.newSingleThreadExecutor();
        executor.execute(() -> {
            try {
                String messageUrl = difyConfig.getChatAssistUrl() + "/chat-messages";

                // 创建请求头
                HttpHeaders headers = new HttpHeaders();
                headers.set("Authorization", difyConfig.getChatAssistAuthorization());
                headers.setContentType(MediaType.APPLICATION_JSON);

                // 创建请求实体
                HttpEntity<ChatMessageDto> requestEntity = new HttpEntity<>(chatMessageDto, headers);

                // 发送请求并处理流式响应
                restTemplate.execute(
                        messageUrl,
                        HttpMethod.POST,
                        request -> {
                            // 设置请求头和请求体
                            request.getHeaders().setContentType(MediaType.APPLICATION_JSON);
                            request.getHeaders().addAll(requestEntity.getHeaders());

                            // 写入请求体
                            if (requestEntity.getBody() != null) {
                                new ObjectMapper().writeValue(request.getBody(), requestEntity.getBody());
                            }
                        },
                        response -> {
                            try (BufferedReader reader = new BufferedReader(new InputStreamReader(response.getBody()))) {
                                String line;
                                while ((line = reader.readLine()) != null) {
                                    log.info("line: {}", line);
                                    // 将每一行数据推送到前端
                                    emitter.send(SseEmitter.event().data(line));
                                }
                                // 完成推送
                                emitter.complete();
                            }
                            return null;
                        }
                );
            } catch (Exception e) {
                // 发生错误时推送错误信息
                emitter.completeWithError(e);
            } finally {
                executor.shutdown();
                log.info("对话结束...");
            }
        });
        // 关闭线程池
        executor.shutdown();
        log.info("对话完成...");
        return emitter;
    }
}


ChatMessageDto

@Data
public class ChatMessageDto {
    @JsonProperty("inputs")
    private Object inputs;

    @JsonProperty("query")
    private String query;

    @JsonProperty("response_mode")
    private String responseMode;

    @JsonProperty("conversation_id")
    private String conversationId;

    @JsonProperty("user")
    private String user;

}

DifyConfig

@Data
@Component
public class DifyConfig {
    @Value("${chatAssist.authorization}")
    private String chatAssistAuthorization;

    @Value("${chatAssist.url}")
    private String chatAssistUrl;

    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

步骤五:启动项目

与若依框架一样,需要启动redis服务

后端

image.png

postman测试接口

image.png

测试该接口发现,需要认证信息,知道该怎么办了把,没错,启动前端!

前端

image.png

修改配置文件,由于Dify在本地部署,默认端口80与Dify冲突,否则造成服务不可用,所以修改为8080

控制台执行命令

npm install # 第一步
npm run dev # 第二步

image.png

自动跳转至登录页

image.png

登录后,f12弹出开发人员常用框

image.png

保存并执行

image.png

至此,后端已成功对接聊天对话的API,其他API操作同理,可以与前端快速的搭建AI对话聊天,基于知识库实现企业级需求!

本人正在打造技术交流群,欢迎志同道合的朋友一起探讨,一起努力,通过自己的努力,在技术岗位这条道路上走得更远。QQ群号:925317809 备注:技术交流 即可通过!

加入技术群可以获取资料,含AI资料、Spring AI中文文档等,等你加入~