LangChain Chinese Introductory Tutorial

LangChain Chinese Introductory Tutorial

colab address (including all cases in this article) , gitbook (easy to read) , github address

  If you want to modify the request root route of OPENAI API to your own proxy address, you can OPENAI\_API\_BASEmodify it by setting the environment variable " ", refer to the code . Or when initializing OpenAI-related model objects, pass in the "openai_api_base" variable, refer to the code .

1. Introduction

LangChain Official Documentation

1.1 Background

  As we all know, OpenAI's API cannot be connected to the Internet, so if you only use your own functions to realize online search and give answers, summarize PDF documents, conduct questions and answers based on a Youtube video, etc., it will definitely not be possible. So, let's introduce a very powerful third-party open source library: LangChain.

LangChain is a framework for developing applications driven by language models. He mainly has 2 abilities:

  1. Possibility to connect LLM models (Large-Scale Language Models) with external data sources
  2. Allows interaction with LLM models

1.2 Basic functions

  • Support multiple model interfaces, such as OpenAI, Hugging Face, AzureOpenAI…
  • Fake LLM for testing
  • Cache support, such as in-mem (memory), SQLite, Redis, SQL
  • usage record
  • Support stream mode (that is, return word by word, similar to typing effect)

Prompt management, support various custom templates

Has a large number of document loaders, such as Email, Markdown, PDF, Youtube...

Support for indexes

  • document splitter
  • vectorization
  • Docking vector storage and search, such as Chroma, Pinecone, Qdrand

Chains

  • LLMChain
  • Various Tools Chain
  • LangChainHub

2. Must-know concepts

  I believe that most of you will be confused after reading the above introduction. Don't worry, the above concepts are not very important at the beginning of learning. After we finish the following examples, you will understand a lot when you come back and read the above content. However, the following concepts must be known.

2.1 Loader loader

Loader documentation

As the name implies, this is to load data from the specified source. for example:

  • folder DirectoryLoader,
  • Azure StorageAzureBlobStorageContainerLoader
  • CSV fileCSVLoader
  • EvernoteEverNoteLoader
  • Google DriveGoogleDriveLoader
  • any web pageUnstructuredHTMLLoader
  • PDF PyPDFLoader
  • S3 S3DirectoryLoader/ S3FileLoader
  • Youtube YoutubeLoader

The above is just a brief list of a few, and the official provides a lot of loaders for you to use.

2.2 Document document

  After using loaderthe loader to read the data source, the data source needs to be converted into Documentan object before it can be used later.

2.3 Text Spltters text segmentation

  As the name suggests, text segmentation is used to segment text. Why do you need to split text? Because every time we send the text as promptor openai apiuse openai api embeddingthe function, there is a character limit.

  For example, if we send a 300-page pdf to openai apihim and ask him to make a summary, he will definitely report an error of exceeding the maximum Token. So here we need to use a text splitter to split what we loadercome in Document.

2.4 Vectorstores vector database

VectorstoresDocumentation

  Because the data correlation search is actually a vector operation. Therefore, whether we use the function or directly query through the vector database, we need to vectorize openai api embeddingour loaded data in order to perform vector operation search. DocumentConverting to a vector is also very simple. We only need to store the data in the corresponding vector database to complete the vector conversion. The official also provides a lot of vector databases for us to use.

2.5 Chain

ChainsDocumentation

  We can understand Chain as a task. A Chain is a task, of course, like a chain, multiple chains can be executed one by one.

2.6 Agent agent

  We can simply understand that it can dynamically help us select and call chains or existing tools. The execution process can refer to the following picture:

insert image description here

2.7 Embedding

  Embedding is used to measure the relevance of text, which is also the key to OpenAI API's ability to build its own knowledge base. Compared with fine-tuningthe biggest advantage is that there is no need for training, and new content can be added in real time, instead of training once after adding new content, and the cost in all aspects is much lower than fine-tuning. For specific comparison and selection, please refer to this video .

Three, actual combat

  The following uses the Open AI example to illustrate, and you can also replace it with the LLM model you need according to the needs of your tasks.

3.1 Single Q&A

  Before starting, we need to set up our openai key, which can be created in the user management, so I won't go into details here.

import os
os.environ["OPENAI_API_KEY"] = '你的api key'

Then we import and execute

from langchain.llms import OpenAI

llm = OpenAI(model_name="text-davinci-003",max_tokens=1024)
llm("怎么评价人工智能")

insert image description here

At this time, we can see the result he returned to us, how is it, is it very simple?

3.2 Google search and return answers

  Next, let's do something interesting. Let's make our OpenAI api search the Internet and return the answer to us.

  Here we need to Serpapiimplement with the help of , Serpapiwhich provides the api interface of google search. First, we need to register a user on the Serpapi official website , and copy him to generate for us api key. openai api keyThen we need to set it to the environment variable as above .

serpapiIt seems that it is not very friendly to Chinese, so the prompt for asking questions suggests using English.

import os
os.environ["OPENAI_API_KEY"] = '你的api key'
os.environ["SERPAPI_API_KEY"] = '你的api key'

Then, start writing my code

from langchain.agents import load_tools
from langchain.agents import initialize_agent
from langchain.llms import OpenAI
from langchain.agents import AgentType

# 加载 OpenAI 模型
llm = OpenAI(temperature=0,max_tokens=2048) 

 # 加载 serpapi 工具
tools = load_tools(["serpapi"])

# 如果搜索完想再计算一下可以这么写
# tools = load_tools(['serpapi', 'llm-math'], llm=llm)

# 如果搜索完想再让他再用python的print做点简单的计算,可以这样写
# tools=load_tools(["serpapi","python_repl"])

# 工具加载后都需要初始化,verbose 参数为 True,会打印全部的执行详情
agent = initialize_agent(tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True)

# 运行 agent
agent.run("What's the date today? What great events have taken place today in history?")

insert image description here

  We can see that he returned the date correctly (with time difference), and returned today in history.

  Both chain and agent objects have verbosethis parameter. This is a very useful parameter. After enabling it, we can see the complete chain execution process. As you can see from the results returned above, he split our problem into several steps, and then got the final answer step by step.

About agent typethe meaning of several options (if you can’t understand it, it will not affect the following learning, and you will understand it naturally if you use it too much):

  • zero-shot-react-description:: Determine which tool to use based on the description of the tool and the content of the request (most commonly used)
  • react-docstore:: Use the ReAct framework to interact with docstore, use Searchand Lookuptools, the former is used to search, the latter is used to search for terms, for example: Wipipediatools
  • self-ask-with-search: This agent only uses one tool: Intermediate Answer, which will look for factual answers to questions (referring to non-gpt-generated answers, but existing in the network and text), such as Google search APItools
  • conversational-react-description:: An agent designed for session settings, its prompt will be designed to be conversational, and it will still use the ReAct framework to decide which tool to use, and store past session interactions in memory

Python implementation of LLM's ReAct pattern: https://til.simonwillison.net/llms/python-react-pattern

  Of course, the official agent has been written ChatGPT Plugins, what plug-ins can be used in chatgpt in the future, we can also use plug-ins in the api, it is very happy to think about it. However, only plug-ins without authorization can be used at present. We look forward to the official solution to this problem in the future. If you are interested, you can read this document .

Chatgpt can only make money for the official, but Openai API can make money for me

3.3 Summarizing super long texts

  If we want to use to openai apisummarize a piece of text, our usual practice is to send it directly to the api for him to summarize. But if the text exceeds the maximum token limit of the api, an error will be reported.

  At this time, we usually segment the article, such as by tiktokencalculating and dividing, and then send each segment to the API for summary, and finally summarize the summary of each segment.

   LangChainIt can help us handle this process very well, and the code is very simple.

from langchain.document_loaders import UnstructuredFileLoader
from langchain.chains.summarize import load_summarize_chain
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain import OpenAI

# 导入文本
loader = UnstructuredFileLoader("/content/sample_data/data/lg_test.txt")
# 将文本转成 Document 对象
document = loader.load()
print(f'documents:{
      
      len(document)}')

# 初始化文本分割器
text_splitter = RecursiveCharacterTextSplitter(
    chunk_size = 500,
    chunk_overlap = 0
)

# 切分文本
split_documents = text_splitter.split_documents(document)
print(f'documents:{
      
      len(split_documents)}')

# 加载 llm 模型
llm = OpenAI(model_name="text-davinci-003", max_tokens=1500)

# 创建总结链
chain = load_summarize_chain(llm, chain_type="refine", verbose=True)

# 执行总结链,(为了快速演示,只总结前5段)
chain.run(split_documents[:5])

  First, we printed the number of documents before and after cutting. We can see that there is only one document before cutting. After cutting, the above document will be cut into 317 documents.

insert image description here

Finally, a summary of the first 5 documents is output.

insert image description here

There are a few parameters to be aware of here:

chunk_overlap1. The parameters of the text splitter

  This means that each document after cutting contains several contents at the end of the previous document. The main function is to increase the context association of each document. For example, chunk_overlap=0when, the first document is aaaaaa, and the second is bbbbbb; at that chunk_overlap=2time , the first document is aaaaaa, and the second is aabbbbbb. However, this is not absolute, it depends on the specific algorithm inside the text segmentation model used.

Text splitter reference this document

2. Chain chain_typeparameters

This parameter mainly controls the way to pass the document to the llm model. There are 4 ways in total:

  • stuff:: This is the most simple and rude, and will pass all documents to the llm model for summary. If there are many documents, it is bound to report an error exceeding the maximum token limit, so this is generally not selected when summarizing the text.

  • map_reduce:: This method will first summarize each document, and finally summarize the results of all documents.

insert image description here

  • refine:: In this way, the first document will be summarized first, and then the content summarized in the first document and the second document will be sent to the llm model for summary, and so on. The advantage of this method is that when summarizing the latter document, it will summarize with the previous document, adding context to the document that needs to be summarized, and increasing the coherence of the summarized content.

insert image description here

  • map_rerank:: This is generally not used in the summary chain, but in the question and answer chain. It is actually a matching method for searching answers. First you have to give a question, he will calculate a probability score for each document according to the question, and then find the document with the highest score, and convert this document into a part of the prompt of the question (question +document) to the llm model, and finally the llm model returns a specific answer.

3.4 Building a local knowledge base question answering robot

Openai embeddings documentation

  In this example, we will introduce how to read multiple documents from our local to build a knowledge base, and use Openai API to search in the knowledge base and give answers. This is a very useful tutorial, for example, it is very convenient to make a robot that can introduce the company's business, or a robot that introduces a product.

from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.vectorstores import Chroma
from langchain.text_splitter import CharacterTextSplitter
from langchain import OpenAI,VectorDBQA
from langchain.document_loaders import DirectoryLoader
from langchain.chains import RetrievalQA

# 加载文件夹中的所有txt类型的文件
loader = DirectoryLoader('/content/sample_data/data/', glob='**/*.txt')
# 将数据转成 document 对象,每个文件会作为一个 document
documents = loader.load()

# 初始化加载器
text_splitter = CharacterTextSplitter(chunk_size=100, chunk_overlap=0)
# 切割加载的 document
split_docs = text_splitter.split_documents(documents)

# 初始化 openai 的 embeddings 对象
embeddings = OpenAIEmbeddings()
# 将 document 通过 openai 的 embeddings 对象计算 embedding 向量信息并临时存入 Chroma 向量数据库,用于后续匹配查询
docsearch = Chroma.from_documents(split_docs, embeddings)

# 创建问答对象
qa = VectorDBQA.from_chain_type(llm=OpenAI(), chain_type="stuff", vectorstore=docsearch,return_source_documents=True)
# 进行问答
result = qa({
    
    "query": "科大讯飞今年第一季度收入是多少?"})
print(result)

insert image description here

We can see from the results that he successfully obtained the correct answer from our given data.

3.5 Building a vector index database

  One step in our last case is to convert document information into vector information and embeddings information and temporarily store them in Chromathe database. Because it is stored temporarily, the above vectorized data will be lost when the above code is executed. If you want to use it next time, you need to calculate embeddings again, which is definitely not what we want.

  In this case, we use Chromaand Pineconethese two databases to talk about how to persist vector data. For more LangChain databases, refer to this document .

1. Chroma
  chroma is a local vector database, and it provides one persist_directoryto set the persistent directory for persistence. When reading, you only need to call from_documentthe method to load.

from langchain.vectorstores import Chroma

# 持久化数据
docsearch = Chroma.from_documents(documents, embeddings, persist_directory="D:/vector_store")
docsearch.persist()

# 加载数据
docsearch = Chroma(persist_directory="D:/vector_store", embedding_function=embeddings)

2. Pinecone

  Pinecone is an online vector database. Therefore, I can still register as the first step, and then get the corresponding api key. (The free version will automatically clear the index if it is not used for 14 days.)

Then create our database:

  • Index Name: This is optional
  • Dimensions: OpenAI's text-embedding-ada-002 model is OUTPUT DIMENSIONS is 1536, so we fill in 1536 here
  • Metric: default cosine
  • Pod Type: choose starter plan
    insert image description here

The code for persisting data and loading data is as follows

# 持久化数据
docsearch = Pinecone.from_texts([t.page_content for t in split_docs], embeddings, index_name=index_name)

# 加载数据
docsearch = Pinecone.from_existing_index(index_name, embeddings)

A simple code to get embeddings from the database and answer is as follows

from langchain.text_splitter import CharacterTextSplitter
from langchain.document_loaders import DirectoryLoader
from langchain.vectorstores import Chroma, Pinecone
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.llms import OpenAI
from langchain.chains.question_answering import load_qa_chain

import pinecone

# 初始化 pinecone
pinecone.init(
  api_key="你的api key",
  environment="你的Environment"
)

loader = DirectoryLoader('/content/sample_data/data/', glob='**/*.txt')
# 将数据转成 document 对象,每个文件会作为一个 document
documents = loader.load()

# 初始化加载器
text_splitter = CharacterTextSplitter(chunk_size=500, chunk_overlap=0)
# 切割加载的 document
split_docs = text_splitter.split_documents(documents)

index_name="liaokong-test"

# 持久化数据
# docsearch = Pinecone.from_texts([t.page_content for t in split_docs], embeddings, index_name=index_name)

# 加载数据
docsearch = Pinecone.from_existing_index(index_name,embeddings)

query = "科大讯飞今年第一季度收入是多少?"
docs = docsearch.similarity_search(query, include_metadata=True)

llm = OpenAI(temperature=0)
chain = load_qa_chain(llm, chain_type="stuff", verbose=True)
chain.run(input_documents=docs, question=query)

insert image description here

3.6 Use the GPT3.5 model to build a question-and-answer robot for YouTube channels

  After the chatgpt api (that is, GPT-3.5-Turbo) model came out, it was loved by everyone because it is better to live with less money, so LangChain also added a dedicated chain and model. Let's follow this example to see how to use it.

import os

from langchain.document_loaders import YoutubeLoader
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.vectorstores import Chroma
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.chains import ChatVectorDBChain, ConversationalRetrievalChain

from langchain.chat_models import ChatOpenAI
from langchain.prompts.chat import (
  ChatPromptTemplate,
  SystemMessagePromptTemplate,
  HumanMessagePromptTemplate
)

# 加载 youtube 频道
loader = YoutubeLoader.from_youtube_url('https://www.youtube.com/watch?v=Dj60HHy-Kqk')
# 将数据转成 document
documents = loader.load()

# 初始化文本分割器
text_splitter = RecursiveCharacterTextSplitter(
  chunk_size=1000,
  chunk_overlap=20
)

# 分割 youtube documents
documents = text_splitter.split_documents(documents)

# 初始化 openai embeddings
embeddings = OpenAIEmbeddings()

# 将数据存入向量存储
vector_store = Chroma.from_documents(documents, embeddings)
# 通过向量存储初始化检索器
retriever = vector_store.as_retriever()

system_template = """
Use the following context to answer the user's question.
If you don't know the answer, say you don't, don't try to make it up. And answer in Chinese.
-----------
{context}
-----------
{chat_history}
"""

# 构建初始 messages 列表,这里可以理解为是 openai 传入的 messages 参数
messages = [
  SystemMessagePromptTemplate.from_template(system_template),
  HumanMessagePromptTemplate.from_template('{question}')
]

# 初始化 prompt 对象
prompt = ChatPromptTemplate.from_messages(messages)


# 初始化问答链
qa = ConversationalRetrievalChain.from_llm(ChatOpenAI(temperature=0.1,max_tokens=2048),retriever,condense_question_prompt=prompt)


chat_history = []
while True:
  question = input('问题:')
  # 开始发送问题 chat_history 为必须参数,用于存储对话历史
  result = qa({
    
    'question': question, 'chat_history': chat_history})
  chat_history.append((question, result['answer']))
  print(result['answer'])

We can see that he can do a Q&A around this youtube video very accurately

insert image description here

It is also convenient to use streaming answers

from langchain.callbacks.base import CallbackManager
from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler

chat = ChatOpenAI(streaming=True, callback_manager=CallbackManager([StreamingStdOutCallbackHandler()]), verbose=True, temperature=0)
resp = chat(chat_prompt_with_values.to_messages())

3.7 Connect thousands of tools with OpenAI

  We mainly use zapier in combination to connect thousands of tools. So our first step is still to apply for an account and its natural language api key. After filling in the basic information of the zapier api key, you can basically see the approved email in the mailbox in seconds.

  Then, we open our api configuration page through the connection in the right button. We click on the right Manage Actionsto configure which applications we want to use. I have configured the action of Gmail to read and send emails here, and all fields are selected to be guessed by AI.

insert image description here

insert image description here

After configuration, we start writing code

import os
os.environ["ZAPIER_NLA_API_KEY"] = ''
from langchain.llms import OpenAI
from langchain.agents import initialize_agent
from langchain.agents.agent_toolkits import ZapierToolkit
from langchain.utilities.zapier import ZapierNLAWrapper


llm = OpenAI(temperature=.3)
zapier = ZapierNLAWrapper()
toolkit = ZapierToolkit.from_zapier_nla_wrapper(zapier)
agent = initialize_agent(toolkit.get_tools(), llm, agent="zero-shot-react-description", verbose=True)

# 我们可以通过打印的方式看到我们都在 Zapier 里面配置了哪些可以用的工具
for tool in toolkit.get_tools():
  print (tool.name)
  print (tool.description)
  print ("\n\n")

agent.run('请用中文总结最后一封"******@qq.com"发给我的邮件。并将总结发送给"******@qq.com"')

insert image description here

  We can see that he successfully read ******@qq.comthe last email sent to him, and sent the summary to him ******@qq.com. Here's what I sent to Gmail:

insert image description here

This is the email he sent to QQ mailbox:
insert image description here

  This is just a small example, because zapierthere are thousands of applications, so we can easily combine openai apito build our own workflow.

  The main knowledge points have been explained, and some interesting small examples are used below as an extension.

4. Small example

4.1 Executing multiple chains

LangChainIt is chained, so he can also execute multiple chains in sequence:

from langchain.llms import OpenAI
from langchain.chains import LLMChain
from langchain.prompts import PromptTemplate
from langchain.chains import SimpleSequentialChain

# location 链
llm = OpenAI(temperature=1)
template = """Your job is to come up with a classic dish from the area that the users suggests.
% USER LOCATION
{user_location}

YOUR RESPONSE:
"""
prompt_template = PromptTemplate(input_variables=["user_location"], template=template)
location_chain = LLMChain(llm=llm, prompt=prompt_template)

# meal 链
template = """Given a meal, give a short and simple recipe on how to make that dish at home.
% MEAL
{user_meal}

YOUR RESPONSE:
"""
prompt_template = PromptTemplate(input_variables=["user_meal"], template=template)
meal_chain = LLMChain(llm=llm, prompt=prompt_template)

# 通过 SimpleSequentialChain 串联起来,第一个答案会被替换第二个中的user_meal,然后再进行询问
overall_chain = SimpleSequentialChain(chains=[location_chain, meal_chain], verbose=True)
review = overall_chain.run("Rome")

insert image description here

4.2 Structured output

Sometimes what we want to output is not text, but structured data like json.

from langchain.output_parsers import StructuredOutputParser, ResponseSchema
from langchain.prompts import PromptTemplate
from langchain.llms import OpenAI

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

# 告诉他我们生成的内容需要哪些字段,每个字段类型式啥
response_schemas = [
    ResponseSchema(name="bad_string", description="This a poorly formatted user input string"),
    ResponseSchema(name="good_string", description="This is your response, a reformatted response")
]

# 初始化解析器
output_parser = StructuredOutputParser.from_response_schemas(response_schemas)

# 生成的格式提示符
# {
    
    
#	"bad_string": string  // This a poorly formatted user input string
#	"good_string": string  // This is your response, a reformatted response
#}
format_instructions = output_parser.get_format_instructions()

template = """
You will be given a poorly formatted string from a user.
Reformat it and make sure all the words are spelled correctly

{format_instructions}

% USER INPUT:
{user_input}

YOUR RESPONSE:
"""

# 将我们的格式描述嵌入到 prompt 中去,告诉 llm 我们需要他输出什么样格式的内容
prompt = PromptTemplate(
    input_variables=["user_input"],
    partial_variables={
    
    "format_instructions": format_instructions},
    template=template
)

promptValue = prompt.format(user_input="welcom to califonya!")
llm_output = llm(promptValue)

# 使用解析器进行解析生成的内容
output_parser.parse(llm_output)

insert image description here

4.3 Crawl web pages and output JSON data

  Sometimes we need to crawl somerelatively strong structurewebpage, and the information in the webpage needs to be returned in the form of JSON. We can use LLMRequestsChainthe class to achieve, for details, please refer to the following code

In order to facilitate understanding, I directly used the Prompt method to format the output results in the example, instead of using the format used in the previous case StructuredOutputParser, which can be regarded as providing another format idea

from langchain.prompts import PromptTemplate
from langchain.llms import OpenAI
from langchain.chains import LLMRequestsChain, LLMChain

llm = OpenAI(model_name="gpt-3.5-turbo", temperature=0)

template = """在 >>> 和 <<< 之间是网页的返回的HTML内容。
网页是新浪财经A股上市公司的公司简介。
请抽取参数请求的信息。

>>> {requests_result} <<<
请使用如下的JSON格式返回数据
{
    
    {
  "company_name":"a",
  "company_english_name":"b",
  "issue_price":"c",
  "date_of_establishment":"d",
  "registered_capital":"e",
  "office_address":"f",
  "Company_profile":"g"

}}
Extracted:"""

prompt = PromptTemplate(
    input_variables=["requests_result"],
    template=template
)

chain = LLMRequestsChain(llm_chain=LLMChain(llm=llm, prompt=prompt))
inputs = {
    
    
  "url": "https://vip.stock.finance.sina.com.cn/corp/go.php/vCI_CorpInfo/stockid/600519.phtml"
}

response = chain(inputs)
print(response['output'])

We can see that he output the formatted result very well

insert image description here

4.4 Customize the tools used in the agent

from langchain.agents import initialize_agent, Tool
from langchain.agents import AgentType
from langchain.tools import BaseTool
from langchain.llms import OpenAI
from langchain import LLMMathChain, SerpAPIWrapper

llm = OpenAI(temperature=0)

# 初始化搜索链和计算链
search = SerpAPIWrapper()
llm_math_chain = LLMMathChain(llm=llm, verbose=True)

# 创建一个功能列表,指明这个 agent 里面都有哪些可用工具,agent 执行过程可以看必知概念里的 Agent 那张图
tools = [
    Tool(
        name = "Search",
        func=search.run,
        description="useful for when you need to answer questions about current events"
    ),
    Tool(
        name="Calculator",
        func=llm_math_chain.run,
        description="useful for when you need to answer questions about math"
    )
]

# 初始化 agent
agent = initialize_agent(tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True)

# 执行 agent
agent.run("Who is Leo DiCaprio's girlfriend? What is her current age raised to the 0.43 power?")

insert image description here

  There is an interesting part in the custom tool. The weight of which tool is used is 工具中描述内容realized by , which is completely different from the previous programming that used numerical values ​​to control the weight.

  For example, Calculator wrote in the description that if you ask questions about mathematics, use him as a tool. We can see in the above execution process that he chose the Calculator tool for calculation in the mathematics part of the prompt we requested.

4.5 Using Memory to implement a dialogue robot with memory

  In the previous example, we used a custom list to store conversations to save history. Of course, you can also use the built-in memory object to achieve this.

from langchain.memory import ChatMessageHistory
from langchain.chat_models import ChatOpenAI

chat = ChatOpenAI(temperature=0)

# 初始化 MessageHistory 对象
history = ChatMessageHistory()

# 给 MessageHistory 对象添加对话内容
history.add_ai_message("你好!")
history.add_user_message("中国的首都是哪里?")

# 执行对话
ai_response = chat(history.messages)
print(ai_response)

4.6 Using the Hugging Face model

Before using the Hugging Face model, you need to set the environment variable

import os
os.environ['HUGGINGFACEHUB_API_TOKEN'] = ''

Use the online Hugging Face model

from langchain import PromptTemplate, HuggingFaceHub, LLMChain

template = """Question: {question}
Answer: Let's think step by step."""

prompt = PromptTemplate(template=template, input_variables=["question"])
llm = HuggingFaceHub(repo_id="google/flan-t5-xl", model_kwargs={
    
    "temperature":0, "max_length":64})
llm_chain = LLMChain(prompt=prompt, llm=llm)

question = "What NFL team won the Super Bowl in the year Justin Beiber was born?"
print(llm_chain.run(question))

Pull the Hugging Face model directly to local use

from langchain import PromptTemplate, LLMChain
from langchain.llms import HuggingFacePipeline
from transformers import AutoTokenizer, AutoModelForCausalLM, pipeline, AutoModelForSeq2SeqLM

model_id = 'google/flan-t5-large'
tokenizer = AutoTokenizer.from_pretrained(model_id)
model = AutoModelForSeq2SeqLM.from_pretrained(model_id)

pipe = pipeline(
    "text2text-generation",
    model=model,
    tokenizer=tokenizer,
    max_length=100
)

local_llm = HuggingFacePipeline(pipeline=pipe)
print(local_llm('What is the capital of France? '))


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

llm_chain = LLMChain(prompt=prompt, llm=local_llm)
question = "What is the capital of England?"
print(llm_chain.run(question))

The benefits of pulling the model to local use:

  • training model
  • Can use local GPU
  • Some models don't work on Hugging Face

4.7 Execute SQL commands through natural language

Refer to the tutorials "Spark SQL Agent" and "SQL Database Agent"

We can implement the operation of executing SQL commands through SQLDatabaseToolkitorSQLDatabaseChain

from langchain.agents import create_sql_agent
from langchain.agents.agent_toolkits import SQLDatabaseToolkit
from langchain.sql_database import SQLDatabase
from langchain.llms.openai import OpenAI

db = SQLDatabase.from_uri("sqlite:///../notebooks/Chinook.db")
toolkit = SQLDatabaseToolkit(db=db)

agent_executor = create_sql_agent(
    llm=OpenAI(temperature=0),
    toolkit=toolkit,
    verbose=True
)

agent_executor.run("Describe the playlisttrack table")
from langchain import OpenAI, SQLDatabase, SQLDatabaseChain

db = SQLDatabase.from_uri("mysql+pymysql://root:[email protected]/chinook")
llm = OpenAI(temperature=0)

db_chain = SQLDatabaseChain(llm=llm, database=db, verbose=True)
db_chain.run("How many employees are there?")

V. Summary

  All the cases are basically over, I hope you can gain something through the study of this article. This article is just a preliminary explanation of LangChain. I hope you will continue to explore the advanced functions. I hope that everyone can combine LangChain to develop more creative products, not just a bunch of products that build chatgpt chat clients with one click.

Guess you like

Origin blog.csdn.net/qq_56591814/article/details/131376763