LangChain+ChatGPT三分钟实现基于pdf等文档问答应用

2023-05-09 19:31:27 浏览数 (3)

什么是LangChain

LangChain是一个用于开发由语言模型驱动的应用程序的框架。它不仅可以通过API调用语言模型,还可以连接语言模型到其他数据源(数据感知),并允许语言模型与其环境进行交互(具有代理性)。LangChain提供了模块化的抽象组件,用于与语言模型一起工作,并为所有这些抽象提供了实现集合。此外,LangChain还提供了特定用例的链(Chains),可以将这些组件以特定方式组装在一起,以最好地完成特定用例。

也许这么讲,你可能一脸懵逼,这到底是个啥玩意,不急,下面就代理领略一下LangChain的风采。

安装LangChain开发环境

要安装LangChain,您可以使用以下命令:

代码语言:txt复制
pip install langchain

或者

代码语言:txt复制
conda install langchain -c conda-forge

安装完成后,您可能需要集成一个或多个模型提供商、数据存储、API等。例如,如果您要使用OpenAI的API,您需要先安装它们的SDK:

代码语言:txt复制
pip install openai

然后,您需要在终端中设置环境变量:

代码语言:txt复制
export OPENAI_API_KEY="..."

或者,您可以在Jupyter笔记本(或Python脚本)中执行此操作:

代码语言:python代码运行次数:0复制
import os
os.environ["OPENAI_API_KEY"] = "..."

但是,我更加建议你下载这个仓库:https://github.com/bravekingzhang/langchain-ts-starter

玩了之后,你可以在这个仓库中找到 .env文件,然后再里面配置你的OPENAI_API_KEY,是一样的道理。

在vscode上可以使用交互式的方式来一行一行的执行Python代码,快捷键shift enter ,非常方便,当执行

代码语言:txt复制
# Load environment variables
load_dotenv(find_dotenv())

就代表环境变量已经加载好了。

如何使用LangChain构建语言模型应用程序?

写一首诗试试,看起来很轻松,和调用openAI的api没啥区别呀,没看到神奇的地方啊,别着急,继续往下看。

我们可以使用Prompt Templates来管理LLM的提示。例如,您可以定义一个prompt模板,然后使用.format方法对其进行格式化:

代码语言:python代码运行次数:0复制
from langchain.prompts import PromptTemplate
prompt = PromptTemplate(
    input_variables=["product"],
    template="What is a good name for a company that makes {product}?",
)
print(prompt.format(product="colorful socks"))

此外,我们还可以使用链(Chains)将多个组件组合在一起,创建一个单一或者连贯的应用程序。例如,创建一个简单的链,它将用户输入格式化为prompt,然后将其发送到LLM:

代码语言:python代码运行次数:0复制
from langchain.chains import LLMChain
chain = LLMChain(llm=llm, prompt=prompt)
chain.run("colorful socks")

早学早致富,LangChain是几分钟搭建一个基

这样,一个取名器就完成了,这就是一个小应用,你可以把他封装为一个微服务,提供给其他模块调用。

更好玩的,使用Agent

在LangChain中,我们可以创建一个链,它接受用户输入,使用它格式化提示,然后将其发送到LLM。例如,可以使用LLMChain,它结合了PromptTemplate和LLM。PromptTemplate可用于通过获取用户输入并构造提示来管理LLM的提示。

代码语言:python代码运行次数:0复制
# --------------------------------------------------------------
# Agents: Dynamically Call Chains Based on User Input
# --------------------------------------------------------------


llm = OpenAI()

get_all_tool_names()
tools = load_tools(["wikipedia", "llm-math"], llm=llm)

# Finally, let's initialize an agent with the tools, the language model, and the type of agent we want to use.
agent = initialize_agent(
    tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True
)

# Now let's test it out!
result = agent.run(
    "中国有多少所大学,数量乘以 3"
)
print(result)

找到感觉了吗,是不是有点AgentGpt的味道了,LangChain提供额很多tools,不仅仅可以从维基百科查找,还可以通过google搜索,必应,都可以,这意味着,ChatGPT不限于他训练的知识,你可能很好奇,这个是如何实现的,其是实现原理也很简单。

1、通过你的prompt来调用openAI,分解出执行你这个目标所需要的步骤。

2、openAI推理出那些目标需要调用哪个tool,例如,我们demo中的“中国有多少所大学”这个需要分配到维基百科这个tool,而拿到的数据进行计算就交给llm-math这个tool。

3、链式执行的结果输出。

如果你理解了这个例子,下面基于文档,视频的内容问答,基本上也是这个原理,注意看:

LangChain实现基于文档、YouTube视频、哔哩哔哩视频的内容问答

代码语言:python代码运行次数:0复制
from langchain.document_loaders import YoutubeLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.vectorstores import FAISS
from langchain.llms import OpenAI
from langchain import PromptTemplate
from langchain.chains import LLMChain
from dotenv import find_dotenv, load_dotenv
import textwrap

load_dotenv(find_dotenv())
embeddings = OpenAIEmbeddings()


def create_db_from_youtube_video_url(video_url: str) -> FAISS:
    loader = YoutubeLoader.from_youtube_url(video_url)
    transcript = loader.load()

    text_splitter = RecursiveCharacterTextSplitter(
        chunk_size=1000, chunk_overlap=100)
    docs = text_splitter.split_documents(transcript)

    db = FAISS.from_documents(docs, embeddings)
    return db


def get_response_from_query(db, query, k=4):
    """
    text-davinci-003 can handle up to 4097 tokens. Setting the chunksize to 1000 and k to 4 maximizes
    the number of tokens to analyze.
    """

    docs = db.similarity_search(query, k=k)
    docs_page_content = " ".join([d.page_content for d in docs])

    llm = OpenAI(model_name="text-davinci-003")

    prompt = PromptTemplate(
        input_variables=["question", "docs"],
        template="""
        You are a helpful assistant that that can answer questions about youtube videos
        based on the video's transcript.

        Answer the following question: {question}
        By searching the following video transcript: {docs}

        Only use the factual information from the transcript to answer the question.

        If you feel like you don't have enough information to answer the question, say "I don't know".

        Your answers should be verbose and detailed.
        """,
    )

    chain = LLMChain(llm=llm, prompt=prompt)

    response = chain.run(question=query, docs=docs_page_content)
    response = response.replace("n", "")
    return response, docs


# Example usage:
video_url = "https://www.youtube.com/watch?v=L_Guz73e6fw"
db = create_db_from_youtube_video_url(video_url)

query = "What are they saying about Microsoft?"
response, docs = get_response_from_query(db, query)
print(textwrap.fill(response, width=85))

这里只给出一个基于YouTube视频的问答的demo,实际上基于文档的问答 原理类似:

1、YouTube流里面解析出文本字幕,内容,保存为doc

2、使用text_splitter进行分割,因为openAI模型有token数限制,所以要分割

3、使用OpenAIEmbeddings进行embeddings操作。

4、基于用户的输入进行一个db.similarity_search,找到最接近的4个小docs,应该在token范围内(3.5是4096)。

5、然后通过chain = LLMChain(llm=llm, prompt=prompt) 这个chain来调用,chain.run(question=query, docs=docs_page_content),这里PromptTemplate威力体现出来了,这样,我们就可以基于每个query调出最相似的内容,然后在一起交给openAI提问了。

LangChain 还有 typescript的版本

https://js.langchain.com/docs/

这个可以说是前端开发的福音,但是有能力,建议还是Python版本的,工具链会齐全不少。

基于文档的问答视频推荐

https://www.youtube.com/watch?v=cVA1RPsGQcw

https://www.youtube.com/watch?v=q2igmj6HC_w

0 人点赞