Hologres+大模型初探,让ChatGPT回答商家问题

简介: 本文介绍基于Hologres+ChatGPT提供智能客服服务的实践。

1.前言

阿里巴巴商家服务团队旨在为商家提供智能化的解决方案,致力于帮助商家自助解决问题。主要的产品包括:

  1. 商家服务大厅:主要通过搜索的方式为商家提供服务,包含了工具、短视频、知识、服务专区等特色内容。同时商家服务大厅以多种形态通过不同渠道为商家提供千人千面的服务。
  2. PC版服务大厅:功能最全的PC主站服务大厅,为商家提供多元化的智能解决方案。
  3. 钉钉商家服务大厅:通过钉钉的方式,为商家提供更加方便、灵活易用的自助服务。 商2.png
  4. 千牛服务大厅:在商家千牛工作台上为商家随时随地提供客服服务。 商3.png
  5. 场景版服务大厅:通过悬浮小球的方式内嵌在商家常用的页面,例如申诉中心,服务触手可达。 商4.png
  6. 万象:智能问答机器人,以问答的模式帮助商家解决问题。如果商家仍未能解决,可以进一步联系人工,通过在、热线的方式联系客服小二帮助解决问题。 商5.png

总体来说,阿里巴巴商家服务团队的主要工作就是围绕“智能”和“服务”这两个关键词展开,为各个商家提供更加自助的解决问题能力,以此提高对商家的自助服务能力,同时也降低平台服务商家的客服人工成本。

在智能服务方面我们团队做了比较多的前沿探索,目前势不可挡的大模型凭借出色的自然语言理解能力,似乎在智能服务这方面大有可为,便萌生了让大模型帮助商家解决问题的想法。我们团队利用ChatGPT在智能答疑机器人场景做了初步的探索,下面是一些实践分享,希望通过这些分享为大家在商家服务、智能客服等场景提供更多的经验和思路。


2. 基于Fine-tuning的初次探索

那么如何让大模型能够回答商家的问题?第一想法就是基于Fine-tuning,通过训练微调的方式提升模型垂直领域的能力,让其掌握一些商家服务领域的知识,以具备回答商家问题的能力。

2.1 准备数据

在知识库中筛选了一些知识并将它们的内容格式化后,整理成如下格式(json line):

{"prompt":"淘宝商家服务大厅","completion":"2021年10月商家服务大厅升级,新增活动大促专题xxxxx"}
{"prompt":"单品宝是什么","completion":"单品宝是原限时打折的升级工具,可支持xxxx"}
{"prompt":"宝贝详情页可以添加多少个视频","completion":"在发布宝贝页一个宝贝在详情页中只能添加一个视频xxxx"}
{"prompt":"店铺经营主体变更需要先还清淘宝贷款吗","completion":"需要还清贷款,因为店铺xxx"}
{"prompt":"天猫活动商品价格力严重溢价是什么意思","completion":"溢价是指预计普惠成交价高于最低成交价严重溢价的意思是指xxxx"}
{"prompt":"买家退货单号虚假、没有物流信息怎么办","completion":"1.建议您先联系买家,确认下是否存在填错运单号等情况。2.若无法联系上买家,您可xxxx"}
{"prompt":"淘管家","completion":"淘管家是1688专业的分销订货平台,在淘管家xxxx"}
{"prompt":"手淘中猜你喜欢频道如何加入","completion":"手淘首页展示的猜你喜欢频道目前无法主动入驻是xxxxx"}
{"prompt":"买家删除了中评/差评,店铺评分(DSR)也会删除吗","completion":"若买家自行删除中差评或修改中差评为好评xxxx"}
{"prompt":"淘宝开店收费吗","completion":"淘宝开店都是免费,但为xxxx"}
...

在上述数据中,prompt字段为商家问题,completion为答案。用这些数据训练后,发现这种简单的一问一答的数据训练效果并不理想,向模型提问时,需要使问题和训练时的prompt保持高度相似时,模型才能够勉强给出较为正确的答案。 既然我们需要通过训练的方式提升模型垂直领域的能力,那么这些知识是否集中于某个领域,或者说大模型是否知道它们是否集中于某个领域呢?于是将原来的prompt按照如下方式进行了改写:

商6.png

  1. 明确AI在回答问题时的身份为“淘宝商家智能客服”,在回答问题时需要保持友善的态度,并且明确其目标为帮助商家解决问题;
  2. 额外给出一个问答样例(one-shot)。

按照这样的方式,最终的训练数据如下:

{
  "prompt":"你是淘宝商家智能客服,你聪明、友善,能够帮助商家解决问题。\n\nCustomer:你是谁?\nAI:您好,我是淘宝商家智能客服,请问有什么可以帮助你吗?\nCustomer:淘宝商家服务大厅\nAI:",
  "completion":"2021年10月商家服务大厅升级,新增活动大促专题xxxx"
}
{
  "prompt":"你是淘宝商家智能客服,你聪明、友善,能够帮助商家解决问题。\n\nCustomer:你是谁?\nAI:您好,我是淘宝商家智能客服,请问有什么可以帮助你吗?\nCustomer:单品宝是什么\nAI:",
  "completion":"单品宝是原限时打折的升级工具,可支持xxx"
}
{
  "prompt":"你是淘宝商家智能客服,你聪明、友善,能够帮助商家解决问题。\n\nCustomer:你是谁?\nAI:您好,我是淘宝商家智能客服,请问有什么可以帮助你吗?\nCustomer:宝贝详情页可以添加多少个视频\nAI:",
  "completion":"在发布宝贝页一个宝贝在详情页中只能添加一个视频,若您想xxx"
}
{
  "prompt":"你是淘宝商家智能客服,你聪明、友善,能够帮助商家解决问题。\n\nCustomer:你是谁?\nAI:您好,我是淘宝商家智能客服,请问有什么可以帮助你吗?\nCustomer:店铺经营主体变更需要先还清淘宝贷款吗\nAI:",
  "completion":"需要还清贷款。因为店铺经营主体变更流程中xxxx"
}
{
  "prompt":"你是淘宝商家智能客服,你聪明、友善,能够帮助商家解决问题。\n\nCustomer:你是谁?\nAI:您好,我是淘宝商家智能客服,请问有什么可以帮助你吗?\nCustomer:天猫活动商品价格力严重溢价是什么意思\nAI:",
  "completion":"溢价是指预计普惠成交价高于最低成交价,严重溢价的意思是指xxxx"
}
...

2.2 训练

在OpenAI目前的模型中只有davincicuriebabbageada,这些GPT-3.0版本的模型可以Fine-tuning适配,但再往后的版本暂不支持。训练的价格如下:

商7.png

可以看到使用训练后的Davinci模型的价格竟然高达0.12美元/1K tokens。再对比一下最新的GPT-4和GPT-3.5模型就知道它有多贵了:

商8.png

准备好数据、选择好模型后,便可以开始Fine-tuning了。方法很简单,只需要将文件上传至OpenAI后,再指定文件id和模型后即可对该模型进行训练了,具体的过程可以参照OpenAI官方文档。

2.3 训练结果

使用训练的模型进行测试,Prompt同样采取如下格式:

你是淘宝商家智能客服,你聪明、友善,能够帮助商家解决问题。
Customer:你是谁?
AI:您好,我是淘宝商家智能客服,请问有什么可以帮助你吗?
Customer:<question>

大概效果如下:

商9.png

2.4 训练效果总结

1.4.1 Fine-tuning是真的啊,加上一开始几次无效的尝试,很快就把免费的18美元的额度花完了,后面只能自己花钱充值了。作为一个纯正的穷哥们,虽然很难受,但也算为自己的兴趣交学费了。

1.4.2 上述基于Fine-tuning的方式效果并不理想,总结了如下几个原因:

  • 训练数据太少。本次训练只提供了100多条数据,对于大模型来说算是九牛一毛了,大模型的训练还需更多优质的数据。
  • 训练方式问题。由于在这方面不够专业,在使用OpenAI提供的Fine-tuning接口时,只上传了一个文件,采用默认参数就完成了训练。如果能够使用更加专业的训练方式,比如RLHF(依据人类反馈的强化学习),那么效果会更好。
  • 训练基于GPT-3模型,使用新的模型能有更好的效果。

1.4.3 Prompt真的很重要。给出一个好的提示,哪怕大模型不知道这个问题的答案,也能根据提示给出一个乍一看很像模像样的答案。

1.4.4 基于Fine-tuning的方式存在另外一个很重要的问题:在商家服务领域,很多知识需要不断更新,时效性较强,需要及时修正大模型中过时的内容,就需要耗费比较多的人力,这又变成了另一个难题。

3. 基于Embedding的实践

在基于Fine-tuning的方式失败后,找到了基于Embeddings的实践方案。首先用一句概括一下这个方法的原理:根据输入问题先通过搜索的方式检索出一些相关信息(Embedding),再将这些信息作为上下文辅助大模型回答这个问题(Chat)。
更简单地说,就是一种先搜再问的方式,下面便通过搜(Embedding)和问(Chat)这两个部分来介绍具体过程。

3.1 基于Embedding的流程介绍

Embedding(嵌入),以我这个小白的理解就是将自然语言转化为机器语言,即将我们说的一段话转化为一堆浮点数(向量),这个向量中包含了模型对自然语言含义和特征的理解。对于两个向量,可以用“距离”来衡量它们的相似度,离的越近的两个向量它们的相似度越高,对应的自然语言文本相似度也就越高。那么我们只需要简单的两步即可:

2.1.1 将商家服务知识库中的知识向量化后存入向量引擎;

2.1.2 将问题向量化后到向量引擎中进行检索,即可得到和问题相关的内容。


整体流程如下图所示:

商10.png

3.2 训练步骤

3.2.1 内容格式化

商家服务大厅中的内容包含如下几类,我们需要关注的是有哪些部分可以参与Embedding。

  • 短视频:包含标题、相似问和描述等文本内容。
  • 工具:商家服务特色操作类解决方案,如发起投诉、申诉、报备等。包含标题、相似问等文本内容。
  • 专区:一类业务解决方案的集合。包含标题、相似问、描述等文本内容。
  • 知识:最常用的解决方案,分两类
  • 文本知识(FAQ):文本知识,包含标题、相似问、知识内容等文本内容。
  • SOP:操作类知识,通过SOP流程驱动帮助商家解决问题。包含标题、相似问等文本内容。

在上面这些内容中,最终选择了知识进行向量化,考虑到以下两点:

  1. 知识绝大部分内容都是文本,可将其最大程度向量化,为后续的向量检索服务;
  2. 知识在商家服务中所有内容的数量占比超过90%,并且也是评价解决率最高的内容类型。

格式化的步骤如下:

  1. 知识的内容为html富文本或markdown,将其处理为纯文本格式,会造成一些内容(如超链)丢失;
  2. 对于过长的知识进行人工筛选,如果需要向量化,则将其以每500字符为一段的方式分为多个chunk,每个chunk的内容如下:
title: 知识标题; tags: 相似问1 相似问2; content: 知识正文内容

3.2.2 数据向量化

通过OpenAI的Embedding接口对格式化后的文本进行向量化,选择最新的text-embedding-ada-002模型,它支持的最大输入为8191个token:

商12.png 它的输出是一个长度为1536的向量(1536个浮点数):

商13.png

同时它的得分也更高:

商14.png

当然了,OpenAI Embedding API的价格也很美好,只需要0.0004美元/1000 tokens

3.2.3 基于Hologres的向量存储

得到向量后需要进行存储和检索。因为我们在实际业务中有使用Hologres,而Hologres本身也集成了达摩院向量检索引擎Proxima,于是我们基于Hologres做了实践,下面是操作步骤:

3.2.3.1 创建表

(详细请参考Hologres向量计算Proxima

-- hologres
begin;
create table sellerservice_content_tb
(
    -- 主键
    id BIGINT,
    -- 内容id
    content_id VARCHAR,
    -- 内容类型
    type INTEGER,
    -- 向量(维度1,长度1536)
    content FLOAT4[] check (ARRAY_NDIMS(content) = 1 and array_length(content, 1) = 1536),
    -- chunk索引(标记本条数据是该知识的第几个chunk)
    idx INTEGER,
    -- 原始文本内容
    row_content TEXT,
    -- 租户id
    bu_id INTEGER 
);
-- 因为测试的数据量较少,所以设置表的分片数量为1
call set_table_property('sellerservice_content_tb', 'shard_count', '1');
-- 为content字段添加proxima索引,采用“平方欧式距离”,数据量达到1000行后构建索引
call set_table_property('sellerservice_content_tb', 'proxima_vectors', '{"content":{"algorithm":"Graph","distance_method":"SquaredEuclidean", "builder_params":{"min_flush_proxima_row_count" : 1000}}}');
commit;

3.2.3.2 将数据导入至该表:

INSERT INTO 
  sellerservice_content_tb (content_id,type,content,row_content,idx,bu_id)
VALUES 
  (123456789,
   0,
   array[0.1,0.2,0.3,0.4,...]::float4[],
   'title:xxxxx; tags:xxxxxx; content:xxxxxxxx',
   0,
   3);

将知识向量化后,就可以开始进行问答了,整个流程如下图:

商15.png

3.2.4 Query向量化

用户输入问题后,首先需要对Query进行向量化。Query的向量化和上面知识的向量化方法一致,只需要将Query作为入参调用OpenAI的Embedding接口即可。需要注意的是向量化Query时使用的模型需要和向量化知识时的保持一致,这样才能使向量的维度保持一致,否则无法进行向量检索。

3.2.5 向量检索

得到了Query的向量后即可在Hologres中检索相关知识。Hologres支持JDBC客户端链接,需要使用42.2.25及以上版本的Postgres JDBC Driver:

<dependency>
  <groupId>org.postgresql</groupId>
  <artifactId>postgresql</artifactId>
  <version>42.2.25.jre6</version>
</dependency>

然后配置Hologresss数据源:

@Bean(name = "hologressDataSource", initMethod = "init", destroyMethod = "close")
public DruidDataSource dataSource() {
    DruidDataSource druidDataSource = new DruidDataSource();
    druidDataSource.setDriverClassName("org.postgresql.Driver");
    druidDataSource.setUrl("jdbc:postgresql://<host>:<port>/hologres_poc?reWriteBatchedInserts=true&tcpKeepAlive=true");
    druidDataSource.setUsername("xxxxxxxx");
    druidDataSource.setPassword("xxxxxxxx");
    return druidDataSource;
}

配置完成后即可进行向量检索:

-- 根据向量检索淘宝Top10最相关的内容
SELECT 
  pm_approx_squared_euclidean_distance(content, '{0.1,0.2,0.3,0.4,...}') AS distance
  content_id,
  type,
  idx
FROM 
  sellerservice_content_tb
WHERE
  bu_id = 3
ORDER BY 
  distance ASC
LIMIT 10 ;

更多Hologres的向量检索查询请参考官网文档向量计算Proxima。向量检索结果测试:

商16.png

3.2.6 Prompt构造

得到了Query相关的知识,最后一步就是构造Prompt了:

{"role":"user","content":"你是谁?"}
{"role":"assistant","content":"亲您好,我是淘宝商家智能客服,请问有什么可以帮您吗?"}
{
  "role":"system",
  "content":"你是淘宝商家智能客服,你聪明、友善,可以帮助商家解决问题,请根据下面几段材料回答商家这个问题。请注意,你需要根据商家的问题从下面的材料中尽可能地提取相关信息,然后对该问题做出回答,答案需要语句通顺、表达完整、格式优美,并且需要给出具体、详细的说明或解决方案。如果下面的材料和问题无关,或者商家和你闲聊,或询问与淘宝商家无关的问题时,请尝试自己回答这个问题。当你无法给出正确答案时请回答:抱歉,我无法回答您这个问题。请再次注意你是淘宝商家智能客服,请站在商家的视角帮助他们解决问题,并时刻记住你的身份。下面是相关材料,每段材料中title是材料的标题(主题),content是材料的具体内容,这几段材料通过\n进行分隔:\ntitle:标题1; content:内容1\ntitle:标题2; content:内容2\ntitle:标题3; content:内容3\ntitle:标题4; content:内容4"
}
{"role":"user","content":"买家骂人怎么办?"}

构造完成后即可通过OpenAI的Chat接口进行对话了。

3.2.7 训练结果

采用gpt-3.5-turbo模型进行问答,temperature参数设置为0.5,效果如下:

商17.png

商18.png


4. 训练效率总结

通过测试来看,训练效果还是可以的,这里总结一下基于Embedding的方式的优缺点:

4.1 优点

4.1.1 知识外化

通过利用上下文提供知识替代用知识训练模型的方式,不存在知识实时性的问题;

4.1.2 可扩展性

由于知识的检索可以通过工程手段实现,可扩展性、可控性相较于训练的方式更强;

4.1.3 易用性强

向量检索可以通过标准SQL表达,上手成本低

4.2 缺点

4.2.1 上下文变长

由于需要在上下文中提供知识,造成了上下文变得比较长,虽然GPT-4已支持32K个token的上下文,但是成本会变高。

4.2.2 模型能力

这种方式相当于为大模型提供了一个有力的外部工具,而模型本身并没有得到训练,模型能力没有得到提升。但这是否算是缺点,还需要打个问号。

对面上面的方案,还有可以进一步探索的地方:

  1. 检索的能力可以进一步增强,具体可以采用如下方法:a. 对Embedding模型进行训练,增强其对阿里巴巴商家服务和电商领域相关文本语义的理解;b. 除了语义匹配外,还可以引入其他模块(如文本匹配模块、query改写模块等)提升检索的准确性。
  2. 自动化检索。对于商家的问题,并不是所有的问题都需要先进行向量检索,比如“你是谁”、“你能帮我解决什么问题”这类问题。因此可以对商家的问题进一步分类,以减少一些不必要的向量检索过程。
  3. 可以丰富检索内容的类型,增强答案的交互性。在本次实践中仅仅引入了知识类型,并且由于格式化问题导致文本中的超链丢失。
  4. Prompt可以进一步优化,temperature参数也可以进行调整,同时将最后的问答模型升级为GPT-4也许会有更好的效果。


以上是我们团队基于ChatGPT以及结合Hologres向量检索能力在商家自助服务场景的探索实践,后续我们也将继续基于ChatGPT做更多探索,并尝试应用在生产中,我们希望通过大模型丰富的能力为阿里巴巴千万商家提供最优质的服务!


了解Hologres

合集.png

作者介绍
目录