在本文中,咱们将学习如安在仅运用CPU的核算机上布置和运用GPT4All模型(我正在运用没有GPU的Macbook Pro!)并学习怎么运用Python与咱们的文档进行交互。一组PDF文件或在线文章将成为咱们问答的知识库。

GPT4All是什么

依据官方网站GPT4All的描绘,它是一个免费运用、本地运转的、注重隐私的谈天机器人。不需求GPU或互联网。

GTP4All是一个生态体系,用于练习和布置在消费级CPU上本地运转的强壮且定制的大型言语模型。

咱们的GPT4All模型是一个4GB的文件,您能够下载并衔接到GPT4All开源生态体系软件中。Nomic AI供给高质量和安全的软件生态体系,努力实现个人和组织轻松练习和本地实施自己的大型言语模型。

它是怎么工作的?

GPT4All:ChatGPT本地私有化部署,终生免费

该进程十分简略(当您了解之后),并且能够在其他模型上重复。具体步骤如下:

  • 加载GPT4All模型

  • 运用Langchain检索并加载咱们的文档

  • 将文档切割成小块,以便嵌入式能够了解

  • 运用FAISS依据咱们要传递给GPT4All的问题创立嵌入式向量数据库

  • 在依据问题的语境中在嵌入式向量数据库上履行相似性搜索(语义搜索):这将作为咱们问题的上下文

  • 运用Langchain将问题和上下文供给给GPT4All,并等候答案。

所以咱们需求的是嵌入式向量。嵌入式向量是一条信息的数值表明,例如文本、文档、图画、音频等。该表明捕捉了被嵌入的语义含义,这正是咱们所需求的。关于这个项目,咱们无法依靠于重型GPU模型:因而,咱们将下载Alpaca原生模型,并运用Langchain中的LlamaCppEmbeddings。不必忧虑!每一步都有具体的解说。

Let’s start coding

创立虚拟环境

为你的新Python项目创立一个新的文件夹,例如GPT4ALL_Fabio(请用你的姓名替换Fabio):

mkdir GPT4ALL_Fabiocd GPT4ALL_Fabio

接下来,创立一个新的Python虚拟环境。如果你装置了多个Python版别,请指定你想要运用的版别。在这个比方中,我将运用与Python 3.10相关的首要装置。

python3 -m venv .venv

指令python3 -m venv .venv创立了一个名为.venv的新虚拟环境(点号会创立一个名为venv的躲藏目录)。

虚拟环境供给了一个阻隔的Python装置环境,答应你仅针对特定项目装置软件包和依靠项,而不会影响体系规模的Python装置或其他项目。这种阻隔有助于保持一致性,并防止不同项目需求之间的潜在冲突。

一旦虚拟环境创立好了,你能够运用以下指令来激活它:

source .venv/bin/activate

GPT4All:ChatGPT本地私有化部署,终生免费

装置依靠

关于咱们正在构建的项目,咱们不需求太多的软件包。咱们只需求以下几个:

  • GPT4All的Python绑定
  • Langchain用于与咱们的文档交互
pip install pygpt4all==1.0.1
pip install pyllamacpp==1.0.6
pip install langchain==0.0.149
pip install unstructured==0.6.5
pip install pdf2image==1.16.3
pip install pytesseract==0.3.10
pip install pypdf==3.8.1
pip install faiss-cpu==1.7.4

关于LangChain,你能够看到咱们指定了版别号。这个库最近正在承受很多更新,所以为了保证咱们的设置明天也能正常工作,最好指定一个咱们知道能正常工作的版别。Unstructured是pdf加载器、pytesseract和pdf2image的必需依靠库。

注意:GitHub存储库中有一个requirements.txt文件,其间包括与此项目相关的一切版别。你能够在将其下载到主项目文件目录后,运用以下指令一次性进行装置:

pip install -r requirements.txt

请记住,某些库有依据你在虚拟环境中运转的Python版别供给的不同版别可用。

下载模型

这是一个十分重要的步骤。

关于这个项目,咱们当然需求

GPT4All模型。在Nomic AI网站上描绘的进程十分复杂,并且需求一些咱们不一定都拥有的硬件(比方我)。所以这儿是现已转换并准备好运用的模型链接。只需点击下载。

GPT4All:ChatGPT本地私有化部署,终生免费

正如简介中扼要描绘的,咱们还需求嵌入模型,这是一个能够在咱们的CPU上运转而不会崩溃的模型。点击这儿的链接【huggingface.co/Pi3141/alpa…

GPT4All:ChatGPT本地私有化部署,终生免费

为什么咱们需求嵌入?如果你还记住流程图中的榜首步,在收集知识库文档之后,咱们需求将它们嵌入。LLamaCPP嵌入来自Alpaca模型,十分适合这项工作,并且这个模型也很小(4 GB)。趁便说一下,你也能够在问答环节中运用Alpaca模型!

2023.05.25更新:Mani Windows用户在运用llamaCPP嵌入时遇到了问题。这首要是由于在装置python包llama-cpp-python时运用了以下指令:

pip install llama-cpp-python

这个指令会从源代码编译库。一般Windows上的机器默认没有装置CMake或C编译器。但不要忧虑,有解决办法。

在Windows上运转llama-cpp-python的装置进程时,需求编译源代码,但由于Windows默认没有装置CMake和C编译器,因而无法从源代码构建。

在Mac用户运用Xtools和Linux用户上,一般操作体系中现已装置了C编译器。

为了防止问题,你有必要运用预编译的wheel。

拜访github.com/abetlen/lla…

找到适用于你架构和Python版别的预编译的wheel版别,你有必要挑选0.1.49版别,由于更高的版别不兼容。

GPT4All:ChatGPT本地私有化部署,终生免费

在我这儿,我运用的是Windows 10 64位,Python 3.10

所以我的文件是llama_cpp_python-0.1.49-cp310-cp310-win_amd64.whl

这个问题在GitHub存储库中有记录【github.com/fabiomatric…

下载完结后,你需求将这两个模型文件放到models目录中,如下所示。

GPT4All:ChatGPT本地私有化部署,终生免费

目录结构和放置模型文件的位置

与GPT4All的根本交互

由于咱们想要对GPT模型的交互进行操控,咱们需求创立一个Python文件(咱们称之为pygpt4all_test.py),导入依靠项并给模型发送指令。你会发现这很容易。

from pygpt4all.models.gpt4all import GPT4All

这是咱们模型的Python绑定。现在咱们能够调用它并开端发问。让咱们试一个有创意的问题。

咱们创立一个函数来读取模型的回调,并要求GPT4All完结咱们的句子。

def new_text_callback(text):
    print(text, end="")
model = GPT4All('./models/gpt4all-converted.bin')
model.generate("Once upon a time, ", n_predict=55, new_text_callback=new_text_callback)

榜首条句子告诉咱们的程序在哪里找到模型(记住咱们在上面的部分所做的事情)。

第二条句子要求模型生成一个答复,并完结咱们的提示文本 “Once upon a time,”。

要运转它,请保证虚拟环境仍处于激活状况,然后简略地运转:

python3 pygpt4all_test.py

你应该会看到模型正在加载的文本和句子的完结。依据你的硬件资源,这或许需求一些时刻。

GPT4All:ChatGPT本地私有化部署,终生免费

成果或许与你的不同… 但对咱们来说重要的是它正在工作,咱们能够继续运用LangChain创立一些高档功用。

注意(更新于2023.05.23):如果你遇到与pygpt4all相关的过错,请检查故障排除部分,其间供给了由Rajneesh Aggarwal或Oscar Jeong给出的解决方案。

LangChain在GPT4All上的模板

LangChain结构是一个十分强壮的库。它供给了组件,以一种易于运用的方式与言语模型进行交互,并且还供给了Chains。能够将Chains视为以特定方式组装这些组件,以最好地完结特定的用例。它们旨在成为一个更高档的接口,使人们能够轻松地开端运用特定的用例。这些Chains也能够进行定制。

在咱们的下一个Python测验中,咱们将运用一个Prompt Template。言语模型承受文本作为输入,这段文本一般被称为prompt。一般状况下,这不仅仅是一个硬编码的字符串,而是模板、示例和用户输入的组合。LangChain供给了多个类和函数,使构建和处理prompt变得简略。让咱们看看怎么实现。

创立一个新的Python文件,命名为my_langchain.py。

# Import of langchain Prompt Template and Chain
from langchain import PromptTemplate, LLMChain
# Import llm to be able to interact with GPT4All directly from langchain
from langchain.llms import GPT4All
# Callbacks manager is required for the response handling 
from langchain.callbacks.base import CallbackManager
from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler
local_path = './models/gpt4all-converted.bin' 
callback_manager = CallbackManager([StreamingStdOutCallbackHandler()])

咱们从LangChain中导入了Prompt Template和Chain,以及GPT4All llm类,以便能够直接与咱们的GPT模型进行交互。

然后,在设置了llm路径之后(与之前相同),咱们实例化了回调管理器,以便能够捕获咱们查询的呼应。

创立一个模板十分简略:依据文档教程,咱们能够运用如下代码:

template = """Question: {question}
Answer: Let's think step by step on it.
"""
prompt = PromptTemplate(template=template, input_variables=["question"])

template变量是一个多行字符串,包括了与模型的交互结构:在花括号中刺进模板的外部变量,关于咱们的状况就是问题。

由于它是一个变量,你能够决议它是一个硬编码的问题仍是用户输入的问题:这儿是两个示例。

# Hardcoded question
question = "What Formula 1 pilot won the championship in the year Leonardo di Caprio was born?"
# User input question...
question = input("Enter your question: ")

关于咱们的测验运转,咱们将注释掉用户输入的问题。现在咱们只需求将咱们的模板、问题和言语模型衔接在一同。

template = """Question: {question}
Answer: Let's think step by step on it.
"""
prompt = PromptTemplate(template=template, input_variables=["question"])
# initialize the GPT4All instance
llm = GPT4All(model=local_path, callback_manager=callback_manager, verbose=True)
# link the language model with our prompt template
llm_chain = LLMChain(prompt=prompt, llm=llm)
# Hardcoded question
question = "What Formula 1 pilot won the championship in the year Leonardo di Caprio was born?"
# User imput question...
# question = input("Enter your question: ")
#Run the query and get the results
llm_chain.run(question)

记住验证你的虚拟环境仍然处于激活状况,并运转以下指令:

python3 my_langchain.py

你或许会得到与我不同的成果。令人惊讶的是,你能够看到GPT4All在尝试为你找到答案时所遵从的整个推理进程。调整问题或许会得到更好的成果。

GPT4All:ChatGPT本地私有化部署,终生免费

运用LangChain和GPT4All答复关于文件的问题

在这儿,咱们开端了令人惊讶的部分,由于咱们将运用GPT4All作为一个谈天机器人来答复咱们的问题。

依据与GPT4All进行问答的工作流程,咱们需求加载咱们的PDF文件,并将其分成块。接下来,咱们需求为咱们的嵌入向量准备一个向量存储库。咱们需求将咱们的分块文档输入到向量存储库中进行信息检索,然后将它们与该数据库上的相似性搜索一同作为LLM查询的上下文进行嵌入。

为此,咱们将直接运用Langchain库中的FAISS。FAISS是Facebook AI Research开发的开源库,旨在快速在大规模高维数据会集查找相似项。它供给索引和搜索办法,使得在数据会集快速找到最相似的项变得更加简略和快速。对咱们来说特别方便的是,它简化了信息检索,并答应咱们本地保存创立的数据库:这意味着在榜首次创立后,将十分快速地加载数据库以供以后运用。

创立向量索引数据库

创立一个新的文件叫做my_knowledge_qna.py:

from langchain import PromptTemplate, LLMChain
from langchain.llms import GPT4All
from langchain.callbacks.base import CallbackManager
from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler
# function for loading only TXT files
from langchain.document_loaders import TextLoader
# text splitter for create chunks
from langchain.text_splitter import RecursiveCharacterTextSplitter
# to be able to load the pdf files
from langchain.document_loaders import UnstructuredPDFLoader
from langchain.document_loaders import PyPDFLoader
from langchain.document_loaders import DirectoryLoader
# Vector Store Index to create our database about our knowledge
from langchain.indexes import VectorstoreIndexCreator
# LLamaCpp embeddings from the Alpaca model
from langchain.embeddings import LlamaCppEmbeddings
# FAISS  library for similaarity search
from langchain.vectorstores.faiss import FAISS
import os  #for interaaction with the files
import datetime

榜首组库与之前运用的相同:另外咱们运用Langchain进行向量存储索引的创立,运用LlamaCppEmbeddings与咱们的Alpaca模型进行交互(运用cpp库进行4位量化和编译),以及PDF加载器。

咱们还要加载具有自己路径的LLMs:一个用于嵌入和一个用于文本生成。

# assign the path for the 2 models GPT4All and Alpaca for the embeddings 
gpt4all_path = './models/gpt4all-converted.bin' 
llama_path = './models/ggml-model-q4_0.bin' 
# Calback manager for handling the calls with  the model
callback_manager = CallbackManager([StreamingStdOutCallbackHandler()])
# create the embedding object
embeddings = LlamaCppEmbeddings(model_path=llama_path)
# create the GPT4All llm object
llm = GPT4All(model=gpt4all_path, callback_manager=callback_manager, verbose=True)

为了测验,让咱们看看是否成功读取了一切的PDF文件:榜首步是声明三个函数,用于处理每个单独的文档。榜首个函数是将提取的文本切割成块,第二个函数是创立带有元数据的向量索引(例如页码等),最终一个函数是用于测验相似性搜索(稍后我将更具体地解说)。

# Split text 
def split_chunks(sources):
    chunks = []
    splitter = RecursiveCharacterTextSplitter(chunk_size=256, chunk_overlap=32)
    for chunk in splitter.split_documents(sources):
        chunks.append(chunk)
    return chunks
def create_index(chunks):
    texts = [doc.page_content for doc in chunks]
    metadatas = [doc.metadata for doc in chunks]
    search_index = FAISS.from_texts(texts, embeddings, metadatas=metadatas)
    return search_index
def similarity_search(query, index):
    # k is the number of similarity searched that matches the query
    # default is 4
    matched_docs = index.similarity_search(query, k=3) 
    sources = []
    for doc in matched_docs:
        sources.append(
            {
                "page_content": doc.page_content,
                "metadata": doc.metadata,
            }
        )
    return matched_docs, sources

现在咱们能够测验文档目录中的索引生成:咱们需求将一切的PDF文件放在那里。Langchain还有一种加载整个文件夹的办法,不论文件类型怎么:由于后续处理比较复杂,我将在下一篇关于LaMini模型的文章中介绍。

GPT4All:ChatGPT本地私有化部署,终生免费

咱们将把这些函数应用到列表中的榜首个文档上。

# get the list of pdf files from the docs directory into a list  format
pdf_folder_path = './docs'
doc_list = [s for s in os.listdir(pdf_folder_path) if s.endswith('.pdf')]
num_of_docs = len(doc_list)
# create a loader for the PDFs from the path
loader = PyPDFLoader(os.path.join(pdf_folder_path, doc_list[0]))
# load the documents with Langchain
docs = loader.load()
# Split in chunks
chunks = split_chunks(docs)
# create the db vector index
db0 = create_index(chunks)

在榜首行中,咱们运用os库来获取docs目录中的PDF文件列表。然后,咱们运用Langchain加载docs文件夹中的榜首个文档(doc_list[0]),将其切割成块,然后运用LLama嵌入创立向量数据库。

正如您所看到的,咱们运用了pyPDF办法。这个办法略微复杂一些,由于您需求逐个加载文件,可是运用pypdf将PDF加载到文档数组中使您能够得到一个数组,其间每个文档都包括页面内容和带有页码的元数据。当您想要知道咱们将经过查询供给给GPT4All的上下文的来历时,这十分方便。以下是来自readthedocs的示例:

GPT4All:ChatGPT本地私有化部署,终生免费

然后履行下面的指令运转:

python3 my_knowledge_qna.py

在加载用于嵌入的模型之后,您将看到令牌在索引中的工作方式:不要慌张,由于这需求时刻,特别是如果您只在CPU上运转,就像我相同(这需求8分钟)。

GPT4All:ChatGPT本地私有化部署,终生免费

正如我之前解说的,pyPDF办法较慢,但为咱们供给了用于相似性搜索的额定数据。为了遍历一切文件,咱们将运用FAISS中的一种便捷办法,它答应咱们将不同的数据库兼并在一同。现在咱们做的是运用上面的代码生成榜首个数据库(咱们将其称为db0),然后运用for循环创立列表中下一个文件的索引,并立即将其与db0兼并。

以下是代码:请注意,我添加了一些日志,以便运用datetime.datetime.now()供给进度状况,并打印结束时刻和开端时刻的差值来核算操作所需的时刻(如果您不喜欢,能够将其删去)。

兼并指令如下:

# merge dbi with the existing db0db0.merge_from(dbi)

最终一条指令是将咱们的数据库保存到本地:整个生成进程或许需求数小时(取决于文档的数量),所以咱们只需履行一次这个操作十分好!

# Save the databasae locallydb0.save_local("my_faiss_index")

以下是完好的代码。当咱们与GPT4All互动并直接从文件夹加载索引时,咱们将对其间许多部分进行注释。

# get the list of pdf files from the docs directory into a list  format
pdf_folder_path = './docs'
doc_list = [s for s in os.listdir(pdf_folder_path) if s.endswith('.pdf')]
num_of_docs = len(doc_list)
# create a loader for the PDFs from the path
general_start = datetime.datetime.now() #not used now but useful
print("starting the loop...")
loop_start = datetime.datetime.now() #not used now but useful
print("generating fist vector database and then iterate with .merge_from")
loader = PyPDFLoader(os.path.join(pdf_folder_path, doc_list[0]))
docs = loader.load()
chunks = split_chunks(docs)
db0 = create_index(chunks)
print("Main Vector database created. Start iteration and merging...")
for i in range(1,num_of_docs):
    print(doc_list[i])
    print(f"loop position {i}")
    loader = PyPDFLoader(os.path.join(pdf_folder_path, doc_list[i]))
    start = datetime.datetime.now() #not used now but useful
    docs = loader.load()
    chunks = split_chunks(docs)
    dbi = create_index(chunks)
    print("start merging with db0...")
    db0.merge_from(dbi)
    end = datetime.datetime.now() #not used now but useful
    elapsed = end - start #not used now but useful
    #total time
    print(f"completed in {elapsed}")
    print("-----------------------------------")
loop_end = datetime.datetime.now() #not used now but useful
loop_elapsed = loop_end - loop_start #not used now but useful
print(f"All documents processed in {loop_elapsed}")
print(f"the daatabase is done with {num_of_docs} subset of db index")
print("-----------------------------------")
print(f"Merging completed")
print("-----------------------------------")
print("Saving Merged Database Locally")
# Save the databasae locally
db0.save_local("my_faiss_index")
print("-----------------------------------")
print("merged database saved as my_faiss_index")
general_end = datetime.datetime.now() #not used now but useful
general_elapsed = general_end - general_start #not used now but useful
print(f"All indexing completed in {general_elapsed}")
print("-----------------------------------")

GPT4All:ChatGPT本地私有化部署,终生免费

向GPT4All发问关于您的文档的问题

现在咱们到了这一步。咱们有了咱们的索引,咱们能够加载它,并运用一个提示模板向GPT4All发问。咱们先从一个硬编码的问题开端,然后循环遍历咱们的输入问题。

将以下代码放入一个名为 db_loading.py 的 Python 文件中,并在终端中运用 python3 db_loading.py 指令运转它:

from langchain import PromptTemplate, LLMChain
from langchain.llms import GPT4All
from langchain.callbacks.base import CallbackManager
from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler
# function for loading only TXT files
from langchain.document_loaders import TextLoader
# text splitter for create chunks
from langchain.text_splitter import RecursiveCharacterTextSplitter
# to be able to load the pdf files
from langchain.document_loaders import UnstructuredPDFLoader
from langchain.document_loaders import PyPDFLoader
from langchain.document_loaders import DirectoryLoader
# Vector Store Index to create our database about our knowledge
from langchain.indexes import VectorstoreIndexCreator
# LLamaCpp embeddings from the Alpaca model
from langchain.embeddings import LlamaCppEmbeddings
# FAISS  library for similaarity search
from langchain.vectorstores.faiss import FAISS
import os  #for interaaction with the files
import datetime
# TEST FOR SIMILARITY SEARCH
# assign the path for the 2 models GPT4All and Alpaca for the embeddings 
gpt4all_path = './models/gpt4all-converted.bin' 
llama_path = './models/ggml-model-q4_0.bin' 
# Calback manager for handling the calls with  the model
callback_manager = CallbackManager([StreamingStdOutCallbackHandler()])
# create the embedding object
embeddings = LlamaCppEmbeddings(model_path=llama_path)
# create the GPT4All llm object
llm = GPT4All(model=gpt4all_path, callback_manager=callback_manager, verbose=True)
# Split text 
def split_chunks(sources):
    chunks = []
    splitter = RecursiveCharacterTextSplitter(chunk_size=256, chunk_overlap=32)
    for chunk in splitter.split_documents(sources):
        chunks.append(chunk)
    return chunks
def create_index(chunks):
    texts = [doc.page_content for doc in chunks]
    metadatas = [doc.metadata for doc in chunks]
    search_index = FAISS.from_texts(texts, embeddings, metadatas=metadatas)
    return search_index
def similarity_search(query, index):
    # k is the number of similarity searched that matches the query
    # default is 4
    matched_docs = index.similarity_search(query, k=3) 
    sources = []
    for doc in matched_docs:
        sources.append(
            {
                "page_content": doc.page_content,
                "metadata": doc.metadata,
            }
        )
    return matched_docs, sources
# Load our local index vector db
index = FAISS.load_local("my_faiss_index", embeddings)
# Hardcoded question
query = "What is a PLC and what is the difference with a PC"
docs = index.similarity_search(query)
# Get the matches best 3 results - defined in the function k=3
print(f"The question is: {query}")
print("Here the result of the semantic search on the index, without GPT4All..")
print(docs[0])

打印的文本是与查询最匹配的前3个来历的列表,还供给了文档称号和页码。

GPT4All:ChatGPT本地私有化部署,终生免费

现在咱们能够运用相似性搜索作为查询的上下文,运用提示模板。在这3个函数之后,只需将一切代码替换为以下内容:

# Load our local index vector db
index = FAISS.load_local("my_faiss_index", embeddings)
# create the prompt template
template = """
Please use the following context to answer questions.
Context: {context}
---
Question: {question}
Answer: Let's think step by step."""
# Hardcoded question
question = "What is a PLC and what is the difference with a PC"
matched_docs, sources = similarity_search(question, index)
# Creating the context
context = "\n".join([doc.page_content for doc in matched_docs])
# instantiating the prompt template and the GPT4All chain
prompt = PromptTemplate(template=template, input_variables=["context", "question"]).partial(context=context)
llm_chain = LLMChain(prompt=prompt, llm=llm)
# Print the result
print(llm_chain.run(question))

运转之后你会得到一个这样的成果:

Please use the following context to answer questions.
Context: 1.What is a PLC
2.Where and Why it is used
3.How a PLC is different from a PC
PLC is especially important in industries where safety and reliability are
critical, such as manufacturing plants, chemical plants, and power plants.
How a PLC is different from a PC
Because a PLC is a specialized computer used in industrial and
manufacturing applications to control machinery and processes.,the
hardware components of a typical PLC must be able to interact with
industrial device. So a typical PLC hardware include:
---
Question: What is a PLC and what is the difference with a PC
Answer: Let's think step by step. 1) A Programmable Logic Controller (PLC), 
also called Industrial Control System or ICS, refers to an industrial computer 
that controls various automated processes such as manufacturing 
machines/assembly lines etcetera through sensors and actuators connected 
with it via inputs & outputs. It is a form of digital computers which has 
the ability for multiple instruction execution (MIE), built-in memory 
registers used by software routines, Input Output interface cards(IOC) 
to communicate with other devices electronically/digitally over networks 
or buses etcetera
2). A Programmable Logic Controller is widely utilized in industrial 
automation as it has the ability for more than one instruction execution. 
It can perform tasks automatically and programmed instructions, which allows 
it to carry out complex operations that are beyond a 
Personal Computer (PC) capacity. So an ICS/PLC contains built-in memory 
registers used by software routines or firmware codes etcetera but 
PC doesn't contain them so they need external interfaces such as 
hard disks drives(HDD), USB ports, serial and parallel 
communication protocols to store data for further analysis or 
report generation.

如果你希望运用用户输入来替换问题:

question = "What is a PLC and what is the difference with a PC"

就像下面这样:

question = input("Your question: ")

结论

现在是你进行实验的时候了。对与你的文档相关的一切主题提出不同的问题,并调查成果。在 Prompt 和模板方面,必定还有很大的改善空间:你能够在这儿找到一些创意。并且 Langchain 的文档真的很棒(我都能够了解!)。

【微信公众号:H5开讲啦】