检索增强生成 和思维链 结合: 如何创建检索增强思维链 (RAT)?

论文地址:https://arxiv.org/pdf/2403.05313

Github地址:https://github.com/CraftJarvis/RAT

想象一下,一个人工智能助手可以像莎士比亚一样写作,像专家一样推理。这听起来很了不起,对吧?但是,如果这个助手有时难以确保事实准确性,依赖过时的信息或只是编造事实,该怎么办?

检索增强思维 (RAT) 是一种创新性的方法,它结合了两种关键技术:检索增强生成 (RAG) 和思维链 (CoT) 提示。大型语言模型 (LLM) 因其模仿人类写作和流畅回答问题的能力而变得流行。但有时,他们的回答需要以现实世界的知识为基础。RAT 通过提供一种革命性的人工智能推理方法来解决这个问题。让我们深入研究并了解 RAT 的代码!

在我们深入讨论之前,让我们先把整个提示分解一下。想象一下,你有这个超酷的人工智能助手,提示语是你用来告诉它你想要什么的目的。你可以让它为你写一个故事,翻译一种语言,或者以一种非常有信息量的方式回答一个问题,这一切都是为了给大模型一个清晰明确的提示。

最酷的部分是:提示工程让你能够激发大模型的全部潜力。你可以用它做各种各样的事情,从写出绝妙的诗歌到解决超级复杂的问题。此外,甚至还有一些高级技术,如一次性、零次、少量、思维链、指导性和迭代性提示,每种技术都适用于简单的任务和复杂的多步骤流程。

现在,我们来谈谈 RAT,这是一种结合了两种强大技术的新方法:检索增强生成 (RAG) 和思维链 (CoT)。让我们探索这两种技术如何将 大模型推理推理提升到新的高度。

检索增强生成 (RAG):知识注入器

想象一下,一个 LLM 正在研究一道数学题。RAG 就像一个乐于助人的导师。它允许 LLM 在推理过程中从外部来源(如公式或定理)获取相关信息。这确保了 LLM 的步骤以事实知识为基础,从而减少了出现奇思妙想解决方案的可能性。

思维链 (CoT):让思考变得可见

思路链提示:帮助大型语言模型展示其工作成果

大型语言模型 (LLM) 擅长生成文本,但它们在解决需要逐步推理的复杂问题(如解决文字问题)时会遇到困难。

CoT 提示通过鼓励 LLM 解释他们的想法来解决这个问题。LLM不只是给出最终答案,而是通过将问题分解为更小的步骤来展示其“工作”。这就像在数学课上展示你的计算一样。

有两种方法可以让 LLM 使用 CoT 提示:

  • 零次提示:我们在提示本身中使用特殊的单词或短语,例如“让我们一步一步思考”,以促使 LLM 解释其推理。
  • 少量提示:我们向 LLM 展示一些如何解决类似问题的例子,其中清楚地解释了解决步骤。

然而,CoT 提示也存在一些挑战。

  • LLM 可能会犯错误:如果他们对主题没有足够的了解,他们的推理步骤可能会错误。
  • LLM 可能会陷入错误的想法:有时,他们可能会提出不基于现实的解释。

思路链提示使大型语言模型能够解决复杂的算术、常识和符号推理任务。图中突出显示了思路链推理过程。

少量提示会给出一些示例来帮助语言模型理解它应该做什么,而思维链提示则会从头到尾展示逐步推理。这有助于完成需要符号推理和中间步骤的复杂任务。它最适合较大的模型,而较小的模型可能会产生奇怪的思维链并且不太精确。在某些情况下,您可以使用零次思维链提示而不显示中间步骤。

RAT:知识与思维链的结合

检索增强思维 (RAT) 是一种简单但有效的提示方法,它将思路链 (CoT) 提示与检索增强生成 (RAG) 相结合,以处理长窗口推理和生成问题。

因此,LLM 生成零样本思维链 (CoT),并与 RAG 合并。使用这些想法作为询问,对其进行因果修正并逐步发展出答案。

使用信息检索迭代修改思维链可显著增强大型语言模型在处理长视域生成任务时的推理和生成能力。这种方法还大大减少了幻觉的发生。我们提出的方法称为检索增强思维 (RAT),它涉及使用从相关来源检索到的信息逐一修改每个思维步骤。这包括任务查询,以及生成初始零样本 CoT 后的当前和过去思维步骤。

通过将 RAT 应用于各种基础模型,我们发现它们在各种长视界生成任务上的表现都有显著提升。平均而言,代码生成评分相对提高 13.63%,数学推理评分提高 16.96%,创意写作评分提高 19.2%,具体任务规划评分提高 42.78%。

在这里插入图片描述

检索增强思维 (RAT) 的管道。给定一个任务提示(在图中表示为 I),RAT 从 LLM 在零样本(“让我们一步一步思考”)中产生的初始分步思维(𝑇1、𝑇2、· · ·、𝑇𝑛)开始。由于幻觉,某些思维步骤(例如图中的 𝑇1)可能存在缺陷。RAT 使用来自外部知识库(表示为 Library)的 RAG 迭代地修改每个思维步骤。

该图概述了检索增强思维 (RAT) 流程,这是一种促使大型语言模型 (LLM) 提高其在长窗口任务中的推理能力的方法。以下是关键模块的原理:

步骤 0:初稿

  • 向 LLM 提出任务提示。
  • 该示例展示了有关在 Minecraft 中获取钻石的提示。

步骤 1-步骤 n:迭代细化

  • LLM 根据对提示的理解生成初始响应(Zero CoT)。由于缺乏具体信息,这可能会存在缺陷。
  • RAT 结合了 CoT 提示,其中 LLM 通过解释每个步骤的理由 (Ti) 来反复修改其响应。

关键组件

  • 任务提示:这是起点,为 LLM 提供要解决的问题。
  • LLM:这代表大型语言模型本身。
  • 初始 CoT(Ti-1、Ti):这些是 LLM 在迭代过程中的初始和修订的思维链。
  • 知识库:这象征着 LLM 可以通过检索增强生成 (RAG) 访问的外部知识库。
  • 增强修订:这指的是 LLM 如何根据检索到的信息和先前的解释来完善其思维链 (Ti)。

RAT 流程

  1. 初始响应: LLM 根据提示 (T0) 生成初始响应。
  2. 解释: LLM 解释了初步回应 (T1-1) 背后的原因。
  3. 检索: RAT 根据解释从外部知识库(Library)检索相关信息。
  4. 修订: LLM 通过整合检索到的信息来修订其思维链 (T1)。
  5. 重复:重复步骤 2-4,直到 LLM 得到满意的解决方案 (Tn)。

下图强调了 RAT 如何通过结合外部知识检索和逐步解释来解决 LLM 在复杂推理任务中的局限性。

图 | 上:不同 LLM 推理方法在创意生成任务上的示例。红色文本表示 LLM 生成的文本中的错误或错觉,而绿色文本表示正确生成。没有 RAG 的方法通常会产生带有幻觉的不正确信息,经典 RAG 与结构松散的检索内容高度相关,而 RAT 生成的文本在准确性和完整性方面表现最佳。下:不同 LLM 推理方法在复杂的具身规划、数学推理、代码生成和创意生成任务上的定量性能比较。我们的 RAT 在所有任务上的表现都优于所有基线。

RAT核心代码

https://github.com/CraftJarvis/RAT/blob/main/app/gradio_app.py
RAT实现如下:

def rat(question):print(f"{datetime.now()} [INFO] Generating draft...")draft = get_draft(question)print(f"{datetime.now()} [INFO] Return draft.")# print(f"##################### DRAFT #######################")# print(draft)# print(f"#####################  END  #######################")print(f"{datetime.now()} [INFO] Processing draft ...")# draft_paragraphs = split_draft(draft)draft_paragraphs = split_draft_openai(question, draft)print(f"{datetime.now()} [INFO] Draft is splitted into {len(draft_paragraphs)} sections.")answer = ""for i, p in enumerate(draft_paragraphs):# print(str(i)*80)print(f"{datetime.now()} [INFO] Revising {i+1}/{len(draft_paragraphs)} sections ...")answer = answer + '\n\n' + p# print(f"[{i}/{len(draft_paragraphs)}] Original Answer:\n{answer.replace(newline_char, ' ')}")# query = get_query(question, answer)print(f"{datetime.now()} [INFO] Generating query ...")res = run_with_timeout(get_query_wrapper, 30, question, answer)if not res:print(f"{datetime.now()} [INFO] Generating query timeout, skipping...")continueelse:query = resprint(f">>> {i}/{len(draft_paragraphs)} Query: {query.replace(newline_char, ' ')}")print(f"{datetime.now()} [INFO] Crawling network pages ...")# content = get_content(query)res = run_with_timeout(get_content_wrapper, 30, query)if not res:print(f"{datetime.now()} [INFO] Parsing network pages timeout, skipping ...")continueelse:content = resLIMIT = 2for j, c in enumerate(content):if  j >= LIMIT: # limit rge number of network pagesbreakprint(f"{datetime.now()} [INFO] Revising answers with retrieved network pages...[{j}/{min(len(content),LIMIT)}]")# answer = get_revise_answer(question, answer, c)res = run_with_timeout(get_revise_answer_wrapper, 30, question, answer, c)if not res:print(f"{datetime.now()} [INFO] Revising answers timeout, skipping ...")continueelse:diff_html = generate_diff_html(answer, res)display(HTML(diff_html))answer = resprint(f"{datetime.now()} [INFO] Answer revised [{j}/{min(len(content),3)}]")# print(f"[{i}/{len(draft_paragraphs)}] REVISED ANSWER:\n {answer.replace(newline_char, ' ')}")# print()res = run_with_timeout(get_reflect_answer_wrapper, 30, question, answer)if not res:print(f"{datetime.now()} [INFO] Reflecting answers timeout, skipping next steps...")else:answer = resreturn draft, answer
  1. 生成初始草稿

    • 使用 GPT-3.5-turbo 生成一个初始的草稿答案(draft)。
    • 草稿答案是基于用户输入的问题生成的,可能包含一些错误或不完整的信息。
  2. 分割草稿

    • 将草稿答案分割成多个段落(draft_paragraphs),每个段落包含一个完整的思路。
    • 分割的目的是为了逐段修正和优化答案。
  3. 逐段修正答案

    • 对每个段落,生成一个检索查询(query),用于从网络中检索相关信息。
    • 根据检索到的内容,修正当前段落的答案。
    • 重复这一过程,直到所有段落都修正完毕。
  4. 结构化输出

    • 最后,为修正后的答案添加标题和副标题,使其更具结构性。
  5. 返回结果

    • 返回初始草稿和修正后的最终答案。

示例流程
假设用户输入的问题是:“介绍爱因斯坦的生平和成就。”

  1. 生成初始草稿

    • GPT-3.5-turbo 生成一个初始答案,可能包含一些不准确的信息。
  2. 分割草稿

    • 将初始答案分割成多个段落,例如:
      • 段落1:爱因斯坦的早期生活。
      • 段落2:爱因斯坦的科学成就。
      • 段落3:爱因斯坦的晚年生活。
  3. 逐段修正

    • 对每个段落生成检索查询,例如:
      • 查询1:“爱因斯坦的早期生活”。
      • 查询2:“爱因斯坦的科学成就”。
      • 查询3:“爱因斯坦的晚年生活”。
    • 根据检索结果修正每个段落的内容。
  4. 结构化输出

    • 为修正后的答案添加标题和副标题,例如:
      • 标题:爱因斯坦的生平和成就
      • 副标题1:早期生活
      • 副标题2:科学成就
      • 副标题3:晚年生活
  5. 返回结果

    • 返回初始草稿和修正后的最终答案。

其中用到的一些提示语如下:

prompt1 = """
尝试用逐步的思考来回答这个问题\指令,并使答案更具结构化。
使用 `\n\n` 来将答案分成几个段落。
直接响应指令。除非被要求,否则不要在答案中添加额外的解释或介绍。
"""prompt2 = """
我想验证给定问题的内容准确性,特别是最后几句话。
请用相应的问题总结内容。
这个总结将被用作必应搜索引擎的查询。
查询应该简短,但需要足够具体,以确保必应能够找到相关知识或页面。
您还可以使用搜索语法,使查询足够简短和清晰,以便搜索引擎能够找到相关的语言数据。
尽量使查询与内容中的最后几句话尽可能相关。
**重要**
直接输出查询。除非被要求,否则不要在答案中添加额外的解释或介绍。
"""prompt3 = """
我想根据在维基百科页面上学到的相关文本来修订答案。
你需要检查答案是否正确。
如果你在答案中发现了错误,请修订答案使其更好。
如果你发现有些必要的细节被忽略了,请根据相关文本添加这些细节,以使答案更加可信。
如果你发现答案是正确的且不需要添加更多细节,请直接输出原始答案。
**重要**
尽量保持修订后答案的结构(多个段落及其子标题),使其更具结构性以便理解。
用 `\n\n` 字符分隔段落。
直接输出修订后的答案。除非被要求,否则在修订后的答案中不要添加额外的解释或声明。
"""

RAT 的优势

  • 提高准确性:通过允许 LLM 访问外部知识并改进其推理,RAT 有助于减少错误并生成更准确的解决方案。
  • 增强的可解释性:带有解释的迭代过程可以深入了解 LLM 的思维过程,从而更容易识别和解决任何问题。
  • 更强的长窗口推理能力: RAT 对于需要多步骤的复杂任务特别有益,因为推理透明度至关重要。

参考资料

  • How Retrieval-Augmented Generation (RAG) and Chain-of-Thought (CoT) Create Retrieval-Augmented-Thought(RAT)?
  • 检索增强思考 RAT(RAG+COT):提升 AI 推理能力的强大组合 原创
  • 【LLM-RAG】RAT:检索增强思维提示实现上下文感知推理
  • 将RAG与CoT结合起来的技术,RAT减轻长文本生成出现的幻觉问题
  • 【AI大模型应用开发】RAT原理与实现:又是一个提高大模型生成能力的方法(附完整代码)

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

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

相关文章

关于数组的一些应用--------数组作函数的返回值(斐波那契数列数列的实现)

数组在作为函数的返回值,一个很经典的例子就是获取斐波那契数列的前N项 代码思路: 设计思路 输入: 输入一个整数 n,表示要生成斐波那契数列的长度。 输出: 输出一个长度为 n 的整数数组,其中每个元素为斐…

【IT人物系列】之MySQL创始人

前言 当今世界有无数的人构成,其中有些人做了一些改变世界的事情,比如:乔布斯缔造了Apple帝国,‌詹姆斯高斯林创造了Java语言等。正是这些优秀的人做的这些优秀的事情,让这个世界更加美好。因此他们值得铭记。 从今天…

【2025最新计算机毕业设计】基于SpringBoot+Vue智慧养老医护系统(高质量源码,提供文档,免费部署到本地)【提供源码+答辩PPT+文档+项目部署】

作者简介:✌CSDN新星计划导师、Java领域优质创作者、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流。✌ 主要内容:🌟Java项目、Python项目、前端项目、PHP、ASP.NET、人工智能…

pytorch镜像源

我以为的 pip install torch2.3.1cu118 torchvision0.18.1cu118 torchaudio2.3.1cu118 -f https://download.pytorch.org/whl/torch_stable.html实际上,有很多加速方案 为提高下载速度可以使用国内的镜像源来安装与 CUDA 11.8 兼容的 PyTorch。 方法 1&#xff1a…

047_小驰私房菜_Qcom 8系列,Jpeg GPU 旋转

【问题背景】 横屏模式下,发现有些三方app拍照旋转了90度。 【修改策略】 adb shell setprop endor.debug.camera.overrideGPURotationUsecase 1 或者在/vendor/etc/camera/camxoverridesettings.txt 里面添加如下内容 overrideGPURotationUsecase1 【解释】 Ga…

源代码编译安装X11及相关库、vim,配置vim(2)

一、编译安装vim 编译时的cofigure选项如下.只有上一步的X11的包安装全了(具体哪些是必须的,哪些是多余的没验证),configure才能认为X的库文件和头文件是可以用的 ./configure --prefixpwd/mybuild \--x-includes/path/to/X11/m…

Go语言性能优化-字符串格式化优化

在 Go 语言中,格式化字符串(例如使用 fmt.Sprintf、fmt.Printf 等函数)确实可能对性能产生影响,尤其是当频繁执行格式化操作时。格式化字符串涉及对格式符的解析和数据类型的转换,这会增加额外的开销。为了减少格式化字符串带来的性能影响,可以采取以下一些优化策略: 1…

LSP介绍并实现语言服务

首发于Enaium的个人博客 LSP (Language Server Protocol) 介绍 前段时间我为Jimmer DTO实现了一个 LSP 的语言服务,这是我第一次实现 LSP,所以在这里我分享一下我实现LSP的经验。 首先来看一下效果,图片太多,我就放一部分&#…

谷粒商城项目125-spring整合high-level-client

新年快乐! 致2025年还在努力学习的你! 你已经很努力了,今晚就让自己好好休息一晚吧! 在后端中选用哪种elasticsearch客户端? elasticsearch可以通过9200或者9300端口进行操作 1)9300:TCP spring-data-elasticsearch:transport-…

springboot3 redis 批量删除特定的 key 或带有特定前缀的 key

在 Spring Boot 3 中与 Redis 一起使用时,可以通过 Redis 的命令来实现批量删除特定的 Key 或带有特定前缀的 Key。以下是实现方式和注意事项。 使用 RedisTemplate RedisTemplate 是 Spring Boot 提供的一个操作 Redis 的工具,支持各种 Redis 操作。 …

MyBatis-plus sql拦截器

因为业务需求,重新写了一套数据权限。项目中用的是mybtis-plus,正好MyBatis-Plus提供了插件数据权限插件 | MyBatis-Plus,那就根据文档来实现这个需求。 实现: 实现MultiDataPermissionHandler 首先创建MultiDataPermissionHan…

Java字符编码与正则表达式深度解析

Java字符编码与正则表达式深度解析 1. 字符编码发展 1.1 ASCII 码 在计算机最初发明时,主要用于数值计算,但随着计算需求的增加,人们发现计算机可以用来处理文本信息。因此,将字符映射为数字来表示。 字母 ‘A’ 映射为 65&am…

前端(十)js的使用

js的使用 文章目录 js的使用一、模态框二、使用js控制盒子变色三、图片轮播效果四、图片5s消失 一、模态框 <!doctype html> <html lang"en"> <head><meta charset"UTF-8"><title>Document</title><style>* {m…

Docker 远程访问完整配置教程以及核心参数理解

Docker 远程访问完整配置教程 以下是配置 Docker 支持远程访问的完整教程&#xff0c;包括参数说明、配置修改、云服务器安全组设置、主机防火墙配置&#xff0c;以及验证远程访问的详细步骤。 1. 理解 -H fd:// 参数的作用&#xff08;理解了以后容易理解后面的操作&#xff…

第十一章 图论

/* * 题目名称&#xff1a;连通图 * 题目来源&#xff1a;吉林大学复试上机题 * 题目链接&#xff1a;http://t.cn/AiO77VoA * 代码作者&#xff1a;杨泽邦(炉灰) */#include <iostream> #include <cstdio>using namespace std;const int MAXN 1000 10;int fathe…

新服务器Linux网络配置

1、查看网口 ifconfig找到enp3s0或者 ens33&#xff0c;如果有ip&#xff0c;不用配置&#xff0c;本文结束。 2、如果不显示ip,打开文件/etc/sysconfig/network-scripts&#xff08;以enp3s0为例&#xff09; vi /etc/sysconfig/network-scripts/ifcfg-enp3s03、修改 //修…

leetcode hot 100 只出现一次的数字

136. 只出现一次的数字 已解答 简单 相关标签 相关企业 提示 给你一个 非空 整数数组 nums &#xff0c;除了某个元素只出现一次以外&#xff0c;其余每个元素均出现两次。找出那个只出现了一次的元素。 你必须设计并实现线性时间复杂度的算法来解决此问题&#xff0c;且…

汇编学习笔记

汇编 1. debug指令 -R命令(register) 查看、改变CPU寄存器的内容 r ax 修改AX中的内容 -D命令(display) 查看内存中的内容 -E命令(enter) 改写内存中的内容 -U命令(unassenble反汇编) 将内存中的机器指令翻译成汇编指令 -T命令(trace跟踪) 执行一条机器指令 -A命令…

Flutter踩坑记-第三方SDK不兼容Gradle 8.0,需适配namespace

最近需要集成Flutter作为Module&#xff0c;Flutter依赖了第三方库&#xff0c;Gradle是8.0版本。 编译报错&#xff1a; 解决办法是在.android根目录下的build.gradle下新增一行代码&#xff1a; buildscript {ext.kotlin_version "1.8.22"repositories {google()…

【Qt】如何保证线程安全(以日志写入为例)

前言 在近日学习中发现&#xff0c;如果开发一个单例模式的日志系统&#xff0c;难免会出现多个线程记录日志的情况&#xff0c;这个时候线程可能导致竞争&#xff0c;或者始料未及的情况发生。 通过学习&#xff0c;如果要保证线程安全&#xff0c;要使用互斥锁QMutex&#xf…