最近业务提了一个保险产品推荐的需求。但是其实业务并不知道如何让AI来做,也不知道AI能做到什么程度。

只是简单地在需求里面写了有车无房推荐车险,已婚未育,推荐xx医疗险。

和业务反复聊了好几轮,其实他们也不知道自己想要什么。

迫于无奈,只能基于自己对医疗险的简单理解,做了一个小小的demo出来引导他们的思路。

Demo实现

Demo的实现,主要是基于Dify。

知识库准备

虽然仅仅是个demo,开始的时候还是希望业务提供一些产品的条款,但是反复拉扯多次,没有拿到,也可能是因为代理业务刚刚开始,没有也是正常。

最后很无奈,只能自己搞一些假数据出来。

知识库构建

就使用父子分段的方式,将假数据,直接导入了知识库。

工作流搭建

这个demo工作流建立的背景主要有以下几点:

  1. 这个产品推荐的Agent后续计划主要面向的是公司的销售人员或者说代理人。
  2. 暂不考虑直接面向客户,所以相对来说,不需要考虑太多业务上的风险,因为代理人可以进行人为筛选或者说复核。
  3. 因为是Demo,所以没必要投入太多时间。

Agent工作流

通过上图可以看到,这个Demo工作流总共有两个LLM节点,一个知识库检索节点。他的整体运行逻辑如下:

信息收集节点

由第一个LLM节点来收集必要的业务信息,比如给谁投保,年龄等。

它的提示词是这样子的:

# 角色
你是一个严谨、高效的AI数据处理专员。你的任务是检查用户输入是否满足推荐保险所需的所有【必要信息】,并生成一个结构化的JSON输出。

# 上下文:必要信息清单
你将收到以下可能包含缺失值的客户信息:
- 与被保人关系: {{start.relationship}}
- 被保人年龄: {{start.insured_age}}
- 被保人健康状况: {{start.insured_health}}
- 投保预算: {{start.budget}}

# 工作指令
1. **检查清单**: 检查上述【必要信息清单】中的每一项是否都已提供。
2. **如果信息完整**:
a. **判定**: `is_complete` 为 `true`。
b. **生成关键词查询 (query)**: 你的目标是生成一个最高效的关键词字符串,用于在知识库中精准检索。**必须**综合利用所有已知信息:
- **人生阶段**: 根据`被保人年龄`判断(例如:小于18岁加“少儿”,大于55岁加“高龄”)。
- **健康状况**: 从`被保人健康状况`中提取核心词(例如:“健康”加“健康体”,“糖尿病”加“糖尿病”)。
- **预算水平**: 根据`投保预算`判断(例如:预算较低加“性价比”,预算充足加“高端”)。
- 将所有关键词用空格连接。
3. **如果信息不完整**:
a. **判定**: `is_complete` 为 `false`。
b. **生成反问**: 遵循“友好、一次性问完、多样化”的原则,动态生成一句反问,要求用户补全**所有**缺失的信息项。

# 输出格式要求 (必须严格遵循)

## 如果信息完整,输出:
{
"is_complete": true,
"query": "[此处放入你生成的【关键词查询】,例如:'少儿 性价比 健康体' 或 '高龄 糖尿病 高端']",
"clarification_question": ""
}

## 如果存在信息缺失,输出:
{
"is_complete": false,
"query": "",
"clarification_question": "[此处放入你遵循原则后,动态生成的一句反问话术,例如:'您好,为了给您推荐最合适的保险,还需要了解一下【被保人的年龄】和【投保预算】是多少呢?']"
}

从提示词(这个提示词非常简单有,也没有深入验证,大家就当个示例看即可),可以看到,他的主要作用就是完成必要信息的收集。

在后续的流转中,可以看到,我使用了一个判断节点,主要就是判断信息是否收集完全了。

如果收集完全就进入知识库检索,如果没有,就继续询问用户。

这个判断节点使用的参数是:is_complete

因此,为了判断节点的正确运转,这里我们必须要是使用Dify的LLM节点的结构化输出功能。

在这里大家如果不会写这个结构输出的代码,我们可以直接使用这个功能:

结构化输出

参数提取节点

下一个节点大家可以看到是一个代码节点,这个节点,我主要是为了从上一步的LLM节点的结构化输出的json中将参数提取出来,用于后续的判断和使用。

def main(json_data: dict) -> dict:
is_complete = str(json_data.get("is_complete"))
query = json_data.get("query")
summary = json_data.get("summary")
clarification_question = json_data.get("clarification_question")
return {
"is_complete": is_complete,
"query": query,
"summary":summary,
"clarification_question": clarification_question,
}

同样的,在这一步,大家不会写代码,也可以让大模型来给我们写,我们只需要验证即可:

代码节点

接下来的条件判断,决定了我是继续和用户沟通收集必要信息,还是确定信息都收集到了,可以开始检索知识库了。

到这里,如果顺利的话,效果大概是这个样子的:

信息收集

知识库检索

知识库的检索这里,就不细说了,因为本身只是个demo,真正的生产环境不可能用这种简单粗暴地方式的。

知识库检索结果后面为什么还新增了一个判断节点呢,主要是为了增加工作流的健壮性,万一知识库什么也检索不出来,那就没必要去调用大模型了,因为结果必然是错的。

产品推荐节点

在这一步,其实就比较简单了:

# 角色
你是一位顶级的、严谨的保险产品推荐专家。

# 核心原则 (必须遵守)
**1. 绝对忠于原文:** 你的所有推荐都必须严格基于知识库:产品资料中提供的产品信息。严禁杜撰。
**2. 简洁至上:** 你的回答要直击要点。

# 上下文
- 客户情况总结:{{#1753782730373.summary#}}
- 相关产品资料: {{#context#}}

# 工作流指令
1. 根据“客户情况总结”,在“相关产品资料”中进行深度分析和比较,选出最匹配的一款产品。
2. 严格按照下面的“输出格式要求”,生成简洁、有力的个性化推荐。

# 输出格式要求
### **给您的专属推荐**
您好,根据您的情况,我为您挑选了最合适的方案。

#### **🏆 首推这款:[请填入得分最高的产品名称]**
**一句话理由:** [请用一句话,凝练地概括为什么这款产品最适合他,必须结合用户的具体情况和产品在知识库中的核心卖点。]

#### **为您划重点,这几个优势很关键:**
* **健康方面:** [说明这款产品如何精准匹配用户的健康状况,直接引用知识库中的“核保亮点”。]
* **需求方面:** [说明这款产品如何满足用户的预算或核心需求,直接引用知识库中的“保费”或“免赔额详情”等特点。]
* **额外亮点:** [从知识库中再找一个最突出的优点。]

#### **还有疑问?随时问我。**

这一步,其实是大模型最擅长做的东西,文本的整合和加工。这一步也主要就是为了,对推荐的产品给出一个推荐理由。

产品推荐生产环境的实现思路

制作Demo的过程中其实也一直在思考生产环境应该如何实现。一个初步的方向是可以通过以下的方式实现。

用户信息—-数据库查询粗筛——健康告知细筛—-最终产品一句话推荐。