LangChain 是一个用来开发大型语言模型(LLM)应用的框架,为了简化构建基于 LLM 的应用,它能够为开发 LLM 应用带来如下能力:
- 根据给定的 Prompt 方便构建上下文,并连接到 LLM, 得到更加符合查询的回答结果
- 在构建整个基于 LLM 的应用提供各种工具,如各种模块(Modules)、LCEL、LangGraph 等
- 提供工具支持,使用户自己的 LLM 应用从原型版本到上线到生产环境过程中,一站式的调试、测试、评估等迭代功能
当前,已经发布了最新的 v0.10.0 稳定版本,可以参考这里 LangChain v0.1.0。本文我们通过介绍 LangChain 框架的方方面面(算是对官方文档的一个入门的内容浓缩)使我们对它有一个更全面的认识,以帮助我们使用 LangChain 构建基于 LLM 的应用,具体包括如下几个方面的内容:
- LangChain 是什么
- LangChain Modules 概览
- LangChain 模块:Model I/O
- LangChain 模块:Retrieval
- LangChain 模块:Agents
- LangChain 模块:Chains
- LangChain 模块:Memory
- LangChain 模块:Callbacks
- LCEL(LangChain Expression Language)
- LangServe 介绍
- LangSmith 介绍
- LangGraph 介绍
LangChain 是什么
LangChain 是一个开源框架,它提供了构建基于 LLM 的 AI 应用所需的各种模块(Modules)与工具,大大降低了开发这一类相关应用的门槛,使得任何人都可以轻松构建基于 OpenAI、Cohere、GPT4All、Huggingface 等提供的大模型的应用。
首先,我们看一下 LangChain 框架的组成,如下图所示:
可见,LangChain 包含如下 4 个主要部分:
- LangChain Libraries
LangChain Libraries 是一个 Python 和 JavaScript 库,是 LangChain 中最核心的部分,在图中对应于下方的深色块。LangChain Libraries 被分为 3 个核心的部分,也是代码组织方式的表现:LangChain、LangChain-Community、LangChain-Core,简要介绍如下:
- LangChain
包括组成应用认知架构(Application’s Cognitive Architecture)的各个部分,如 Chains、Agents 以及 检索策略(Retrieval Strategies)等。
- LangChain-Community
所有用来与第三方集成的功能,都会放到 LangChain-Community 中,方便构建 LLM 应用的人更集中关注集成的能力,比如提供 LLM 的各个 Provider。
- LangChain-Core
包含 LangChain 的基本抽象和 LCEL(LangChain Expression Language)。
- LangChain Templates
提供了一组用于简化部署的参考架构,方便构建基于 LLM 应用的中的各种任务。
- LangServe
提供了用来将 LangChain 部署为 REST API 服务的工具,以供应用的其他模块调用。LangChain 使用了 FastAPI 来实现这种服务能力。
- LangSmith
LangSmith 是 LangChain 提供的开发平台,方便开发人员进行调试、测试、评估、监控等。
LangChain 模块(Modules)概览
LangChain 提供了一个标准的可扩展的接口,可以方便地与外部其他组件进行交互以满足面向特定领域 LLM 应用的需求,它也能够与外部其它组件/中间件连接和交互。这些模块根据功能及行为方式,分为 6 个类别,如下表所示:
模块名称 | 模块功能 |
Model I/O | 用于与 LLM 语言模型交互 |
Retrieval | 用于与应用特定的数据进行交互 |
Agents | 用于确定 LLM 需要采用的 Action 及其顺序的决策,即智能体应用 |
Chains | 用于构建顺序调用的多个构建块(Building Block),主要支持通过 LCEL 的方式构建 |
Memory | 用于在多轮对话过程中保存应用状态 |
Callbacks | 回调系统,用来支持 LLM 应用的日志记录、监控、Streaming 处理,等等 |
通过上面表格,我们基本了解了 LangChain 提供的一些方便构建 LLM 应用的模块及其对应的功能,下面,针对每个模块进行更详细的说明。
LangChain 模块:Model I/O
Model I/O 模块是基于 LangChain 框架构建 LLM 应用的最核心的模块,因为我们必须要与 LLM 进行交互,没有它其他什么都做不了。使用 Model I/O 模块的基本流程,如下图所示:
我们以使用开源 LLM 为例,基于 Llama 2 模型来说明如何快速使用 Model I/O 的方法,分为如下几个步骤:
- 选择并连接到 LLM
使用 Ollama 在本地就可以启动一个模型服务,然后我们就可以使用 LangChain 创建对应的 LLM 和 ChatModel,示例代码如下:
from langchain_community.llms import Ollama from langchain_community.chat_models import ChatOllama llm = Ollama(model="llama2") chat_model = ChatOllama()
通过 llm 和 chat_model 我们就可以与 LLM 进行交互。我们需要知道,llm 和 chat_model 是不同的(具体区别查看这里:LLM vs Chat Models),但是都能通过它们与大模型对话,其中 chat_model 是基于 llm 的,而且进一步进行了调优,使整个持续对话过程更加丰富和完善。
- 调用与 LLM 对话
使用 LangChain 与 LLM 进行对话,示例代码如下:
from langchain.schema import HumanMessage text = "What would be a good company name for a company that makes colorful socks?" messages = [HumanMessage(content=text)] llm.invoke(text) # >> Feetful of Fun chat_model.invoke(messages) # >> AIMessage(content="Socks O'Color")
- 创建 Prompt Template
Prompt Template 包含了我们要查询 LLM 的请求内容,以及我们所基于的上下文,这样就限制了预训练的 LLM 能够基于我们提供的上下文来给出更准确的回答。示例代码如下:
from langchain.prompts.chat import ChatPromptTemplate template = "You are a helpful assistant that translates {input_language} to {output_language}." human_template = "{text}" chat_prompt = ChatPromptTemplate.from_messages([ ("system", template), ("human", human_template), ]) chat_prompt.format_messages(input_language="English", output_language="French", text="I love programming.")
这样就能够把当前要查询的请求内容,以及相关的上线文消息信息整合到一起,然后调用 LLM 进行对话。
- 创建并配置 OutputParser,指定 LLM 返回消息格式
LangChain 提供了不同类型的 OutputParser,能够将 LLM 输出的消息进行格式化,方便下游应用任务使用。比如,下面示例中使用 CommaSeparatedListOutputParser,将消息按照逗号分割,并返回一个列表:
from langchain.output_parsers import CommaSeparatedListOutputParser output_parser = CommaSeparatedListOutputParser() output_parser.parse("hi, bye") # >> ['hi', 'bye']
- 使用 LCEL 组装上面的各种配置
使用 LCEL 将上面的 Prompt Template、ChatModel、OutputParser 组合到一起,并实现了与 LLM 的交互,示例代码如下:
template = "Generate a list of 5 {text}.\n\n{format_instructions}" chat_prompt = ChatPromptTemplate.from_template(template) chat_prompt = chat_prompt.partial(format_instructions=output_parser.get_format_instructions()) chain = chat_prompt | chat_model | output_parser chain.invoke({"text": "colors"}) # >> ['red', 'blue', 'green', 'yellow', 'orange']
LangChain 模块:Retrieval
我们在使用 LLM 构建应用时,往往会根据自己的应用场景使用自己的数据,而不是直接使用预训练的 LLM 提供的内容,所以我们就会从自己的系统中输入数据来影响与 LLM 对话返回的结果内容。LangChain 通过 Retrieval 模块来处理有关数据连接的功能,比如常用的 RAG(Retrieval Augmented Generation)架构能够增强 LLM 的表达。LangChain 提供了 RAG 架构所需要的各种 Building Block,简化我们开发 LLM 应用的难度。
LangChain 基于 RAG 实现的 Retrieval 模块的基本流程,如下图所示:
下面简要说明流程中涉及到的各个部分,有关 RAG 更详细内容可以参考其它资料。
- Document Loaders
从指定的数据源加载数据,通过 LangChain 的 Document Loader 实现,并转换成对应的 Document 对象(一个文本块及其相关信息),示例如下:
from langchain_community.document_loaders import TextLoader loader = TextLoader("./index.md") loader.load()
- Text Splitting
将一个 Document 分割成多个文本块(Text Chunk),根据输入 LLM 的 Prompt 得到与对话查询最相关的文本块,以此作为对话上下文,提高对话返回结果的相关性和精确度。
- Text Embedding Model
对输入 LLM 的 Prompt,以及我们上面得到的文本块,需要通过调用选定的 Text Embedding Model 模型来得到对应的 Embedding,以此获取丰富的语义表达,这样就能够得到与 Prompt 最相关的文本块作为与 LLM 此次对话的上下文。
- Vector Store
Vector Store 也叫 Vector DB,用来存储我们自己数据的向量表示内容(Embedding),以支持 Retrieval 模块的检索匹配。
- Retriever
Retriever 称为检索器,从我们构建好的 Vector Store 中进行检索。LangChain 提供了各种支持检索的算法,比如:ParentDocumentRetriever、SelfQueryRetriever、EnsembleRetriever、MultiVectorRetriever,等等。
下面以 SelfQueryRetriever 为例说明使用方法,示例代码如下所示:
from langchain.schema import Document from langchain_community.vectorstores import Chroma from langchain_openai import OpenAIEmbeddings docs = [ Document( page_content="A bunch of scientists bring back dinosaurs and mayhem breaks loose", metadata={"year": 1993, "rating": 7.7, "genre": "science fiction"}, ), Document( page_content="Leo DiCaprio gets lost in a dream within a dream within a dream within a ...", metadata={"year": 2010, "director": "Christopher Nolan", "rating": 8.2}, ), ] vectorstore = Chroma.from_documents(docs, OpenAIEmbeddings()) from langchain.chains.query_constructor.base import AttributeInfo from langchain.retrievers.self_query.base import SelfQueryRetriever from langchain_openai import ChatOpenAI metadata_field_info = [ AttributeInfo( name="genre", description="The genre of the movie. One of ['science fiction', 'comedy', 'drama', 'thriller', 'romance', 'action', 'animated']", type="string", ), AttributeInfo( name="year", description="The year the movie was released", type="integer", ), ] document_content_description = "Brief summary of a movie" llm = ChatOpenAI(temperature=0) retriever = SelfQueryRetriever.from_llm( llm, vectorstore, document_content_description, metadata_field_info, ) # This example only specifies a filter retriever.invoke("I want to watch a movie rated higher than 8.5")
上面代码,首先,构建 Document,生成对应的 Embedding 保存到 Vector Store 中;然后,创建 SelfQueryRetriever,需要指定 LLM、Vector Store、Document 相关的元数据信息(如果对搜索引擎索引数据比较熟悉,就会理解这么做的原因:是为了构建倒排索引);最后,就可以通过 retriever 来进行查询得到与输入 Prompt 最相关的 Document,并基于这些 Document 作为对话上下文,输入给 LLM 得到最终的对话输出结果。
LangChain 模块:Agents
Agent 通过 LLM 来推理,能够自然地、持续多轮地与 LLM 交互,这也是智能体所具备与支持的基本能力。
为了说明 Agent 框架的使用方法,使用 Tavily 和 Retriever 两个工具来构建 Agent,其中 Tavily 是一个支持 Online 搜索的工具。
- 准备 Tavily 和 Retriever
from langchain_community.tools.tavily_search import TavilySearchResults search = TavilySearchResults() from langchain.text_splitter import RecursiveCharacterTextSplitter from langchain_community.document_loaders import WebBaseLoader from langchain_community.vectorstores import FAISS from langchain_openai import OpenAIEmbeddings loader = WebBaseLoader("https://docs.smith.langchain.com/overview") docs = loader.load() documents = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200).split_documents(docs) vector = FAISS.from_documents(documents, OpenAIEmbeddings()) retriever = vector.as_retriever() from langchain.tools.retriever import create_retriever_tool retriever_tool = create_retriever_tool( retriever, "langsmith_search", "Search for information about LangSmith. For any questions about LangSmith, you must use this tool!", )
- 创建 Agent
from langchain_openai import ChatOpenAI tools = [search, retriever_tool] llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0) from langchain import hub prompt = hub.pull("hwchase17/openai-functions-agent") # Get the prompt to use from langchain.agents import create_openai_functions_agent agent = create_openai_functions_agent(llm, tools, prompt) from langchain.agents import AgentExecutor agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
- 运行 Agent
运行 Agent,示例代码如下:
agent_executor.invoke({"input": "hi!"})
这样的交互不会记忆上下文,是无状态的。所以,如果考虑上下文,需要把以往的记录加入到 Memory,示例代码如下:
from langchain_core.messages import AIMessage, HumanMessage agent_executor.invoke( { "chat_history": [ HumanMessage(content="hi! my name is bob"), AIMessage(content="Hello Bob! How can I assist you today?"), ], "input": "what's my name?", } )
也可以直接使用 LangChain 提供的 ChatMessageHistory、RunnableWithMessageHistory 来实现自动跟踪历史消息的功能,可以参考 LangChain 文档。
LangChain 模块:Chains
Chains 是一个调用/处理/计算任务序列的抽象,可以根据我们自己的需求来构建不同的调用链、处理链,等等。Chains 是通过 LangChain 提供的 LCEL 来构建的。下面是 LainChain 提供的一些 LCEL Constructor,可以方便构建一个 Chain,如下所示:
- create_stuff_documents_chain
- create_openai_fn_runnable
- create_structured_output_runnable
- load_query_constructor_runnable
- create_sql_query_chain
- create_history_aware_retriever
- create_retrieval_chain
通过名称,就可以大致了解每个 LCEL Constructor 实现的 Chain 的功能。
LangChain 模块:Memory
Memory 模块主要用来支持读(READ)和写(WRITE)两个基本的操作。在与 LLM 交互过程中需要能够即时地获取、保存对话信息,具体交互流程如下图所示:
下面以一个与 LLM 交互的过程为例,说明如何使用 LangChain 提供的 ConversationBufferMemory,示例代码如下:
from langchain_openai import OpenAI from langchain.prompts import PromptTemplate from langchain.chains import LLMChain from langchain.memory import ConversationBufferMemory llm = OpenAI(temperature=0) prompt = PromptTemplate.from_template(template) memory = ConversationBufferMemory(memory_key="chat_history") # need to align the `memory_key` conversation = LLMChain(llm=llm, prompt=prompt, verbose=True, memory=memory)
当然也可以直接使用 ChatModel 来实现整个对话过程,具体例子可以参考 LangChain 官网文档。
Memory 模块提供了多个不同的实现,具体也可以根据自己实际应用需求来实现,如下所示是 LangChain 提供的一些实现:
- ConversationBufferMemory
- ConversationBufferWindowMemory
- ConversationEntityMemory
- ConversationKGMemory
- ConversationSummaryMemory
- ConversationSummaryBufferMemory
- ConversationTokenBufferMemory
- VectorStoreRetrieverMemory
具体功能和使用方法,可以点击对应链接查看官网文档的详细说明。
LangChain 模块:Callbacks
LangChain 支持使用 Callbacks,通过 Hook 到基于 LLM 的应用的任何位置,来实现类似日志记录、监控、Streaming 处理以及其它任务等等。要想实现自定义的 Callback 能力,可以直接实现 CallbackHandler 接口,开发满足自己应用需求的 CallbackHandler。
LangChain 实现的 StdOutCallbackHandler 是一个非常基础的 Callback,使用示例如下:
from langchain.callbacks import StdOutCallbackHandler from langchain.chains import LLMChain from langchain_openai import OpenAI from langchain.prompts import PromptTemplate handler = StdOutCallbackHandler() llm = OpenAI() prompt = PromptTemplate.from_template("1 + {number} = ") chain = LLMChain(llm=llm, prompt=prompt, callbacks=[handler]) # Constructor callback chain.invoke({"number":2}) chain = LLMChain(llm=llm, prompt=prompt, verbose=True) # Use verbose flag to achieve callbacks chain.invoke({"number":2}) chain = LLMChain(llm=llm, prompt=prompt) # Request callbacks chain.invoke({"number":2}, {"callbacks":[handler]})
LCEL(LangChain Expression Language)
LCEL(LangChain Expression Language),是一种声明式表达式语言,可以非常容易地构建松耦合的执行链(Chain),主要优点如下所示:
- 支持流式处理:可以通过 Streaming 的方式与 LLM 交互,比如根据自己构建的 LLM 应用的负载情况和处理能力,从 LLM 以 Streaming 的方式处理 LLM 输出的消息结果。
- 支持异步:通过 LCEL 实现异步处理,也能方便地将同步方式改成异步方式,使 LLM 应用能够获得更好的性能。
- 支持优化的并行执行:可以在 LangChain 底层对 LCEL chain 的每一步进行并行化,提高处理性能。
- 支持重试与容错处理:可以对 LCEL chain 的每一步进行失败重试、容错处理,提高 LLM 应用的可靠性和健壮性。
- 支持访问中间结果:通过访问 LCEL chain 中每一步的中间结果,能够对整个应用的处理过程进行透明化,并根据实际情况评估从而制定优化应用的方案。
- 支持配置输入/输出 Schema:可以方便地用于验证输入/输出,同时更好地方便 LangServe 实现。
- 支持无缝集成 LangSmith 跟踪监控:所有步骤执行的细节都可以记录到 LangSmith,从而最大限度地实现可观察性和可调试性。
- 支持无缝集成 LangServe 部署:基于 LCEL 实现的 chain 可以非常方便地使用 LangServe 来完成部署。
下面通过一个实现 prompt + model + output parser 的例子,用来说明使用 LCEL 带来的直观性和便利性,示例代码如下:
from langchain_core.output_parsers import StrOutputParser from langchain_core.prompts import ChatPromptTemplate from langchain_openai import ChatOpenAI prompt = ChatPromptTemplate.from_template("tell me a short joke about {topic}") model = ChatOpenAI(model="gpt-4") output_parser = StrOutputParser() chain = prompt | model | output_parser chain.invoke({"topic": "ice cream"})
首先定义每一步中的逻辑,然后使用 UNIX 管道符 “|” 顺序连接,就可以构建好一个 LCEL chain,并启动执行该 LCEL chain。
上面例子,是最简单的使用串行方式构建 LCEL chain,LangChain 也支持更加复杂的 LCEL chain,可以根据自己的应用需求来进行编排。下面是官网文档中相对复杂的一个例子,如图所示:
具体代码实现,参考官网这里 RAG Search Example。
LangServe 工具介绍
LangServe 提供了将 LangChain 的 runnables 和 chains 部署为 REST API 的能力,它是使用 FastAPI 来实现的。使用 LangServe 部署基于 LLM 的应用,会包含两个部分:Server(提供 LLM ChatModel 服务)、Client(调用模型服务)。
下面通过一个例子来说明如何构建。
- 实现 Server 端
Server 包括 OpenAI ChatModel 和 Anthropic ChatModel,它们可以提供对话服务能力,示例代码如下:
#!/usr/bin/env python from fastapi import FastAPI from langchain.prompts import ChatPromptTemplate from langchain.chat_models import ChatAnthropic, ChatOpenAI from langserve import add_routes import uvicorn app = FastAPI( title="LangChain Server", version="1.0", description="A simple api server using Langchain's Runnable interfaces", ) add_routes( app, ChatOpenAI(), path="/openai", ) add_routes( app, ChatAnthropic(), path="/anthropic", ) model = ChatAnthropic() prompt = ChatPromptTemplate.from_template("tell me a joke about {topic}") add_routes( app, prompt | model, path="/joke", ) if __name__ == "__main__": uvicorn.run(app, host="localhost", port=8000)
如果没有报错,打开浏览器浏览 localhost:8080/docs 可以看到对应的页面,说明 Server 端部署成功。
- 实现 Client 端
Client 端用来与 Server 端进行交互:调用 Server 端提供的 REST API 就可以实现。Client 端示例的 Python 代码如下:
from langchain.schema import SystemMessage, HumanMessage from langchain.prompts import ChatPromptTemplate from langchain.schema.runnable import RunnableMap from langserve import RemoteRunnable openai = RemoteRunnable("http://localhost:8000/openai/") anthropic = RemoteRunnable("http://localhost:8000/anthropic/") joke_chain = RemoteRunnable("http://localhost:8000/joke/") joke_chain.invoke({"topic": "parrots"}) # or async await joke_chain.ainvoke({"topic": "parrots"}) prompt = [ SystemMessage(content='Act like either a cat or a parrot.'), HumanMessage(content='Hello!') ] # Supports astream async for msg in anthropic.astream(prompt): print(msg, end="", flush=True) prompt = ChatPromptTemplate.from_messages( [("system", "Tell me a long story about {topic}")] ) # Can define custom chains chain = prompt | RunnableMap({ "openai": openai, "anthropic": anthropic, }) chain.batch([{"topic": "parrots"}, {"topic": "cats"}])
上面代码给出了不同的调用方式:同步调用、异步调用、流式调用,甚至可以根据 Server 端提供的服务接口实现自定义的 Chain 调用。
LangSmith 工具介绍
使用 LangChain 可以方便、快速构建我们的 LLM 应用或 Agent 的原型,但是并不能方便地实现从原型到生产环境的部署。所以就有了 LangSmith,LangSmith 可以非常方便地对原型进行调试、测试,持续地迭代直至满足生产环境要求。
使用 LangSmith 平台,需要通过 https://smith.langchain.com/ 创建一个 LangSmith 账号并注册一个 API Key 才能使用。具体如何使用,可以参考官方文档 https://docs.smith.langchain.com/user_guide,这里不再过多说明。
LangGraph 介绍
LangGraph 是一个用来构建有状态的、多 Actor 的 LLM 应用的库,它是在 LangChain 框架的基础之上构建实现的。LangGraph 的灵感来自 Pregel 和 Apache Beam,支持基于 LCEL 的能力构建一个带有循环的(Cyclic)的应用模式,从而实现协调多个 Chain 跨多个计算步骤(Computation Steps)的能力。可见,LangGraph 是支持带环的计算图模式的,并不是简单的 DAG(有向无环图)。
下面以官网的入门例子为例,说明如何使用 LangGraph,如下所示:
- 构建一个 Online 搜索工具 Tavily
from langchain_community.tools.tavily_search import TavilySearchResults tools = [TavilySearchResults(max_results=1)] from langgraph.prebuilt import ToolExecutor tool_executor = ToolExecutor(tools) # wrap Tavily tool using LangGraph ToolExecutor
- 构建 LLM 对象
from langchain_openai import ChatOpenAI # We will set streaming=True so that we can stream tokens model = ChatOpenAI(temperature=0, streaming=True) from langchain.tools.render import format_tool_to_openai_function functions = [format_tool_to_openai_function(t) for t in tools] model = model.bind_functions(functions) # Bind tools to the model
- 定义 Agent 状态
langgraph 提供的图主要是指 StatefulGraph,它可以被一个状态对象参数化(Parameterized)。状态对象在图中的每个节点之间传递,每一个节点会返回更新状态对象的操作,从而实现状态的更新。
这里的状态会跟踪对话过程中产生的消息的列表,构建的图中的每个节点需要把消息添加到列表中,所以使用 TypedDict 来实现 Agent 状态,如下所示:
from typing import TypedDict, Annotated, Sequence import operator from langchain_core.messages import BaseMessage class AgentState(TypedDict): messages: Annotated[Sequence[BaseMessage], operator.add]
- 定义图节点(Node)和边(Edge)
在 langgraph 中,图节点是一个 function 对象或 runnable 对象;然后通过边来连接各个节点,在 langgraph 中有两种类型的边:Conditional Edge 和 Normal Edge,可以通过定义函数来实现,确定从一个节点到另一个节点的路径。示例代码如下:
from langgraph.prebuilt import ToolInvocation import json from langchain_core.messages import FunctionMessage # Define the function that determines whether to continue or not def should_continue(state): messages = state['messages'] last_message = messages[-1] if "function_call" not in last_message.additional_kwargs: return "end" else: return "continue" # Define the function that calls the model def call_model(state): messages = state['messages'] response = model.invoke(messages) return {"messages": [response]} # Return a list to add to the existing list # Define the function to execute tools def call_tool(state): messages = state['messages'] # Based on the continue condition, we know the last message involves a function call last_message = messages[-1] # We construct an ToolInvocation from the function_call action = ToolInvocation( tool=last_message.additional_kwargs["function_call"]["name"], tool_input=json.loads(last_message.additional_kwargs["function_call"]["arguments"]), ) response = tool_executor.invoke(action) # Call the tool_executor and get back a response function_message = FunctionMessage(content=str(response), name=action.tool) # use the response to create a FunctionMessage return {"messages": [function_message]}
上面代码定义了一个 LangGraph 中需要个节点(call_model 和 call_tool 代表图中的两个计算节点)和边(通过 should_continue 函数决定计算下一个节点),节点和边的连接构建组合成图的逻辑,会在下一步进行。
- 定义 StateGraph
from langgraph.graph import StateGraph, END workflow = StateGraph(AgentState) # Define the two nodes we will cycle between workflow.add_node("agent", call_model) workflow.add_node("action", call_tool) workflow.set_entry_point("agent") # Set the entrypoint as `agent` # Add a conditional edge workflow.add_conditional_edges( "agent", # First, we define the start node. We use `agent`. should_continue, # Next, the function will determine which node is called next. # Finally we pass in a mapping, and based on which one it matches, that node will then be called. { "continue": "action", # If `tools`, then we call the tool node. "end": END # Otherwise we finish. } ) # Add a normal edge from `tools` to `agent`: after `tools` is called, `agent` node is called next. workflow.add_edge('action', 'agent') app = workflow.compile() # # Compiles it into a LangChain Runnable,
- 执行定义好的 LangGraph
from langchain_core.messages import HumanMessage inputs = {"messages": [HumanMessage(content="what is the weather in sf")]} app.invoke(inputs)
通过上面 1~6 步骤,就可以构建并执行一个基于 LangGraph 的简单 LLM 应用。
参考资源
- https://python.langchain.com/docs/get_started/introduction
- https://blog.langchain.dev/langchain-v0-1-0/
- https://blog.langchain.dev/the-new-langchain-architecture-langchain-core-v0-1-langchain-community-and-a-path-to-langchain-v0-1/
- https://python.langchain.com/docs/langsmith/
- https://python.langchain.com/docs/langsmith/walkthrough
- https://docs.smith.langchain.com/
- https://python.langchain.com/docs/langgraph
本文基于署名-非商业性使用-相同方式共享 4.0许可协议发布,欢迎转载、使用、重新发布,但务必保留文章署名时延军(包含链接:http://shiyanjun.cn),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系。