拥抱生成式大模型 -- langchain篇 (博客搬家至知乎,同步更新)

曹恩
2023-12-01

langchain 的 概念

Langchain 是 一套使用大模型的应用开发框架,当前的版本0.0.157。 它赋予LLM两大核心能力:数据感知(Be data-aware),让语言模型可以与其他数据源相连接;代理能力(Be agentic),允许语言模型与其环境互动。

langchain 的基本架构

LangChain提供支持的几个主要模块。对于每个模块,我们都提供了一些入门示例、操作指南、参考文档和概念指南。这些模块按复杂性递增的顺序分别是:

模型(Models):LangChain支持的各种模型类型和模型集成。

LangChain中可以使用的不同类型的模型。我们将简要介绍模型类型

LLMs

大型语言模型(LLMs)是我们首先涵盖的模型类型。这些模型将文本字符串作为输入,并返回文本字符串作为输出。

from langchain.llms import OpenAI
llm = OpenAI(model_name="text-ada-001", n=2, best_of=2)
llm("Tell me a joke")

聊天模型

聊天模型是我们涵盖的第二种模型类型。这些模型通常由语言模型支持,但它们的API更加结构化。具体而言,这些模型将聊天消息列表作为输入,并返回聊天消息。

文本嵌入模型

第三种模型类型是文本嵌入模型。这些模型将文本作为输入,并返回浮点数列表。

提示(Prompts):包括提示管理、提示优化和提示序列化。

调用一个LLM是一个很好的第一步,但这只是个开始。通常在应用程序中使用LLM时,你不会直接将用户输入发送到LLM。相反,你可能会接收用户输入并构建一个提示,然后将其发送到LLM。

例如,在前面的示例中,我们传入的文本是硬编码的,要求输入制造彩色袜子公司的名称。在这个想象中的服务中,我们想要做的是只接收用户描述公司业务的输入,然后用这些信息格式化提示。

在LangChain中,这很容易做到!

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"))

记忆(Memory):记忆是在调用链/代理的各个调用之间保持状态的概念。LangChain为记忆提供了一个标准接口、一组记忆实现和使用记忆的链/代理的示例。

到目前为止,我们所涉及的所有链和代理都是无状态的。但是通常情况下,您可能希望链或代理具有某种“记忆”概念,以便它可以记住其先前的交互信息。这最清晰和简单的例子是设计聊天机器人-您希望它记住以前的消息,以便它可以利用上下文来进行更好的对话。这将是一种“短期记忆”类型。在更复杂的一面,您可以想象一个链/代理随着时间的推移记住关键信息-这将是一种“长期记忆”形式。有关后者的更具体想法,请参见这篇精彩的论文。

LangChain提供了几个专门为此目的创建的链。本笔记本演示了如何使用其中一个链(ConversationChain)和两种不同类型的存储器。

默认情况下,ConversationChain具有一种简单的存储器类型,该存储器会记住所有先前的输入/输出并将它们添加到传递的上下文中。让我们看一下如何使用此链(将verbose设置为True以便我们可以看到提示)。

from langchain import OpenAI, ConversationChain

llm = OpenAI(temperature=0)
conversation = ConversationChain(llm=llm, verbose=True)

output = conversation.predict(input="Hi there!")
print(output)

output = conversation.predict(input="I'm doing well! Just having a conversation with an AI.")
print(output)

索引(Indexes):语言模型通常与您自己的文本数据结合使用时更加强大,该模块介绍了这样做的最佳实践。

链(Chains):链不仅仅是单个LLM调用,而是一系列调用(无论是对LLM还是其他实用程序)。LangChain为链提供了一个标准接口、许多其他工具的集成和常见应用的端到端链。

到目前为止,我们一直只是单独使用PromptTemplate和LLM原语进行操作。但是,实际的应用不仅仅是一个原语,而是由它们的组合构成的。

在LangChain中,链由链接组成,链接可以是LLM等原语或其他链。

最核心的链类型是LLMChain,它由一个PromptTemplate和一个LLM组成。

延续前面的例子,我们可以构建一个LLMChain,它接受用户输入,使用PromptTemplate对其进行格式化,然后将格式化的响应传递给LLM。

from langchain.prompts import PromptTemplate
from langchain.llms import OpenAI

llm = OpenAI(temperature=0.9)
prompt = PromptTemplate(
    input_variables=["product"],
    template="What is a good name for a company that makes {product}?",
)
from langchain.chains import LLMChain
chain = LLMChain(llm=llm, prompt=prompt)
chain.run("colorful socks")

代理(Agents):代理涉及LLM决定采取哪些操作,采取该操作,看到一个观察值,然后重复这个过程直到完成。LangChain为代理提供了一个标准接口、一些可供选择的代理和端到端代理的示例。这里代理使用了google的查询接口api

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

# First, let's load the language model we're going to use to control the agent.
llm = OpenAI(temperature=0)

# Next, let's load some tools to use. Note that the `llm-math` tool uses an LLM, so we need to pass that in.
tools = load_tools(["serpapi", "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!
agent.run("What was the high temperature in SF yesterday in Fahrenheit? What is that number raised to the .023 power?")

回调(Callbacks):在链或代理内部跟踪所有发生的事情可能很困难,回调可以帮助添加一定程度的可观察性和内省能力。

langchain的使用

借用document的的一个例子,整体性的介绍一下langchain框架的使用

from langchain.agents import Tool
from langchain.agents import AgentType
from langchain.memory import ConversationBufferMemory
from langchain import OpenAI
from langchain.utilities import SerpAPIWrapper
from langchain.agents import initialize_agent
search = SerpAPIWrapper()
tools = [
    Tool(
        name = "Current Search",
        func=search.run,
        description="useful for when you need to answer questions about current events or the current state of the world"
    ),
]
memory = ConversationBufferMemory(memory_key="chat_history")
llm=OpenAI(temperature=0)
agent_chain = initialize_agent(tools, llm, agent=AgentType.CONVERSATIONAL_REACT_DESCRIPTION, verbose=True, memory=memory)
agent_chain.run(input="hi, i am bob")
> Entering new AgentExecutor chain...

Thought: Do I need to use a tool? No
AI: Hi Bob, nice to meet you! How can I help you today?

> Finished chain.
'Hi Bob, nice to meet you! How can I help you today?'

agent_chain.run(input="what's my name?")
> Entering new AgentExecutor chain...

Thought: Do I need to use a tool? No
AI: Your name is Bob!

> Finished chain.
'Your name is Bob!'

agent_chain.run("what are some good dinners to make this week, if i like thai food?")
> Entering new AgentExecutor chain...

Thought: Do I need to use a tool? Yes
Action: Current Search
Action Input: Thai food dinner recipes
Observation: 59 easy Thai recipes for any night of the week · Marion Grasby's Thai spicy chilli and basil fried rice · Thai curry noodle soup · Marion Grasby's Thai Spicy ...
Thought: Do I need to use a tool? No
AI: Here are some great Thai dinner recipes you can try this week: Marion Grasby's Thai Spicy Chilli and Basil Fried Rice, Thai Curry Noodle Soup, Thai Green Curry with Coconut Rice, Thai Red Curry with Vegetables, and Thai Coconut Soup. I hope you enjoy them!

> Finished chain.
"Here are some great Thai dinner recipes you can try this week: Marion Grasby's Thai Spicy Chilli and Basil Fried Rice, Thai Curry Noodle Soup, Thai Green Curry with Coconut Rice, Thai Red Curry with Vegetables, and Thai Coconut Soup. I hope you enjoy them!"

agent_chain.run(input="tell me the last letter in my name, and also tell me who won the world cup in 1978?")
> Entering new AgentExecutor chain...

Thought: Do I need to use a tool? Yes
Action: Current Search
Action Input: Who won the World Cup in 1978
Observation: Argentina national football team
Thought: Do I need to use a tool? No
AI: The last letter in your name is "b" and the winner of the 1978 World Cup was the Argentina national football team.

> Finished chain.
'The last letter in your name is "b" and the winner of the 1978 World Cup was the Argentina national football team.'

agent_chain.run(input="whats the current temperature in pomfret?")
>Entering new AgentExecutor chain...
Thought: Do I need to use a tool? Yes
Action: Current Search
Action Input: Current temperature in Pomfret
Observation: Partly cloudy skies. High around 70F. Winds W at 5 to 10 mph. Humidity41%.
Thought: Do I need to use a tool? No
AI: The current temperature in Pomfret is around 70F with partly cloudy skies and winds W at 5 to 10 mph. The humidity is 41%.

> Finished chain.
'The current temperature in Pomfret is around 70F with partly cloudy skies and winds W at 5 to 10 mph. The humidity is 41%.'

 类似资料: