使用图数据库进行检索增强生成
这个项目旨在探索如何结合检索和生成模型来提高自然语言处理任务的性能。我们使用图数据库来存储和检索知识,并将其集成到生成模型中,以增强生成的结果。通过这种方式,我们希望能够更好地利用外部知识来帮助生成模型生成更准确和多样化的文本。
这个笔记本展示了如何将LLMs与图数据库Neo4j结合使用,执行检索增强生成(RAG)。
为什么使用RAG?
如果您想要使用LLMs根据自己的内容或知识库生成答案,而不是在提示模型时提供大量上下文,您可以在数据库中获取相关信息,并使用这些信息生成响应。
这样可以让您: - 减少虚构内容 - 为用户提供相关的最新信息 - 利用自己的内容/知识库
为什么使用图数据库?
如果您的数据中数据点之间的关系很重要,而您可能希望利用这一点,那么考虑使用图数据库可能是值得的,而不是传统的关系数据库。
图数据库适合解决以下问题: - 导航深层次结构 - 查找项目之间的隐藏连接 - 发现项目之间的关系
使用案例
图数据库特别适用于推荐系统、网络关系或分析数据点之间的相关性。
使用图数据库进行RAG的示例用例包括: - 推荐聊天机器人 - AI增强型CRM - 用自然语言分析客户行为的工具
根据您的使用情况,您可以评估是否使用图数据库是有意义的。
在这个笔记本中,我们将构建一个产品推荐聊天机器人,使用包含亚马逊产品数据的图数据库。
设置
我们将从安装和导入相关的库开始。
确保您已经设置好您的OpenAI账户,并且您随手准备好了OpenAI API密钥。
# 可选操作:如果你尚未安装这些库,可以运行以下命令在本地进行安装。
!pip3 install langchain
!pip3 install openai
!pip3 install neo4j
import os
import json
import pandas as pd
# 可选操作:运行以从 .env 文件加载环境变量。
# 如果你已经通过其他方式导出了环境变量,或者你手动设置了它,那么这一步就不是必需的。
!pip3 install python-dotenv
from dotenv import load_dotenv
load_dotenv()
# 手动设置OpenAI API密钥环境变量
# os.environ["OPENAI_API_KEY"] = "<your_api_key>"
# print(os.environ["OPENAI_API_KEY"])
数据集
我们将使用一个从关系数据库创建并转换为json格式的数据集,利用completions API在实体之间创建关系。
然后,我们将加载这些数据到图形数据库中,以便能够对其进行查询。
加载数据集
# 从文件加载JSON数据集
file_path = 'data/amazon_product_kg.json'
with open(file_path, 'r') as file:
jsonData = json.load(file)
df = pd.read_json(file_path)
df.head()
product_id | product | relationship | entity_type | entity_value | PRODUCT_ID | TITLE | BULLET_POINTS | DESCRIPTION | PRODUCT_TYPE_ID | PRODUCT_LENGTH | |
---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1925202 | Blackout Curtain | hasCategory | category | home decoration | 1925202 | ArtzFolio Tulip Flowers Blackout Curtain for D... | [LUXURIOUS & APPEALING: Beautiful custom-made ... | None | 1650 | 2125.98 |
1 | 1925202 | Blackout Curtain | hasBrand | brand | ArtzFolio | 1925202 | ArtzFolio Tulip Flowers Blackout Curtain for D... | [LUXURIOUS & APPEALING: Beautiful custom-made ... | None | 1650 | 2125.98 |
2 | 1925202 | Blackout Curtain | hasCharacteristic | characteristic | Eyelets | 1925202 | ArtzFolio Tulip Flowers Blackout Curtain for D... | [LUXURIOUS & APPEALING: Beautiful custom-made ... | None | 1650 | 2125.98 |
3 | 1925202 | Blackout Curtain | hasCharacteristic | characteristic | Tie Back | 1925202 | ArtzFolio Tulip Flowers Blackout Curtain for D... | [LUXURIOUS & APPEALING: Beautiful custom-made ... | None | 1650 | 2125.98 |
4 | 1925202 | Blackout Curtain | hasCharacteristic | characteristic | 100% opaque | 1925202 | ArtzFolio Tulip Flowers Blackout Curtain for D... | [LUXURIOUS & APPEALING: Beautiful custom-made ... | None | 1650 | 2125.98 |
连接到数据库
# 数据库凭证
url = "bolt://localhost:7687"
username ="neo4j"
password = "<your_password_here>"
from langchain.graphs import Neo4jGraph
graph = Neo4jGraph(
url=url,
username=username,
password=password
)
导入数据
def sanitize(text):
text = str(text).replace("'","").replace('"','').replace('{','').replace('}', '')
return text
# Loop through each JSON object and add them to the db
i = 1
for obj in jsonData:
print(f"{i}. {obj['product_id']} -{obj['relationship']}-> {obj['entity_value']}")
i+=1
query = f'''
MERGE (product:Product {{id: {obj['product_id']}}})
ON CREATE SET product.name = "{sanitize(obj['product'])}",
product.title = "{sanitize(obj['TITLE'])}",
product.bullet_points = "{sanitize(obj['BULLET_POINTS'])}",
product.size = {sanitize(obj['PRODUCT_LENGTH'])}
MERGE (entity:{obj['entity_type']} {{value: "{sanitize(obj['entity_value'])}"}})
MERGE (product)-[:{obj['relationship']}]->(entity)
'''
graph.query(query)