TC-RAG: 图灵完备的检索增强

1. 背景

大型语言模型在众多关键领域均已取得显著进展,并在各种下游任务中展现出卓越性能。

在医疗领域,这些模型尤显潜力,特别是在对责任感和可靠性要求极高的健康护理领域。这些模型通过全面的医学知识预训练,不仅能支持医生做出精确诊断和制定治疗计划,还能改善医疗资源分配。

然而,尽管医疗LLMs取得了显著成就,仍面临一些关键挑战,包括如何避免幻觉、知识更新以及专业化知识等问题。为解决这些问题,提出了检索增强生成(RAG)技术,通过利用外部知识库提供的医疗知识作为上下文信息来增强内容生成:一种有前景且必要的解决方案。

然而,尽管现有通过RAG增强LLMs的方法表现出一定前景,但它们通常忽略了系统状态变量的引入,这些变量对于确保自适应控制、检索停止和系统收敛至关重要。

此外,这些现有的RAG方法并非图灵完备,缺乏动态管理和监控检索过程的能力,无法保证在复杂的医疗场景中得出可靠的结论。在这些复杂的医疗场景中,决策通常需要复杂的多步骤推理和自适应响应,图灵完备性的缺失显著限制了系统的有效性和可靠性。

所以作者提出一种新的方法:构建一个图灵完备(Turing-Complete)的系统来有效管理状态变量,利用有限的逻辑框架来增强RAG过程。这种方法旨在克服现有技术的局限,并提高系统在处理复杂查询时的效率和准确性。

1.1 挑战1: 设计具有监控状态变量的图灵完备RAG系统

现有的RAG方法并未整合能动态跟踪和控制检索过程的监控状态变量。设计一个图灵完备的RAG系统需要引入能够实时准确地计算和反映系统演变上下文的状态变量。这些变量对于指导检索过程中的关键决策——如是否继续、停止或改进检索过程——至关重要。挑战在于如何在模型的前向传递过程中有效管理这些状态变量,同时保持对复杂医疗查询的适应性。

1.2 挑战2: 动态规划检索以维持最佳状态

一旦可以评估状态,如何动态管理状态以达到预期的最优状态成为关键问题。在现实中,医生通常根据对问题的理解程度决定是否进行检索以及检索什么内容,而不是盲目进行检索。这可能导致模型基于已有冗余信息作出混乱甚至误导的推断。因此,挑战在于如何系统地分析和计划后续步骤,并有效利用LLMs内部的参数化知识来维持最佳状态。

1.3 挑战3: 避免无关噪声影响系统状态

传统的RAG检索过程通常由查询关键词驱动,而非根据模型的具体需求,这可能引入大量无关和噪声的上下文。错误的知识随着检索和推理过程的积累而持续增加,导致资源浪费、无效记忆的累积,以及“lost in middle”问题的出现。解决这一挑战的关键在于如何有效地消除错误知识,以维持系统状态的准确性和完整性。

1.4 解决方案

针对上述挑战,本文作者(蒋欣科、方悦、秋日红,以上名称均为音译)提出了图灵完备的RAG(TC-RAG):一个为领域特定LLMs提供可靠且可信的医疗分析的图灵完备系统。

  • • 对于挑战1,设计了一个具有内存堆栈的图灵完备RAG系统,该系统监控中间状态,确保检索过程可靠地收敛到最佳结论。

  • • 对于挑战2,通过广泛收集医疗数据并预训练医疗LLM,提高了其推理和规划能力。

  • • 对于挑战3,TC-RAG结合了内存堆栈系统,利用回溯和总结操作及时删除错误并压缩冗余知识,减轻了错误信息和噪声的积累,从而提升了整体系统的效率和准确性。

2. 图灵完备的记忆栈定义(Tc Stack)

在TC-RAG中,记忆栈是核心组件,用于管理和控制大模型的状态和决策过程。

记忆栈TC定义为 TC=(S,A,M,δ,s0,F,σ),其中各元素具有以下含义:

  • • S(状态):表示大模型可能处于的状态。这里使用具体数值表示大模型的确定性程度,数值越小,表示大模型对当前任务的回答越确定。

  • • A(动作):代表大模型可以执行的动作。在基于栈的记忆系统中,通过“push”和“pop”这两个基本操作的组合,TC-RAG能够有效地管理大模型的交互记忆,精炼交互过程中的记忆内容,以及消除检索过程中引入的噪声。

  • • M(记忆栈):表示大模型的记忆栈,任务开始时用户的查询将被压入栈底。

  • • δ(状态转移函数):管理状态的变化,控制模型从一个状态到另一个状态的过渡。

  • • s0(初始状态):表示大模型的起始状态,通常设为一个高值(Large_Value),代表起始时的不确定性。

  • • F(终止状态):表示大模型的停止状态。当模型需要输出结论,且状态值低于 σ 阈值时,推理结束,此时栈顶的内容作为最终输出。

3. TC-RAG

TC-RAG定义了五种操作行为

  • • 思考:激发大模型的决策能力,让模型根据已有信息分析和处理,然后决定下一步行为。相关内容会被push到记忆栈中。

  • • 工具调用:当大模型凭借现有知识无法解答问题时,可调用网络搜索、文档检索、知识图谱检索等外部工具获取辅助信息。工具的名称及检索结果随后被push到记忆栈中。

  • • 反思:如果大模型发现记忆栈顶的内容与任务无关或有害,可以通过pop操作将这些元素移除,避免干扰。

  • • 总结:当栈顶信息过长或包含噪音时,模型通过总结操作处理信息——先pop出栈顶元素,进行总结,然后将精炼后的文本push回栈中。

  • • 结论:当模型准备给出最终答案且系统状态变量满足终止条件时,执行结论操作,结束整个决策过程。

这种基于栈的动态记忆管理方式使TC-RAG能够在复杂的决策环境中有效地控制信息流,确保生成的输出既准确又相关。

3.1 记忆栈和系统监测方法

图片

TC-RAG(图灵完备的检索增强生成)通过其基于栈的记忆系统和状态变量来管理整个RAG框架的状态,并实现终止判定,允许模型自适应地进行检索并在适当的时刻输出最终答案。这一过程的实施细节如下:

  1. 1. 初始化与操作执行:

    • • 压栈操作: 一开始,大模型将用户的查询(Query)压入栈底。

    • • 复合操作(Composed Action Set): 大模型继续执行定义好的一系列操作,如思考(push)、反思(pop)、工具执行(push)和总结(pop->push)。

      在执行工具调用时,模型可以接入多源数据(如图谱、文档库、网页百科等),丰富回答的内容和质量。

  2. 2. 状态变量更新与重置:

    • • 状态更新: 在大模型执行到结论(Conclusion)或深入思考(Thought)的过程中,系统会不断更新其状态变量。

    • • 状态重置: 当执行包含pop动作的操作时,状态变量会被重置为上一个思考动作后的值,以保证系统的状态完备性和连续性。

  3. 3. 终止与输出:

    • • 判定终止条件: 当大模型输出结论且状态变量小于设定的阈值时,输出最终答案。

      如果不满足条件,大模型将继续其推理过程。

3.2 状态变量的监控与停机问题的解决

为解决自适应检索中的停机问题,TC-RAG在系统中引入了状态变量,这些变量有助于监测系统状态并决定何时停止系统运行。这些状态变量主要包括:

  • • 条件困惑度(Conditional Perplexity): 这一度量通过计算大模型在用户提问的基础上生成栈顶输出内容时的困惑度来得到。困惑度越低,表明模型对其输出的确定性越高。

图片

  • • 不确定性(Uncertainty): 通过计算栈顶输出信息的熵值得到,熵值较低表明大模型对输出结果的信心较高,即模型的输出更加确定。

图片

当这些状态变量的值低于预设的阈值时,表明大模型对于最终结果具有较高的信心,系统则可以决定输出最终答案并停止运行。这种基于状态变量的动态监控和管理,确保了TC-RAG在处理复杂查询时的有效性和准确性,同时也解决了传统检索增强模型中的终止问题。

整个方法部分的伪代码如下:

def whitebox_pop_react_executor(self, text):# todo 引入了status value'''最关键的就是executor的执行循环了,executor会始终进行如下事件循环直到 目标被解决了 或者 思考迭代次数超过了最大次数:根据之前已经完成的所有步骤(一个步骤包括 ReAct框架中的 Thought、Action、Observation)和 目标(用户的问题)规划出接下来的Action(使用什么工具 以及 工具的输入)检测是否已经达成目标,即Action是不是ActionFinish。是的话就返回结果,不是的话说明还有行动要完成根据Action,执行具体的工具,等待工具返回结果。工具返回的结果就是这一轮步骤的Observation保存当前步骤到记忆上下文,如此反复'''# 0. 组装promptself.renew_message_list()  # 将消息队列先置为空,并将当前状态置于最大值# 1. 将user query放入message list中user_query = "Question:" + textself.push_message(user_query)actions_taken = 0while actions_taken < self.rc_max_react_loop:# 1. 先plan,得到新的responsemessages = [{"role": "system", "content": self.system_prompt}, {"role": "user", "content": self.message_list_to_str()}]call_results = self.model.generate(messages, use_logprob=True, use_attention=True, use_entropy=True, use_logits=True)## 从call_results中取出text,attention和logprobs,entropies等信息出来new_response = call_results["text"]             # 文本# 1.5 判错条件new_response = self.process_no_regular_output(new_response)logger.info(f"response: {new_response}")# 2. 判断是否包含结束标识符Final Answer (LLM如果理解错了new_response也会输出final answer)if 'Final Answer:' in new_response:  # 忽略topK 次if actions_taken >= self.topK:# 将结果加入消息队列中new_response = self.parse_latest_final_answer(new_response)# 当出现是final_answer和thought的时候,再更新系统的状态变量需要用到的tensor:## 只取出new_response的内容,避免其他的影响self.update_status_value(call_results, new_response)self.calculate_now_state_value(top_content=new_response)## 停止条件:出现final answer且次数太多了,且小于sigmaif self.obtain_now_state() < self.sigma:      # 为final answer且小于simga, 模型结束, 压栈self.push_message(new_response)breakelse:# 这个时候由于以及压栈status了,下面又会被替换为thought,所以会被重复压栈,需要pop出去状态statusself.backtrack_now_state()# else:# 如果未达到指定次数,或阈值不满足要求,则替换为thought => note 这里可以做创新,step back and rethoughtnew_response = new_response.replace("Final Answer:", "Thought:")# else:   # action / thought# 3. 解析可能需要使用的工具:这里的response需要将大模型回答的observation截去;保留thoughtplugin_name, plugin_args, new_response_before_detact = self.parse_latest_plugin_call(new_response)# 3.5 如果new_response中存在Backtrack,这时应该丢弃所有其他的动作new_response = self.detact_backtrack(new_response_before_detact)# 保留当前栈顶信息,如果当前栈顶是thought,且下一次行动是backtrack,那么状态需要回撤top_stack_content = self.top_message()self.push_message(new_response)if "Thought" in new_response:                             # push进站,检查thought是否存在,以及是否需要更新status# 当出现是final_answer和thought的时候,再更新系统的状态变量需要用到的tensor:## fixme 只取出new_response的内容,避免其他的影响self.update_status_value(call_results, new_response)self.calculate_now_state_value()                      # 得到当前的state并更新系统status值self.pop_message()                  # 检查是否需要pop message# 如果pop了thought,那么就需要回撤statusif 'Thought' in top_stack_content and "Backtrack" in new_response:self.backtrack_now_state() # 回撤之前的status# 4. 解析完工具后调用, 添加observation进入记忆中if plugin_name and new_response == new_response_before_detact:observations = self.call_plugin(plugin_name, plugin_args)self.push_message(observations)actions_taken += 1return self.top_message(), self.message_list_to_str(), self.absoulte_message_list_to_str()

提示词如下所示:

图片

3.3 和ReACT的对比:

Tc-RAG 做了一个实验与ReACT进行对比:

图片

处理无关噪声的能力

  • • 1.ReACT的限制: 在可视化分析中,ReACT处理无关噪声的累积存在困难,容易导致系统的过度自信和错误结论。例如,当遇到单位不一致时,ReACT可能会做出错误的判断。

  • • 2.TC-RAG的优势: 相比之下,TC-RAG通过其内存堆栈系统有效管理内存,并利用总结和回溯操作修剪错误的检索结果,避免了因噪声累积导致的误判,从而得出更加简洁和准确的结论。

状态管理和监控

  • • 1.ReACT的缺陷:ReACT缺乏有效的状态管理机制,可能在系统状态值较高时过早地确定答案,导致结论的不准确。

  • • 2.TC-RAG的方法:TC-RAG则通过动态地监控整个RAG过程中的状态变量,确保系统状态值符合设定的终止条件。这种细致的状态管理使得TC-RAG在决策过程中更为谨慎,能够在适当的时刻给出最终答案。

4. 效果评估

TC-RAG(图灵完备的检索增强生成)系统通过在多个医疗相关数据集上的表现展示了其优越性。

4.1 TC-RAG在利用相同数据库资源的情况下,是否超越了当前最顶尖的RAG方法?

图片

上表展示了在MMCU-Medical、CMB-Exam和CMB-Clin数据集上的准确率结果。

对比RAG方法与基础LLM。考虑到患者咨询的复杂度,发现Naive RAG方法相较于无RAG基准线的提升微乎其微。而Adaptive RAG的表现则显著优于Advanced RAG,大幅领先其他方法。表明在特定领域情境下,采用更精细子模块进行高级和自适应检索的重要性。

对比TC-RAG与其他RAG方法。TC-RAG模型在所有数据集上均明显超越了基线模型,各项指标的平均提升幅度高达7.20%。例如,EM和BLEU-4的得分分别提升了约2.60%-5.62%和8.23%-13.72%。这些成果凸显了TC-RAG模块在系统状态与记忆管理以及自适应检索方面的高效性。此外,特定领域的LLM显著优于通用LLM,这进一步证实了预训练医疗LLM以支持TC-RAG的必要性,与C2相契合。

4.2 TC-RAG的堆叠框架是否奏效?各个组成部分对整体效能有何具体影响?

通过消融实验来评估TC-RAG中各个组件的作用,包括三种变体:

  • • (1) 缺少回溯功能的TC-RAG(标记为“无回溯”)

  • • (2) 缺少摘要功能的TC-RAG(标记为“无摘要”)

  • • (3) 缺少状态监控器的TC-RAG,仅依赖LLM的“最终答案”来决定何时结束,转变为一个黑箱系统(标记为“无状态监控”)。

实验结果表明,每个组件都对TC-RAG的整体表现起到了积极作用。任何一个组件的缺失都会导致效果显著下降。特别是,缺少状态监控器会导致性能大幅下降,这凸显了监控过程中系统状态变量的关键性,对于防止过度自信和确保恰当的终止至关重要,从而避免检索过度或不足。

此外,移除回溯和摘要功能进一步强调了有效记忆管理的必要性。这些功能对于减少无关干扰和保持系统状态最优化至关重要。

4.3 TC-RAG能否真正地触发错误的执行记忆,注入噪声,并实现有效的记忆管理?

对比分析了两种RAG系统:一种缺乏记忆和状态管理功能的ReACT系统,以及TC-RAG系 统。

评估了这两种系统在状态管理、信息检索和推理过程中的表现,尤其是在处理不相关或错误噪声时。

基于ReACT的方法在积累不相关噪声时表现不佳,这会导致过度自信和错误结论。

与此相对,TC-RAG系统能够有效地管理其记忆,并运用摘要和回溯操作来剔除错误的检索结果,从而得出更精炼和准确的结论,这凸显了TC-RAG在处理复杂任务时的卓越性能(符合C3标准)。

此外,发现基于ReACT的方法在系统状态值较高时容易过早地确定答案,这是由于缺乏有效的状态管理。而TC-RAG则能动态监控RAG处理过程,确保系统状态值达到终止条件,这强调了构建系统状态的重要性。

4.4 TC-RAG对于不同系统类型cppl和uct的超参数σ的敏感度如何?

为展示系统状态变量的效能,在MMCU-Medical和CMB-Exam数据集上,利用两个大型语言模型(LLM)对TC-RAG进行了实验。

图片

如上图所示,随着σ值的增加,系统状态受到的约束减少,LLM表现出“过度自信”,在未完全分析和规划必要步骤前便急于下结论。

反之,当σ值降低,状态变量对输出的影响增强,使得系统更难达到终止状态。因此,LLM变得过于谨慎,频繁尝试多种操作,从而略微降低了效率。总体来看,可以通过调整σ值来平衡TC-RAG的性能与准确性。

来源 | 大语言模型论文综述

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

Python语法(二)——函数

文章目录 函数语法格式函数参数链式调用嵌套调用函数递归变量作用域 函数 一段可以被重复使用的代码片段 求数列的和, 不使用函数 # 1.求1-100的和 sum 0 for i in range(1, 101):sum i print(fsum {sum})# 2.求300-400的和 sum 0 for i in range(300, 401):sum i print(…

NASA:ATLAS/ICESat-2 L3A 陆地和植被高度速览,第 6 版

目录 简介 参数 代码 引用 网址推荐 0代码在线构建地图应用 机器学习 ATLAS/ICESat-2 L3A 陆地和植被高度速览&#xff0c;第 6 版 ATLAS/ICESat-2 L3A Land and Vegetation Height Quick Look V006 简介 ATL08QL 是 ATL08 的快速查看版本。 一旦 ATL08 的最终文件可…

MongoDB在Linux系统中的安装与配置指南

在这篇文章中&#xff0c;我们将介绍如何在CentOS 7服务器上安装MongoDB&#xff0c;并通过DataX将数据从MongoDB迁移到MySQL数据库。这将包括MongoDB的安装、配置、数据准备以及使用DataX进行数据迁移的详细步骤。 MongoDB简介 MongoDB是一个高性能、开源、无模式的文档型数据…

[Java并发编程] synchronized(含与ReentrantLock的区别)

文章目录 1. synchronized与ReentrantLock的区别2. synchronized的作用3. synchronized的使用3.1 修饰实例方法&#xff0c;作用于当前实例&#xff0c;进入同步代码前需要先获取实例的锁3.2 修饰静态方法&#xff0c;作用于类的Class对象&#xff0c;进入修饰的静态方法前需要…

数据结构:二叉树(2)

ps&#xff1a;爆更第二期 前言 普通的树的实用价值比较小&#xff0c;将树更一步特殊化成二叉树&#xff0c;将获得更多的特殊性质。 例如搜索二叉树&#xff0c;红黑树等。 这篇博文主要介绍二叉树的基础知识&#xff0c;进阶版高级二叉树&#xff0c;后续会持续更新。 二叉…

RK3568平台(基础篇)万用表的使用

一.万用表的通断判断 万用表两个笔头的插法:黑笔头是插在COM的孔里面,红色笔头可以插在其他的三个孔里面,20A和mA分别用来测电流,另外一个孔可以用来测其他(电压 电阻)。 以下这个三角符号(像wifi一样的)可以用来测通断: 使用万用表的红笔和黑笔进行短接,这时候两端…

PAT (Advanced Level) Practice——1020Tree Traversals

链接&#xff1a; 1020 Tree Traversals - PAT (Advanced Level) Practice (pintia.cn) 题目大意&#xff1a; 首先给出一个整数n&#xff0c;表示序列一共有多少个数。接下来给出一棵树的后序遍历和中序遍历&#xff0c;根据后序遍历和中序遍历给出层序遍历。 题解&#x…

【技术调研】三维(7)-Unity基础笔记

安装 ​ 最好使用长期维护版本。 创建项目 ​ 略 窗口布局 Hierarchy:层级面板,展示当前打开的场景里面有哪些物体。 Scene:场景面板,显示当前场景的样子 Game:游戏面板,场景运行的时候的样子 Inspector:检视面板(或属性面板),查看一个游戏物体由哪些组件组成。 …

德勤校招网申笔试综合能力测试SHL题库与面试真题攻略

德勤的综合能力测试&#xff08;General Ability&#xff09;是其校园招聘在线测评的关键环节&#xff0c;旨在评估应聘者的多项认知能力。以下是对这部分内容的全面整合&#xff1a; 综合能力测试&#xff08;General Ability&#xff09; 测试时长为46分钟&#xff0c;包含…

9.3Otsu阈值分割

基本概念 在OpenCV中&#xff0c;Otsu阈值分割是一种全局阈值分割方法&#xff0c;但它会自动选择一个最佳的阈值来分割图像&#xff0c;这个阈值是通过最小化类内方差或等价地最大化类间方差来确定的。OpenCV提供了cv::threshold函数来实现这一功能&#xff0c;其中可以指定c…

线段树-认识线段树+实现线段树

一、认识线段树 1、定义 线段树是平衡二叉树 2、特点 线段树将一个区间划分成单元区间&#xff0c;每个单元区间对应线段树中的一个结点 3、应用 频繁查找一个数组中指定区间内的和、最值 学了动态规划后使用迭代要好过使用递归&#xff0c;因为递归每次进去是有空间损耗…

如何在qtcreator debugger上运行gdb命令

How to run gdb commands from qtcreator debugger? | Qt Forum gdb 调试基础操作和在qtcreator中使用gdb调试_qt gdb-CSDN博客 输出变量名&#xff1a; p变量名 ------------ gdb调试技巧&#xff08;二&#xff09;———— gdb 条件断点_gdb设置带函数入参判断的条件断点…

UE Asset Batch Duplication插件

目录 准备工作 "Scripting library" 三个最重要的功能&#xff08;前两个是UEditorUtilityLibrary中的&#xff09; 自动创建声明&#xff1a; TArray T 的含义 F 的含义 Live Coding &#xff08;Ctrlalt F11&#xff09; Live Coding 的工作流程&#xff…

时序预测|基于灰狼优化LightGBM的时间序列预测Matlab程序GWO-LightGBM 单变量和多变量 含基础模型

时序预测|基于灰狼优化LightGBM的时间序列预测Matlab程序GWO-LightGBM 单变量和多变量 含基础模型 文章目录 一、基本原理原理概述流程注意事项 二、实验结果三、核心代码四、代码获取五、总结 一、基本原理 时序预测中使用灰狼优化&#xff08;GWO&#xff09;结合LightGBM的…

Hash-通过哈希桶解决Hash冲突

哈希桶 基本结构 template<class T> struct HashNode {T _data;HashNode<T>* _next; }; template<class K,class T,class KeyOfT> class HashTable {typedef HashNode<T> Node; public:private:vector<Node*> _tables;size_t _num; }; insert …

《飞机大战游戏》实训项目(Java GUI实现)(设计模式)(简易)

目录 一、最终实现后&#xff0c;效果如下。 &#xff08;1&#xff09;简单介绍本游戏项目&#xff08;待完善&#xff09; &#xff08;2&#xff09;运行效果图&#xff08;具体大家自己可以试&#xff09; 初始运行情况。 手动更换背景图。 通过子弹攻击敌机&#xff0c;累…

java之单链表的基本概念及创建

1.链表的概念: 链表是一种 物理存储结构上非连续 存储结构&#xff0c;数据元素的 逻辑顺序 是通过链表中的 引用链接 次序实现的 。 组成结构: 由一系列节点组成&#xff0c;每个节点包含数据域和指向下一个节点的指针。 优点: 动态大小&#xff0c;易于插入和删除操作。 缺点…

无人机集群路径规划:​北方苍鹰优化算法(Northern Goshawk Optimization,NGO)​求解无人机集群路径规划,提供MATLAB代码

一、单个无人机路径规划模型介绍 无人机三维路径规划是指在三维空间中为无人机规划一条合理的飞行路径&#xff0c;使其能够安全、高效地完成任务。路径规划是无人机自主飞行的关键技术之一&#xff0c;它可以通过算法和模型来确定无人机的航迹&#xff0c;以避开障碍物、优化…

51单片机——LED灯篇

一、LED与单片机P2管脚相连 二、点亮一个LED灯 #include <STC89C5xRC.H> void main() { P2 0xFE; //1111 1110 } P2有8个管脚&#xff0c;对应8个二进制位。 LED灯右侧接电源是正极&#xff08;1&#xff09;&#xff0c;左侧给负极&#xff08;0&#xff09;即可…

Web_php_include 攻防世界

<?php show_source(__FILE__); echo $_GET[hello]; $page$_GET[page]; while (strstr($page, "php://")) { 以是否检测到php://为判断执行循环$pagestr_replace("php://", "", $page);//传入空值&#xff0c;替换 } include($page); ?&g…