AI知识库

53AI知识库

学习大模型的前沿技术与行业应用场景


基于LangGraph构建LLM Agent
发布日期:2024-09-18 18:12:47 浏览次数: 1824 来源:大模型之路



在人工智能(AI)快速发展的今天,检索增强生成(RAG)系统(LLM Agent应用场景:Agentic RAG)已成为处理简单查询和生成上下文相关响应的常用工具。然而,随着对更复杂AI应用需求的日益增长,开发能够执行复杂多步骤任务、跨交互维持状态并动态适应新信息的系统变得尤为重要。

LangGraph,作为LangChain库的一个强大扩展,正是为解决这一挑战而生。它支持构建具有状态管理和循环计算能力的高级LLM Agent(探索新一代大模型代理(LLM agent)及其架构),让开发者能够创建智能、适应性强且适用于现实世界的AI系统。本文将深入探讨LangGraph如何变革AI开发,并通过一个计算太阳能板节能潜力的AI代理示例,展示其独特功能和应用价值。


LangGraph 简介

LangGraph通过无缝管理图结构、状态和协调,重新定义了AI开发,为创建复杂多参与者应用程序提供了强大支持。自动状态管理确保在交互之间保持上下文,使AI能够智能地响应不断变化的输入。此外,其高效的代理协调机制保证了精确的执行和高效的信息交换,让开发者能够专注于创新工作流程的设计,而不是技术复杂性。其核心由三个关键组件构成:节点(Nodes)、状态(State)和边(Edges)。


节点(Nodes)

节点是图的基本构建块,代表独立的计算步骤或函数。每个节点执行特定任务,如处理输入、做出决策或与外部系统交互。LangGraph支持高度定制化的节点,使得开发者能够根据需要执行广泛的操作。

状态(State)

状态代表了随着计算进行而维护和更新的上下文或记忆。它确保了图中的每个步骤都能访问来自前一步骤的相关信息,从而支持基于累积数据的动态决策制定。这种机制是构建具有长期记忆和复杂行为LLM Agent的关键。

边(Edges)

边连接图中的节点,定义了计算从一个步骤到下一个步骤的流动。它们支持条件逻辑,允许根据当前状态和数据改变执行路径,促进数据和控制流在节点之间的传递,从而支持复杂的多步骤工作流程。

LangGraph 的优势

  1. 自动状态管理:确保跨交互的上下文得以保存,使 AI 能够智能地响应变化的输入。

  2. 流畅的代理协调:保证精确执行和高效的信息交换,让开发者专注于创新工作流程而非技术细节。

  3. 灵活性和可扩展性:支持定制化的高性能应用开发,同时保持系统的健壮性和可靠性,即使在企业级应用中也表现优异。

利用LangGraph构建LLM Agent

接下来,我们将通过一个具体的例子——计算太阳能板节能的LLM Agent,来展示如何使用LangGraph。这个AI代理可以作为太阳能板销售商网站上的潜在客户开发工具,通过提供个性化的节能估算来吸引潜在客户,并帮助销售团队进行后续跟进。

步骤 1: 导入必要的库

首先,需要导入构建AI助理所需的Python库和模块:

from langchain_core.tools import toolfrom langchain_community.tools.tavily_search import TavilySearchResultsfrom langchain_core.prompts import ChatPromptTemplatefrom langchain_core.runnables import Runnablefrom langchain_aws import ChatBedrockimport boto3from typing import Annotatedfrom typing_extensions import TypedDictfrom langgraph.graph.message import AnyMessage, add_messagesfrom langchain_core.messages import ToolMessagefrom langchain_core.runnables import RunnableLambdafrom langgraph.prebuilt import ToolNode
步骤 2: 定义节能计算工具

在构建LLM Agent之前,需要定义Agent将使用的工具。这些工具可以是任何能够执行特定任务的函数或类。例如,在太阳能面板节能计算的场景中,可以定义一个compute_savings工具,该工具根据用户的月度电费计算潜在的节能收益。

@tooldef compute_savings(monthly_cost: float) -> float:"""Tool to compute the potential savings when switching to solar energy based on the user's monthly electricity cost.Args:monthly_cost (float): The user's current monthly electricity cost.Returns:dict: A dictionary containing:- 'number_of_panels': The estimated number of solar panels required.- 'installation_cost': The estimated installation cost.- 'net_savings_10_years': The net savings over 10 years after installation costs."""def calculate_solar_savings(monthly_cost):# Assumptions for the calculationcost_per_kWh = 0.28cost_per_watt = 1.50sunlight_hours_per_day = 3.5panel_wattage = 350system_lifetime_years = 10
# Monthly electricity consumption in kWhmonthly_consumption_kWh = monthly_cost / cost_per_kWh# Required system size in kWdaily_energy_production = monthly_consumption_kWh / 30system_size_kW = daily_energy_production / sunlight_hours_per_day# Number of panels and installation costnumber_of_panels = system_size_kW * 1000 / panel_wattageinstallation_cost = system_size_kW * 1000 * cost_per_watt# Annual and net savingsannual_savings = monthly_cost * 12total_savings_10_years = annual_savings * system_lifetime_yearsnet_savings = total_savings_10_years - installation_costreturn {"number_of_panels": round(number_of_panels),"installation_cost": round(installation_cost, 2),"net_savings_10_years": round(net_savings, 2)}
# Return calculated solar savingsreturn calculate_solar_savings(monthly_cost)
步骤 3: 设置状态管理和错误处理

有效的状态管理是构建健壮AI系统的关键。在LangGraph中,状态通常被定义为一个包含消息列表的字典,这些消息记录了用户输入、Agent输出以及工具调用的结果。使用Python的TypedDict可以帮助定义状态的结构,确保类型安全。

def handle_tool_error(state) -> dict:"""Function to handle errors that occur during tool execution.Args:state (dict): The current state of the AI agent, which includes messages and tool call details.Returns:dict: A dictionary containing error messages for each tool that encountered an issue."""# Retrieve the error from the current stateerror = state.get("error")# Access the tool calls from the last message in the state's message historytool_calls = state["messages"][-1].tool_calls# Return a list of ToolMessages with error details, linked to each tool call IDreturn {"messages": [ToolMessage(content=f"Error: {repr(error)}\n please fix your mistakes.",# Format the error message for the usertool_call_id=tc["id"],# Associate the error message with the corresponding tool call ID)for tc in tool_calls# Iterate over each tool call to produce individual error messages]}
def create_tool_node_with_fallback(tools: list) -> dict:"""Function to create a tool node with fallback error handling.Args:tools (list): A list of tools to be included in the node.Returns:dict: A tool node that uses fallback behavior in case of errors."""# Create a ToolNode with the provided tools and attach a fallback mechanism# If an error occurs, it will invoke the handle_tool_error function to manage the errorreturn ToolNode(tools).with_fallbacks([RunnableLambda(handle_tool_error)],# Use a lambda function to wrap the error handlerexception_key="error"# Specify that this fallback is for handling errors)

步骤 4: 定义状态和助理类

创建State类和Assistant类,分别用于管理对话的上下文和执行LLM Agent的逻辑。

class State(TypedDict):messages: Annotated[list[AnyMessage], add_messages]
class Assistant:def __init__(self, runnable: Runnable):# Initialize with the runnable that defines the process for interacting with the toolsself.runnable = runnable
def __call__(self, state: State):while True:# Invoke the runnable with the current state (messages and context)result = self.runnable.invoke(state)# If the tool fails to return valid output, re-prompt the user to clarify or retryif not result.tool_calls and (not result.contentor isinstance(result.content, list)and not result.content[0].get("text")):# Add a message to request a valid responsemessages = state["messages"] + [("user", "Respond with a real output.")]state = {**state, "messages": messages}else:# Break the loop when valid output is obtainedbreak
# Return the final state after processing the runnablereturn {"messages": result}

步骤 5: 设置大型语言模型(LLM)

LLM(大模型哪个好用?)是Agent的“大脑”,负责理解用户输入并生成响应。可以使用AWS Bedrock或其他LLM服务来配置LLM。配置过程包括设置模型ID、客户端参数等,以确保Agent能够访问LLM并与之交互。

def get_bedrock_client(region):return boto3.client("bedrock-runtime", region_name=region)
def create_bedrock_llm(client):return ChatBedrock(model_id='anthropic.claude-3-sonnet-20240229-v1:0', client=client, model_kwargs={'temperature': 0}, region_name='us-east-1')
llm = create_bedrock_llm(get_bedrock_client(region='us-east-1'))

步骤 6: 定义助理的工作流程

工作流程定义了LLM Agent如何与用户交互,何时调用工具,以及如何响应用户输入。这通常通过创建一个包含系统消息和占位符的提示模板来实现。系统消息为Agent提供了指导,而占位符则允许动态插入对话中的消息,这里使用ChatPromptTemplate定义对话模板,并将计算节能的工具绑定到工作流中。

primary_assistant_prompt = ChatPromptTemplate.from_messages([("system",'''You are a helpful customer support assistant for Solar Panels Belgium.You should get the following information from them:- monthly electricity costIf you are not able to discern this info, ask them to clarify! Do not attempt to wildly guess.
After you are able to discern all the information, call the relevant tool.''',),("placeholder", "{messages}"),])

步骤 7: 构建图结构

LangGraph使用图结构来描述和编排Agent的控制流。在图结构中,节点代表操作(如调用Assistant或工具),边代表这些操作之间的连接。使用LangGraph的API可以创建节点、添加边,并定义条件边以处理不同的执行路径。

builder = StateGraph(State)builder.add_node("assistant", Assistant(part_1_assistant_runnable))builder.add_node("tools", create_tool_node_with_fallback(part_1_tools))builder.add_edge(START, "assistant")# Start with the assistantbuilder.add_conditional_edges("assistant", tools_condition)# Move to tools after inputbuilder.add_edge("tools", "assistant")# Return to assistant after tool executio
memory = MemorySaver()graph = builder.compile(checkpointer=memory)

步骤 8: 运行示例对话

模拟一个用户与AI助理的对话,以验证整个系统的有效性和功能性。

# import shutilimport uuid
# Let's create an example conversation a user might have with the assistanttutorial_questions = ['hey','can you calculate my energy saving',"my montly cost is $100, what will i save"]
# Update with the backup file so we can restart from the original place in each section# shutil.copy(backup_file, db)thread_id = str(uuid.uuid4())
config = {"configurable": {# The passenger_id is used in our flight tools to# fetch the user's flight information# "passenger_id": "3442 587242",# Checkpoints are accessed by thread_id"thread_id": thread_id,}}
_printed = set()for question in tutorial_questions:events = graph.stream({"messages": ("user", question)}, config, stream_mode="values")for event in events:_print_event(event, _printed)


通过上述步骤,我们成功构建了一个基于LangGraphLLM Agent,用于计算太阳能板的节能效益。这一过程展示了LangGraph在处理复杂、多步骤流程中的强大能力,也说明了如何通过结合先进的AI工具和灵活的图形结构来快速构建高度定制化的智能系统。LangGraph为AI开发者提供了一个强大的平台,帮助他们在各个行业中实现高效、智能的自动化解决方案。


53AI,企业落地应用大模型首选服务商

产品:大模型应用平台+智能体定制开发+落地咨询服务

承诺:先做场景POC验证,看到效果再签署服务协议。零风险落地应用大模型,已交付160+中大型企业

联系我们

售前咨询
186 6662 7370
预约演示
185 8882 0121

微信扫码

与创始人交个朋友

回到顶部

 
扫码咨询