基于langchain的简单RAG的实现

闲来无事,想研究一下RAG的实现流程,看网上用langchain的比较多,我自己在下面也跑了跑,代码很简单,以次博客记录一下,方便回顾

langchain

LangChain 是一个基于大型语言模型(LLM)开发应用程序的框架。LangChain 简化了LLM应用程序生命周期的每个阶段。

比如,在下面的实现中,LangChain可以将LLM提示词模板检索器组合在一起快速的完成检索增强整个流程,而不需要你去关心底层具体是怎么实现的。

代码demo

实现思路:

  1. 加载文档,并对文档进行切分
  2. 将切分后的文档转化为向量,存储到向量库中
  3. 根据用户query去向量库中检索,找到最相关的回复,并拼接到prompt中
  4. 根据最新的prompt调用大模型产生增强回复

加载文档 -> 切分文档 -> 创建向量数据库 -> 执行相似度搜索 -> 构建并增强 prompt -> 使用模型生成回答

python 复制代码
import os
from openai import OpenAI
import requests
from langchain.text_splitter import CharacterTextSplitter
from weaviate.embedded import EmbeddedOptions
from langchain.prompts import ChatPromptTemplate
from langchain.schema.runnable import RunnablePassthrough
from langchain.schema.output_parser import StrOutputParser

from langchain_community.document_loaders import TextLoader
from langchain_community.chat_models import ChatOpenAI
from langchain_community.vectorstores import Chroma
from langchain_community.embeddings import HuggingFaceEmbeddings
from langchain.schema import Document
from langchain_core.messages import HumanMessage, SystemMessage


"""
实现一
"""
def method_one(vectorstore,llm,query):

    # 根据用户query进行检索,并将检索结果拼接到prompt中
    def augment_prompt(query: str):

        # 获取top2的文本片段
        results = vectorstore.similarity_search(query, k=1)
        source_knowledge = "\n\n".join([x.page_content for x in results])

        # 构建prompt
        augmented_prompt = f"""你叫david,你需要解答xxx问题

        ###参考样例###
        {source_knowledge}
        """
        return augmented_prompt

    prompt=augment_prompt(query)
    print(prompt)

    # 封装输入
    messages = [
        SystemMessage(content=prompt),
        HumanMessage(content=query),
    ]

    # 生成检索增强回复
    res = llm.invoke(messages)

    return res.content


"""
实现二
"""
def method_two(vectorstore,llm,query):
    
    # 将 vectorstore 转换为一个检索器
    retriever = vectorstore.as_retriever()

    # 定义提示模板
    template = """你叫david,你需要解答xxx问题

    ###参考样例###
    {context}

    ###用户问题###
    {question}
    """

    prompt = ChatPromptTemplate.from_template(template)

    print(prompt)

    # LangChain 提供了一个高度模块化和可组合的框架就是链,使得你可以根据任务的特性自定义每个组件,并将它们按需组合成执行流程
    # 定义一个执行流程链,包含如下组件
    # {"context": retriever,  "question": RunnablePassthrough()}:用来将上下文(通过检索器获得)和用户问题传递给后续组件
    # prompt里面的占位符与上述定义的context和question是要保持一致的
    # StrOutputParser():该组件用于解析模型的输出,将其转换为字符串格式
    rag_chain = (
        {"context": retriever,  "question": RunnablePassthrough()}
        | prompt
        | llm
        | StrOutputParser()
    )

    response = rag_chain.invoke(query)

    return response



if __name__=="__main__":

    # 加载单个文档,这里只需要匹配单个文档里面的片段
    path="../rag/faq.txt"
    loader = TextLoader(path)
    documents = loader.load()

    # 如果需要加载多个文档,将上述path改为跟路径即可,然后通过下述两行代码对多个文档进行切分
    # text_splitter = CharacterTextSplitter()
    # doc = text_splitter.split_documents(documents)

    # 切分文档,给定的文档内容主要是通过换行符分隔的
    text = documents[0].page_content
    chunks = [Document(page_content=chunk) for chunk in text.split("\n\n\n") if chunk.strip()]

    #  将文档片段转化为向量,并存储到 
    # Chroma 是一个 开源的向量数据库,用于存储和检索向量嵌入
    model_name = "../model/bge-base-zh-v1.5"
    embedding = HuggingFaceEmbeddings(model_name=model_name)
    vectorstore_hf = Chroma.from_documents(documents=chunks, embedding=embedding , collection_name="huggingface_embed")
    vectorstore = Chroma.from_documents(chunks, embedding)

    # 初始化对话模型
    llm = ChatOpenAI(
        openai_api_key="",
        openai_api_base="",
        model='qwen-max'
    )
    
    # 用户query
    query = "今天天气如何?"

    # 检索增强之后的回答
    enhanced_result=method_one(vectorstore,llm,query)
    # enhanced_result=method_two(vectorstore,llm,query)

    print(enhanced_result)

思考

  • 在尝试中发现,文档的嵌入模型选择对匹配结果也影响很大
  • 文档越规范越好切(不同的切分规则对检索和增强都有影响)
相关推荐
玄同76537 分钟前
从 0 到 1:用 Python 开发 MCP 工具,让 AI 智能体拥有 “超能力”
开发语言·人工智能·python·agent·ai编程·mcp·trae
小瑞瑞acd1 小时前
【小瑞瑞精讲】卷积神经网络(CNN):从入门到精通,计算机如何“看”懂世界?
人工智能·python·深度学习·神经网络·机器学习
火车叼位1 小时前
也许你不需要创建.venv, 此规范使python脚本自备依赖
python
火车叼位1 小时前
脚本伪装:让 Python 与 Node.js 像原生 Shell 命令一样运行
运维·javascript·python
孤狼warrior1 小时前
YOLO目标检测 一千字解析yolo最初的摸样 模型下载,数据集构建及模型训练代码
人工智能·python·深度学习·算法·yolo·目标检测·目标跟踪
Katecat996632 小时前
YOLO11分割算法实现甲状腺超声病灶自动检测与定位_DWR方法应用
python
玩大数据的龙威2 小时前
农经权二轮延包—各种地块示意图
python·arcgis
ZH15455891312 小时前
Flutter for OpenHarmony Python学习助手实战:数据库操作与管理的实现
python·学习·flutter
belldeep2 小时前
python:用 Flask 3 , mistune 2 和 mermaid.min.js 10.9 来实现 Markdown 中 mermaid 图表的渲染
javascript·python·flask
喵手2 小时前
Python爬虫实战:电商价格监控系统 - 从定时任务到历史趋势分析的完整实战(附CSV导出 + SQLite持久化存储)!
爬虫·python·爬虫实战·零基础python爬虫教学·电商价格监控系统·从定时任务到历史趋势分析·采集结果sqlite存储