对于那些渴望直接深入代码的人来说,代码可以在我的GitHub仓库中找到。然而,我建议在深入之前花点时间通读这篇文章,以便全面理解。README文件提供了一个关于如何无障碍使用代码的全面指南。
代码:https://github.com/ritun16/chain-of-verification
介绍

在处理大型语言模型(LLMs)时,尤其是在事实问题和回答方面,一个重要的挑战是幻觉问题。幻觉发生在答案看似合理但实际上是错误的情况。在高层次的检查中检测这些幻觉可能很有挑战性,通常需要更详细的检查。
为了应对这一挑战,Meta AI团队引入了一种称为链式验证(CoVe)的方法,它包括以下四个连续步骤:
1. 初始基线响应创建:在这一步中,生成对原始问题的初始响应作为起点。
2. 验证问题生成:验证问题被创建用于核实基线回应的事实。这些问题旨在审查初始回应的准确性
3. 执行验证:验证问题独立回答,以尽量减少任何潜在偏见。此步骤确保验证过程客观且彻底。
4. 最终精炼答案生成:基于验证过程的结果,生成一个最终精炼的答案。这个答案预期会更准确可靠,减少响应中出现幻觉的可能性。
链式验证(CoVe)方法旨在通过系统地验证和完善回答来提高大型语言模型在事实性问题回答场景中提供答案的可靠性,以减少不准确性。
链式验证

链式验证(CoVe)的概念基于这样一个观点:大型语言模型(LLM)生成的回应可以用来自我验证。这种自我验证过程被用来评估初始回应的准确性并对其进行改进,以提高精确度。实现这一点依赖于巧妙地设计和排序LLM提示。
根据研究论文,我们将深入探讨创建一个连贯链条的每个步骤,该链条使得大型语言模型能够自我验证其响应。
生成基线响应:当提出一个初始查询时,它会直接输入到LLM中,不需要任何其他特殊提示就能得到一个初始响应。这个初始步骤不仅作为CoVe流程的起点,也作为旨在通过这个CoVe流程进行增强的基线。由于这样的基线响应往往容易出现幻觉,CoVe方法旨在在后续阶段检测并纠正这些不准确之处。
计划验证:以原始查询和基线响应为条件,模型被指示生成一系列验证问题,旨在评估初始基线响应中所做事实断言的准确性。需要强调的是,这些验证问题不是预先定义的模板;相反,语言模型可以灵活地以任何它认为合适的方式来表述这些问题。尽管如此,这些验证问题应该构建成这样:它们的答案将有助于完善基线响应。
执行验证:一旦规划好了验证问题,接下来的步骤就是系统地回答这些问题,以确定是否存在任何幻觉。这个验证过程可以包括使用工程技术/外部工具,比如通过网络搜索进行验证。此外,你可以在CoVe过程的所有阶段都依赖LLM本身,它将验证自己的响应。作者探索了几种不同的验证执行方法,包括联合、两步、分解和修正+复审等变体。
1. 执行验证:一旦规划好了验证问题,接下来的步骤就是系统地回答这些问题,以确定是否存在任何幻觉。这个验证过程可以包括使用工程技术/外部工具,比如通过网络搜索进行验证。此外,你可以在CoVe过程的所有阶段都依赖LLM本身,它将验证自己的响应。作者探索了几种不同的验证执行方法,包括联合、两步、分解和修正+复审等变体。
2. 二步骤:这一步骤与“联合”步骤正好相反。在第一步中生成验证问题,在第二步中回答验证问题。
3. 分解回答:与其使用一个大的回答,不如分别回答每个问题。这样,答案就不会仅仅是基线回答的复制。这种方法还有助于避免不同问题之间的混淆,并且尽管可能计算成本较高,但它可能能够处理更多的验证问题。
4. 分解+修订:在我们得到验证问题的答案后,CoVe流程需要检查答案是否与基线响应相匹配。这是通过将答案与基线响应进行比较来完成的。这是通过使用额外的提示为LLM设置的一个单独步骤。这个额外的步骤帮助系统更仔细地思考这一比较。
实现:Python 🐍 + Langchain 🔗 + OpenAI 🦾 + Search Tool 🔍

作者引入的验证过程通过一系列问题进行基准测试。这些问题被分为三个主要组别(尽管作者最初将它们分为四个类别):
1. Wiki Data & Wiki Category List:这一类别涉及的问题期望以实体列表的形式回答。例如,像“哪些政治家出生在波士顿?”或者“列举一些越南特有的兰花种类?”这样的问题,应该得到呈现特定实体列表的答案。

2. Multi-Span QA:这一类别的问题寻求多个独立的答案,每个答案都来自文本的不同非相邻部分。例如:“谁发明了第一台机械化印刷机,是在哪一年?”答案是“约翰内斯·古腾堡,1450年”。
3. Long-form Generation:这一类主要包括传记类问题,正如作者的基准测试所强调的。然而,它并不局限于传记。任何需要详细或冗长回答的问题都属于这个类别。
这一类主要包括传记类问题,正如作者的基准测试所强调的。然而,它并不局限于传记。任何需要详细或冗长回答的问题都属于这个类别。
路由机制:当用户输入他们的查询或问题时,该机制立即启动。它将用户的问题归类为前面提到的三个类别之一:维基列表问题、多跨度问题或长篇问题。根据这个分类,路由器随后将问题引导至适当的处理链,每个处理链都专门设计来处理这三种问题类型之一。这种分类是通过使用一个简单的小样本提示设计来实现的。你可以在这里了解更多关于提示的信息。
基线响应:这个阶段很直接,不需要任何提示的构建。此时,用户的查询将由大型语言模型(LLM)处理,产生我们所说的“基线响应”。这个初始响应随后将被评估和完善,以产生最终答案。你可以在这里了解更多关于所有类型问题的提示。
验证问题生成:这个阶段至关重要,需要精心设计和优化提示,以确保验证问题与原始查询无缝对齐。如果这些验证问题偏离了主要意图,整个链条的目的可能会受到影响。为了更好地理解这一点,我们来考虑一个例子。
原问题:Name of the CEOs of US based organizations who were Indian origin.
基线回应:1. Satya Nadella (CEO of Microsoft), 2. Sundar Pichai (CEO of Google) 3. Mark Zuckerberg (CEO of Meta)
验证问题(第一组):
1. Is Satya Nadella CEO of Microsoft? 
2. Is Sundar Pichai CEO of Google? 
3. Is Mark Zuckerberg CEO of Meta?
验证问题(第二组):
1. Is Satya Nadella CEO of Microsoft was an Indian origin? 
2. Is Sundar Pichai CEO of Google was an Indian origin? 
3. Is Mark Zuckerberg CEO of Meta was an Indian origin?
在仔细检查这两组验证问题后,我们可以观察到以下情况:
在第一组中,所有三个问题都将得到“是”的验证答案。最终精炼的回应将包括基线回应中提供的三个名字。这不是预期的结果,因为问题的主要目的是识别那些具有印度血统的首席执行官。第一组中的问题未能捕捉到这一特定意图。
相反,第二组设置更符合我们的目标。例如,第三个核查问题将正确排除Mark Zuckerberg,因为尽管他是Meta的首席执行官,但他并非印度血统。
因此,精确的提示工程设计和彻底的实验在这个阶段至关重要。如果需要进一步了解不同问题类型的提示结构,您可以参考这里:https://github.com/ritun16/chain-of-verification/blob/7f9972218fb030c08b4cdaa5108cb238c432a528/src/prompts.py#L21-L69
执行验证问题:这个阶段和前一个阶段一样关键。即使有高度准确的验证问题与主要目标一致,最终精炼答案的质量也极大地取决于这个阶段。尽管作者完全依赖LLM来处理生成的验证问题,但人们可以灵活地使用各种概念或外部工具来达到这个目的。在我的方法中,我使用了一个免费的搜索工具“duckduckgo-search”来寻找答案。这些搜索结果随后作为LLM处理每个验证问题的参考上下文。其他选择包括更复杂的搜索工具、基于RAG的系统、数据库或其他检索工具和机制来回答之前制定的验证问题。如果想进一步了解提示结构,可以参考这里:https://github.com/ritun16/chain-of-verification/blob/7f9972218fb030c08b4cdaa5108cb238c432a528/src/prompts.py#L72-L87
最终精炼答案:这一步相对直接。它涉及使用所有之前的数据(原始查询、基线回应、验证问题及其各自的答案)来制定一个提示,以提供最终精炼的答案。参见示例提示以供参考:https://github.com/ritun16/chain-of-verification/blob/7f9972218fb030c08b4cdaa5108cb238c432a528/src/prompts.py#L90-L97
如何提升整体CoVe流程效率

1. 提示工程:提高任何基于大型语言模型(LLM)应用性能的主要方法之一是通过提示工程和提示优化。你可以在我的GitHub实现中检查所有使用的提示。尝试你自己的提示工程,并在你的用例中进行实验。
2. 外部工具:由于最终输出在很大程度上取决于验证问题的答案,根据不同的使用案例,你可以尝试不同的工具。对于事实性问题和回答,你可以使用高级搜索工具,如谷歌搜索或serp API等。对于定制的使用案例,你总是可以使用RAG方法或其他检索技术来回答验证问题。
3. 更多链条:根据作者在研究中使用的三种问题类型(维基数据、多跨度问答和长形式问答),我已经实现了三条链条。根据您的使用情况,您可以创建其他可以处理其他类型问答方法的链条,以增加变化性。
4. Human In Loop (HIL): HIL 是许多由大型语言模型(LLM)驱动的应用中的一个重要步骤。在您的特定应用中,整个流程可以设计为纳入HIL,无论是用于生成适当的验证问题还是回答验证问题,以进一步改进整体的CoVe流程。
局限性

链式验证(CoVe)方法的主要局限性:
1. 不完全去除幻觉:CoVe并不能完全消除生成内容中的幻觉,这意味着它仍然可能产生错误或误导性的信息。
2. 幻觉缓解的有限范围:CoVe 主要解决直接陈述的事实不准确性形式的幻觉,但可能无法有效处理其他形式的幻觉,例如推理错误或观点错误。
3. 增加了计算成本:在CoVe中生成和执行验证以及响应会增加计算成本,这与其他推理方法(如思维链)类似。
4. 改进的上限:CoVe的有效性受到底层语言模型整体能力的限制,特别是在其识别和纠正自身错误的能力方面。
结论

该论文介绍了链式验证(CoVe)方法,这是一种旨在使大型语言模型更加批判性地思考其回答,并在需要时对自身进行纠正的策略。研究发现,这些模型在回答详细的验证问题时,比仅回答最初的问题要好。这是因为这种方法将验证分解成更简单、更易于管理的问题。此外,还发现防止模型回顾其先前的答案有助于避免重复任何错误或“幻觉”。简单来说,这项技术通过让模型复查其答案,极大地改善了模型的响应。一个潜在的改进可能是给CoVe额外的工具,比如允许它从外部来源提取信息,这可能会进一步提高其性能。
原文:https://sourajit16-02-93.medium.com/chain-of-verification-cove-understanding-implementation-e7338c7f4cb5
继续阅读
阅读原文