基于 RAG 实现大模型商品智能检索

概述

传统商品检索需要依赖人工解析和构建商品的描述字段,将商品信息存入 ElasticSearch 或数据库,然后通过分词查询结合多重条件(类别或其他属性)检索到匹配的商品。

但是在传统检索中,因为分词本身的特点,经常会遇到误匹配的问题,例如:我们检索 "苹果耳机"的时候,往往会出现苹果和耳机的相关商品,导致客户体验效果不佳。

为了让检索更人性化,我们可以借助 RAG 技术,在传统分词搜索的基础上融入向量检索的能力,从而获得更贴近人类需求的检索效果。

名词解释

在开始之前,我们先把本文中需要用到的一些技术/接口/产品的专有名词做个说明,方便大家更好地理解文档:

  • RAG: 检索增强生成(Retrieval-augmented Generation),简称 RAG

  • ES: Elasticsearch 是一个开源的分布式搜索和分析引擎,常用于实时搜索、日志分析、数据可视化等应用

  • BES:百度 Elasticsearch(BES)是百度托管的 Elasticsearch 服务,完全兼容开源 Elasticsearch 的功能

  • Embedding:向量是一种数学技术,用于将对象或概念映射到高维空间,通过向量表示捕捉语义关系和数据结构

  • Prompt:用户或程序向模型提供的输入文本或指令,以引导模型生成特定类型或内容的响应

  • ERINIE 4.0: 百度自行研发的文心产业级知识增强大语言模型 4.0 版本

思路分析

好了,我们看一下整体的实现思路:

  1. 数据准备:解析文档中的商品信息

  2. 数据切片:商品信息按照一定规则进行切片

  3. 向量化:对切片信息进行向量化处理

  4. 数据存储:将商品信息及其向量信息存储到向量数据库

  5. 数据检索:将检索的内容进行向量化存储,利用向量数据库的向量检索能力召回最近似的商品切片信息

  6. 重排序:对于召回的数据利用重排序算法,按照相似度由高到低重新排序

  7. 返回数据处理:利用大模型解读排序后的商品切片信息,输出给用户

本文使用python编码。

整体的实现流程如下图所示:

数据准备 & 数据切片

我们准备了一个示例文档,大家可以这个文档来解析商品信息,也可以自己准备对应的数据。

DocParser支持 PDF、JPG、DOC、TXT、XLS、PPT 等 17 种文档内容的解析,可解析得到文档内容、版式信息、位置坐标、表格结构等信息。

我们使用下面的代码解析示例的 PDF 文件:

from appbuilder.core.components.doc_parser.doc_parser import DocParser
from appbuilder.core.message import Message
msg = Message(file_path)
parser = DocParser()
parse_result = parser(msg)
page_contents = parse_result.content.page_contents

请注意 PageContent 类型信息比较零散,需要手动合并内容:

chunk = []
for layout in doc.page_layouts:
    chunk.append(layout.text)
# 标题置顶
if doc.titles:
    chunk.insert(0, doc.titles[0].text)
# 若有表格,此案例暂无
if doc.tables:
    pass
    
return "\n".join(chunk)

按页对数据进行合并,并添加元信息:

docs = []
metadata = []
for page_content in page_contents:
    result = merge_chunk(page_content)
    docs.append(result)
    metadata.append({"page": page_content.page_num + 1, "filename": file_path.split("/")[-1], "type": "pdf"}) ##获取内容文件元数据信息,方便追溯召回数据
return docs, metadata

提示:这时提取的数据粒度比较粗,要获取更好的最终效果,可以考虑将切分后的数据传给大模型,进一步提炼和完善。

向量化 & 数据存储

请注意传给模型的信息需要符合模型限制条件,通常文字长度更简短,语义更准确会有更好的向量检索效果:

  • 参数中一次传入的文本数量不能超过 16 个

  • 每个文本长度不能超过 384 tokens 且不能超过 1000 字符

将文本切分成小于 max_tokens 的字符串数组,并确保每个切片有 overlap_ratio 的重叠:

overlap_size = int(chunk_size * overlap_ratio)
chunks = []
start = 0
while start < len(text):
    end = min(start + chunk_size, len(text))
    chunks.append(text[start:end])
    start += chunk_size - overlap_size
return chunks

调用 embedding 模型将数据向量化,并存入 BES :

text_slices = []
if text_tokens > 500:
    print(f"Notice: {text_tokens} tokens, too long. Splitting text...")
    text_slices = split_text_with_overlap(page_text)
else:
    text_slices = [page_text]

for slice_text in text_slices:
    resp = qianfan.Embedding().do(model="embedding-v1", texts=[slice_text]) ##使用千帆 SDK 请求 embedding-v1 模型
    data_list = resp.get('data', [])
    if data_list and isinstance(data_list[0], dict):
        embedding_info = data_list[0].get('embedding') ##获取 384 维的向量数据
        page_info = {
            "filename": file_path.name,
            "page_num": page_content.page_num+1,
            "text": slice_text,
            "embeddings": embedding_info
        }
        res = es.index(index="intellisearchproduct", body=page_info) ##调用 es 接口将数据写入对应索引,注意索引对应向量字段也得是 384 维
        #print(f"es write info: {page_info}\n,write result: {res}")

数据检索(我们省略了重排序步骤,感兴趣的小伙伴可以自行了解以下 rerank 模型)

接下来需要将客户查询的内容也转为向量数据:

input_text = request.json.get('input_text')
if not input_text:
    return jsonify({'error': 'Missing input_text parameter'}), 400
resp = qianfan.Embedding().do(model="embedding-v1", texts=[input_text])
data_list = resp.get('data', [])
if data_list and isinstance(data_list[0], dict):
    results = search_es(input_text, data_list[0].get('embedding'))
    if results:
        final_json = perform_source_tracking(input_text,results)
    else:
        return jsonify({'message': '未找到相关结果'})
else:
    return jsonify({'message': '向量转化接口异常,数据列表为空或格式不正确'})

return jsonify(final_json)

以下是一个简单得查询示例:

    query_body = {
        "size": 3,
        "query": {
            "script_score": {
                "query": {
                    "match_all": {}
                },
                "script": {
                    "source": "bpack_knn_script",   
                    "lang": "knn",
                    "params": {
                        "k": 10,  ##查询的最近邻的数量
                        "ef": 20, ##通过ef参数指定在每个shard检索时的候选队列大小,用于平衡查询性能和召回率,等同于ES8的num_candidates参数
                        "space": "cosine",
                        "field": "embeddings",
                        "vector": embedding_text
                    }
                }
            }
        }
    }
    res = es.search(index="intellisearchproduct", body=query_body)
    docs = []
    for r in res["hits"]["hits"]:
        print({"text": r["_source"]["text"], "filename": r["_source"]["filename"], "page_num": r["_source"]["page_num"], "score": r["_score"]})
        docs.append({"text": r["_source"]["text"], "filename": r["_source"]["filename"], "page_num": r["_source"]["page_num"], "score": r["_score"]})

    return docs

返回数据处理

将召回的结果传给大模型,通过提示词让大模型理解并提供更人性化的输出:

    texts = ""
    results_list = []
    for idx, result in enumerate(results):
        url = f"http://xxxx/{result['filename']}?x-bce-process=doc/preview,tt_image,p_{result['page_num']}"
        result_info = {
            "页码": result['page_num'],
            "分数": result['score'],
            "文本": result['text'],
            "图片URL": url
        }
        results_list.append(result_info)
        texts += result['text']

    querytext = f"""用户问题:{input_text}
    [参考资料]:
    ```
    {texts}
    ```
    根据参考资料里的知识点回答用户问题,未检索到的礼貌拒答
    """

    resp = qianfan.ChatCompletion().do(endpoint="completions_pro", messages=[{"role":"user","content": querytext}], temperature=0.95, top_p=0.8, penalty_score=1, disable_search=False, enable_citation=False)
    ## 通过千帆 SDK 调用 ERINIE-4.0-8K 模型解读客户的查询
     
    final_json = {
        "results": results_list,
        "resp_body_result": resp.body['result']
    }

    return final_json

到这里就初步完成了,当然除了本文中列出来的这些技术点,还有很多其他的优化手段,感兴趣的小伙伴可以自行探索一下。最终的实现效果是这个样子:

如何系统的去学习大模型LLM ?

作为一名热心肠的互联网老兵,我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在人工智能学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。

但苦于知识传播途径有限,很多互联网行业朋友无法获得正确的资料得到学习提升,故此将并将重要的 AI大模型资料 包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来

😝有需要的小伙伴,可以V扫描下方二维码免费领取🆓

一、全套AGI大模型学习路线

AI大模型时代的学习之旅:从基础到前沿,掌握人工智能的核心技能!

img

二、640套AI大模型报告合集

这套包含640份报告的合集,涵盖了AI大模型的理论研究、技术实现、行业应用等多个方面。无论您是科研人员、工程师,还是对AI大模型感兴趣的爱好者,这套报告合集都将为您提供宝贵的信息和启示。

img

三、AI大模型经典PDF籍

随着人工智能技术的飞速发展,AI大模型已经成为了当今科技领域的一大热点。这些大型预训练模型,如GPT-3、BERT、XLNet等,以其强大的语言理解和生成能力,正在改变我们对人工智能的认识。 那以下这些PDF籍就是非常不错的学习资源。

img

在这里插入图片描述

四、AI大模型商业化落地方案

img

阶段1:AI大模型时代的基础理解

  • 目标:了解AI大模型的基本概念、发展历程和核心原理。
  • 内容
    • L1.1 人工智能简述与大模型起源
    • L1.2 大模型与通用人工智能
    • L1.3 GPT模型的发展历程
    • L1.4 模型工程
    • L1.4.1 知识大模型
    • L1.4.2 生产大模型
    • L1.4.3 模型工程方法论
    • L1.4.4 模型工程实践
    • L1.5 GPT应用案例

阶段2:AI大模型API应用开发工程

  • 目标:掌握AI大模型API的使用和开发,以及相关的编程技能。
  • 内容
    • L2.1 API接口
    • L2.1.1 OpenAI API接口
    • L2.1.2 Python接口接入
    • L2.1.3 BOT工具类框架
    • L2.1.4 代码示例
    • L2.2 Prompt框架
    • L2.2.1 什么是Prompt
    • L2.2.2 Prompt框架应用现状
    • L2.2.3 基于GPTAS的Prompt框架
    • L2.2.4 Prompt框架与Thought
    • L2.2.5 Prompt框架与提示词
    • L2.3 流水线工程
    • L2.3.1 流水线工程的概念
    • L2.3.2 流水线工程的优点
    • L2.3.3 流水线工程的应用
    • L2.4 总结与展望

阶段3:AI大模型应用架构实践

  • 目标:深入理解AI大模型的应用架构,并能够进行私有化部署。
  • 内容
    • L3.1 Agent模型框架
    • L3.1.1 Agent模型框架的设计理念
    • L3.1.2 Agent模型框架的核心组件
    • L3.1.3 Agent模型框架的实现细节
    • L3.2 MetaGPT
    • L3.2.1 MetaGPT的基本概念
    • L3.2.2 MetaGPT的工作原理
    • L3.2.3 MetaGPT的应用场景
    • L3.3 ChatGLM
    • L3.3.1 ChatGLM的特点
    • L3.3.2 ChatGLM的开发环境
    • L3.3.3 ChatGLM的使用示例
    • L3.4 LLAMA
    • L3.4.1 LLAMA的特点
    • L3.4.2 LLAMA的开发环境
    • L3.4.3 LLAMA的使用示例
    • L3.5 其他大模型介绍

阶段4:AI大模型私有化部署

  • 目标:掌握多种AI大模型的私有化部署,包括多模态和特定领域模型。
  • 内容
    • L4.1 模型私有化部署概述
    • L4.2 模型私有化部署的关键技术
    • L4.3 模型私有化部署的实施步骤
    • L4.4 模型私有化部署的应用场景

学习计划:

  • 阶段1:1-2个月,建立AI大模型的基础知识体系。
  • 阶段2:2-3个月,专注于API应用开发能力的提升。
  • 阶段3:3-4个月,深入实践AI大模型的应用架构和私有化部署。
  • 阶段4:4-5个月,专注于高级模型的应用和部署。
这份完整版的大模型 LLM 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

😝有需要的小伙伴,可以Vx扫描下方二维码免费领取🆓

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值