Skip to content

构建一个基础聊天机器人

在本教程中,您将构建一个基础聊天机器人。这个聊天机器人是后续一系列教程的基础,在这些教程中,您将逐步添加更复杂的功能,并沿途介绍关键的 LangGraph 概念。让我们开始吧!🌟

先决条件

在开始本教程之前,请确保您能够访问支持工具调用功能的LLM,例如 OpenAIAnthropicGoogle Gemini

1. 安装包

安装所需的包:

pip install -U langgraph langsmith

Tip

注册 LangSmith 可以快速发现并解决您的 LangGraph 项目中的问题,提升性能。LangSmith 允许您使用跟踪数据来调试、测试和监控使用 LangGraph 构建的 LLM 应用。有关如何入门的更多信息,请参阅 LangSmith 文档

2. 创建一个 StateGraph

现在你可以使用 LangGraph 创建一个基本的聊天机器人。这个聊天机器人将直接响应用户的消息。

首先,创建一个 StateGraph。一个 StateGraph 对象将我们的聊天机器人结构定义为“状态机”。我们将添加 nodes 来表示聊天机器人可以调用的 llm 和函数,并添加 edges 来指定聊天机器人如何在这些函数之间进行转换。

API Reference: StateGraph | START | END | add_messages

from typing import Annotated

from typing_extensions import TypedDict

from langgraph.graph import StateGraph, START, END
from langgraph.graph.message import add_messages


class State(TypedDict):
    # 消息的类型是 "list"。注解中的 `add_messages` 函数
    # 定义了此状态键应如何更新
    # (在此情况下,它会将消息追加到列表中,而不是覆盖它们)
    messages: Annotated[list, add_messages]


graph_builder = StateGraph(State)

现在,我们的图可以处理两个关键任务:

  1. 每个 node 可以接收当前的 State 作为输入,并输出对状态的更新。
  2. 由于使用了预构建的 add_messages 函数和 Annotated 语法,对 messages 的更新将被追加到现有列表中,而不是覆盖它。

概念

在定义图时,第一步是定义其 StateState 包含图的 schema 和用于处理状态更新的 reducer 函数。在我们的示例中,State 是一个带有单个键 messagesTypedDict。我们使用了 add_messages reducer 函数,以便将新消息追加到列表中,而不是覆盖它。没有 reducer 注解的键将覆盖之前的值。有关状态、reducer 和相关概念的更多信息,请参见 LangGraph 参考文档

3. 添加一个节点

接下来,添加一个 "chatbot" 节点。**节点**代表工作单元,通常是普通的 Python 函数。

首先,我们选择一个聊天模型:


{}

pip install -U "langchain[openai]"
import os
from langchain.chat_models import init_chat_model

os.environ["OPENAI_API_KEY"] = "sk-..."

llm = init_chat_model("openai:gpt-4.1")

pip install -U "langchain[anthropic]"
import os
from langchain.chat_models import init_chat_model

os.environ["ANTHROPIC_API_KEY"] = "sk-..."

llm = init_chat_model("anthropic:claude-3-5-sonnet-latest")

pip install -U "langchain[openai]"
import os
from langchain.chat_models import init_chat_model

os.environ["AZURE_OPENAI_API_KEY"] = "..."
os.environ["AZURE_OPENAI_ENDPOINT"] = "..."
os.environ["OPENAI_API_VERSION"] = "2025-03-01-preview"

llm = init_chat_model(
    "azure_openai:gpt-4.1",
    azure_deployment=os.environ["AZURE_OPENAI_DEPLOYMENT_NAME"],
)

pip install -U "langchain[google-genai]"
import os
from langchain.chat_models import init_chat_model

os.environ["GOOGLE_API_KEY"] = "..."

llm = init_chat_model("google_genai:gemini-2.0-flash")

pip install -U "langchain[aws]"
from langchain.chat_models import init_chat_model

# 按照此处的步骤配置您的凭证:
# https://docs.aws.amazon.com/bedrock/latest/userguide/getting-started.html

llm = init_chat_model(
    "anthropic.claude-3-5-sonnet-20240620-v1:0",
    model_provider="bedrock_converse",
)

我们现在可以将聊天模型整合到一个简单的节点中:

def chatbot(state: State):
    return {"messages": [llm.invoke(state["messages"])]}


# 第一个参数是唯一的节点名称
# 第二个参数是在节点被使用时调用的函数或对象。
graph_builder.add_node("chatbot", chatbot)

注意 chatbot 节点函数如何以当前 State 作为输入,并返回一个字典,其中包含在键 "messages" 下更新后的 messages 列表。这是所有 LangGraph 节点函数的基本模式。

我们 State 中的 add_messages 函数会将 LLM 的响应消息追加到状态中已有的消息上。

4. 添加一个 entry

添加一个 entry 点,以告诉图 每次运行时从何处开始工作

graph_builder.add_edge(START, "chatbot")

5. 添加一个 exit

添加一个 exit 点以指示 图应该在哪里结束执行。这对于更复杂的流程很有帮助,即使是在像这样的简单图中,添加一个结束节点也能提高清晰度。

graph_builder.add_edge("chatbot", END)
这告诉图在运行完 chatbot 节点后终止。

6. 编译图

在运行图之前,我们需要先编译它。我们可以通过调用图构建器上的 compile() 方法来实现这一点。这将创建一个 CompiledGraph,我们可以在状态上调用它。

graph = graph_builder.compile()

7. 可视化图(可选)

你可以使用 get_graph 方法和其中一个“绘制”方法,如 draw_asciidraw_png 来可视化图。每个 draw 方法都需要额外的依赖项。

from IPython.display import Image, display

try:
    display(Image(graph.get_graph().draw_mermaid_png()))
except Exception:
    # 这需要一些额外的依赖项,并且是可选的
    pass

basic chatbot diagram

8. 运行聊天机器人

现在运行聊天机器人!

Tip

任何时候都可以通过输入 quitexitq 来退出聊天循环。

def stream_graph_updates(user_input: str):
    for event in graph.stream({"messages": [{"role": "user", "content": user_input}]}):
        for value in event.values():
            print("Assistant:", value["messages"][-1].content)


while True:
    try:
        user_input = input("User: ")
        if user_input.lower() in ["quit", "exit", "q"]:
            print("Goodbye!")
            break
        stream_graph_updates(user_input)
    except:
        # 如果 input() 不可用,则作为后备
        user_input = "What do you know about LangGraph?"
        print("User: " + user_input)
        stream_graph_updates(user_input)
        break
Assistant: LangGraph 是一个旨在使用语言模型构建有状态多代理应用程序的库。它提供了创建工作流和状态机的工具,以协调多个 AI 代理或语言模型交互。LangGraph 基于 LangChain 构建,利用其组件并添加了基于图的协调功能。它特别适用于开发更复杂、具有状态的 AI 应用程序,这些应用超出了简单的查询-响应交互。
Goodbye!

恭喜! 您已使用 LangGraph 创建了第一个聊天机器人。这个机器人可以通过接收用户输入并使用 LLM 生成响应来进行基本对话。您可以查看上面调用的 LangSmith Trace

以下是本教程的完整代码:

API Reference: init_chat_model | StateGraph | START | END | add_messages

from typing import Annotated

from langchain.chat_models import init_chat_model
from typing_extensions import TypedDict

from langgraph.graph import StateGraph, START, END
from langgraph.graph.message import add_messages


class State(TypedDict):
    messages: Annotated[list, add_messages]


graph_builder = StateGraph(State)


llm = init_chat_model("anthropic:claude-3-5-sonnet-latest")


def chatbot(state: State):
    return {"messages": [llm.invoke(state["messages"])]}


# 第一个参数是唯一的节点名称
# 第二个参数是当节点被使用时将被调用的函数或对象。
graph_builder.add_node("chatbot", chatbot)
graph_builder.add_edge(START, "chatbot")
graph_builder.add_edge("chatbot", END)
graph = graph_builder.compile()

下一步

你可能已经注意到,机器人的知识仅限于其训练数据中的内容。在接下来的部分中,我们将添加一个网络搜索工具,以扩展机器人的知识,使其更具能力。