
提升智能ai:如何通过reasoning Augmented Generation修复rag的缺陷
推理增强生成工作流程
检索增强生成(RAG)承诺了更智能的人工智能,但其缺陷让我们止步不前。这就是推理增强生成(ReAG)是我们所需升级的原因。
❌ 传统 RAG 的问题
传统 RAG 系统就像记忆力差的图书管理员:
- 语义搜索不够智能 🤖:它们根据表面相似性检索文档(例如,将“空气污染”与“汽车排放”匹配),但错过了上下文相关的内容(例如,一项标题为“城市肺病趋势”的研究)23。
- 基础设施噩梦 🏗️:分块、嵌入和向量数据库增加了复杂性。每一步都存在过时索引或不匹配分割等错误的风险 2。
- 静态知识 ⏳:更新索引文档的速度很慢——对于像医学或金融这样的领域来说,这简直是死刑,因为数据每天都在变化 2。
想象一下,问“北极熊为什么在减少?”却得到关于“北极冰融化”的笼统答案,同时错过了一项关于无冰喂养干扰的关键研究。这就是 RAG 的缺陷。
🚀 进入 ReAG:让模型推理,而不仅仅是检索
ReAG 完全跳过了 RAG 流程。它不是将文档预处理成可搜索的片段,而是直接将 原材料(文本文件、电子表格、URL)输入到语言模型中。LLM 然后:
- 阅读完整文档 📖:不进行分块或嵌入 — 保留完整上下文。
- 提出两个问题 ❓:
- “这份文档有用吗?” (相关性检查)
- “哪些具体部分重要?” (内容提取)
- 综合答案 🧩:像人类研究者一样结合见解,即使关键词不匹配也能连接点 25。
示例:对于北极熊的问题,ReAG 可能解析一份名为 “海冰的热力学” 的气候报告,并提取一个将冰层减少与破坏的觅食模式联系起来的部分 — 即使“北极熊”这个词从未出现。
⚙️ ReAG 的工作原理:技术分析
📂原始文档摄取:
- 无预处理 — 文档按原样摄取(markdown、PDF、URLs)
⚡并行 LLM 分析:
- 每个文档同时进行相关性检查和内容提取。
🌐动态合成:
- 无关文档被过滤;经过验证的内容推动答案生成。
💡 为什么 ReAG 胜出:优势与权衡
✅ 优势
- 处理动态数据 📰: 实时新闻、实时市场信息或不断发展的研究?ReAG 可实时处理更新 — 无需重新嵌入。
- 解决复杂查询 🧠: 像 “2008 年后监管如何影响社区银行?” 这样的问题需要将不同来源的信息拼凑在一起。ReAG 在推断间接联系方面优于 RAG。
- 多模态掌握 📊: 同时分析图表、表格和文本 — 无需额外预处理。
⚠️ 权衡
- 更高的成本 💸: 通过 ReAG 处理 100 个文档意味着 100 次 LLM 调用,而 RAG 的便宜向量搜索只有 25 次。
- 规模化较慢 🐢: 对于百万文档数据集,混合方法(RAG + ReAG)可能效果更好 2。
🛠️ 支撑 ReAG 的技术栈
🌐 组件拆解
1. GROQ + Llama-3.3–70B-Versatile 🚀
角色: 相关性评估 (第一阶段过滤)
为什么它优秀:
- 通过GROQ的LPU架构实现超快推理(500+ tokens/秒)🔥
- 70B参数使得即使对于间接查询也能进行细致的文档相关性评分。
- 大上下文窗口 128 K tokens
示例: 将题为_“海冰的热动力学”_的气候报告标记为与“北极熊数量下降”相关,尽管没有关键词重叠。
2. Ollama + DeepSeek-R1:14B 🧠
角色: 响应合成 (第二阶段推理)
为何它出色:
- 轻量级、经济高效的14B模型,经过微调以进行提取/总结。
- 通过Ollama本地运行,确保数据隐私并降低云成本。
- 大上下文窗口128 K令牌
示例: 从标记文档中提取 “自2010年以来,冰冻喂养窗口减少了22%”。
3. LangChain 🎻
角色: 编排与工作流自动化
主要特性:
- 并行处理 GROQ(相关性)和 Ollama(合成)任务。
- 管理文档路由、错误处理和输出聚合。
⚡ 为什么这个技术栈有效
- 成本效率 💸: 将重负载转移到GROQ的硬件优化API,而Ollama在本地处理轻量级任务。
- 可扩展性 📈: GROQ的LPU可以处理数千个并发文档评估。
- 灵活性 🧩: 更换模型(例如,将Mistral替换为Ollama)而无需重写管道。
注意:个人观察:为了更好地利用ReAG,在文档中有超过50页的情况下使用基于大上下文窗口的LLM
🪀ReAG的代码实现
安装所需依赖
!pip install langchain langchain_groq langchain_ollama langchain_community pymupdf pypdf
下载数据
!mkdir ./data !mkdir ./chunk_caches !wget “https://www.binasss.sa.cr/int23/8.pdf” -O ”./data/fibromyalgia.pdf”
设置LLM
from langchain_groq import ChatGroq
from langchain_ollama import ChatOllama
import os
os.environ[“GROQ_API_KEY”] = “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”
llm_relevancy = ChatGroq(
model=“llama-3.3-70b-versatile”,
temperature=0,)
llm = ChatOllama(model=“deepseek-r1:14b”,
temperature=0.6,
max_tokens=3000,
)
定义系统提示
REAG_SYSTEM_PROMPT = """
角色和目标
您是一个智能知识检索助手。您的任务是分析提供的文档或URL,以提取与用户查询最相关的信息。
指令
- 仔细分析用户的查询,以识别关键概念和需求。
- 在提供的来源中搜索相关信息,并在“content”字段中输出相关部分。
- 如果在文档中找不到必要的信息,返回’isIrrelevant: true’,否则返回’isIrrelevant: false’。
约束
- 不要做出超出可用数据的假设
- 清楚地指明如果未找到相关信息
- 在来源选择中保持客观性 """
定义 RAG 提示
rag_prompt = """您是问答任务的助手。使用以下检索到的上下文片段来回答问题。如果您不知道答案,请直接说您不知道。最多使用三句话,并保持答案简洁。 问题: {question} 上下文: {context} 答案: """
定义响应模式
from pydantic import BaseModel,Field from typing import List from langchain_core.output_parsers import JsonOutputParser
class ResponseSchema(BaseModel): content: str = Field(…,description=“与所提问题相关或足以回答问题的文档页面内容”) reasoning: str = Field(…,description=“选择与所提问题相关的页面内容的推理”) is_irrelevant: bool = Field(…,description=“如果文档中的内容不足或与所提问题无关,则指定’True’,否则如果上下文或页面内容足以回答所提问题,则指定’False’”)
class RelevancySchemaMessage(BaseModel): source: ResponseSchema
relevancy_parser = JsonOutputParser(pydantic_object=RelevancySchemaMessage)
加载和处理输入文档
from langchain_community.document_loaders import PyMuPDFLoader
file_path = ”./data/fibromyalgia.pdf” loader = PyMuPDFLoader(file_path)
docs = loader.load() print(len(docs)) print(docs[0].metadata)
响应
8 {‘producer’: ‘Acrobat Distiller 6.0 for Windows’, ‘creator’: ‘Elsevier’, ‘creationdate’: ‘2023-01-20T09:25:19-06:00’, ‘source’: ’./data/fibromyalgia.pdf’, ‘file_path’: ’./data/fibromyalgia.pdf’, ‘total_pages’: 8, ‘format’: ‘PDF 1.7’, ‘title’: ‘纤维肌痛症:诊断与管理’, ‘author’: ‘Bradford T. Winslow MD’, ‘subject’: ‘美国家庭医生, 107 (2023) 137-144’, ‘keywords’: ”, ‘moddate’: ‘2023-02-27T15:02:12+05:30’, ‘trapped’: ”, ‘modDate’: “D:20230227150212+05’30’”, ‘creationDate’: “D:20230120092519-06’00’”, ‘page’: 0}
格式化文档的辅助函数
from langchain.schema import Document def format_doc(doc: Document) -> str: return f”Document_Title: {doc.metadata[‘title’]}\nPage: {doc.metadata[‘page’]}\nContent: {doc.page_content}”
提取相关上下文的辅助函数
from langchain_core.prompts import PromptTemplate
def extract_relevant_context(question,documents):
result = []
for doc in documents:
formatted_documents = format_doc(doc)
system = f”{REAG_SYSTEM_PROMPT}\n\n# 可用来源\n\n{formatted_documents}”
prompt = f"""确定提供的’可用来源’内容是否足够且相关,以回答所提问题。
问题: {question}
#遵循的指令
1. 彻底分析提供的上下文,以检查其与帮助形成所提问题的响应的相关性。
2, 严格按照以下描述的 JSON 结构提供响应:
```json
{{“content”:<<与所提问题相关或足以回答问题的文档页面内容>>,
“reasoning”:<<选择与所提问题相关的页面内容的推理>>,
“is_irrelevant”:<<如果文档中的内容不足或与所提问题无关,则指定’True’。如果页面内容足以回答问题,则指定’False’>>
}}
```
"""
messages =[ {“role”: “system”, “content”: system},
{“role”: “user”, “content”: prompt},
]
response = llm_relevancy.invoke(messages)
print(response.content)
formatted_response = relevancy_parser.parse(response.content)
result.append(formatted_response)
final_context = []
for items in result:
if (items[‘is_irrelevant’] == False) or ( items[‘is_irrelevant’] == ‘false’) or (items[‘is_irrelevant’] == ‘False’):
final_context.append(items[‘content’])
return final_context
调用函数以检索相关上下文
question = “什么是纤维肌痛症?” final_context = extract_relevant_context(question,docs) print(len(final_context))
生成响应的辅助函数
def generate_response(question,final_context): prompt = PromptTemplate(template=rag_prompt, input_variables=[“question”,“context”],) chain = prompt | llm response = chain.invoke({“question”:question,“context”:final_context}) print(response.content.split(“\n\n”)[-1]) return response.content.split(“\n\n”)[-1]
生成响应
final_response = generate_response(question,final_context) final_response
‘纤维肌痛症是一种慢性疾病,其特征是广泛的肌肉骨骼疼痛、疲劳、睡眠中断和认知困难,如“纤维雾”。由于神经系统处理的改变,它通常与对疼痛的敏感性增强相关。诊断时考虑的症状包括长期疼痛、疲劳和没有基础炎症或损伤的睡眠问题。’
问题 2
question = “纤维肌痛症的原因是什么?” final_context = extract_relevant_context(question,docs) final_response = generate_response(question,final_context)
纤维肌痛症可能是由于中枢疼痛处理失调导致的敏感性增强(痛觉过敏和触痛)。可能的原因包括下丘脑-垂体-肾上腺轴功能障碍、炎症、胶质细胞激活、小纤维神经病、感染(如EB病毒或莱姆病)和遗传因素。其他疾病,如感染或药物副作用,也可能导致类似症状。
问题 3
question = “患有风湿性疾病的人可能会有纤维肌痛症吗?” final_context = extract_relevant_context(question,docs) final_response = generate_response(question,final_context)
是的,患有风湿性疾病的人,如类风湿性关节炎或银屑病关节炎,也可能有纤维肌痛症。这是因为它们有重叠的症状,使得诊断变得具有挑战性。
问题 4
question = “提到纤维肌痛症的非药物治疗方法?” final_context = extract_relevant_context(question,docs) final_response = generate_response(question,final_context)
纤维肌痛症的非药物治疗包括患者教育、锻炼和认知行为疗法(CBT)。
问题 5
question = “根据2016年美国风湿病学会纤维肌痛症的诊断标准是什么?” final_context = extract_relevant_context(question,docs) final_response = generate_response(question,final_context)
2016年美国风湿病学会的纤维肌痛症诊断标准要求在至少五个身体区域中有广泛的疼痛,持续至少三个月。此外,患者必须满足广泛疼痛指数(WPI)得分≥7且症状严重性量表(SSS)得分≥5,或WPI得分≥4且SSS得分≥9。必须排除其他可能解释症状的疾病。
问题 6
question = “阿米替林的起始剂量是多少?” final_context = extract_relevant_context(question,docs) final_response = generate_response(question,final_context)
阿米替林的起始剂量通常为每天25至50毫克,通常从晚上5至
[‘多洛西汀、米氮平、普瑞巴林和阿米替林是治疗纤维肌痛的潜在有效药物。非甾体抗炎药和阿片类药物未能显示对纤维肌痛的益处,并且有显著的局限性。’, ‘阿米替林、环索普利、杜洛西汀(Cymbalta)、米氮平(Savella)和普瑞巴林(Lyrica)对纤维肌痛的疼痛有效。43,46-48,50,52,54’, ‘阿米替林(三环类抗抑郁药) - 每晚5到10毫克,每晚20到30毫克。环索普利(肌肉松弛剂;三环衍生物) - 每晚5到10毫克,每天10到40毫克,分1到3次服用。杜洛西汀(Cymbalta;5-羟色胺-去甲肾上腺素再摄取抑制剂) - 每天早晨20到30毫克,每天早晨60毫克。米氮平(Savella;5-羟色胺-去甲肾上腺素再摄取抑制剂) - 每天早晨12.5毫克,每天两次50毫克。普瑞巴林(Lyrica;加巴喷丁类) - 睡前25到50毫克,睡前150到450毫克。’, ‘纤维肌痛通常使用普瑞巴林(Lyrica)和杜洛西汀(Cymbalta)等药物进行治疗。普瑞巴林可以以每天两次75毫克的剂量开始,最大剂量为450毫克/天。杜洛西汀可以以每天一次30毫克的剂量开始,目标剂量为60毫克/天。’, ‘纤维肌痛通常使用普瑞巴林(Lyrica)和杜洛西汀(Cymbalta)等药物进行治疗。普瑞巴林可以以每天两次75毫克的剂量开始,最大剂量为450毫克/天。杜洛西汀可以以每天一次30毫克的剂量开始,目标剂量为60毫克/天。’]
print(final_response)
治疗纤维肌痛的常用药物包括:
-
阿米替林:一种三环类抗抑郁药,通常在晚上服用,剂量范围为5到30毫克。
-
环索普利:一种肌肉松弛剂和三环衍生物,通常以每日分次服用,最大剂量为40毫克。
-
杜洛西汀(Cymbalta):一种5-羟色胺-去甲肾上腺素再摄取抑制剂,早晨服用,起始剂量为20-30毫克,如有需要可增加至60毫克。
-
米氮平(Savella):另一种5-羟色胺-去甲肾上腺素再摄取抑制剂,早晨起始剂量为12.5毫克,可增加至每天两次50毫克。
-
普瑞巴林(Lyrica):一种加巴喷丁类药物,睡前服用,起始剂量为每天两次75毫克,最大剂量为450毫克/天。
这些药物对管理与纤维肌痛相关的疼痛有效。需要注意的是,剂量应在医生的监督下进行调整,从低剂量开始,根据需要逐渐增加。此外,由于效果有限和潜在副作用,不推荐使用NSAIDs和阿片类药物治疗纤维肌痛。
🌍真实世界的用例
- 医学研究 🩺: 从原始临床试验数据和期刊中综合洞察。
- 金融市场 📉: 分析实时财报和SEC文件以制定实时投资策略。
- 法律分析 ⚖️: 解析密集的案例法以识别先例关系。
🔮 ReAG的未来
- 混合系统 🤝: 使用RAG进行初步过滤,然后使用ReAG进行深入分析3。
- 更便宜的模型 📉: 开源LLMs(例如,DeepSeek)和量化将降低成本2。
- 更大的上下文窗口 🪟: 未来的模型将处理十亿标记的文档,使ReAG更加强大2。
🎯 最终总结
ReAG 并不是要取代 RAG — 而是 重新思考 AI 如何与知识互动。通过将检索视为推理任务,ReAG 反映了人类研究的特点:整体性、细致性和以情境为驱动。
参考文献与进一步阅读: