LangGraph和Agents应用程序
什么是LangGraph?
LangGraph使我们能够尽可能轻松地创建具有状态的多角色应用程序,利用LargeLanguageModels(LLMs)。它扩展了LangChain的功能,引入了创建和管理循环图的能力。
当我们深入了解代理系统时,langGraph 的范围被充分利用。 代理系统利用LLMs来管理应用程序的控制流。 其关键功能是路由决策,工具选择和评估输出的充分性。 这种代理系统采用代理循环机制,其中存在一个持续的决策过程,让代理人能够解决复杂任务。 代理循环的简要回顾如下。
一个实际的用例可以用于客户支持代理的发展。
场景:一个由LLM提供支持的客户服务代理。
用户输入:顾客询问订单状态。
LLM决定:确定它是否可以直接提供状态,或者是否需要从数据库中获取数据。
采取的行动:如果需要获取数据,代理会查询数据库并向用户更新订单状态。
LLM代理的优势是:
- 代理商通过确定应采取的最佳行动来适应各种任务,提供了灵活性。
- LLM代理商擅长使用工具执行专业任务。
- LLM代理提供多代理协作,并能够执行或完成复杂任务。
主动型系统的关键组成部分:
所有这些关键组件的功能就像一个工作流程或模式,我们将所有这些组件建模成一个图形。因此,由代理构建的工作流通常被结构化为图形。
因此,LangGraph旨在构建具有一些核心原则的机构应用程序。
- 提供低级控制,增加在代理系统中的可靠性。
- 内置持久层增强人类与代理之间的交互模式。
- 支持事件和令牌的流媒体,为用户提供实时反馈。
LangGraph的基本组件是:
- 节点:Python函数,实现代理人的逻辑,将当前状态作为输入并返回一个更新后的状态。
- 边缘/条件边缘: 实现固定/条件转换的功能,以便根据当前状态确定要执行的下一个节点。
LangGraph 中的图表受... 的驱动:
- 状态:随着节点执行并沿边传递消息,共享数据结构会随时间演变。
- 消息传递:节点发送消息以激活其他节点,在离散迭代或“超级步骤”中促进工作流的执行。
现在让我们使用下面的代码进行应用程序部分。
- 导入语句:
from langgraph.graph import StateGraph, MessagesState, START, END
from pydantic import BaseModel
from langchain_openai import ChatOpenAI
from langgraph.prebuilt import ToolNode
from langchain_community.tools import TavilySearchResults
from IPython.display import Image
from dotenv import load_dotenv
导入构建基于LangGraph和LangChain的图形代理所需的必要库和模块。
- StateGraph, MessageState, START, 和 END 是 LangGraph 中用来定义对话状态和流程的类和常量。
- ChatOpenAI 是用于生成回复的LLM。
- ToolNode是一个预定义的LangGraph节点,可用于调用外部工具。
- TavilySearchResults 是一个用于执行搜索和检索结果的工具。
- Ipython.display通过使用Image和Markdown类帮助可视化图表。
- load_dotenv 从 .env 文件中加载环境变量。
2. 创建一个语言模型实例:
llm = ChatOpenAI(model='gpt-4o-mini', temperature=0)
3. 为图表定义条件逻辑:
def should_continue(state: MessagesState) -> bool:
messages = state['messages']
last_message = messages[-1]
if last_message.tool_calls:
return 'tools'
else:
return END
检查代理是否应继续移动到另一个节点,根据最后一条消息是否包含工具调用。
- 如果调用一个工具,则图形移动到工具节点。
- 如果不是,则转移到“END”节点,表示互动结束。
4. 调用LLM:
def call_model(state: MessagesState):
messages = state['messages']
response = llm.invoke(messages)
return {'messages': messages + [response]}
调用LLM根据状态中的消息生成响应。
- 获取当前状态的消息,调用LLM,并返回添加了生成响应的更新状态。
5. 创建状态图:
graph = StateGraph(MessagesState)
- 初始化一个有状态的图,该图使用MessageState来跟踪用户和代理之间交换的消息。
- Explanation: StateGraph 根据定义的逻辑管理节点和状态转换。
6. 向图中添加节点:
graph.add_node('agent', call_model)
search_tool = TavilySearchResults(max_results=5)
tools = [search_tool]
tool_node = ToolNode(tools)
graph.add_node('tools', tool_node)
- 在图中添加一个代理节点,该节点调用LLM生成回复。
- 定义一个搜索工具,从搜索引擎检索最多5个结果。
- 将工具包装在一个ToolNode内,并将其添加到图形中作为工具节点。
7. 定义图的边缘和条件过渡:
graph.add_edge(START, "agent")
graph.add_conditional_edges('agent', should_continue)
graph.add_edge('tools', 'agent')
定义图表中的对话流程。
- 开始 ➔ 代理: 对话始终从代理节点开始。
- 代理 ➔ 应继续: 在代理节点之后,使用 should_continue 检查是否要过渡到工具或结束。
- 工具 ➔ 代理:如果工具节点被激活,则在工具操作完成后,图形转换回代理。
8. 编译和可视化图表:
graph_compiled = graph.compile()
Image(graph_compiled.get_graph().draw_mermaid_png())
- 编译图表并使用mermaid.js生成可视化表示。Image函数显示可视化的图表。
- Explanation: 通过视觉帮助理解节点之间对话的流程。
9. 运行带初始输入的图表:
output = graph_compiled.invoke({'messages': [
('user', 'Write a simple report on how to use Generative AI in Healthcare Sector.')
]})
- 调用图表,使用用户初始输入要求在医疗保健领域生成AI报告。
- 说明:图表从这个输入开始,并遵循定义的节点和逻辑,以生成完整的响应。
10. 显示最终输出:
from IPython.display import Markdown
Markdown(output['messages'][-1].content)
结论:
这段代码构建了一个有状态的图形,用于管理用户和聊天机器人之间的对话流程。它使用LangGraph来定义图形结构,使用LangChain来集成LLMs和外部工具。核心逻辑涉及根据条件(是否调用了工具)在节点(代理和工具)之间进行转换,使其成为复杂的、分步的对话人工智能应用程序的强大框架。整个工作流程被可视化,最终通过一个测试查询被调用,展示了响应生成过程。