微信扫码
与创始人交个朋友
我要投稿
论文地址:https://arxiv.org/pdf/2403.05313
Github地址:https://github.com/CraftJarvis/RAT
想象一下,一个人工智能助手可以像莎士比亚一样写作,像专家一样推理。这听起来很了不起,对吧?但是,如果这个助手有时难以确保事实准确性,依赖过时的信息或只是编造事实,该怎么办?
检索增强思维 (RAT)
是一种创新性的方法,它结合了两种关键技术:检索增强生成 (RAG) 和思维链 (CoT) 提示。大型语言模型 (LLM) 因其模仿人类写作和流畅回答问题的能力而变得流行。但有时,他们的回答需要以现实世界的知识为基础。RAT 通过提供一种革命性的人工智能推理方法来解决这个问题。让我们深入研究并了解 RAT 的代码!
在我们深入讨论之前,让我们先把整个提示分解一下。想象一下,你有这个超酷的人工智能助手,提示语是你用来告诉它你想要什么的目的。你可以让它为你写一个故事,翻译一种语言,或者以一种非常有信息量的方式回答一个问题,这一切都是为了给大模型一个清晰明确的提示。
最酷的部分是:提示工程让你能够激发大模型的全部潜力。你可以用它做各种各样的事情,从写出绝妙的诗歌到解决超级复杂的问题。此外,甚至还有一些高级技术,如一次性、零次、少量、思维链、指导性和迭代性提示,每种技术都适用于简单的任务和复杂的多步骤流程。
现在,我们来谈谈 RAT,这是一种结合了两种强大技术的新方法:检索增强生成 (RAG) 和思维链 (CoT)。让我们探索这两种技术如何将 大模型推理推理提升到新的高度。
大型语言模型 (LLM) 擅长生成文本,但它们在解决需要逐步推理的复杂问题(如解决文字问题)时会遇到困难。
CoT提示通过鼓励 LLM 解释他们的想法来解决这个问题。LLM不只是给出最终答案,而是通过将问题分解为更小的步骤来展示其“工作”。这就像在数学课上展示你的计算一样。
有两种方法可以让 LLM 使用 CoT 提示:
然而,CoT 提示也存在一些挑战。
思路链提示使大型语言模型能够解决复杂的算术、常识和符号推理任务。图中突出显示了思路链推理过程。
少量提示会给出一些示例来帮助语言模型理解它应该做什么,而思维链提示则会从头到尾展示逐步推理。这有助于完成需要符号推理和中间步骤的复杂任务。它最适合较大的模型,而较小的模型可能会产生奇怪的思维链并且不太精确。在某些情况下,您可以使用零次思维链提示而不显示中间步骤。
因此,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) 提高其在长窗口任务中的推理能力的方法。以下是关键模块的原理:
Ti-1、Ti
):这些是 LLM 在迭代过程中的初始和修订的思维链。Ti
)。下图强调了 RAT 如何通过结合外部知识检索和逐步解释来解决 LLM 在复杂推理任务中的局限性。
图 | 上:不同 LLM 推理方法在创意生成任务上的示例。红色文本表示 LLM 生成的文本中的错误或错觉,而绿色文本表示正确生成。没有 RAG 的方法通常会产生带有幻觉的不正确信息,经典 RAG 与结构松散的检索内容高度相关,而 RAT 生成的文本在准确性和完整性方面表现最佳。下:不同 LLM 推理方法在复杂的具身规划、数学推理、代码生成和创意生成任务上的定量性能比较。我们的 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...")
continue
else:
query = res
print(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 ...")
continue
else:
content = res
LIMIT = 2
for j, c in enumerate(content):
if j >= LIMIT: # limit rge number of network pages
break
print(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 ...")
continue
else:
diff_html = generate_diff_html(answer, res)
display(HTML(diff_html))
answer = res
print(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 = res
return draft, answer
生成初始草稿:
draft
)。分割草稿:
draft_paragraphs
),每个段落包含一个完整的思路。逐段修正答案:
query
),用于从网络中检索相关信息。结构化输出:
返回结果:
示例流程假设用户输入的问题是:“介绍爱因斯坦的生平和成就。”
生成初始草稿:
分割草稿:
逐段修正:
结构化输出:
返回结果:
其中用到的一些提示语如下:
prompt1 = """
尝试用逐步的思考来回答这个问题\指令,并使答案更具结构化。
使用 `\n\n` 来将答案分成几个段落。
直接响应指令。除非被要求,否则不要在答案中添加额外的解释或介绍。
"""
prompt2 = """
我想验证给定问题的内容准确性,特别是最后几句话。
请用相应的问题总结内容。
这个总结将被用作必应搜索引擎的查询。
查询应该简短,但需要足够具体,以确保必应能够找到相关知识或页面。
您还可以使用搜索语法,使查询足够简短和清晰,以便搜索引擎能够找到相关的语言数据。
尽量使查询与内容中的最后几句话尽可能相关。
**重要**
直接输出查询。除非被要求,否则不要在答案中添加额外的解释或介绍。
"""
prompt3 = """
我想根据在维基百科页面上学到的相关文本来修订答案。
你需要检查答案是否正确。
如果你在答案中发现了错误,请修订答案使其更好。
如果你发现有些必要的细节被忽略了,请根据相关文本添加这些细节,以使答案更加可信。
如果你发现答案是正确的且不需要添加更多细节,请直接输出原始答案。
**重要**
尽量保持修订后答案的结构(多个段落及其子标题),使其更具结构性以便理解。
用 `\n\n` 字符分隔段落。
直接输出修订后的答案。除非被要求,否则在修订后的答案中不要添加额外的解释或声明。
"""
53AI,企业落地应用大模型首选服务商
产品:大模型应用平台+智能体定制开发+落地咨询服务
承诺:先做场景POC验证,看到效果再签署服务协议。零风险落地应用大模型,已交付160+中大型企业
2025-01-06
RAG,看这一篇就够了!
2025-01-06
CoW帮我成为时间管理大师后,被封号了
2025-01-06
IBM推出文档处理利器Docling,基于LangChain打造RAG应用
2025-01-06
GraphRAG:基于知识图谱的RAG,好用,贼贵!
2025-01-06
RAG成为过去式?缓存增强生成(CAG)is All You Need?
2025-01-06
GraphRAG × AutoGen × Ollama × Chainlit = 本地免费多代理 RAG 超级 AI 助手
2025-01-05
装上记忆,Agent牛了!
2025-01-04
我如何利用 ChromaDB 和 Chainlit 构建基于 Graph-RAG 系统的 LLM 应用程序
2024-07-18
2024-09-04
2024-05-05
2024-06-20
2024-05-19
2024-07-09
2024-07-09
2024-06-13
2024-07-07
2024-07-07
2025-01-06
2025-01-04
2024-12-30
2024-12-27
2024-12-26
2024-12-24
2024-12-21
2024-12-14