LLM之RAG实战(十五)| RAG的自动源引文验证技术

​       在过去的一年里,检索增强生成(RAG)已经成为一种基于LLM的流行架构,旨在解决在基于知识的LLM最常见的挑战之一,可怕的幻觉

一、RAG如何解决幻觉?

       RAG Pipeline包括两个关键组件:(1)检索器:选择和过滤数据(2)LLM推理:指示LLM使用过滤后的数据回答问题。这两个步骤对需要利用私人知识(如一组合同、财务分析或客户支持数据)的企业来说尤其有效。

二、证据验证

      RAG工作流程中有一个关键的第三步,最近越来越受到关注,那就是LLM推理后发生的事情,特别是:对于潜在的大规模LLM推理,系统如何验证LLM响应是否与引用的特定来源相对应?最终,这是RAG系统的真正回报,但需要一个集成的管道,该管道捕获导致LLM提示的各种输入,然后集成所有LLM推理数据,以实现后处理、源验证、持续审查和审计,并创建一个持续改进的循环。

       在这个博客中,我们将展示一系列强大的技术,作为RAG工作流中的第三步后处理,提供来源验证和自动来源引用。我们将使用llmware(https://www.github.com/llmware-ai/llmware.git),一个用于开发验证LLM应用程序的领先开源框架,来构建RAG工作流,该工作流提供基本的合同分析,然后与合同中的源段落相比,验证LLM响应的准确性。

       LLMware在Prompt类中提供了几种现成的工具,用于简单直观的验证RAG工作流中的来源和证据,具体如下:

·evidence_check_numbers——检查一组提示响应对象,并验证llm_response中的数字是否在提供的源材料中;

·evidence_check_sources——审查llm响应和整个证据,以“确定”最有可能的文本片段、它们的文档和页码,这些文本片段构成llm响应的“源”参考书目;

·evidence_comparison_stats——提供快速的token比较,来分析响应与证据中的令牌以及已确认和未确认的令牌的总体匹配;

·classification_not_found_response——提供三个不同的函数来评估llm_response是否可能被归类为“未找到”响应,以便在工作流中正确处理(包括丢弃);

·save_state——提示状态可以保存整个管道捕获llm事务的各种信息,可能还有一系列事务,并将其保存到一个包装良好的jsonl字典中进行离线分析,或方便地插入到文档数据存储中。该状态还可以用于快速生成微调数据集。

三、代码实现

3.1 安装llmware包

pip install llmware

3.2 使用Setup()命令来下拉一组数百个有用的示例文档,这些文档打包在llmware公共repo中

from llmware.setup import Setupsample_files_path=Setup().load_sample_files()contracts_path = os.path.join(sample_files_path, "Agreements")

       在本演示中,我们将使用“Agreements”文件夹中的一些高管雇佣协议样本,当然也可以使用客户用户数据

       一旦有了样本合同文件,我们就可以开始构建RAG工作流程了。

       让我们看一下代码的每个组件,然后将所有部分放在一起。

Step1创建Prompt对象——在llmware中,Prompt是处理端到端提示交互的主要类,RAG过程的所有步骤都可以在特定的提示中处理。提示将处理加载模型、包装和过滤源材料、应用提示说明以及后期处理生命周期。

      在第一步中,我们要做的就是实例化一个提示对象,并附加我们选择的模型。

prompter = Prompt().load_model(“gpt-4”, api_key=open_api_key)

       在这个演示中,我们将使用“gpt-4”,您可以直接传递api_key,也可以将其加载到os.environ变量中:

openai_api_key = os.environ.get(“OPENAI_API_KEY”,””)

(顺便说一句,我们鼓励您尝试其他模型,包括基于Huggingface的开源LLM模型,如单独的教程中所述。llmware的功能之一是可以通过简单地更改模型字符串名称并传递其api密钥来快速交换另一个模型。)

Step2创建源材料——这是RAG工作流程中的关键一步,我们将把“add_source_document”方法指向我们的合同文件夹和特定的合同,然后这个方法将找出文档类型,通过解析文档特定的格式(例如PDF或Word文档)来提取内容,对文本进行分组,然后可以应用一个可选的过滤器,然后作为一个“上下文”进行批处理和打包,为推理做好准备,这样我们就不必再考虑它,也不必进行所有的数据操作——所有这些都是在这个强大的方法调用的幕后处理的。Llmware用一句简单的俏皮话让这一步变得轻而易举:

source = prompter.add_source_document(exec_emp_fp, contract, query=”base salary”)

       在这种情况下,我们将分析所选文件夹中的合同,无论文件类型如何,然后我们将基于“base salary”主题进行进一步筛选,并将其打包为具有元数据的源,以包含在LLM的提示中。

Step3运行推理——这是主要的处理步骤,将上一步准备的原料加载到提示中,通过查询提示指令温度设置来调用LLM并获得LLM响应。

responses = prompter.prompt_with_source(“What is the executive’s base salary?”, prompt_name = “just_the_facts”, temperature=0.3)

       推理的输出是一个标准的响应字典,其中包括一个或多个llm响应,根据输入上下文的大小,它将自动将上下文分为多个批,并在需要时运行几个推理。

Step4源数据检查——这是提示完成后的最后一个主要步骤,即响应字典的后期处理。如上所述,提供了几种来源和自动证据检查工具:

ev_numbers = prompter.evidence_check_numbers(responses)ev_sources = prompter.evidence_check_sources(responses)ev_stats = prompter.comparison_stats(responses)not_found_status = prompter.classify_not_found_response(responses,                                                         parse_response=True,                                                         evidence_match=True,                                                        ask_the_model=False)

一旦我们运行代码,我们将查看这些方法中每一个的输出。

综合来看,以下是我们将运行的完整代码(也可以在llmware repo中完整找到):

from llmware.prompts import Promptfrom llmware.configs import LLMWareConfigimport osos.environ["USER_MANAGED_OPENAI_API_KEY"] = "insert-your-openai-key"
def contract_analysis_w_fact_checking (model_name):    contracts_path = "/path/to/your/sample/documents/"    # create prompt object    prompter = Prompt().load_model(model_name)    research = {"topic": "base salary", "prompt": "What is the executive's base salary?"}    for i, contract in enumerate(os.listdir(contracts_path)):        print("\nAnalyzing Contract - ", str(i+1), contract)        print("Question: ", research["prompt"])        # contract is parsed, text-chunked, and then filtered by "base salary'        source = prompter.add_source_document(contracts_path, contract, query=research["topic"])        # calling the LLM with 'source' information from the contract automatically packaged into the prompt        responses = prompter.prompt_with_source(research["prompt"], prompt_name="just_the_facts", temperature=0.3)        # run several fact checks        ev_numbers = prompter.evidence_check_numbers(responses)        ev_sources = prompter.evidence_check_sources(responses)        ev_stats = prompter.evidence_comparison_stats(responses)        z = prompter.classify_not_found_response(responses, parse_response=True, evidence_match=True,ask_the_model=False)        for r, response in enumerate(responses):            print("LLM Response: ", response["llm_response"])            print("Numbers: ",  ev_numbers[r]["fact_check"])            print("Sources: ", ev_sources[r]["source_review"])            print("Stats: ", ev_stats[r]["comparison_stats"])            print("Not Found Check: ", z[r])            # We're done with this contract, clear the source from the prompt            prompter.clear_source_materials()    # Save jsonl report to jsonl to /prompt_history folder    print("\nupdate: prompt state saved at: ", os.path.join(LLMWareConfig.get_prompt_path(),prompter.prompt_id))    prompter.save_state()

       运行脚本并在控制台中,将很快看到与每个合同文档的分析相对应的一系列输出,每个文档的代表性输出类似于以下内容:

Analyzing Contract -  1 Nyx EXECUTIVE EMPLOYMENT AGREEMENT.docxQuestion:  What is the executive's base salary?LLM Response:  $200,000.Numbers:  [{'fact': '$200,000,', 'status': 'Confirmed', 'text': ' ... pay Executive a base salary at the annual rate of $200,000, payable semimonthly in accordance with Employer's normal payroll practices.  ... ', 'page_num': '3', 'source': 'Nyx EXECUTIVE EMPLOYMENT AGREEMENT.docx'}]Sources:  [{'text': 'pay Executive a base salary at the annual rate of $200000 payable semimonthly in accordance with Employer's normal payroll practices ', 'match_score': 1.0, 'source': 'Nyx EXECUTIVE EMPLOYMENT AGREEMENT.docx', 'page_num': '4'}]Stats:  {'percent_display': '100.0%', 'confirmed_words': ['200000'], 'unconfirmed_words': [], 'verified_token_match_ratio': 1.0, 'key_point_list': [{'key_point': '$200,000.', 'entry': 0, 'verified_match': 1.0}]}Not Found Check:  {'parse_llm_response': False, 'evidence_match': False, 'not_found_classification': False}Numbers:  [{'fact': '$200,000,', 'status': 'Confirmed', 'text': ' ... pay Executive a base salary at the annual rate of $200,000, payable semimonthly in accordance with Employer’s normal payroll practices.  ... ', 'page_num': '3', 'source': 'Nyx EXECUTIVE EMPLOYMENT AGREEMENT.docx'}]

让我们更详细地解释每一个事实核查。

Numbers——这将审查LLM响应,识别响应中的任何数字,然后在源材料中查找匹配的数字值,如果提供,则会提供一个包含已确认事实的词典,显示事实、状态,以及提供确认的源和页码文本片段。提供了基本的正则表达式处理(例如,删除“$”、逗号等)以及浮点值比较(例如,12.00与12相同),以增强检查的稳健性。

Sources——该方法审查上下文中提供的所有来源,并根据匹配标记的密度提供统计衍生的审查,以确定llm输出最可能的特定来源,包括来源文档和页码。

Stats–这是一个非常有用的快速检查,也是识别潜在问题响应的最可靠的简单方法之一–它显示了按token匹配的百分比(不包括停止词和基本格式项),并显示了已确认和未确认的关键token的列表。

Not Found Classification——根据经验,这是RAG处理中最重要、也是最不被理解的检查之一。在几乎任何RAG自动化中,都会出现许多情况,其中特定的段落被包含在上下文中,并且该段落不足以回答目标问题或分析。这些时候往往是错误的最高风险,因为模型试图通过结合上下文中的信息来创建答案来“提供帮助”,即使上下文并不具体适用。此外,当工作流最有用的输出是“未找到”的分类时,模型在回答这些问题时往往会冗长地解释为什么它不能提供答案,从而将特定的推理事务排除在进一步分析之外。在这种情况下,“False”表示双重否定,例如,事务“not”是“not found”事务。

Prompt State–最后,所有经过检查的llm响应对象都保存在控制台输出底部链接的提示状态历史记录中。更多信息可以查看此.jsonl文件,该文件提供了特定LLM事务的所有元数据的完整视图,这些元数据可用于多种目的:

·对总体准确性和错误/幻觉率的分析;

·不同模型的比较;

·审计和合规活动;

·持续改进以识别常见问题。

      这五种机制(包括numbers, sources, stats, not-found, and prompt state)的结合为几乎所有RAG工作流提供了一个强大的工具包,可以快速识别潜在的错误和风险暴露。

参考文献:

[1] https://medium.com/@darrenoberst/using-llmware-for-rag-evidence-verification-8611abf2dbeb

[2] https://www.github.com/llmware-ai/llmware.git

[3] https://www.huggingface.co/llmware/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/623698.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java零基础教学文档servlet(1)

【Web开发和HTTP协议】 1. Web开发概述 1.1 web概述 万维网(英语:World Wide Web)亦作WWW、Web、全球广域网,是一个透过互联网访问的,由许多互相链接的超文本组成的信息系统。英国科学家蒂姆伯纳斯-李于1989年发明了…

类脑研究之脑组成及神经系统相关理论!大脑是什么?大脑和脑有什么区别?大脑皮层和脑膜什么关系?人的神经系统有哪些?

目录 1 引言2 神经系统3 脑组成3.1 大脑成分3.2 大脑外部:脑膜3.3 大脑中部:大脑皮层3.4 大脑内部3.5 脑干3.6 小脑 1 引言 为了深入研究类脑,必须了解大脑的结构和机制。从神经系统分级和脑组成两个角度出发,详细介绍了大脑的生…

1.如何记录每个变量携带的数据:DataFrame与Series

序列格式和列表区别:序列格式可以直接汇总:均值,总和,百分位数等 DataFrame Series

[链路层] 点对点协议 PPP

目录 1、PPP协议的特点 2、PPP协议的组成和帧格式 3、PPP协议的工作状态 目前使用得最广泛的数据链路层协议是点对点协议PPP(Point-to-Point Protocol)。 1、PPP协议的特点 我们知道,互联网用户通常都要连接到某个 ISP 才能接入到互联网。PPP 协议就是用户计算机…

Codeforces Round 918 (Div. 4)补题

Odd One Out&#xff08;Problem - A - Codeforces&#xff09; 题目大意&#xff1a;有三个数&#xff0c;其中两个相同&#xff0c;找出不同的那个数。 #include<bits/stdc.h> using namespace std; int main() {int t;scanf("%d",&t);while(t--){vect…

【面试合集】说说提高微信小程序的应用速度的手段有哪些?

面试官&#xff1a;说说提高微信小程序的应用速度的手段有哪些&#xff1f; 一、是什么 小程序启动会常常遇到如下图场景&#xff1a; 这是因为&#xff0c;小程序首次启动前&#xff0c;微信会在小程序启动前为小程序准备好通用的运行环境&#xff0c;如运行中的线程和一些基…

Endothelin-1(内皮素-1) ELISA kit

灵敏、快速的内皮素-1 ELISA试剂盒&#xff0c;适用于心血管和应激相关研究 内皮素&#xff08;Endothelin, ET&#xff09;是由血管内皮细胞产生的异肽&#xff0c;具有强大的血管收缩活性。这种肽由三个独立的基因编码&#xff0c;经过加工产生39个残基的 大ET 分子&#xff…

服务器 conda update 失败解决方法

1. 强制 conda update 租借一台服务器&#xff0c;发现 conda 版本是4.10.3&#xff0c;需要升级&#xff0c;使用了如下命令都没有效果&#xff0c;仍然是一样的版本 conda update conda update --all conda update -n base -c defaults conda最后强制用conda-forge通道更新…

D25XB60-ASEMI电机整流桥D25XB60

编辑&#xff1a;ll D25XB60-ASEMI电机整流桥D25XB60 型号&#xff1a;D25XB60 品牌&#xff1a;ASEMI 封装&#xff1a;GBJ-5&#xff08;带康铜丝&#xff09; 特性&#xff1a;插件、整流桥 平均正向整流电流&#xff08;Id&#xff09;&#xff1a;25A 最大反向击穿…

Jenkins实现自作自定义镜像并推送Harbor并编写目标服务器准备脚本

Jerkin 制作自定义镜像推送到Harbor docker build -t mytest:$tag . docker login -u admin -p Harbor12345 178.119.30.133:80 docker tag mytest:$tag 178.119.30.133:80/repo/mytest:$tag docker push 178.119.30.133:80/repo/mytest:$tag编写部署脚本 部署项目需要通过Pub…

Everything-一切尽在掌握之中

软件推荐&#xff0c;电脑文件繁多的时候&#xff0c;想要快速找到文件&#xff0c;少不了它 反应速度简直了&#xff0c;一秒响应 官网下载连接&#xff1a;下载 - voidtools

three.js设置模型边界线

three.js设置模型边界线 图例 步骤 拿到模型&#xff08;如果是外部模型需要遍历&#xff09;&#xff0c;设置透明度根据模型的几何体创建EdgesGeometry几何体创建线条材质创建LineSegments线模型模型加入线模型 代码 const m model.scene.getObjectByName("仓库&qu…

广州市工信局、天河区商务金融局及广州专精特新促进会走访思迈特

2024年1月11日下午&#xff0c;广州市工信局、天河区商务金融局及广州专精特新促进会相关负责人莅临广州思迈特软件总部调研指导&#xff0c;思迈特软件总裁兼COO姚诗成代表公司热情接待&#xff0c;并陪同调研。 调研组实地参观了思迈特软件&#xff0c;深入了解了思迈特发展历…

flutter使用get依赖实现全局loading效果,弹窗loading状态

get dialog的官网文档&#xff1a;GetDialogRoute class - dialog_route library - Dart API 可以使用Get.dialog()方法来创建一个自定义的加载弹窗&#xff0c;get框架是支持自定义弹窗效果的&#xff0c;所以我们就使用这个方式来自定义一个弹窗效果&#xff0c;并且点击遮罩…

集合(二)Collection集合Set

一、Set介绍&#xff1a; 是一个散列的集合&#xff0c;数据会按照散列值存储的&#xff0c;如两个hello的散列值相同&#xff0c;会存储在同一个地址中&#xff0c;所以看到的就是只有一个hello在集合中了。 1、Set集合有两个主要的实现子类&#xff1a;Hashset和Treeset。ha…

【java八股文】之Spring系列篇

【java八股文】之JVM基础篇-CSDN博客 【java八股文】之MYSQL基础篇-CSDN博客 【java八股文】之Redis基础篇-CSDN博客 【java八股文】之Spring系列篇-CSDN博客 【java八股文】之分布式系列篇-CSDN博客 【java八股文】之多线程篇-CSDN博客 【java八股文】之JVM基础篇-CSDN博…

CLion中想要在一个项目中有多个C源文件(有多个main函数)

我们知道&#xff0c;一个项目中只能有一个main()函数&#xff0c;但是我们不想分开创建这么多个C源文件&#xff0c;我们想要在一个工程中允许存在多个main方法了&#xff0c;而且可以独立运行&#xff0c;那么只需要以下步骤即可&#xff1a; 1&#xff09;在 File - Settin…

利用CHAT写实验结论

问CHAT&#xff1a;通过观察放置在玻璃表面上的单个水滴&#xff0c;人们可以观察到水滴充当成像系统。探究这样一个透镜的放大倍数和分辨率。 CHAT回复&#xff1a;实验报告标题&#xff1a;利用玻璃表面的单一水滴观察成像系统的放大倍数和分辨率&#xff1a; 一、 实验目的…

TEMU、亚马逊、shein平台崛起迅猛,掌握自养号测评必备运营攻略

2023年12月&#xff0c;SimilarWeb发布的数据显示&#xff0c;TEMU的独立访客数量达到4.67亿&#xff0c;与Aliexpress持平&#xff0c;全球排名第二。亚马逊以26.59亿用户位居第一&#xff0c;而SHEIN则拥有1.723亿用户&#xff0c;排名第三。 然而&#xff0c;仅仅六个月前的…

vue 渲染数组,拖拽排序,渲染同一个数组拖拽排序不影响其他选中行状态

当我们能够设置单行状态改变的时候&#xff0c;那么肯定可以拿到选中的当前行的id或者下标index。 只要设定一个初始化值在拖拽开始的时候重新赋值&#xff0c;然后再处理选中状态的时候进行判断即可。 前期写的时候没有注意到这个问题&#xff0c;可以看这个文章。 在复测的时…