SpringBoot+Vue+MySQL招聘系统平台设计与部署全攻略
2026/9/24 18:40:28
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)