langgraph -- 从0构建ReAct agent
2026/9/24 17:55:29 网站建设 项目流程

文章目录

  • 基础介绍
  • 简单案例

基础介绍

  • 单一的LLM的只能通过提示词来生成答复内容,自身不能执行任何行为,相当于人的大脑,仅限于思考与回答问题,能力有限;
  • 单一Agent,将LLM + Tools 组合,不仅可以思考,还可以通过工具调用完成某种行为,相当于给大脑加上了手臂,可以完成稍微复杂一点的任务;
  • ReAct agent, 即 Reason and Act, 推理一步执行一步,再推理再执行流程,来完成一个目标任务;
  • pip install -U langgraph, 安装最新的版本

简单案例

importosfromlanggraph.graphimportStateGraph,MessagesState,START,ENDfromlanggraph.graph.messageimportadd_messagesfromtypingimportAnnotated,TypedDict,Listfromlangchain_core.messagesimportBaseMessage,AIMessage,HumanMessage,ToolMessagefromlangchain_openaiimportChatOpenAI# tool 装饰器fromlangchain_core.toolsimporttool,Toolfromlangchain_core.promptsimportChatPromptTemplate# 定义工具@tool(description="这是一个加法运算工具,用于完成两个数值的相加")defadd(p1,p2):""" :param p1: :param p2: :return: p1+p2 """returnp1+p2## prompt = ChatPromptTemplate.from_messages([# ("system", "你是一个数学科学家,可以帮助用户进行数学计算"),# ("user", "{question}") # 占位符字符串# ])# 创建LLM访问,并关联工具llm=ChatOpenAI(# 环境变量中需要配置调用LLM的密钥base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",model="qwen-plus",api_key=os.environ.get("OPENAI_API_KEY"),temperature=0.3,# 越大越具有创造性)tools=[add]llm_with_tools=llm.bind_tools(tools=tools)# llm_chain = prompt | llm_with_tools# agent中的状态数据classMyState(TypedDict):# 同 MessageState# 各种消息的列表# Annotated 类型注解[类型, metadata, ...]messages:Annotated[List[BaseMessage],add_messages]# 在每个节点返回字典后,langgraph底层通过metadata 更新字典# 若没有add_messages 元数据,则会直接覆盖原始数据# LLM调用,并返回数据defreason_llm(state:MyState):# state 表示状态数据messages=state["messages"]# 获取到所有的Message对象# 得到AIMessageresponse=llm_with_tools.invoke(messages)# 返回一个MyState同结构的字典或者 key子集字典return{"messages":[response]}deftool_call(state:MyState):# LLM 推理返回的文本中,只是包含了需要调用的工具名称及参数# 并不会真正的自己去调用工具, 只是将调用工具的逻辑封装了message=state["messages"][-1]ifhasattr(message,"tool_calls")andmessage.tool_calls:# 说明需要调用工具# 这里实现调用工具的逻辑# [{'name': 'add', 'args': {'p1': 3, 'p2': 5}, 'id': 'call_c1daa4d2e4d74c4f85da5e', 'type': 'tool_call'}]print("工具调用:",message.tool_calls)cur_tool=message.tool_calls[0]cur_tool_name=cur_tool.get("name")cur_tool_args=cur_tool.get("args")cur_tool_id=cur_tool.get("id")else:...# 将工具调用的结果封装为ToolMessagemessage=ToolMessage(content="tool result",tool_call_id=cur_tool_id)return{"messages":[message]}defshould_exit(state:MyState):message=state["messages"][-1]ifhasattr(message,"tool_calls")andmessage.tool_calls:return"tool"return"end"# 创建状态图graph=StateGraph(MyState)# 添加推理节点 (名称, 函数)graph.add_node("reason_llm",reason_llm)# 添加工具节点graph.add_node("tool_call",tool_call)# 添加有向边graph.add_edge(START,"reason_llm")graph.add_conditional_edges("reason_llm",should_exit,{"tool":"tool_call","end":END})graph.add_edge("tool_call","reason_llm")# 编译图graph=graph.compile()# 调用图,并传入MyState 实例result_state=graph.invoke({"messages":[("user","帮我计算3+5等于多少?")]})# 从 end 节点中输出state对象, messages属性中包含了所有的Message对象print("result:",result_state)# ipynb中可以通过Ipython查看图# from IPython.display import Image, display# display(Image(graph.get_graph().draw_mermaid()))img_bytes=graph.get_graph().draw_png()# pip install pygraphviz 绘制图片,返回字节数据withopen("ReAct-agent.png","wb")asf:f.write(img_bytes)

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询