更新:最近我们开源了我们的KG Studio:https://medium.com/enterprise-rag/open-sourcing-the-whyhow-knowledge-graph-studio-powered-by-nosql-edce283fb341
知识图谱是一种稀疏且有方向性的信息表示方式。这种有方向性的表示方式非常有用。在这种有方向性的表示方式下,你知道要捕捉或隔离的内容,或者你的文档遵循某种特定的结构。
一个使用结构化表示法的重要好处是,您可以从多个数据源收集信息,并执行跨多个文档的RAG,确保所有需要的信息都被完全且彻底地检索到。简单来说,使用知识图的主要好处就是在RAG中优化“完整性”指标。
与向量数据库将信息表示为嵌入不同,知识图谱明确地建模实体间的关系,从而实现更结构化和语境化的检索。
我们采用的是来自世界线的Luxin Zhang(https://blog.worldline.tech/2024/01/12/metric-driven-rag-development.html)的完备性定义,如下:
“完整性通过比较生成的回答与基准答案,来衡量生成的回答是否涵盖了所有要点。如果该分数较低,首先应检查检索召回(IR 召回)是否足够好,因为它是上限。然后,可以检查检索准确率(IR 准确率),以确定 LLM 是否被无关信息误导。最后,可能需要调查“黄金标准数据集”中的每个测试查询,并调整提示以提高生成回答的完整性。LLM:大型语言模型。”
我们想强调我们是如何从图中提取完整答案的过程。以下是这个抽取逻辑的工作流程:
- 首先,基于现有的模式、三元组及其实体和问题,大型语言模型确定要提取的正确三元组和它们的关系,并以结构化的方式提取这些实体和它们的关系。
- 接下来,我们执行混合RAG功能,对三元组进行向量检索操作,以找到可能遗漏的其他三元组。
让我们通过一个例子来说明这一点。在这个例子中,我们感兴趣的是了解亚马逊多年来涉及的法律案件。这涉及检索2020年至2024年期间亚马逊的5份10-K年报中的特定类型的信息内容。无论是向量模型还是图形模型,我们只处理了每个10-K年报中“法律程序”部分的信息(包括嵌入或提取三元组),而不是整个文档。
我们可以试试两种方法解决这个问题。
- 向量检索
- 图谱检索
在向量检索中,完整性始终会是一个问题,因为大型语言模型永远无法确定检索何时完成。大型语言模型很难判断提到法律案例的向量片段数量是5个、10个还是15个,并且在达到目标数量之前停止搜索或继续搜索。这是因为向量检索的关注点在于语义相似度,而不是语义完整性。虽然理论上可以通过设置置信度阈值、重构造查询和递归检索来解决这一问题,但这些方法似乎相当随意。对于知识图谱来说,完整且详尽的提取只需选择所有与亚马逊相关的实体类型(如“法律案例”)即可。通过片段链接,可以将向量片段链接到节点上,从而可以进行详尽的向量片段检索(即全面检索所有相关的向量片段),同时还可以执行混合检索和生成(即从图谱和向量检索中检索和比较或组合答案)。
在图形检索中,因为我们定义了法律案件是我们关心的内容之一,所以识别并预处理了一系列具体的法律案件。因此,从图中检索实际上就是从预处理的法律案件列表中检索。有时甚至可以在没有定义模式的情况下进行检索。这在知识图谱创建过程中尤为显著,因为在实体提取(有时不是根据预定义的模式,而是通过提示驱动)时,这意味着您关心的每个实体都具备被预处理和分类的能力。
向量检索与图检索的区别在当我们考虑向量检索的其他限制,特别是上下文窗口限制和top-k检索时变得更加明显。假设一下,我们能够检索出每一个包含亚马逊所涉及的每一起法律案件的所有提及的片段(在所有文档中),并且top-k设置为16。
向量块的数量很可能超过top-k集合,特别是如果信息分布在多个页面和文档中。在这种情况下,我们几乎没有什么选择,只能希望提到的每一个法律案例恰好都在最相关的前8个块中。鉴于这种类型的问题(“列出所有X”)很常见,我们可能会决定将top-k设置得更大,比如32。然而,使用更大的top-k可能会触及上下文窗口的上限,这会导致幻觉、增加成本以及延迟的风险。
这在跨多个文档的搜索过程中尤其有用。因为多个文档意味着相关且独特的向量片段的数量按定义会增加。这使得之前提到的顶级向量检索问题变得更加复杂。然而,通过使用跨多个文档的模式,我们可以将出现在多个文档中的案例法存储为额外的子节点,从而简化了检索过程。
多文档图和向量基准测试
为了实验,我们每2000个字符将文本分成一段,并将top-k设置为64,以容纳我们预计要查找的32个案例。我们在附录中附上了原始的向量检索结果。
# 使用1536维度和2000字符文本大小获取嵌入向量
index = pc.Index("demo")
embeddings = OpenAIEmbeddings()
query = "亚马逊正在处理哪些诉讼?"
query_embedding = embeddings.embed_query(query)
concatenatedChunks = ""
query_response = index.query(
top_k=64,
vector=query_embedding,
include_metadata=True
)
for chunk in query_response.matches:
concatenatedChunks += chunk.metadata['pageContent'] + ' '
# 根据响应中的片段生成答案
prompt = f"""
背景信息:
你是一个乐于助人的聊天机器人。请仅根据下方提供的信息回答问题。
问题:{query}。
背景信息:{concatenatedChunks}
回答:"""
response = openai_client.chat.completions.create(
model="gpt-4o",
messages=[{
"role": "user",
"content": prompt
}],
max_tokens=4000
)
对于图表,我们采用了以下图表提取逻辑。
async def extract_triples(text, company_name):
prompt = f"""
根据以下内容,提取相关的公司并以以下JSON格式输出:
[{{"head": {{"type": "Company", "id": {company_name}}}, "relation": "INVOLVED_WITH", "tail": {{"type": "Legal Proceeding", "id": <案件名称>}}}}, ...]
不包括辅助信息。不要用JSON格式包裹响应。如果没有相关信息,返回空数组。
文本内容:{text}
"""
response = openai_client.chat.completions.create(
model="gpt-4o",
messages=[
{"role": "user", "content": prompt},
],
max_tokens=4000,
temperature=0.1
)
triples = json.loads(response.choices[0].message.content)
return triples
然后我们运行了以下查询逻辑,该逻辑会接收自然语言查询并检索合适的实体和关系。
schema_id = whyhow_client.graphs.get(graph_id=graph.graph_id).schema_id
schema = whyhow_client.schemas.get(schema_id)
entities = [entity.name for entity in schema.entities]
relations = [relation.name for relation in schema.relations]
query = "亚马逊正在处理哪些诉讼?"
# 使用图中的实体和关系,从问题中提取相关实体和关系以构建结构化查询。
prompt = f"""
对以下问题执行实体和关系提取,使用提供的实体类型和关系类型列表。
输出应包含三个数组:
"entity_types",即在问题中检测到的实体类型
"relation_types",即在问题中检测到的关系类型
"values",即在问题中检测到的相关实体名称。
输出应如下:
{{"entity_types": ["Person", "Place"], "relation_types": ["LIVES_IN"], "values": ["John Doe", "New York"]}}
不包含支持信息。不要用 JSON 标记包装响应。如果没有相关内容,返回一个空数组。
问题:{query}
实体类型:{entities}
关系:{relations}
"""
response = openai_client.chat.completions.create(
model="gpt-4o",
messages=[
{"role": "user", "content": prompt},
],
max_tokens=4000,
temperature=0.1
)
structured_query = json.loads(response.choices[0].message.content)
# 运行非结构化查询
unstructured_query_response = whyhow_client.graphs.query_unstructured(query=query, graph_id=graph.graph_id)
# 使用从问题中提取的实体和关系运行结构化查询,然后通过结合结构化和非结构化查询的结果生成响应
query_response = whyhow_client.graphs.query_structured(
entities=structured_query["entity_types"],
relations=structured_query["relation_types"],
values=structured_query["values"],
graph_id=graph.graph_id
)
# 使用结构化输出生成问题的响应
prompt = f"""
使用自然语言回答和以下结构化三元组中的支持信息,提供对问题的详细回答:
问题:{query}
自然语言回答:{unstructured_query_response.answer}
结构化三元组:{query_response}
"""
answer = openai_client.chat.completions.create(
model="gpt-4o",
messages=[
{"role": "user", "content": prompt},
],
max_tokens=4000,
temperature=0.1
)
这是我们所获得的结果。下面列出的32个案例是我们从亚马逊的10-K报告中挑选出的法律诉讼的黄金数据集。我们根据检索到的案例数量来计算完整度得分,即(10/32=31.25%)。对于包含10份文档的测试,我们还加入了沃尔玛的10-K报告,以体现实际的数据处理过程中可能包含各种无关文档。
所使用的图形有:如下等
结果如下所示:
- 绿色代表正确的识别案例
- 红色代表错误且不相关的
- 白色代表事实的准确总结,但不是一个具体的案例,并且不会影响准确性得分
需要注意,在包含10篇文档的图检索中,第24个案例被分成了两个独立的节点,分别是伦斯勒理工学院和CF Dynamics。而包含5篇文档的图检索则将其表示为一个节点。
在实验中,我们找到了以下几点。
- 向量检索在多文档检索任务中的准确性下降。
- 图检索始终能够检索出一整套法律案例(100%),相比之下,向量检索的成功率则在31%到41%之间。
我们发现的一个有趣的问题是,随着更多文档加入知识库,向量检索的准确性从41%下降到31%。虽然我们预计随着文档数量的增加,准确性会因为接近 top-k 限制而下降,但实际返回的案例数量也有所减少。我们怀疑这是由于更多的向量片段降低了检索准确性,并且超出了上下文窗口。
还可以观察到,随着LLM被允许检索的文档数量的增加,它更倾向于提供概括性的而不是具体的信息。这可以从向量检索(10个文档)中返回的空白单元格数量中看出(例如,“反垄断和消费者保护诉讼”和“一般就业和消费者诉讼”)。我们担心最初的问题(“亚马逊正在处理哪些诉讼?”)可能会偏向我们的实验结果,因此我们重新措辞为“列出亚马逊面临的所有法律案件”,并运行了查询。在这里,我们发现返回了一些虚构的信息,检索结果仅略有改善。
综上所述,我们展示了信息检索的一致性和完整性,并获得了很高的完整性评分,而基于向量片段的搜索在多个文档中难以实现完全准确的信息检索。
从稍微复杂一点的角度来看,知识图谱有助于将一个搜索过程转变为更确定的查找过程。搜索过程是在你还不清楚自己想要找什么时进行的。查找过程则是从结构化的知识库中直接检索信息,这更确定且直接。知识图谱并不是随意构建结构,而是构建一种能够有效帮助检索的结构。大语言模型在这方面来说很擅长帮助我们围绕信息构建结构,将搜索过程转变为查找过程。知识图谱恰好是一种很好的存储灵活的数据结构的方式,随着我们不断添加新的结构化和非结构化数据源,这种结构也会不断扩展和完善。
WhyHow.AI的知识图谱平台(目前处于测试版)是建立模块化的智能知识图谱的最简单方式,集成了大型语言模型、开发人员以及非技术背景专家的工作流程。
如果你正在考虑或将知识图谱纳入RAG中以提高准确性、记忆和确定性,欢迎通过team@whyhow.ai与我们交流,或者订阅我们的WhyHow.AI通讯。加入我们的Discord讨论有关规则、确定性和知识图谱在RAG中的相关话题。
附录GitHub仓库链接: https://whyhow-ai.github.io/whyhow-sdk-docs/examples/query_completeness/ ,这是一个查询完整性的示例页面。
RAG向量(10文档数),
- 十份10K文档(5份AMZN和5份WMT)大约1600页
- Top_k 为64
- 问题:“亚马逊现在在处理什么诉讼?”
亚马逊正面临多起诉讼,包括:
1. **集体诉讼案(美国和加拿大)**:
- 涉及亚马逊与其第三方卖家之间的价格操控安排的指控。
- 垄断行为及企图垄断的指控。
- 消费者保护和不当得利的索赔。
- 索赔数十亿美元的赔偿,包括三倍赔偿、惩罚性赔偿、禁令救济、民事罚款、律师费和诉讼费用。
2. **联邦贸易委员会和各州总检察长诉讼(2023年9月)**:
- 涉及违反联邦和州的反垄断和消费者保护法的指控。
- 指控亚马逊在在线超级商店和市场服务市场中拥有垄断地位,通过反竞争的手段维持。
3. **专利侵权诉讼**:
- **BroadbandiTV, Inc.(2020年10月)**:针对亚马逊Prime Video功能和服务的指控。
- **伦斯勒理工学院(2018年5月)**:针对“Alexa语音软件和Alexa启用设备”的指控。
- **Kove IO, Inc.(2018年12月)**:涉及亚马逊S3和DynamoDB的指控。
- **Acceleration Bay, LLC(2022年7月)**:针对多个AWS和亚马逊服务的指控。
- **LightGuide, Inc.(2022年11月)**:针对亚马逊的耐克意图检测系统的指控。
- **Dialect, LLC(2023年5月)**:针对Alexa启用的产品和服务的指控。
- **Vocalife LLC(2019年4月)**:涉及亚马逊Echo设备的指控。
4. **生物识别数据收集**:
- 自2019年6月起,伊利诺伊州有多起案件,指控违反伊利诺伊州生物识别信息隐私法。
- 与亚马逊Photos、Alexa、AWS、Ring、Amazon Connect、Flex司机应用和虚拟试穿技术有关的指控。
5. **监管行动**:
- **欧洲委员会(2020年11月)**:关于使用市场卖家数据的指控。
- **卢森堡国家数据保护委员会(2021年7月)**:关于遵守欧盟一般数据保护条例的指控。
- **意大利竞争管理局(2021年12月)**:关于市场和物流做法的指控。
6. **阿片类药物诉讼**:
- 涉及阿片类药物分发和分发做法的多起案件。
- 与美国政府机构发出的传票和调查有关。
7. **工资和工作时间诉讼**:
- 涉及联邦和州工资和工时法律的集体诉讼案件。
- 涉及因安全检查及其他劳工纠纷未支付时间的索赔。
此外,亚马逊还涉及各种其他法律程序、监管调查和与专利侵权、竞争和反垄断问题、隐私和数据保护、消费者保护和商业争议相关的索赔。
RAG向量(5份文档)
- 五份10-K文件(均为AMZN公司的),大约550页
- Top_k = 64
- 问题:关于亚马逊正在处理哪些诉讼?
亚马逊正面临多个领域的多起诉讼,包括:
1. **生物识别数据**:涉及亚马逊照片、Alexa、AWS云服务、Ring、Amazon Connect、亚马逊Flex司机应用程序以及亚马逊虚拟试穿技术等多个案件,均在美国联邦和州法院进行,包括伊利诺伊州生物识别信息隐私法下的集体诉讼。
2. **价格操纵和反垄断**:以Frame-Wilson v. Amazon.com, Inc.为开端,美国和加拿大多起案件指控亚马逊存在价格操纵、垄断、消费者保护问题及不当得利。哥伦比亚特区和加利福尼亚州的检察长,联邦贸易委员会(Federal Trade Commission,简称FTC)以及多个州检察长也发起了类似诉讼。
3. **专利侵权**:
- *BroadbandITV, Inc. v. 亚马逊*:亚马逊Prime Video涉嫌侵犯专利。
- *伦斯勒理工学院和CF Dynamic Advances LLC v. 亚马逊*:指控Alexa语音软件及相关设备侵犯专利。
- *Kove IO, Inc. v. 亚马逊云服务*:指控亚马逊S3和DynamoDB侵犯专利。
- *Acceleration Bay, LLC v. 亚马逊云服务*:指控亚马逊多项AWS服务和设备侵犯专利。
- *LightGuide, Inc. v. 亚马逊*:指控亚马逊Nike意图识别系统(Nike Intent Detection System)侵犯专利。
- *Dialect, LLC v. 亚马逊*:指控亚马逊Alexa设备侵犯专利。
- *诺基亚技术公司 v. 亚马逊*:指控亚马逊Prime Video及其他技术在多个国家涉嫌侵犯专利。
4. **监管和隐私**:
- *欧盟委员会*:因违反竞争规则发出异议声明。
- *卢森堡国家数据保护委员会*:有关GDPR合规的决定。
- *意大利竞争管理局*:关于市场和物流做法违反欧盟竞争规则的决定。
5. **其他**:其他多种指控涉及税收、劳工和就业、消费者保护以及数据保护等问题。
亚马逊否认这些不当行为的指控,并打算就这些案件积极进行辩护。
共同学习,写下你的评论
评论加载中...
作者其他优质文章