点击上方蓝字关注我们


基于DeepSeek-R1+LlamaIndex的RAG -
将RAG转化为RAT(检索增强思维)
基于DeepSeek-R1的RAG
模型:开源DeepSeek-R1+Ollama本地推理 RAG框架:LlamaIndex -
UI原型:Streamlit
下载Ollama:https://ollama.com/ -
安装后运行:ollama run deepseek-r1
...
llm = Ollama(model="deepseek-r1")
embed_model = OllamaEmbedding(model_name="milkey/dmeta-embedding-zh:f16")
Settings.llm = llm
Settings.embed_model = embed_model
...
# 上传文件(这里允许上传的类型为 txt/ PDF)
uploaded_file = st.file_uploader("", type=["pdf", "txt"])
if uploaded_file is not None:
# 计算文件内容的哈希值
file_content = uploaded_file.getvalue()
new_file_hash = hashlib.md5(file_content).hexdigest()
# 如果文件发生变化或第一次上传,则重新创建 query_engine
if st.session_state.file_hash != new_file_hash:
st.session_state.file_hash = new_file_hash
with st.spinner("正在处理文档..."):
st.session_state.messages = []
# 将上传的文件保存到临时位置
with open("temp.pdf", "wb") as f:
f.write(file_content)
...
...
# 加载并处理文档
docs = SimpleDirectoryReader(input_files=["temp.pdf"]).load_data()
# 创建向量存储索引
index = VectorStoreIndex.from_documents(docs)
# 使用自定义提示创建查询引擎
query_prompt = """
1. 使用以下上下文来回答最后的问题。
2. 如果你不知道答案,请直接说"我不知道",不要编造答案。
3. 保持答案简洁,限制在3-4句话内。
上下文:{context_str}
问题:{query_str}
答案:"""
st.session_state.query_engine = index.as_query_engine(
text_qa_template=PromptTemplate(query_prompt),
similarity_top_k=3,
)
...
# 显示聊天历史
for message in st.session_state.messages:
with st.chat_message(message["role"]):
st.write(message["content"])
# 聊天输入
if prompt := st.chat_input("请输入您的问题"):
# 显示用户问题
with st.chat_message("user"):
st.write(prompt)
st.session_state.messages.append({"role": "user", "content": prompt})
# 生成回答
with st.chat_message("assistant"):
with st.spinner("思考中..."):
response = st.session_state.query_engine.query(prompt)
st.markdown(response.response)
st.session_state.messages.append({"role": "assistant", "response": response.response})
else:
st.write("上传 PDF 文件以开始对话。")
...
# 添加清除对话历史的按钮
if st.button("清除对话历史"):
st.session_state.messages = []
st.rerun()


...
# 处理回答中的标签
text = response.response
text = re.sub(
r'([\s\S]*?) ',
lambda m: f'{m.group(1)}',
text,
flags=re.DOTALL
)
st.markdown(text, unsafe_allow_html=True)
clean_text = re.sub(r'[\s\S]*? ', '', response.response).strip()
st.session_state.messages.append({"role": "assistant", "content": clean_text})

DeepSeek-R1将RAG转化为RAT

基于CoT生成:借助CoT模式生成更加深思熟虑与完善的答案。 迭代推理:通过多次迭代推理精细化CoT,借助外部知识完善。 -
动态检索:每次根据新的迭代推理结果,来调整检索的上下文。
综合问答:比如一些需要结合多个关联内容的对比、计算、总结等 编程任务:借助CoT可以让LLM更准确的理解需求并生成更精准的代码 -
数学推理、游戏步骤推理、机器人路径规划等

-
迭代完善CoT时,使用上一次的CoT结果进行检索,并把检索出的上下文交给DeepSeek,用来再次完善CoT
...
THINK_PROMPT = """
请结合下面提供的上下文(context字段),仔细思考我的问题(question字段),完善之前的推理过程(thoughts字段)。
如果上下文与问题并不相关,请忽略context字段,直接思考问题。
注意你只需思考该问题,不需要输出答案,答案部分直接输出"Reasoning Done"即可。
"""
# 初始化组件
reasoning_llm = Ollama(model="deepseek-r1:1.5b")
class DeepSeek:
def __init__(self, reasoning_llm, reasoning_times=1):
self.reasoning_llm = reasoning_llm
self.reasoning_times = reasoning_times
#检索相关上下文
def retrieve(self, query):
nodes = st.session_state.query_engine.retrieve(query["question"])
return {
"context": nodes,
"question": query["question"]
}
#迭代推理,并返回最终COT
def think(self, input: str) -> str:
thoughts = input
for _ in range(self.reasoning_times):
retrieved_docs = self.retrieve({"question": thoughts})
docs_content = "\n\n".join(
node.text for node in retrieved_docs["context"]
)
prompt_json = {
"context": docs_content,
"question": input,
"thoughts": thoughts
}
response = self.reasoning_llm.complete(THINK_PROMPT + '\n\n' + dumps(prompt_json, ensure_ascii=False))
think = re.findall(r'(.*?) ', response.text, re.DOTALL)
if not think:
return thoughts or "No reasoning available."
thoughts = think[0]
st.write(f"thoughts: {thoughts}")
return thoughts

THE END
福利时间
为了帮助LLM开发人员更系统性与更深入的学习RAG应用,特别是企业级的RAG应用场景下,当前主流的优化方法与技术实现,我们编写了《基于大模型的RAG应用开发与优化 — 构建企业级LLM应用》这本长达500页的开发与优化指南,与大家一起来深入到LLM应用开发的全新世界。
更多细节,点击链接了解
此处购买享5折优惠
