- 作者:老汪软件技巧
- 发表时间:2024-11-09 04:01
- 浏览量:
一、引子
AI客服的概念早已不再新鲜,随着自然语言处理技术的不断进步,越来越多的企业尝试将 AI 客服引入实际业务中。然而,尽管大模型具备强大的语言理解能力,受限于业务场景的复杂性和大模型自身的局限性,AI 客服在许多企业中的应用落地效果并不理想。尤其是在面对多领域、多场景的客户需求时,单一的 AI 模型往往难以提供精准且符合上下文的回答,进而影响了用户体验和企业的运营效率。
二、业务梳理
业务场景的多样性使得客户问题不仅限于某一个方面。客户可能会询问产品信息(售前)、订单和退换货等服务(售后),以及公司政策或流程等日常事务(业务支持)。面对这些高度垂直化的需求,传统的 AI 客服难以兼顾各个领域,导致服务体验割裂、回答不准确。
为了解决这一问题,我们采用了一种更为灵活的方式,将客服系统按照业务维度进行划分,拆解为多个专门负责不同领域的 AI 客服模块。比如,可以按照问题类型分别构建售前、售后和日常业务三大问题领域的AI客服,对于用户发送的问题,首先通过一个中转服务利用AI进行判断属于那个领域的问题,再转发到适配的客服。
三、架构设计
在本次的设计中,我们需要用到一个平台 - Dify,我们通过它去连接大模型可以单独部署AI应用,这样在项目里只需要封装API进行调用即可,把业务系统与AI应用进行解耦。因此,我们可以抽象出业务架构图如下:
通过架构图可以看出,我们这个系统需要4个AI应用来支持,每个应用的开发和维护都通过Dify进行,我们的业务系统直接调用即可。
四、技术实现部署Dify
本文对Dify的部署不予演示,感兴趣的同学直接去官网下载即可,部署非常简单,通过docker可以一键部署。
创建应用
接下来开始创建AI应用,应用开发的重点在提示词的编写。我们先以判断客户需求的AI客服为例,如下:
提示词如下:
提示词编写完成后,可以在右侧测试效果,同时记得点击发布,如下:
同理,另外三个业务客服都采用上述方式创建。另外,每个应用都支持关联知识库,在实际场景中,可以把企业客服知识文档放进去。
API封装
Dify已经对API封装的格式做了说明,如下:
这里需要说明下,我们在每个应用里创建的API-Key都是调用这个应用的凭证,所以在项目里调用应用都需要先生成它的Key,并把它配置在项目里,如下:
public class DifyServerConstants {
/**
* The base URL of the Dify API.
*/
public static final String BASE_URL = "https://dify.xxxxxxxx.com.cn/v1";
/**
* XX应用api key
*/
public static final String APP_API_KEY = "XXXXXXXXXX";
}
在实际中根据自己的应用使用情况可以把key都统一管理起来,常量类是种实现,写在配置文件里也是。然后我们基于官方的文档简单封装下,代码如下:
private String getResultByDify(String text, String BearerAuth) {
//设置请求体
JSONObject body = new JSONObject();
body.put("query", text);
body.put("response_mode", "blocking");
// 注:这个userId是调用dify应用的必须参数,一般取当前登录用户即可,如没有特殊要求也可随意指定
Long userId = LoginHelper.getUserId();
body.put("inputs", "");
// 封装请求体和请求头
String jsonString = body.toJSONString();
//发送post请求,阻塞式
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.setAccept(List.of(MediaType.APPLICATION_JSON));
headers.setBearerAuth(BearerAuth);
// 封装请求体和请求头
HttpEntity entity = new HttpEntity<>(jsonString, headers);
//url
String url = DifyServerConstants.BASE_URL + "/chat-messages";
//发送请求
ResponseEntity stringResponseEntity =
restTemplate.postForEntity(url, entity, String.class);
//获取answer字段
if (ObjectUtil.isNotEmpty(stringResponseEntity.getBody())) {
JSONObject jsonObject = JSONObject.parseObject(stringResponseEntity.getBody());
String answer = jsonObject.getString("answer");
//去掉markdown
answer = StrUtil.removeAll(answer, "```json");
answer = StrUtil.removeAll(answer, "```");
return answer;
}
return null;
}
我们可以把它声明为一个接口或者工具类,只需要传入问题和应用的key就可以实现通用调用了,如下:
String answer = getResultByDify(question, DifyServerConstants.XXX_KEY);
转发逻辑实现
编写一个接口用来接收用户输入的问题,代码如下:
/**
* 根据问题分类并调用相应的Dify服务获取答案
*
* @param userQuery 用户提出的问题
* @param BearerAuth Dify的Bearer token
* @return Dify返回的答案
*/
public String handleUserQuery(String userQuery, String BearerAuth) {
// 调用分类模型,获取类型
String domainJson = getResultByDify(userQuery, BearerAuth);
// 解析结果json并返回类型
int domainType = extractTypeFromJson(domainJson);
// 根据分类结果调用不同的Dify服务
switch (domainType) {
case 1:
return getResultByDify(userQuery, BearerAuth); // 售前
case 2:
return getResultByDify(userQuery, BearerAuth); // 售后
case 3:
return getResultByDify(userQuery, BearerAuth); // 日常业务
// 后续可扩展的其他领域,如技术支持
default:
return "抱歉,我无法识别您的问题类别。";
}
}
另外,还需要对AI返回的结果解析下,代码如下:
/**
* 从分类结果的JSON中提取领域类型
*
* @param jsonResponse 分类结果的JSON字符串
* @return 领域类型数字
*/
private int extractTypeFromJson(String jsonResponse) {
JSONObject jsonObject = JSONObject.parseObject(jsonResponse);
return jsonObject.getInteger("type");
}
至此,我们就简单地实现了这个AI客服智能分发系统,我们通过日志记录下一次测试过程,如下:
五、小结
其实上述的这个小demo仅仅依靠dify的工作流就可以实现多应用的协作,但实际业务中,我们可能会遇到在现有的客服系统中去集成AI;或者我们的系统需要先接入AI客服,但客户问题并未得到解决,再接入人工客服,自然就需要我们需要相应的服务管理。因此,本文重点在实现的思路和方案上,希望对大家有所帮助!