langchain框架,ollama调用deepseek r1 实现RAG问答
文章目录
- 装包
- 文件加载
- 召回效果
- 大模型选择
- 手动实现问答
- langchain 简洁实现
装包
!pip install modelscope langchain sentence_transformers langchain-huggingface onnxruntime
!pip install -qU "langchain-chroma>=0.1.2"
langchain 的更新很频繁,现在使用langchain_huggingface
加载向量嵌入模型。
import os
from langchain_huggingface import HuggingFaceEmbeddings
from langchain_community.document_loaders.text import TextLoader
from langchain_text_splitters import CharacterTextSplitter
from langchain_chroma import Chroma
# embedding 模型下载
from modelscope import snapshot_download
model_dir = snapshot_download('BAAI/bge-m3')
基于下述文件构建向量知识库:
文件加载
# load the document and split it into chunks
chunks = []
PREFIX = "以下是{file_name}年政府工作报告的节选部分:"
fold = "data"
for file in os.listdir(fold):
file_name = os.path.join(fold, file)
if file.endswith(".txt"):
prefix = PREFIX.format(file_name=file.split(".")[0])
else:
continue
loader = TextLoader(file_name)
documents = loader.load()
# split it into chunks
text_splitter = CharacterTextSplitter(chunk_size=200, chunk_overlap=20)
tmp_chunks = (text_splitter.split_documents(documents))
for chunk in tmp_chunks:
chunk.page_content = prefix + chunk.page_content
chunks.extend(tmp_chunks)
chunks[0], chunks[-1]
输出:
(Document(metadata={'source': 'data\\七台河市2024.txt'}, page_content='以下是七台河市2024年政府工作报告的节选部分:七台河市政府工作报告(2024年1月12日 李兵)\n2024年04月01日 17:21 来源:七台河市政府网 \n[手机看新闻][字号 大 中 小][打印本稿]\n\u3000\u3000——2024年1月12日在七台河市第十二届人民代表大会第三次会议上\n\n\u3000\u3000李兵\n\n\u3000\u3000各位代表:\n\n\u3000\u3000现在,我代表市政府向大会报告工作,请予审议,并请政协委员提出意见。\n\n\u3000\u3000一、2023年工作回顾'),
Document(metadata={'source': 'data\\内蒙古自治区2024.txt'}, page_content='以下是内蒙古自治区2024年政府工作报告的节选部分:“七个作模范”:在感党恩听党话、紧跟...奋进新征程上作模范,在铸牢中华民族共同体意识上作模范,在民族地区推进中国式现代化建设中作模范,在边疆民族地区走向共同富裕的道路上作模范,在兴边稳边固边上作模范,在边疆地区联通国内国际双循环上作模范,在弘扬新风正气上作模范。'))
为了区分不同文件的文本,在每一个文件的chunk文件的开头加上一个前缀,区分不同的文件内容。
前缀:"以下是{file_name}年政府工作报告的节选部分:"
embedding 模型加载,向量数据库把文本编码成向量并保存到向量数据库中
# create the open-source embedding function
bge_m3_embedding = HuggingFaceEmbeddings(
model_name=model_dir, model_kwargs={
"trust_remote_code": True,
}
)
# https://python.langchain.com/docs/how_to/vectorstores/
vector_store = Chroma(
collection_name="demo_db",
embedding_function=bge_m3_embedding,
# Where to save data locally, remove if not necessary
persist_directory="./chroma_langchain_db",
)
# 默认使用GPU计算,除非torch不能使用cuda
vector_store.add_documents(chunks)
下述是保存到本地的向量数据库:
召回效果
query = "上海市2024年工作报告中提到新增就业岗位多少个?"# 新增就业岗位60.6万个
relevant_docs = vector_store.similarity_search(query)
relevant_docs
输出:
[Document(id='f82c6f6f-63dd-44bb-917f-d2aa304cc4ca', metadata={'source': 'data\\上海市2024.txt'},
page_content='以下是上海市2024年政府工作报告的节选部分:加强就...'),
Document(id='e5e89d26-b83d-44a4-a802-396372bcc68e', metadata={'source': 'data\\上海市2023.txt'},
page_content='以下是上海市2023年政府工作报告的节选部分:促进高质量充分就业...'),
Document(id='061e0710-20aa-4423-9b8a-fb4330413208', metadata={'source': 'data\\上海市2024.txt'},
page_content='以下是上海市2024年政府工作报告的节选部分:基本民生保障持续加强。...'),
Document(id='f136e02e-39d6-4a56-b101-4228652cd4e3', metadata={'source': 'data\\上海市2022.txt'},
page_content='以下是上海市2022年政府工作报告的节选部分:提升就业服务和社会保障水平。...')]
大模型选择
我使用本地的ollama模型
from langchain_community.llms import Ollama
# from langchain.schema import SystemMessage, HumanMessage
llm = Ollama(model="deepseek-r1:7b", temperature=0)
# prompt = [SystemMessage("You are a helpful assistant"), HumanMessage("Who are you?")]
# print(llm.invoke(prompt))
手动实现问答
下述代码实现把用户问题与候选文本拼接到一起回答用户的问题:
context = "\n\n".join([doc.page_content for doc in relevant_docs])
PROMPT = f"""
你是一个智能助手,擅长从提供的背景知识中提取关键信息来回答问题。
请根据以下提供的背景知识回答问题,如果无法找到答案,请直接说“我不知道”。
背景知识:
{context}
问题:
{query}
答案:
"""
query = "上海市2024年工作报告中提到新增就业岗位多少个?"# 新增就业岗位60.6万个
relevant_docs = vector_store.similarity_search(query)
context = "\n\n".join([doc.page_content for doc in relevant_docs])
answer = llm.invoke(
PROMPT.format(context=context, query=query).lstrip()
)
print(answer)
<think>
好的,我现在需要回答关于上海市2024年政府工作报告中提到的新增就业岗位数量的问题。首先,我会仔细阅读用户提供的背景知识,找出与这个问题相关的部分。
在提供的信息中,有两个部分提到了2024年的政府工作报告。第一个是第一页,其中明确指出“新增就业岗位60.6万个”。第二个是第三页,同样提到“新增就业岗位60.6万个”。这两个部分都来自同一个年份的报告,所以数据应该是相同的。
接下来,我需要确认是否有其他地方可能有相关的数字,但看起来只有这两处提到了60.6万。因此,我可以确定上海市2024年工作报告中新增的就业岗位数量是60.6万个。
</think>
上海市2024年政府工作报告中提到新增就业岗位60.6万个。
langchain 简洁实现
from langchain.chains import RetrievalQA
# 创建 RAG QA Chain
qa = RetrievalQA.from_chain_type(llm=llm, chain_type="stuff", retriever=vector_store.as_retriever())
# 直接提问
query = "上海市2024年工作报告中提到新增就业岗位多少个?"
answer = qa.invoke(query)
print(answer)
{
'query': '上海市2024年工作报告中提到新增就业岗位多少个?',
'result': '<think>\n好的,我现在需要回答用户的问题:上海市2024年政府工作报告中提到新增就业岗位多少个?
首先,我查看了提供的上下文。在2024年的报告中有两段提到了新增就业岗位的情况。
第一段提到:“完善创业担保贷款、职业培训补贴等稳就业政策,城镇新增就业55万人以上。”这里明确指出新增就业岗位超过55万。
接着,在同一报告的另一部分中说:“公共就业招聘新平台上线运行,新增就业岗位60.6万个。”这进一步确认了新增就业岗位的数量是60.6万个。
现在,我需要将这两个数字整合起来。虽然第一段用了“以上”,但第二段给出了具体的数字,所以更准确的是以60.6万为准。</think>
上海市2024年政府工作报告中提到新增就业岗位60.6万个。'
}