day2-GPT本地+langchain进行智能问答

455 阅读3分钟

已经成功复现了教程中的豆包模型langchain部署

下面实现本地langchain+gpt部署

明天准备实现一下ollama本地微调+langchain部署

解决难点:

1根据GPT官方API调用文档修改代码中调用时使用的代码

也就是chat模型和Embeddings模型的调用需要修改

2下载本地部署所需要的py库

还有个隐藏难点(魔法问题需自行解决

使用API:openai-api

Step by step:

先到openai的文档找到这两个代码

platform.openai.com/docs/guides…

把这两段代码直接复制给GPT让他帮我在原教程代码基础上修改(可以试试marscode能不能一次到位GPT是一次到位)

然后在vscode的terminal(终端)里pip所有需要的库(这一步我也是问ai我有哪些库需要下载一次性告诉我

也可以win+r输入cmd进入终端进行py库的下载和更新

最终代码:(我是用第一节课说的单独设置一个.env文件调用的APIkey,嫌麻烦可以直接直接问ai怎么改成直接使用或者看一下上节课的教程)

"""本文件是【用LangChain快速构建基于“易速鲜花”本地知识库的智能问答系统】章节的配套代码,课程链接:https://juejin.cn/book/7387702347436130304/section/7388069933021986856
您可以点击最上方的“运行“按钮,直接运行该文件;更多操作指引请参考Readme.md文件。
"""
# 1.Load 导入Document Loaders
import os
from langchain_community.document_loaders import PyPDFLoader
from langchain_community.document_loaders import Docx2txtLoader
from langchain_community.document_loaders import TextLoader
from typing import Dict, List, Any
from langchain.embeddings.base import Embeddings
from pydantic import BaseModel
from dotenv import load_dotenv
from openai import OpenAI

# 加载 .env 文件
load_dotenv()

# 获取 API_KEY
api_key = os.getenv("OPENAI_API_KEY")

# 创建 OpenAI 客户端
client = OpenAI(api_key=api_key)

# 打印 API Key 确认正确性
print(api_key)

# 加载Documents
base_dir = r"C:\Users\10260\product Manager\marscode\02_文档QA系统\OneFlower"

documents = []
for file in os.listdir(base_dir):
    # 构建完整的文件路径
    file_path = os.path.join(base_dir, file)
    if file.endswith(".pdf"):
        loader = PyPDFLoader(file_path)
        documents.extend(loader.load())
    elif file.endswith(".docx"):
        loader = Docx2txtLoader(file_path)
        documents.extend(loader.load())
    elif file.endswith(".txt"):
        loader = TextLoader(file_path)
        documents.extend(loader.load())

# 2.Split 将Documents切分成块以便后续进行嵌入和向量存储
from langchain.text_splitter import RecursiveCharacterTextSplitter

text_splitter = RecursiveCharacterTextSplitter(chunk_size=200, chunk_overlap=10)
chunked_documents = text_splitter.split_documents(documents)

# 3.Store 将分割嵌入并存储在矢量数据库Qdrant中
from langchain_community.vectorstores import Qdrant

class OpenAIEmbeddings(BaseModel, Embeddings):
    model: str = "text-embedding-3-small"  # 选择 OpenAI 的嵌入模型

    def embed_query(self, text: str) -> List[float]:
        """生成输入文本的 embedding.
        Args:
            text (str): 要生成 embedding 的文本.
        Return:
            embeddings (List[float]): 输入文本的 embedding,一个浮点数值列表.
        """
        response = client.embeddings.create(
            input=text,
            model=self.model
        )
        return response.data[0].embedding

    def embed_documents(self, texts: List[str]) -> List[List[float]]:
        return [self.embed_query(text) for text in texts]

vectorstore = Qdrant.from_documents(
    documents=chunked_documents,  # 以分块的文档
    embedding=OpenAIEmbeddings(model="text-embedding-3-small"),  # 使用 OpenAI 的嵌入模型
    location=":memory:",  # in-memory 存储
    collection_name="my_documents",
)  # 指定collection_name

# 4. Retrieval 准备模型和Retrieval链
import logging  # 导入Logging工具
from langchain_community.chat_models import ChatOpenAI # ChatOpenAI模型
from langchain.retrievers.multi_query import MultiQueryRetriever  # MultiQueryRetriever工具
from langchain.chains import RetrievalQA  # RetrievalQA链

# 设置Logging
logging.basicConfig()
logging.getLogger("langchain.retrievers.multi_query").setLevel(logging.INFO)

# 实例化一个大模型工具 - OpenAI的GPT-4
llm = ChatOpenAI(model="gpt-4o", temperature=0)  # 指定使用 GPT-4

# 实例化一个MultiQueryRetriever
retriever_from_llm = MultiQueryRetriever.from_llm(
    retriever=vectorstore.as_retriever(), llm=llm
)

# 实例化一个RetrievalQA链
qa_chain = RetrievalQA.from_chain_type(llm, retriever=retriever_from_llm)

# 5. Output 问答系统的UI实现
from flask import Flask, request, render_template

app = Flask(__name__)  # Flask APP

@app.route("/", methods=["GET", "POST"])
def home():
    if request.method == "POST":
        # 接收用户输入作为问题
        question = request.form.get("question")

        # RetrievalQA链 - 读入问题,生成答案
        result = qa_chain({"query": question})

        # 把大模型的回答结果返回网页进行渲染
        return render_template("index.html", result=result)

    return render_template("index.html")

if __name__ == "__main__":
    app.run(host="0.0.0.0", debug=True, port=5000)

文本框架:(注意html的位置,这个文件是用来实现前端ui界面的就是那个生成的链接)

最后实现:

run一下这个代码,进入接口链接就好了 第一个是豆包,第二个是4o(效果上还是4o更强(一分钱一分货啊))