在这篇文章中,您将仔细研究用于语义搜索的嵌入文档。通过示例,您将了解嵌入如何影响搜索结果以及如何改进结果。享受吧!
简介
在上一篇文章中,使用 LangChain4j 和 LocalAI 进行了讨论。结论之一是文档格式对结果有很大影响。在这篇文章中,您将仔细研究源数据的影响及其嵌入方式,以获得更好的搜索结果。
源文档是两个维基百科文档。您将使用唱片目录和布鲁斯·斯普林斯汀录制的歌曲列表。这些文档的有趣之处在于它们包含事实并且主要采用表格格式。上一篇文章中使用了相同的文档,因此看看该文章中的发现与本文中使用的方法相比如何会很有趣。
如果您熟悉所使用的概念,则无需阅读以前的博客即可阅读此博客。如果没有,建议阅读先决条件段落中提到的之前的博客。
本博客中使用的源代码可以在 GitHub 上找到。 p>
先决条件
此博客的先决条件是:
- 嵌入和向量存储的基本知识
- Java基础知识:使用Java 21
- LangChain4j基础知识-参见之前的博客:
- 如果您想运行本博客末尾的示例,您需要 LocalAI。请参阅之前的博客,了解如何利用 LocalAI。本博客使用的是 2.2.0 版本。
嵌入整个文档
嵌入文档的最简单方法是读取文档,将其分割成块,然后嵌入这些块。嵌入意味着将文本转换为向量(数字)。您要问的问题也需要嵌入。
向量存储在向量存储中,该向量存储能够找到最接近您的问题的结果,并用这些结果进行响应。 源代码由以下部分组成:
- 需要嵌入文本。为此需要一个嵌入模型;为简单起见,请使用
AllMiniLmL6V2EmbeddingModel
。该模型使用了BERT模型,这是一种流行的嵌入模型。 - 嵌入需要存储在嵌入存储中。通常,矢量数据库用于此目的;但在这种情况下,您可以使用内存中的嵌入存储。
- 读取两个文档并将它们添加到
DocumentSplitter
中。在这里,您将定义将文档拆分为 500 个字符的块,且不重叠。 - 通过
DocumentSplitter
,文档被分成TextSegments
。 - 嵌入模型用于嵌入
TextSegments
。TextSegments
及其嵌入的对应项存储在嵌入存储中。 - 该问题也嵌入到同一模型中。
- 要求嵌入商店查找与嵌入问题相关的嵌入段。您可以定义商店应检索多少结果。在这种情况下,只要求一个结果。
- 如果找到匹配项,以下信息将打印到控制台:
- 分数:表示结果与问题的对应程度的数字
- 原始文本:片段的文本
- 元数据:将向您显示该片段来自的文档
0.7036564758755796
赞特(助理)
1978年[18]
“沉迷于浪漫”布鲁斯·斯普林斯汀她来找我了
(原声带)
布莱斯·德斯纳 2023
[19]
[20]
“还不够好
你”布鲁斯·斯普林斯汀《承诺》
乔恩·兰道
布鲁斯
斯普林斯汀
2010年
[21]
[22]
布鲁斯·斯普林斯汀《Ain't Got You》爱情隧道
乔恩·兰道
查克·普洛特金
布鲁斯
斯普林斯汀
1987年[23]
《我所想的一切》布鲁斯·斯普林斯汀《魔鬼与尘埃》
布伦丹·奥布莱恩
查克·普洛特金
布鲁斯
斯普林斯汀
2005年[24]
“All or Nothing at All”布鲁斯·斯普林斯汀人性化
元数据 { 元数据 = {absolute_directory_path=/<项目目录>/mylangchain4jplanet/target/classes/example-files, index=5, file_name=List_of_songs_recorded_by_Bruce_Springsteen.pdf, document_type=PDF} }
信息在正确的文档中找到,但同样,该段在可以找到答案的行中被分割。这可以解释上一篇文章中给出的不完整答案。
结论
两个答案是正确的,一个是部分正确的,两个是错误的。
嵌入 Markdown 文档
将 PDF 文档转换为 Markdown 文件后会发生什么变化? Markdown 文件中的表格可能比 PDF 文档中的表格更容易识别,并且它们允许您在行级别而不是任意块大小对文档进行分段。仅转换包含问题答案的文档部分;这意味着唱片目录中的录音室专辑和合辑专辑以及录制的歌曲列表。
分段完成如下:
- 将文档行逐行拆分。
- 检索变量
dataOnly
中的表数据。 - 将表的标题保存在变量
header
中。 - 为
dataOnly
中的每一行创建一个TextSegment
,并将标题添加到该段。
源代码如下:
0.6108392657222184
|歌曲|作者 |原创发布 |生产者 |年份|
|------------------------------------------------ ----------------------------|--------------------- -------------------------------------------------- ----------------|--------------------------------- --------------------------------|----------------- -------------------------------------------------- ----|-|
|“在高速公路上工作”|布鲁斯·斯普林斯汀|出生于美国 |乔恩·兰道 查克·普洛特金 布鲁斯·斯普林斯汀 史蒂文·范·赞特 |1984|
元数据 { 元数据 = {absolute_directory_path=/<项目目录>/mylangchain4jplanet/target/classes/markdown-files, file_name=bruce_springsteen_list_of_songs_recorded.md, document_type=UNKNOWN} }
答案不正确。找到了正确的文档,但选择了错误的段。
问题 5
以下是问题 5 的结果:“谁制作了《All or Nothingth’ at All》?”
这次答案正确且完整。
结论
三个答案正确且完整。有两个答案是错误的。请注意,错误答案与之前的问题不同。不过,结果比 PDF 文件稍好一些。
替代问题
让我们在此基础上进一步发展。您在这里没有使用大型语言模型 (LLM),这将帮助您解决您提出的问题和结果解释之间的文本差异。当您更改问题以使用更接近文档中数据的术语时,也许会有所帮助。源代码可以在 这里。
问题 1
让我们将问题 1 从“Adam Raising a Cain”最初发行在哪张专辑中?到“《亚当举起该隐”的原始版本是什么?”。表中的列名为原始版本,因此可能会有所不同。
结果如下:
0.6076896858171996
|歌曲|作者 |原创发布 |生产者 |年份|
|———————————————— —————————-|——————— ————————————————– —————-|——————————— ——————————–|—————– ————————————————– —-|-|
|“转!转!转!” (与罗杰·麦吉恩)|皮特·西格 † |魔法之旅精彩集锦(EP) |约翰·库珀 | 2008年|
元数据 { 元数据 = {absolute_directory_path=/<项目目录>/mylangchain4jplanet/target/classes/markdown-files, file_name=bruce_springsteen_list_of_songs_recorded.md, document_type=UNKNOWN} }
0.6029946650419344
|歌曲|作者 |原创发布 |生产者 |年份|
|———————————————— —————————-|——————— ————————————————– —————-|——————————— ——————————–|—————– ————————————————– —-|-|
|“达灵顿县”|布鲁斯·斯普林斯汀 |出生于美国 |乔恩·兰道 查克·普洛特金 布鲁斯·斯普林斯汀 史蒂文·范·赞特 | 1984年|
元数据 { 元数据 = {absolute_directory_path=/<项目目录>/mylangchain4jplanet/target/classes/markdown-files, file_name=bruce_springsteen_list_of_songs_recorded.md, document_type=UNKNOWN} }
0.6001672430441461
|歌曲|作者 |原创发布 |生产者 |年份|
|———————————————— —————————-|——————— ————————————————– —————-|——————————— ——————————–|—————– ————————————————– —-|-|
|“下行列车”|布鲁斯·斯普林斯汀 |出生于美国 |乔恩·兰道 查克·普洛特金 布鲁斯·斯普林斯汀 史蒂文·范·赞特 |1984|
元数据 { 元数据 = {absolute_directory_path=/<项目目录>/mylangchain4jplanet/target/classes/markdown-files, file_name=bruce_springsteen_list_of_songs_recorded.md, document_type=UNKNOWN} }
0.5982557901838741
|歌曲|作者 |原创发布 |生产者 |年份|
|———————————————— —————————-|——————— ————————————————– —————-|——————————— ——————————–|—————– ————————————————– —-|-|
|《公路巡警》 |布鲁斯·斯普林斯汀 |内布拉斯加州 |布鲁斯·斯普林斯汀 | 1982年|
元数据 { 元数据 = {absolute_directory_path=/<项目目录>/mylangchain4jplanet/target/classes/markdown-files, file_name=bruce_springsteen_list_of_songs_recorded.md, document_type=UNKNOWN} }’ data-lang=”text/x-sh”>
0.6108392657222184
|歌曲|作者 |原创发布 |生产者 |年份|
|------------------------------------------------ ----------------------------|--------------------- -------------------------------------------------- ----------------|--------------------------------- --------------------------------|----------------- -------------------------------------------------- ----|-|
|“在高速公路上工作”|布鲁斯·斯普林斯汀|出生于美国 |乔恩·兰道 查克·普洛特金 布鲁斯·斯普林斯汀 史蒂文·范·赞特 |1984|
元数据 { 元数据 = {absolute_directory_path=/<项目目录>/mylangchain4jplanet/target/classes/markdown-files, file_name=bruce_springsteen_list_of_songs_recorded.md, document_type=UNKNOWN} }
0.6076896858171996
|歌曲|作者 |原创发布 |生产者 |年份|
|------------------------------------------------ ----------------------------|--------------------- -------------------------------------------------- ----------------|--------------------------------- --------------------------------|----------------- -------------------------------------------------- ----|-|
|“转!转!转!” (与罗杰·麦吉恩)|皮特·西格 † |魔法之旅精彩集锦(EP) |约翰·库珀 | 2008年|
元数据 { 元数据 = {absolute_directory_path=/<项目目录>/mylangchain4jplanet/target/classes/markdown-files, file_name=bruce_springsteen_list_of_songs_recorded.md, document_type=UNKNOWN} }
0.6029946650419344
|歌曲|作者 |原创发布 |生产者 |年份|
|------------------------------------------------ ----------------------------|--------------------- -------------------------------------------------- ----------------|--------------------------------- --------------------------------|----------------- -------------------------------------------------- ----|-|
|“达灵顿县”|布鲁斯·斯普林斯汀 |出生于美国 |乔恩·兰道 查克·普洛特金 布鲁斯·斯普林斯汀 史蒂文·范·赞特 | 1984年|
元数据 { 元数据 = {absolute_directory_path=/<项目目录>/mylangchain4jplanet/target/classes/markdown-files, file_name=bruce_springsteen_list_of_songs_recorded.md, document_type=UNKNOWN} }
0.6001672430441461
|歌曲|作者 |原创发布 |生产者 |年份|
|------------------------------------------------ ----------------------------|--------------------- -------------------------------------------------- ----------------|--------------------------------- --------------------------------|----------------- -------------------------------------------------- ----|-|
|“下行列车”|布鲁斯·斯普林斯汀 |出生于美国 |乔恩·兰道 查克·普洛特金 布鲁斯·斯普林斯汀 史蒂文·范·赞特 |1984|
元数据 { 元数据 = {absolute_directory_path=/<项目目录>/mylangchain4jplanet/target/classes/markdown-files, file_name=bruce_springsteen_list_of_songs_recorded.md, document_type=UNKNOWN} }
0.5982557901838741
|歌曲|作者 |原创发布 |生产者 |年份|
|------------------------------------------------ ----------------------------|--------------------- -------------------------------------------------- ----------------|--------------------------------- --------------------------------|----------------- -------------------------------------------------- ----|-|
|《公路巡警》 |布鲁斯·斯普林斯汀 |内布拉斯加州 |布鲁斯·斯普林斯汀 | 1982年|
元数据 { 元数据 = {absolute_directory_path=/<项目目录>/mylangchain4jplanet/target/classes/markdown-files, file_name=bruce_springsteen_list_of_songs_recorded.md, document_type=UNKNOWN} }
如您所见,Highway Patrolman 是一个结果,但只是第五个结果。不过,这有点奇怪。
问题 4:尝试#2
让我们将问题 4 改为“《公路巡警》于哪一年上映?”到“歌曲‘高速公路巡警’是哪一年发行的?”因此,您将“歌曲”添加到问题中。
结果是:
0.6444919056791143
|歌曲|作者 |原创发布 |生产者 |年份|
|———————————————— —————————-|——————— ————————————————– —————-|——————————— ——————————–|—————– ————————————————– —-|-|
|“达灵顿县”|布鲁斯·斯普林斯汀 |出生于美国 |乔恩·兰道 查克·普洛特金 布鲁斯·斯普林斯汀 史蒂文·范·赞特 | 1984年|
元数据 { 元数据 = {absolute_directory_path=/<项目目录>/mylangchain4jplanet/target/classes/markdown-files, file_name=bruce_springsteen_list_of_songs_recorded.md, document_type=UNKNOWN} }
0.6376680100362238
|歌曲|作者 |原创发布 |生产者 |年份|
|———————————————— —————————-|——————— ————————————————– —————-|——————————— ——————————–|—————– ————————————————– —-|-|
|《公路巡警》 |布鲁斯·斯普林斯汀 |内布拉斯加州 |布鲁斯·斯普林斯汀 | 1982年|
元数据 { 元数据 = {absolute_directory_path=/<项目目录>/mylangchain4jplanet/target/classes/markdown-files, file_name=bruce_springsteen_list_of_songs_recorded.md, document_type=UNKNOWN} }
0.6367565537138745
|标题|专辑详情|美国 |澳大利亚 |德国 | IRE |全国民主联盟|新西兰|挪威|瑞典|英国
|————————————————————|- ————|—|—|—|—|—|—|—|—|—|
|布鲁斯·斯普林斯汀精华|14|41|—|—|5|22|—|4|2|15|
元数据 { 元数据 = {absolute_directory_path=/<项目目录>/mylangchain4jplanet/target/classes/markdown-files, file_name=bruce_springsteen_discography_compilation_albums.md, document_type=UNKNOWN} }
0.6364950606665447
|歌曲|作者 |原创发布 |生产者 |年份|
|———————————————— —————————-|——————— ————————————————– —————-|——————————— ——————————–|—————– ————————————————– —-|-|
|“举起你的手”(现场)(埃迪·弗洛伊德封面)|史蒂夫·克罗珀 埃迪·弗洛伊德·阿尔弗蒂斯·伊斯贝尔 † | 1975–85 现场演出 |乔恩·兰道 查克·普洛特金 布鲁斯·斯普林斯汀 |1986 |
元数据 { 元数据 = {absolute_directory_path=/<项目目录>/mylangchain4jplanet/target/classes/markdown-files, file_name=bruce_springsteen_list_of_songs_recorded.md, document_type=UNKNOWN} }
‘ data-lang=”text/x-sh”>
0.6468954949440158
|歌曲|作者 |原创发布 |生产者 |年份|
|------------------------------------------------ ----------------------------|--------------------- -------------------------------------------------- ----------------|--------------------------------- --------------------------------|----------------- -------------------------------------------------- ----|-|
|“在高速公路上工作”|布鲁斯·斯普林斯汀|出生于美国 |乔恩·兰道 查克·普洛特金 布鲁斯·斯普林斯汀 史蒂文·范·赞特 |1984|
元数据 { 元数据 = {absolute_directory_path=/<项目目录>/mylangchain4jplanet/target/classes/markdown-files, file_name=bruce_springsteen_list_of_songs_recorded.md, document_type=UNKNOWN} }
0.6444919056791143
|歌曲|作者 |原创发布 |生产者 |年份|
|------------------------------------------------ ----------------------------|--------------------- -------------------------------------------------- ----------------|--------------------------------- --------------------------------|----------------- -------------------------------------------------- ----|-|
|“达灵顿县”|布鲁斯·斯普林斯汀 |出生于美国 |乔恩·兰道 查克·普洛特金 布鲁斯·斯普林斯汀 史蒂文·范·赞特 | 1984年|
元数据 { 元数据 = {absolute_directory_path=/<项目目录>/mylangchain4jplanet/target/classes/markdown-files, file_name=bruce_springsteen_list_of_songs_recorded.md, document_type=UNKNOWN} }
0.6376680100362238
|歌曲|作者 |原创发布 |生产者 |年份|
|------------------------------------------------ ----------------------------|--------------------- -------------------------------------------------- ----------------|--------------------------------- --------------------------------|----------------- -------------------------------------------------- ----|-|
|《公路巡警》 |布鲁斯·斯普林斯汀 |内布拉斯加州 |布鲁斯·斯普林斯汀 | 1982年|
元数据 { 元数据 = {absolute_directory_path=/<项目目录>/mylangchain4jplanet/target/classes/markdown-files, file_name=bruce_springsteen_list_of_songs_recorded.md, document_type=UNKNOWN} }
0.6367565537138745
|标题|专辑详情|美国 |澳大利亚 |德国 | IRE |全国民主联盟|新西兰|挪威|瑞典|英国
|------------------------------------------------------------|- ------------|---|---|---|---|---|---|---|---|---|
|布鲁斯·斯普林斯汀精华|14|41|—|—|5|22|—|4|2|15|
元数据 { 元数据 = {absolute_directory_path=/<项目目录>/mylangchain4jplanet/target/classes/markdown-files, file_name=bruce_springsteen_discography_compilation_albums.md, document_type=UNKNOWN} }
0.6364950606665447
|歌曲|作者 |原创发布 |生产者 |年份|
|------------------------------------------------ ----------------------------|--------------------- -------------------------------------------------- ----------------|--------------------------------- --------------------------------|----------------- -------------------------------------------------- ----|-|
|“举起你的手”(现场)(埃迪·弗洛伊德封面)|史蒂夫·克罗珀 埃迪·弗洛伊德·阿尔弗蒂斯·伊斯贝尔 † | 1975–85 现场演出 |乔恩·兰道 查克·普洛特金 布鲁斯·斯普林斯汀 |1986 |
元数据 { 元数据 = {absolute_directory_path=/<项目目录>/mylangchain4jplanet/target/classes/markdown-files, file_name=bruce_springsteen_list_of_songs_recorded.md, document_type=UNKNOWN} }
再次改进:高速公路巡警现在列为第三个结果。不过,奇怪的是为什么它没有被列为第一个结果。但是,通过添加更多信息,它在结果列表中的排名会更高。这符合预期。
结论
使用更接近源数据的术语更改问题有助于获得更好的结果。为问题添加更多背景信息也有帮助。显示更多结果可以让您获得更多见解,并让您从结果列表中确定正确答案。
Markdown 嵌入与 LLM 相结合
到目前为止的结论是:
- 文档的格式以及文档的分段和嵌入方式对结果有重大影响。
- 如果问题使用与文档中的数据接近的术语,则会取得更好的结果。
在上一篇博客中,使用 PDF 文件作为源数据。现在可以通过使用 Markdown 以及更好的分段和嵌入来解决这个问题。上面的第二个要点可能可以通过使用法学硕士来解决。
让我们看看将这篇文章中的嵌入与上一篇文章中的法学硕士结合起来会发生什么。完整的源代码可以在 GitHub。
问题和结果是:
- 问:“Adam Raising a Cain”最初出现在哪张专辑中发布?
A:专辑“Adam Raising a Cain”最初于 1995 年在 The Essential Bruce Springsteen 专辑中发行。- 此答案是错误的,但对应于之前的第一个嵌入结果。
- 问:“来自新泽西州阿斯伯里帕克的问候”在美国的最高排行榜位置是多少?
答:《Greetings from Asbury Park, NJ》在美国排行榜最高排名为 60 位。- 这个答案是正确的。
- 问:专辑“Tracks”在加拿大的最高排行榜位置是多少?
答: Metallica 的专辑《Tracks》尚未达到加拿大排行榜的最高位置。根据提供的信息,它在加拿大的最高排行榜排名为#27。- 这个答案是错误的。之前的第一个嵌入结果是正确的,所以这里给出了错误的答案,这很奇怪。
- 问:高速公路巡警于哪一年发行?
答: 歌曲“高速公路巡警” ”于 1984 年发布。- 答案是错误的,但可以解释。早些时候的第一个嵌入结果显示了Working on the Highway的结果,这首歌于 1984 年发行。
- 问:“高速公路巡警”是哪一年发行的?
答: 歌曲“高速公路巡警” ”于 1984 年发布。- 此处的问题存在拼写错误。结果与上一个类似,所以这是一致的。
- 问:《All or Nothinghin’ at All》的制作人是谁?
答:歌曲《All or Nothinghin’ at All》是由由布鲁斯·斯普林斯汀、乔恩·兰道、查克·普洛特金和罗伊·比特坦制作。它最初发布在 Springsteen 1992 年的专辑“Human Touch”中。- 此答案正确且完整。使用 PDF 作为源数据,答案总是不完整。
结果比使用 PDF 文件作为源文档更糟糕。然而,当给出正确答案时,它就完成了。答案也是一致的;一个小错别字不会像以前那样改变答案。
Markdown 嵌入与系统消息结合
在上一篇博客中,最终的解决方案还包括将系统消息添加到聊天内存中。让我们看看将其与 Markdown 源文档结合起来会发生什么。完整的源代码可以在 GitHub。以下是系统消息的一小部分摘录。