AI领域正以惊人的速度发展,各种概念层出不穷,例如生成式AI、AI Agent和Agentic AI。如果你想构建复杂的AI系统,理解这些概念之间的根本区别至关重要。本文将深入探讨这三大支柱,并指导你如何使用强大的LangGraph框架构建基于Agent的应用程序。
1. 生成式AI:内容创造者
生成式AI的核心在于创造新的内容。无论是使用GPT-4写诗,用DALL-E生成图像,还是用Claude起草电子邮件,你都在与生成式AI系统交互。
核心特征:
- 被动响应: 它们响应你的提示,但不会主动发起行动。
- 内容聚焦: 它们的主要任务是生成文本、图像、音频或视频。
- 无状态交互: 每次对话都是独立的,没有记忆。
技术原理: 这些系统基于大型语言模型(LLM),LLM 接受海量数据集的训练,例如 Llama 3 和 GPT-4 等模型,它们已经消耗了大量的人类知识,成为了内容生成的强大工具。
实际案例: 你向ChatGPT 提出要求:“为我的新产品发布撰写一封营销电子邮件。” 它会根据它的训练数据生成一封完整的电子邮件。但它无法检查你当前的库存,访问你的客户数据库或安排发送这封电子邮件。这说明了生成式AI的局限性。
2. AI Agent:专业工作者
AI Agent更进一步,它不仅仅是生成内容,还能利用外部工具和数据源执行特定任务。可以把它想象成你的生成式AI模型,但现在它有能力在现实世界中采取行动。
核心特征:
- 工具赋能: 可以调用外部API,搜索网络,查询数据库。
- 任务特定: 专门设计用于解决特定问题。
- 主动行动: 可以根据情况主动采取行动。
突破性概念: 工具调用。当LLM 意识到它没有回答你问题所需的信息时,它可以调用外部工具来收集该信息,处理信息,然后为你提供全面的响应。
实际案例: 你询问一个AI Agent:“今天关于AI 发展的最新消息是什么?” 该Agent 意识到它没有最新的信息,于是调用一个新闻API(如Tavily),检索今天的人工智能新闻,然后将其总结成连贯的响应。这展示了AI Agent 的强大之处,它超越了单纯的内容生成,能够主动获取和处理信息。
3. Agentic AI:协同工作流
Agentic AI 代表着一种完整的范式转变。它不是由单个AI 处理一项任务,而是由多个AI Agent协同工作、沟通和协调,以解决复杂的多步骤问题。
核心特征:
- 多Agent 协作: 多个AI Agent 协同工作。
- 工作流自动化: 可以处理复杂的多步骤流程。
- Agent间通信: Agent 可以共享信息并在彼此的工作基础上进行构建。
- 目标导向: 整个系统朝着实现特定目标而努力。
颠覆性变革: 这不仅仅是拥有多个AI Agent,而是让它们智能地协作。一个Agent 的输出成为另一个Agent 的输入,从而创建复杂的工作流程,处理单个AI 系统无法完成的任务。
实际案例: 你想将你的YouTube 视频转换为一篇博客文章。一个Agentic AI 系统可能会部署:
- Agent 1: 从你的YouTube 视频中提取转录。
- Agent 2: 从转录中创建一个引人入胜的标题。
- Agent 3: 撰写引人入胜的描述。
- Agent 4: 撰写一个总结所有内容的结论。
- 协调器: 将所有输出组合成一篇最终的、润色的博客文章。
从生成式AI 到Agentic AI 的演变
生成式AI → AI Agent → Agentic AI
(被动响应) (主动行动) (协同工作)
这种演变不仅仅代表着技术的进步,更代表着我们构建AI 解决方案方式的根本转变。我们正在从简单地响应提示的系统,转向能够推理、计划和自主执行复杂工作流程的系统。
使用LangGraph 构建你的第一个AI Agent
现在让我们用LangGraph 来构建一个简单的AI Agent。
理解LangGraph 的核心概念
在深入研究代码之前,让我们回顾一下LangGraph 的关键概念。每个复杂的LangGraph 多Agent 系统都遵循我们即将探讨的模式:
- 状态管理: 信息如何在系统中流动。
State
类定义了agent之间的共享数据结构,确保了信息的连贯性。 - 节点: 单独的处理单元(你的AI Agent)。每个节点都执行特定的任务,例如调用LLM 或执行工具。
- 边: 这些单元如何连接和通信。边定义了节点之间的信息流,以及它们之间的依赖关系。
- 图编译: 将所有这些组合在一起。编译后的图可以执行,并根据定义的状态和边在节点之间传递信息。
掌握这四个概念,你将理解LangGraph 的大部分强大之处。
搭建基本聊天机器人
步骤 1:设置你的环境
首先,确保你已安装了所有必要的库:
pip install langgraph langchain langchain-groq python-dotenv langchain-tavily
然后,创建一个 .env
文件,并在其中添加你的Groq API 密钥:
GROQ_API_KEY=YOUR_GROQ_API_KEY
TAVILY_API_KEY=YOUR_TAVILY_API_KEY
from typing import Annotated
from typing_extensions import TypedDict
from langgraph.graph import StateGraph, START, END
from langgraph.graph.message import add_messages
import os
from dotenv import load_dotenv
# 加载环境变量,创建 .env 文件并从 https://console.x.ai/team/YOUR_TEAM_ID/api-keys/create 获取你的 grok api 密钥
load_dotenv()
步骤 2:定义你的状态
LangGraph 与传统的聊天机器人不同,它以状态的概念来思考:
class State(TypedDict):
# 消息类型为 "list"。`add_messages` 函数
# 在注释中定义了如何更新此状态键
# (在这种情况下,它将消息附加到列表中,而不是覆盖它们)
messages: Annotated[list, add_messages]
此状态定义非常强大,因为它会自动维护对话历史记录。add_messages
函数确保每次交互都建立在前一次交互的基础上,从而创建真正的对话上下文。
步骤 3:连接你的LLM
from langchain_groq import ChatGroq
from langchain.chat_models import init_chat_model
# 两种初始化方式 - 都完美工作
llm = ChatGroq(model="llama3-8b-8192")
# 或者使用 init_chat_model 帮助器
#llm = init_chat_model("groq:llama3-8b-8192")
这里使用Groq,因为它对于学习来说速度快且具有成本效益。你可以轻松地将其替换为OpenAI、Anthropic 或任何其他与LangChain 兼容的模型。
步骤 4:创建你的节点函数
def chatbot(state: State):
return {"messages": [llm.invoke(state["messages"])]}
这个简单的函数:
- 接收当前状态(对话历史记录)。
- 将其传递给LLM。
- 返回以预期格式包装的LLM 的响应。
接收状态 -> 处理 -> 返回新状态
这种模式是每个LangGraph 节点的基础,无论它是一个简单的聊天机器人还是一个复杂的数据分析Agent。
步骤 5:构建和编译你的图
# 初始化图构建器
graph_builder = StateGraph(State)
# 将你的聊天机器人添加为节点
graph_builder.add_node("llmchatbot", chatbot)
# 定义流程:START -> chatbot -> END
graph_builder.add_edge(START, "llmchatbot")
graph_builder.add_edge("llmchatbot", END)
# 编译图
graph = graph_builder.compile()
步骤 6:可视化你的创建
from IPython.display import Image, display
try:
display(Image(graph.get_graph().draw_mermaid_png()))
except Exception:
pass
这会创建你的图的可视化表示,这在构建复杂的多Agent 系统时非常宝贵。
步骤 7:测试你的聊天机器人
# 单次交互
response = graph.invoke({"messages": "你好"})
print(response["messages"][-1].content)
# 输出:"你好!很高兴认识你。有什么我可以帮你的或者你想聊天的吗?"
# 流式响应(更具交互性)
for event in graph.stream({"messages": "你好吗?"}):
for value in event.values():
print(value["messages"][-1].content)
# 响应:你好!我只是一个语言模型,所以我没有像人类那样的情感或感觉,但我工作正常,可以帮助你解决任何问题或任务!今天我能帮你做什么?
从简单的聊天机器人到ReAct Agent:添加超能力
现在,让我们更进一步,将我们基本聊天机器人转变为ReAct Agent,它可以搜索网络、执行计算和推理复杂任务。
步骤 1:添加工具
我们将添加两种类型的工具:
- 网络搜索: 用于访问实时信息。
- 自定义函数: 用于执行计算。
from langchain_tavily import TavilySearch
# 网络搜索工具
tool = TavilySearch(max_results=2)
# 测试一下
tool.invoke("什么是langgraph")
# 自定义函数工具
def multiply(a: int, b: int) -> int:
"""Multiply a and b
Args:
a (int): first int
b (int): second int
Returns:
int: output int
"""
return a * b
# 合并工具
tools = [tool, multiply]
# 将工具绑定到我们的LLM
llm_with_tool = llm.bind_tools(tools)
步骤 2:构建启用工具的图
我们需要创建一个可以执行以下操作的图:
- 处理用户输入。
- 确定是否使用工具。
- 执行工具(如果需要)。
- 返回结果。
from langgraph.graph import StateGraph, START, END
from langgraph.prebuilt import ToolNode
from langgraph.prebuilt import tools_condition
# 节点定义
def tool_calling_llm(state: State):
return {"messages": [llm_with_tool.invoke(state["messages"])]}
# 构建图
builder = StateGraph(State)
builder.add_node("tool_calling_llm", tool_calling_llm)
builder.add_node("tools", ToolNode(tools))
# 添加边
builder.add_edge(START, "tool_calling_llm")
builder.add_conditional_edges(
"tool_calling_llm",
# 如果来自助理的最新消息是工具调用 -> 路由到工具
# 如果不是工具调用 -> 路由到 END
tools_condition
)
builder.add_edge("tools", END)
# 编译图
graph = builder.compile()
步骤 3:测试工具集成
# 测试网络搜索
response = graph.invoke({"messages": "最近的人工智能新闻是什么?"})
print(response['messages'][-1].content)
# 测试自定义函数
response = graph.invoke({"messages": "5 乘以 2 等于多少?"})
for m in response['messages']:
m.pretty_print()
# 测试需要多个工具的复杂查询
response = graph.invoke({"messages": "给我最近的人工智能新闻,然后将 5 乘以 10"})
for m in response['messages']:
m.pretty_print()
ReAct 架构
ReAct 代表推理和行动。这是一种Agent:
- 推理它需要做什么。
- 通过使用工具来行动。
- 观察结果。
- 再次推理下一步骤。
- 重复直到任务完成。
步骤 4:实现ReAct 架构
# 相同的节点定义
def tool_calling_llm(state: State):
return {"messages": [llm_with_tool.invoke(state["messages"])]}
# 相同的图设置
builder = StateGraph(State)
builder.add_node("tool_calling_llm", tool_calling_llm)
builder.add_node("tools", ToolNode(tools))
# 关键区别:创建一个循环
builder.add_edge(START, "tool_calling_llm")
builder.add_conditional_edges(
"tool_calling_llm",
tools_condition
)
# 这是神奇的一行 - 工具流回LLM
builder.add_edge("tools", "tool_calling_llm")
# 编译
graph = builder.compile()
关键区别在于,我们使用builder.add_edge("tools", "tool_calling_llm")
而不是builder.add_edge("tools", END)
。这会创建一个循环,其中:
- LLM 可以使用工具。
- 工具结果流回LLM。
- LLM 可以推理结果并使用更多工具。
- 该过程会继续,直到LLM 确定它已完成。
步骤 5:ReAct Agent 实战
response = graph.invoke({"messages": "给我最近的人工智能新闻,然后将 5 乘以 10"})
for m in response['messages']:
m.pretty_print()
内部发生了什么:
- 用户: “给我最近的人工智能新闻,然后将 5 乘以 10”
- LLM 推理: “我首先需要搜索人工智能新闻”
- 行动: 调用 TavilySearch 工具
- 观察: 获取搜索结果
- LLM 推理: “现在我有了新闻,我需要将 5 乘以 10”
- 行动: 调用 multiply 函数
- 观察: 获取计算结果
- LLM 推理: “我已经有了这两条信息,我可以回复”
- 最终响应: 结合两个结果
结论
本文介绍了生成式AI、AI Agent 和 Agentic AI 的核心概念,并引导你使用LangGraph 构建了一个基本的聊天机器人和一个ReAct Agent。通过学习本文,你应该对如何使用LangGraph 构建更强大的AI 系统有了更深入的了解。在未来的博客中,我们将讨论关于存储、复杂工作流程、MCP 集成的内容,我们将使用上面所有的概念通过 langgraph 构建至少 20 个现实世界的复杂Agent。