在日常生活中,我们主要致力于构建端到端的应用程序。有许多自动化机器学习平台和CI/CD流水线可以用来自动化我们的机器学习流程。
现如今大模型的出现,如果我们想要借助OpenAI或hugging face创建一个LLM应用程序,在自己的本地部署并使用,但是手动安装大模型步骤太繁琐了,而且涉及到的环境,编译接口集成问题太多了,
相对比之下,LangChain简化了LLM模型的集成和开发过程,提供了更高的开发效率和易用性,同时保持了可扩展性和灵活性。它使开发人员能够更专注于应用程序的业务逻辑和达到同样的目的,它帮助我们创建端到端的LLM模型应用程序或流程。让我们更多地了解一下Langchain。
LangChain是一个用于开发基于语言模型的应用程序开发框架。总的来说,LangChain是一个链接面向用户程序和LLM之间的一个中间层。
LangChain 可以轻松管理与语言模型的交互,将多个组件链接在一起,并集成额外的资源,例如 API 和数据库。其组件包括了模型(各类LLM),提示模板(Prompts),索引,代理(Agent),记忆等等。
当提到LangChain是一个链接面向用户程序和LLM之间的一个中间层时,意思是LangChain提供了一个桥梁,连接了用户编写的应用程序和底层的大型语言模型(LLM)。它充当一个中间层,使得用户能够更方便地与LLM进行交互。通常情况下,用户编写应用程序时,需要考虑如何与底层的LLM进行通信、调用和处理结果。这可能涉及到与LLM的接口、数据传输、请求和响应的处理等方面。而LangChain的目标是简化这个过程,提供一个统一的接口和功能,使用户能够轻松地构建、管理和集成LLM应用程序。通过LangChain,用户可以通过一系列的模块来组织和管理LLM的调用过程。
跟pytorch,tensorflow框架一个道理,用户通过调用框架的函数和接口来实现底层算子的运算。
Langchain由几个模块组成,每个模块连接成一个链,并最后使用该链一次性调用所有模块。
这些模块包括以下内容:
pip install langchain
模型选择上,模型主要涵盖大型语言模型(LLM)。一个具有相当规模的大型语言模型是由具有大量参数的神经网络组成,并且在大量无标签文本上进行训练。有各种技术巨头开发的LLM,比如:
LangChain为许多不同的LLM提供了一个通用接口。它们中的大多数通过其API工作,但您也可以运行本地模型。
pip install openai
import os
os.environ["OPENAI_API_KEY"] ="YOUR_OPENAI_TOKEN"
from langchain.llms import OpenAI
llm = OpenAI(temperature=0.9) # model_name="text-davinci-003"
text = "What would be a good company name for a company that makes colorful socks?"
print(llm(text))
pip install huggingface_hub
os.environ["HUGGINGFACEHUB_API_TOKEN"] = "YOUR_HF_TOKEN"
from langchain import HuggingFaceHub
# https://huggingface.co/google/flan-t5-xl
llm = HuggingFaceHub(repo_id="google/flan-t5-xl", model_kwargs={"temperature":0, "max_length":64})
llm("translate English to German: How old are you?")
Prompts提示是我们提供给系统的输入,用于优化我们的答案,使其根据我们的用例更准确或更具体。
很多时候,你可能希望获得比纯文本更结构化的信息。许多基于对比预训练和零样本学习的新型目标检测和分类算法都将提示作为有效的结果输入。举个例子,OpenAI的CLIP和META的Grounding DINO都使用提示作为预测的输入。
在Langchain中,我们可以将自己提供的需求Prompts转换为标准的Prompt格式,就是优化Prompt的意思
并且LangChain提供了预先设计的提示模板,可以为不同类型的任务生成提示。然而,在某些情况下,预设的模板可能无法满足您的要求。在默认情况下,我们可以使用自定义提示模板。
例如:
from langchain import PromptTemplate
# This template will act as a blue print for prompt
template = """
I want you to act as a naming consultant for new companies.
What is a good name for a company that makes {product}?
"""
prompt = PromptTemplate(
input_variables=["product"],
template=template,
)
prompt.format(product="colorful socks")
# -> I want you to act as a naming consultant for new companies.
# -> What is a good name for a company that makes colorful socks?
在LangChain中,链(Chains)和代理(Agents)默认情况下以无状态模式运行,这意味着它们独立处理每个传入的查询。然而,在某些应用程序中,比如聊天机器人,保留先前的交互是非常重要的,无论是短期还是长期。这就是“记忆”概念发挥作用的地方。
保留历史查询的记录
LangChain以两种形式提供记忆组件。首先,LangChain提供了管理和操作先前聊天消息的辅助工具,这些工具被设计为模块化且无论用例如何都很有用。其次,LangChain提供了一种将这些工具轻松集成到链中的方法。这使它们非常灵活和适应任何情况。
例如:
from langchain.memory import ChatMessageHistory
history = ChatMessageHistory()
history.add_user_message("hi!")
history.add_ai_message("whats up?")
history.messages
输出
[HumanMessage(content='hi!', additional_kwargs={}),
AIMessage(content='whats up?', additional_kwargs={})]
链提供了将各种组件合并为统一应用程序的方法。例如,可以创建一个链,接收用户输入,使用PromptTemplate进行格式化,然后将格式化的回复传输给LLM。通过将多个链与其他组件集成,可以生成更复杂的链。
跟深度学习网络中的nn.Sequential()原理类似
LLMChain被认为是查询LLM对象最广泛使用的方法之一。它根据提示模板格式化提供的输入键值和记忆键值(如果存在),然后将格式化的字符串发送给LLM,LLM产生输出并返回。
#Here we are chaining everything
from langchain.chat_models import ChatOpenAI
from langchain.prompts.chat import (
ChatPromptTemplate,
HumanMessagePromptTemplate,
)
human_message_prompt = HumanMessagePromptTemplate(
prompt=PromptTemplate(
template="What is a good name for a company that makes {product}?",
input_variables=["product"],
)
)
chat_prompt_template = ChatPromptTemplate.from_messages([human_message_prompt])
chat = ChatOpenAI(temperature=0.9)
# Temperature is about randomness in answer more the temp, random the answer
#Final Chain
chain = LLMChain(llm=chat, prompt=chat_prompt_template)
print(chain.run("colorful socks"))
在LangChain中,代理(Agents)是指一种能够根据用户的输入作出决策并执行相应操作的机制。代理充当了与用户交互和处理用户请求的中间层。它可以根据用户的输入来决定是否调用特定的工具或模块,并确定传递给这些工具的输入。代理在完成操作后会观察到结果,并根据结果决定下一步的行动。
代理的作用是增强LangChain的灵活性和适应性。它使LangChain能够根据具体情况动态选择调用哪些工具,并根据实际情况调整处理流程。代理的使用可以使LangChain在处理复杂的任务和多样化的用户需求时更加强大和智能化。通过代理,LangChain可以根据具体情况做出决策,提供更准确和个性化的回应,以满足不同用户的需求。
就是告诉模型,这个任务是什么类型的任务
工具是代理可以用来与外界的函数库进行交互的功能。这些工具可以是通用的实用程序(例如搜索)。例如可以使用以下代码片段加载工具:
from langchain.agents import load_tools
from langchain.agents import initialize_agent
pip install wikipedia
#这里加载一个维基百科的库
from langchain.llms import OpenAI
llm = OpenAI(temperature=0)
tools = load_tools(["wikipedia", "llm-math"], llm=llm)
agent = initialize_agent(tools, llm, agent="zero-shot-react-description", verbose=True)
agent.run("In what year was the film Departed with Leopnardo Dicaprio released? What is this year raised to the 0.43 power?")
将语言模型与自己的文本数据结合使用。这个过程的第一步是将数据加载到文档中(即一些文本片段)。
from langchain.document_loaders import NotionDirectoryLoader
loader = NotionDirectoryLoader("Notion_DB")
docs = loader.load()
索引是指以最佳方式对文档进行结构化,以便语言模型(LLMs)能够与其进行最佳交互。这个模块包含了处理文档的实用函数。
嵌入(Embeddings):嵌入是对信息(例如文本、文档、图像、音频等)的数值表示。通过嵌入,可以将信息转换为向量形式,以便计算机能够更好地理解和处理。
文本拆分器(Text Splitters):当需要处理较长的文本时,有必要将文本分割成多个块。文本拆分器是用于将长文本分割成更小片段的工具。
向量数据库(Vectorstores):向量数据库存储和索引来自自然语言处理模型的向量嵌入,用于理解文本字符串、句子和整个文档的含义和上下文,从而获得更准确和相关的搜索结果。请参阅可用的向量数据库。
import requests
url = "https://raw.githubusercontent.com/hwchase17/langchain/master/docs/modules/state_of_the_union.txt"
res = requests.get(url)
with open("state_of_the_union.txt", "w") as f:
f.write(res.text)
# Document Loader
from langchain.document_loaders import TextLoader
loader = TextLoader('./state_of_the_union.txt')
documents = loader.load()
# Text Splitter
from langchain.text_splitter import CharacterTextSplitter
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
docs = text_splitter.split_documents(documents)
pip install sentence_transformers
# Embeddings
from langchain.embeddings import HuggingFaceEmbeddings
embeddings = HuggingFaceEmbeddings()
#text = "This is a test document."
#query_result = embeddings.embed_query(text)
#doc_result = embeddings.embed_documents([text])
pip install faiss-cpu
from langchain.vectorstores import FAISS
db = FAISS.from_documents(docs, embeddings)
query = "What did the president say about Ketanji Brown Jackson"
docs = db.similarity_search(query)
print(docs[0].page_content)