langchain系列(九)- LangGraph 子图详解
目录
一、导读
二、原理说明
1、简介
2、子图图示
3、使用说明
三、基础代码实现
1、实现功能
2、Graph 图示
3、代码实现
4、输出
5、分析
四、人机交互
1、实现中断
2、历史状态(父图)
3、历史状态(子图)
4、历史回溯
5、整体代码
五、子图状态更改
1、修改状态
2、恢复执行
3、整体代码
4、更新节点
5、更新子图
一、导读
环境:OpenEuler、Windows 11、WSL 2、Python 3.12.3 langchain 0.3 langgraph 0.2
背景:前期忙碌的开发阶段结束,需要沉淀自己的应用知识,过一遍LangGraph
时间:20250307
说明:技术梳理,LangGraph 的多代理(多智能体)可以基于子图实现,此处对子图进行说明,案例基于官方文档进行部分的修改
官方文档地址:LangGraph 子图实现
二、原理说明
1、简介
子图允许构建具有多个组件的复杂系统,这些组件本身是图。使用子图的常见用例是构建多代理系统。子图其本质就是一个节点,只不过该节点是一个图而已。由此可知:也有孙子图、曾孙子图等
在添加子图时,主要问题是父图和子图如何进行通信,即它们如何在图执行期间相互传递状态。这里有两种情况:
父图和子图共享state。在这种情况下,您可以添加一个编译后的子图节点
父图和子图具有不同的state。在这种情况下,您必须添加一个调用子图的节点函数:当父图和子图具有不同的状态模式时,这在调用子图之前或之后需要转换状态时很有用
2、子图图示
主节点具有选择性,分别是subgraph1、subgraph2

3、使用说明
一种常见的情况是父图和子图通过共享state进行通信。例如,在多代理系统中,代理通常通过共享的state进行通信。
如果你的子图与父图共享state,你可以按照以下步骤将其添加到父图中:
定义子图工作流(如下例中的subgraph_builder)并进行编译
在定义父图工作流时,将编译后的子图传递给.add_node方法
三、基础代码实现
1、实现功能
开始节点进行意图分类,如果天气相关则走天气相关的子图;否则走智能助手节点。
2、Graph 图示

3、代码实现
from langgraph.graph import StateGraph, END, START, MessagesState
from langchain_core.tools import tool
from langchain_openai import ChatOpenAI
from typing import Literal
from langgraph.checkpoint.memory import MemorySaver@tool
def get_weather(city: str):"""获取天气信息"""return f"{city},晴空万里,阳光明媚!"# 添加记忆存储
memory = MemorySaver()# 配置信息,用于记录对话记录
config = {"configurable": {"thread_id": "1"}}# 指定大模型的API Key 等相关信息
llm = ChatOpenAI(base_url="https://lxxxxx.enovo.com/v1/", api_key="sxxxxxxxwW",model_name="qwen2.5-instruct")# 绑定工具
model = raw_model.bind_tools([get_weather])# 子图的state
class SubGraphState(MessagesState):city: str# 识别地点(城市)
def model_node(state: SubGraphState):system_message = """用户的问题是某个地方的天气问题,请辨别具体城市名称,并输出城市名称。"""messages = [{"role": "system", "content": system_message}] + state["messages"]result = raw_model.invoke(messages)return {"city": result.content}# 天气工具节点
def weather_node(state: SubGraphState):result = get_weather.invoke({"city": state["city"]})return {"messages": [{"role": "assistant", "content": result}]}# 子图的添加节点、边以及编译图
subgraph = StateGraph(SubGraphState)
subgraph.add_node(model_node)
subgraph.add_node(weather_node)
subgraph.add_edge(START, "model_node")
subgraph.add_edge("model_node", "weather_node")
subgraph.add_edge("weather_node", END)
subgraph = subgraph.compile()# 意图分类state
class RouterState(MessagesState):route: Literal["天气", "其他"]# 意图分类节点
def router_node(state: RouterState):system_message = """用户输入与天气相关则输出"天气",与天气无关返回"其他”"""messages = [{"role": "system", "content": system_message}] + state["messages"]route = raw_model.invoke(messages)return {"route": route.content}# 智能助手节点
def normal_llm_node(state: RouterState):response = raw_model.invoke(state["messages"])return {"messages": [response]}# 选择边函数
def route_after_prediction(state: RouterState):if state["route"] == "天气":return "weather_graph"else:return "normal_llm_node"# 父图的添加边、节点以及编译父图
graph = StateGraph(RouterState)
graph.add_node(router_node)
graph.add_node(normal_llm_node)
# 将子图作为一个节点添加到父图中
graph.add_node("weather_graph", subgraph)
graph.add_edge(START, "router_node")
graph.add_conditional_edges("router_node", route_after_prediction)
graph.add_edge("normal_llm_node", END)
graph.add_edge("weather_graph", END)
graph = graph.compile(checkpointer=memory)# 以流式调用图
def stream_graph_updates(user_input: str):for event in graph.stream({"messages": [{"role": "user", "content": user_input}]}, config=config, stream_mode="updates"):if event.get("router_node"):continueelse:for value in event.values():print("Assistant:", value["messages"][-1].content)# 设置聊天退出方法
while True:try:user_input = input("User: ")if user_input.lower() in ["quit", "exit", "q"]:print("Goodbye!")breakstream_graph_updates(user_input)except Exception as e:print(e)user_input = "What do you know about LangGraph?"print("User: " + user_input)stream_graph_updates(user_input)break
4、输出
User: 北京天气怎么样
Assistant: 北京,晴空万里,阳光明媚!
User: hi
Assistant: Hello! How can I assist you today?
User: 天津的天气怎么样
Assistant: 天津,晴空万里,阳光明媚!
5、分析
据上述输出可知,询问天气则会返回相关信息;其他对话内容会按照普通助手功能回复。
四、人机交互
1、实现中断
子图实现中断仅需在编译的时候添加 interrupt_before=["节点名称"],修改如下:
subgraph = subgraph.compile(interrupt_before=["weather_node"])
这样修改就会导致在weather_node发生中断,且输出值为 {'__interrupt__': ()},所以判断该dict是否存在__interrupt__即可。
调用图的地方进行判断,如下:
def stream_graph_updates(user_input: str):for event in graph.stream({"messages": [{"role": "user", "content": user_input}]}, config=config, stream_mode="updates"):if "__interrupt__" in event:print("中断")elif event.get("router_node"):continueelse:for value in event.values():print("Assistant:", value["messages"][-1].content)
循环输出内容如下:
User: 北京天气怎么样
中断
User:
2、历史状态(父图)
由于此时运行状态已经到了while True:,所以此时也不存在graph等变量信息。
所以,想要实现人机交互,需要在输出中断的地方即:print("中断"),下方执行逻辑并恢复状态
添加如下代码,来查看所有的历史节点
for h in graph.get_state_history(config=config):print(h.next)
else:print("遍历结束")
其输出信息如下:
User: 北京天气怎么样
中断
('weather_graph',)
('router_node',)
('__start__',)
遍历结束
User:
3、历史状态(子图)
显然,存在问题,由上述的Graph图示可知,该问题到达了model_node节点,但是遍历却没有。该问题是由于子图的问题。如何查询所有的遍历呢?weather_graph是子图,可以先获取子图的state,然后再遍历子图的历史记录,方法如下
# 以流式调用图
def stream_graph_updates(user_input: str):for event in graph.stream({"messages": [{"role": "user", "content": user_input}]}, config=config, stream_mode="updates"):if "__interrupt__" in event:print("中断")for h in graph.get_state_history(config): print(h.next)if h.next == ("weather_graph",):weather_graph_state = h.tasks[0].statefor h in graph.get_state_history(weather_graph_state):print(h.next)if h.next == ("model_node",):model_node_state = hprint(model_node_state.next)elif event.get("router_node"):continueelse:for value in event.values():print("Assistant:", value["messages"][-1].content)
此处代码为了遍历所有,并未将判断后就停止遍历
输出内容
User: 北京天气怎么样
中断
('weather_graph',)
('router_node',)
('__start__',)
('weather_node',)
('model_node',)
('__start__',)
('model_node',)
User:
最开始打印的是父图的节点信息,获得子图的state后,定义为weather_graph_state,之后遍历weather_graph_state的历史记录,找到指定的model_node,抵达目标历史记录定位。
4、历史回溯
实现时空穿梭,此时如果在 print(model_node_state.next)下添加stream_graph_updates(user_input),如果user_input发生变化,则按照逻辑去执行,反之实现死循环,部分代码如下:
# 以流式调用图
def stream_graph_updates(user_input: str):for event in graph.stream({"messages": [{"role": "user", "content": user_input}]}, config=config, stream_mode="updates"):if "__interrupt__" in event:print("中断")for h in graph.get_state_history(config): print(h.next)if h.next == ("weather_graph",):weather_graph_state = h.tasks[0].statefor h in graph.get_state_history(weather_graph_state):print(h.next)if h.next == ("model_node",):model_node_state = hprint(model_node_state.next)stream_graph_updates(user_input)elif event.get("router_node"):continueelse:for value in event.values():print("Assistant:", value["messages"][-1].content)
输出内容如下
User: 北京天气怎么样
中断
('weather_graph',)
('router_node',)
('__start__',)
('weather_node',)
('model_node',)
('__start__',)
('model_node',)
中断
('weather_graph',)
('router_node',)
('__start__',)
('weather_graph',)
('router_node',)
('__start__',)
('weather_node',)
('model_node',)
('__start__',)
('model_node',)
中断
('weather_graph',)
('router_node',)
('__start__',)
('weather_graph',)。。。
此处添加自己的逻辑,可以实现如果出现错误,实现自动回溯功能
5、整体代码
from langgraph.graph import StateGraph, END, START, MessagesState
from langchain_core.tools import tool
from langchain_openai import ChatOpenAI
from typing import Literal
from langgraph.checkpoint.memory import MemorySaver@tool
def get_weather(city: str):"""获取天气信息"""return f"{city},晴空万里,阳光明媚!"# 添加记忆存储
memory = MemorySaver()# 配置信息,用于记录对话记录
config = {"configurable": {"thread_id": "1"}}# 指定大模型的API Key 等相关信息
llm = ChatOpenAI(base_url="https://lxxxxx.enovo.com/v1/", api_key="sxxxxxxxwW",model_name="qwen2.5-instruct")# 绑定工具
model = raw_model.bind_tools([get_weather])# 子图的state
class SubGraphState(MessagesState):city: str# 识别地点(城市)
def model_node(state: SubGraphState):system_message = """用户的问题是某个地方的天气问题,请辨别具体城市名称,并输出城市名称。"""messages = [{"role": "system", "content": system_message}] + state["messages"]result = raw_model.invoke(messages)return {"city": result.content}# 天气工具节点
def weather_node(state: SubGraphState):result = get_weather.invoke({"city": state["city"]})return {"messages": [{"role": "assistant", "content": result}]}# 子图的添加节点、边以及编译图
subgraph = StateGraph(SubGraphState)
subgraph.add_node(model_node)
subgraph.add_node(weather_node)
subgraph.add_edge(START, "model_node")
subgraph.add_edge("model_node", "weather_node")
subgraph.add_edge("weather_node", END)
# subgraph = subgraph.compile()
subgraph = subgraph.compile(interrupt_before=["weather_node"])# 意图分类state
class RouterState(MessagesState):route: Literal["天气", "其他"]# 意图分类节点
def router_node(state: RouterState):system_message = """用户输入与天气相关则输出"天气",与天气无关返回"其他”"""messages = [{"role": "system", "content": system_message}] + state["messages"]route = raw_model.invoke(messages)return {"route": route.content}# 智能助手节点
def normal_llm_node(state: RouterState):response = raw_model.invoke(state["messages"])return {"messages": [response]}# 选择边函数
def route_after_prediction(state: RouterState):if state["route"] == "天气":return "weather_graph"else:return "normal_llm_node"# 父图的添加边、节点以及编译父图
graph = StateGraph(RouterState)
graph.add_node(router_node)
graph.add_node(normal_llm_node)
# 将子图作为一个节点添加到父图中
graph.add_node("weather_graph", subgraph)
graph.add_edge(START, "router_node")
graph.add_conditional_edges("router_node", route_after_prediction)
graph.add_edge("normal_llm_node", END)
graph.add_edge("weather_graph", END)
graph = graph.compile(checkpointer=memory)# 以流式调用图
def stream_graph_updates(user_input: str):for event in graph.stream({"messages": [{"role": "user", "content": user_input}]}, config=config, stream_mode="updates"):if "__interrupt__" in event:print("中断")for h in graph.get_state_history(config): print(h.next)if h.next == ("weather_graph",):weather_graph_state = h.tasks[0].statefor h in graph.get_state_history(weather_graph_state):print(h.next)if h.next == ("model_node",):model_node_state = hprint(model_node_state.next)stream_graph_updates(user_input)elif event.get("router_node"):continueelse:for value in event.values():print("Assistant:", value["messages"][-1].content)# 设置聊天退出方法
while True:try:user_input = input("User: ")if user_input.lower() in ["quit", "exit", "q"]:print("Goodbye!")breakstream_graph_updates(user_input)except Exception as e:print(e)user_input = "What do you know about LangGraph?"print("User: " + user_input)stream_graph_updates(user_input)break
五、子图状态更改
我会询问北京天气怎么,通过中断,将其state中的city的value修改为天津,实现该demo的功能。
此处我会将部分代码修改,因为上述代码本身为了能够清晰明了的展示其功能
1、修改状态
城市获取的节点是model_node,通过人机交互回溯到该节点,并更新该历史状态中的city信息。
获取当前状态
state = graph.get_state(config)
将city对应的value修改为 天津
graph.update_state(state.tasks[0].state, {"city": "天津"})
部分代码如下
# 以流式调用图
def stream_graph_updates(user_input: str):for event in graph.stream({"messages": [{"role": "user", "content": user_input}]}, config=config, stream_mode="updates"):if "__interrupt__" in event:print("中断")for h in graph.get_state_history(config): if h.next == ("weather_graph",):weather_graph_state = h.tasks[0].statebreakfor h in graph.get_state_history(weather_graph_state):if h.next == ("model_node",):state = graph.get_state(config)graph.update_state(state.tasks[0].state, {"city": "天津"})breakelif event.get("router_node"):continueelse:for value in event.values():print("Assistant:", value["messages"][-1].content)
该段代码实现了将第一个task的city值,修改为天津
2、恢复执行
因为此节点不需要输入信息,故而此处输入信息为None,代码如下
# 恢复执行graph
def update_city():for event in graph.stream(None, config=config, stream_mode="updates"):print(event.get("weather_graph").get("messages")[-1].content)
此函数在graph.update_state(state.tasks[0].state, {"city": "天津"})添加update_city()
graph.update_state(state.tasks[0].state, {"city": "天津"})
update_city()
3、整体代码
from langgraph.graph import StateGraph, END, START, MessagesState
from langchain_core.tools import tool
from langchain_openai import ChatOpenAI
from typing import Literal
from langgraph.checkpoint.memory import MemorySaver@tool
def get_weather(city: str):"""获取天气信息"""return f"{city},晴空万里,阳光明媚!"# 添加记忆存储
memory = MemorySaver()# 配置信息,用于记录对话记录
config = {"configurable": {"thread_id": "1"}}# 指定大模型的API Key 等相关信息
llm = ChatOpenAI(base_url="https://lxxxxx.enovo.com/v1/", api_key="sxxxxxxxwW",model_name="qwen2.5-instruct")# 绑定工具
model = raw_model.bind_tools([get_weather])# 子图的state
class SubGraphState(MessagesState):city: str# 识别地点(城市)
def model_node(state: SubGraphState):system_message = """用户的问题是某个地方的天气问题,请辨别具体城市名称,并输出城市名称。"""messages = [{"role": "system", "content": system_message}] + state["messages"]result = raw_model.invoke(messages)return {"city": result.content}# 天气工具节点
def weather_node(state: SubGraphState):result = get_weather.invoke({"city": state["city"]})return {"messages": [{"role": "assistant", "content": result}]}# 子图的添加节点、边以及编译图
subgraph = StateGraph(SubGraphState)
subgraph.add_node(model_node)
subgraph.add_node(weather_node)
subgraph.add_edge(START, "model_node")
subgraph.add_edge("model_node", "weather_node")
subgraph.add_edge("weather_node", END)
# subgraph = subgraph.compile()
subgraph = subgraph.compile(interrupt_before=["weather_node"])# 意图分类state
class RouterState(MessagesState):route: Literal["天气", "其他"]# 意图分类节点
def router_node(state: RouterState):system_message = """用户输入与天气相关则输出"天气",与天气无关返回"其他”"""messages = [{"role": "system", "content": system_message}] + state["messages"]route = raw_model.invoke(messages)return {"route": route.content}# 智能助手节点
def normal_llm_node(state: RouterState):response = raw_model.invoke(state["messages"])return {"messages": [response]}# 选择边函数
def route_after_prediction(state: RouterState):if state["route"] == "天气":return "weather_graph"else:return "normal_llm_node"# 父图的添加边、节点以及编译父图
graph = StateGraph(RouterState)
graph.add_node(router_node)
graph.add_node(normal_llm_node)
# 将子图作为一个节点添加到父图中
graph.add_node("weather_graph", subgraph)
graph.add_edge(START, "router_node")
graph.add_conditional_edges("router_node", route_after_prediction)
graph.add_edge("normal_llm_node", END)
graph.add_edge("weather_graph", END)
graph = graph.compile(checkpointer=memory)# 恢复执行graph
def update_city():for event in graph.stream(None, config=config, stream_mode="updates"):print(event.get("weather_graph").get("messages")[-1].content)# 以流式调用图
def stream_graph_updates(user_input: str):for event in graph.stream({"messages": [{"role": "user", "content": user_input}]}, config=config, stream_mode="updates"):if "__interrupt__" in event:print("中断")for h in graph.get_state_history(config): if h.next == ("weather_graph",):weather_graph_state = h.tasks[0].statebreakfor h in graph.get_state_history(weather_graph_state):if h.next == ("model_node",):state = graph.get_state(config)# state.values["city"] = "天津"graph.update_state(state.tasks[0].state, {"city": "天津"})update_city()breakelif event.get("router_node"):continueelse:for value in event.values():print("Assistant:", value["messages"][-1].content)# 设置聊天退出方法
while True:try:user_input = input("User: ")if user_input.lower() in ["quit", "exit", "q"]:print("Goodbye!")breakstream_graph_updates(user_input)except Exception as e:print(e)user_input = "What do you know about LangGraph?"print("User: " + user_input)stream_graph_updates(user_input)break
输出内容
User: 北京天气怎么样
中断
天津,晴空万里,阳光明媚!
User:
4、更新节点
指定节点,指定输出内容
只需将
graph.update_state(state.tasks[0].state, {"city": "天津"})
替换为
graph.update_state(state.tasks[0].state,{"messages": [{"role": "assistant", "content": "天津,晴空万里,阳光明媚!"}]},as_node="weather_node",
)
输出内容
User: 北京天气怎么样
中断
天津,晴空万里,阳光明媚!
User:
5、更新子图
指定子图(子图本质就是一个节点),指定输出内容
由于是针对整个子图操作,所以不再需要update_city方法,部分代码如下
for h in graph.get_state_history(weather_graph_state):if h.next == ("model_node",):graph.update_state(config,{"messages": [{"role": "assistant", "content": "天津,晴空万里,阳光明媚!"}]},as_node="weather_graph",)messages = graph.get_state(config).values["messages"]print(messages[-1].content)break
输出内容
User: 北京天气怎么样
中断
天津,晴空万里,阳光明媚!
User:
由于此处代码变化有些多,此处提供完整代码
from langgraph.graph import StateGraph, END, START, MessagesState
from langchain_core.tools import tool
from langchain_openai import ChatOpenAI
from typing import Literal
from langgraph.checkpoint.memory import MemorySaver@tool
def get_weather(city: str):"""获取天气信息"""return f"{city},晴空万里,阳光明媚!"# 添加记忆存储
memory = MemorySaver()# 配置信息,用于记录对话记录
config = {"configurable": {"thread_id": "1"}}# 指定大模型的API Key 等相关信息
llm = ChatOpenAI(base_url="https://lxxxxx.enovo.com/v1/", api_key="sxxxxxxxwW",model_name="qwen2.5-instruct")# 绑定工具
model = raw_model.bind_tools([get_weather])# 子图的state
class SubGraphState(MessagesState):city: str# 识别地点(城市)
def model_node(state: SubGraphState):system_message = """用户的问题是某个地方的天气问题,请辨别具体城市名称,并输出城市名称。"""messages = [{"role": "system", "content": system_message}] + state["messages"]result = raw_model.invoke(messages)return {"city": result.content}# 天气工具节点
def weather_node(state: SubGraphState):result = get_weather.invoke({"city": state["city"]})return {"messages": [{"role": "assistant", "content": result}]}# 子图的添加节点、边以及编译图
subgraph = StateGraph(SubGraphState)
subgraph.add_node(model_node)
subgraph.add_node(weather_node)
subgraph.add_edge(START, "model_node")
subgraph.add_edge("model_node", "weather_node")
subgraph.add_edge("weather_node", END)
# subgraph = subgraph.compile()
subgraph = subgraph.compile(interrupt_before=["weather_node"])# 意图分类state
class RouterState(MessagesState):route: Literal["天气", "其他"]# 意图分类节点
def router_node(state: RouterState):system_message = """用户输入与天气相关则输出"天气",与天气无关返回"其他”"""messages = [{"role": "system", "content": system_message}] + state["messages"]route = raw_model.invoke(messages)return {"route": route.content}# 智能助手节点
def normal_llm_node(state: RouterState):response = raw_model.invoke(state["messages"])return {"messages": [response]}# 选择边函数
def route_after_prediction(state: RouterState):if state["route"] == "天气":return "weather_graph"else:return "normal_llm_node"# 父图的添加边、节点以及编译父图
graph = StateGraph(RouterState)
graph.add_node(router_node)
graph.add_node(normal_llm_node)
# 将子图作为一个节点添加到父图中
graph.add_node("weather_graph", subgraph)
graph.add_edge(START, "router_node")
graph.add_conditional_edges("router_node", route_after_prediction)
graph.add_edge("normal_llm_node", END)
graph.add_edge("weather_graph", END)
graph = graph.compile(checkpointer=memory)# 恢复执行graph
def update_city():for event in graph.stream(None, config=config, stream_mode="updates"):print(event)print(event.get("weather_graph").get("messages")[-1].content)# 以流式调用图
def stream_graph_updates(user_input: str):for event in graph.stream({"messages": [{"role": "user", "content": user_input}]}, config=config, stream_mode="updates"):if "__interrupt__" in event:print("中断")for h in graph.get_state_history(config): if h.next == ("weather_graph",):weather_graph_state = h.tasks[0].statebreakfor h in graph.get_state_history(weather_graph_state):if h.next == ("model_node",):graph.update_state(config,{"messages": [{"role": "assistant", "content": "天津,晴空万里,阳光明媚!"}]},as_node="weather_graph",)messages = graph.get_state(config).values["messages"]print(messages[-1].content)breakelif event.get("router_node"):continueelse:for value in event.values():print("Assistant:", value["messages"][-1].content)# 设置聊天退出方法
while True:try:user_input = input("User: ")if user_input.lower() in ["quit", "exit", "q"]:print("Goodbye!")breakstream_graph_updates(user_input)except Exception as e:print(e)user_input = "What do you know about LangGraph?"print("User: " + user_input)stream_graph_updates(user_input)break
六、综述
1、子图是父图的节点,可是孙图绝不是父图的节点
2、愚公移山 :子子孙孙,无穷尽也
3、子图的使用基本是在多智能体中使用
4、通信尽量使用state,避免函数调用
相关文章:
langchain系列(九)- LangGraph 子图详解
目录 一、导读 二、原理说明 1、简介 2、子图图示 3、使用说明 三、基础代码实现 1、实现功能 2、Graph 图示 3、代码实现 4、输出 5、分析 四、人机交互 1、实现中断 2、历史状态(父图) 3、历史状态(子图) 4、历史…...
搜索引擎是如何理解你的查询并提供精准结果的?
目录 一、搜索引擎简单介绍 二、搜索引擎整体架构和工作过程 (一)整体分析 (二)爬虫系统 三个基本点 爬虫系统的工作流程 关键考虑因素和挑战 (三)索引系统 网页处理阶段 预处理阶段 反作弊分析…...
【前端】【组件】【vue2】封装一个vue2的ECharts组件,不用借助vue-echarts
在Vue2项目中使用ECharts 5.6的完整实现步骤如下: 安装依赖 npm install echarts5.6.2 --save # 指定安装5.x最新版本基础组件实现(新建components/ECharts.vue) <template><div ref"chartDom" class"echarts-co…...
18天 - 常见的 HTTP 状态码有哪些?HTTP 请求包含哪些内容,请求头和请求体有哪些类型?HTTP 中 GET 和 POST 的区别是什么?
常见的 HTTP 状态码有哪些? HTTP 状态码用于指示服务器对客户端请求的响应结果,常见的 HTTP 状态码可以分为以下几类: 1. 信息类(1xx) 100 Continue:客户端应继续发送请求。101 Switching Protocols&…...
IDEA软件安装环境配置中文插件
一、Java环境配置 1. JDK安装8 访问Oracle官网下载JDK8(推荐JDK8,11)Java Downloads | Oracle 双击安装程序,保持默认设置连续点击"下一步"完成安装 验证JDK安装,winR键 然后输入cmd,输入java…...
循环神经网络(RNN):时序建模的核心引擎与演进之路
在人工智能处理序列数据的战场上,循环神经网络(RNN)如同一个能够理解时间的智者。从 2015 年谷歌神经机器翻译系统颠覆传统方法,到 2023 年 ChatGPT 实现对话连续性,这些突破都植根于 RNN 对时序建模的深刻理解。本文将…...
HTML 表单 (form) 的作用解释
表单在网页中主要负责的是数据采集功能,一个表单基本由三部分组成: 表单标签:这里面包含了处理表单数据所用 CGI (Common Gateway Interface,通用网关接口)程序的 URL (Uniform Resource Locati…...
Windows控制台函数:控制台读取输入函数ReadConsoleA()
目录 什么是 ReadConsoleA? 它长什么样? 怎么用它? 它跟 std::cin 有什么不一样? 注意事项 什么是 ReadConsoleA? ReadConsoleA 是一个 Windows API 函数,用来从控制台读取用户输入。想象一下&#…...
网络tcp协议设置,网络tcp协议设置不了
网络TCP协议的设置通常涉及到多个方面,包括IP地址、子网掩码、默认网关、DNS服务器等参数的配置,以及TCP/IP协议栈本身的配置。如果遇到网络TCP协议设置不了的问题,可能是由多种原因导致的。以下是一些可能的原因及解决方法: 一、…...
电脑总显示串口正在被占用处理方法
1.现象 在嵌入式开发过程中,有很多情况下要使用串口调试,其中485/422/232转usb串口是非常常见的做法。 根据协议,接口芯片不同,需要安装对应的驱动程序,比如ch340,cp2102,CDM212364等驱动。可…...
R语言和RStudio安装
整体还是比较简单的,主要是记录个流程。 官方镜像站列表R语言官网 1 安装R(2025/3/6) R语言官网:The R Project for Statistical Computing 打开之后就Hello world一下吧 配置环境变量 2 安装RStudio 下载地址:htt…...
RHEL/CentOS 7.9使用firewalld限制出方向策略
背景 通常使用firewalld时候多为限制入方向访问,本次因有系统需要在生产环境部署测试环境,需求人希望在该测试环境中限制访问的对象,避免对生产造成影响 基础团队小伙伴参照rich-files,通过CLI,GUI反复进行进行配置验…...
设计模式之建造者模式:原理、实现与应用
引言 建造者模式(Builder Pattern)是一种创建型设计模式,它通过将复杂对象的构建过程分解为多个简单的步骤,使得对象的创建更加灵活和可维护。建造者模式特别适用于构建具有多个组成部分的复杂对象。本文将深入探讨建造者模式的原…...
1688店铺所有商品数据接口详解
一、接口概述淘宝开放平台提供 1688.items.onsale.get/taobao.item_search_shop 接口,可批量获取店铺在售商品列表,包含商品 ID、标题、价格、销量、图片等核心信息。该接口适用于商品库管理、竞品监控、数据分析等场景 二、接口调用流程 前期准…...
【C#学习笔记02】基本元素与数据类型
引言 深入了解C语言的基本元素、计算机存储器结构、常量与变量的概念以及数据类型。这些内容是C语言编程的基础,掌握它们对于编写高效、可靠的嵌入式程序至关重要。 1.C语言的基本元素 编程语言的发展离不开自然语言,所以编程语言的语法和词汇也是由…...
【语料数据爬虫】Python爬虫|批量采集工作报告数据(1)
前言 本文是该专栏的第4篇,后面会持续分享Python爬虫采集各种语料数据的的干货知识,值得关注。 在本文中,笔者将主要来介绍基于Python,来实现批量采集“工作报告”数据。同时,本文也是采集“工作报告”数据系列的第1篇。 采集相关数据的具体细节部分以及详细思路逻辑,笔…...
<建模软件安装教程1>Blender4.2系列
Blender4.2安装教程 0注意:Windows环境下安装 第一步,百度网盘提取安装包。百度网盘链接:通过网盘分享的文件:blender.zip 链接: https://pan.baidu.com/s/1OG0jMMtN0qWDSQ6z_rE-9w 提取码: 0309 --来自百度网盘超级会员v3的分…...
Docker极简部署开源播放器Splayer结合内网穿透远程流畅在线听歌
前言 嘿,各位音乐发烧友们!如果你厌倦了广告的打扰,渴望在忙碌的生活中找到一片宁静的音乐天地,那么今天这篇教程绝对适合你——如何在Ubuntu上用Docker快速搭建一款高颜值、无广告的某抑云音乐播放器Splayer。 Splayer不仅界面…...
基于YOLO(以YOLOv8为例)模型开发算法的详细步骤,包含算法代码、训练指导、数据集准备以及可能的改进方向
以下是一个基于YOLO(以YOLOv8为例)模型开发算法的详细步骤,包含算法代码、训练指导、数据集准备以及可能的改进方向。 1. 环境准备 首先,你需要安装必要的库。可以使用以下命令创建一个新的虚拟环境并安装所需的库: …...
显示器长时间黑屏
现象 电脑启动后,进入登录界面前会随机黑屏,有时候十几秒,有时候几分钟 进入桌面后,长时间不操作电脑黑屏,移动鼠标,点击键盘后尝试点亮屏幕,也会消耗较长时间 尝试 重装系统,或者重新安装显卡,都能够恢复,但过段时间以后又出现黑屏情况 集成显卡,独立显卡都出现过 操作系统…...
linux docker相关指令
1、镜像操作 0)、搜索:docker search 镜像名称 1)、拉取:docker pull 2)、推送:docker push 3)、查看:docker images 4)、查看所有镜像ID:d…...
V8引擎中的垃圾回收机制如何工作?
V8引擎中的垃圾回收机制主要通过分代回收和增量标记清除算法来管理内存。以下是其工作原理的详细说明: V8 的垃圾回收机制基于以下核心设计原则: 1. 分代假设:大多数对象的生命周期很短,只有少数对象会存活较长时间;…...
内网安全-横向移动PTH 哈希PTT 票据PTK 密匙Kerberos密码喷射
一.域横向pth,mimkatz,NTLM windwos server 2012 R2之前可能是NTLM和LM,之后为NTLM 1.mimkatz ptk 使用mimkatz进行横向移动 mimikatz sekurlsa::pth /user:administrator(目标本地用户名) /domain:192.168.3.32&a…...
自然语言处理文本分析:从词袋模型到认知智能的进化之旅
清晨,当智能音箱准确识别出"播放周杰伦最新专辑"的模糊语音指令时;午间,企业舆情系统自动标记出十万条评论中的负面情绪;深夜,科研人员用GPT-4解析百万篇论文发现新材料线索——这些场景背后,是自…...
洛谷 P2234:[HNOI2002] 营业额统计 ← STL set
【题目来源】 https://www.luogu.com.cn/problem/P2234 【题目描述】 Tiger 最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况。 Tiger 拿出了公司的账本,账本上记录了公司成立以来每天的营业额。分析…...
linux---天气爬虫
代码概述 这段代码实现了一个天气查询系统,支持实时天气、未来天气和历史天气查询。用户可以通过终端菜单选择查询类型,并输入城市名称来获取相应的天气信息。程序通过 TCP 连接发送 HTTP 请求,并解析返回的 JSON 数据来展示天气信息。 #in…...
STM32如何精准控制步进电机?
在工业自动化、机器人控制等场合,步进电机以其高精度、开环控制的特性得到了广泛应用。而在嵌入式系统中,使用STM32进行步进电机的精确控制,已成为开发者的首选方案之一。 本文将从嵌入式开发者的角度,深入探讨如何基于STM32 MCU…...
C语言:确定进制
题目: 6942对于十进制来说是错误的,但是对于13进制来说是正确的。即, 6(13) 9(13) 42(13), 而 42(13)4131213054(10)。 任务是写一段程序,读入三个整数p、q和 r,然后确定一个进制 B(2<B<40) 使得 p q r。 如果…...
[免费]微信小程序(图书馆)自习室座位预约管理系统(SpringBoot后端+Vue管理端)(高级版)【论文+源码+SQL脚本】
大家好,我是java1234_小锋老师,看到一个不错的微信小程序(图书馆)自习室座位预约管理系统(SpringBoot后端Vue管理端)(高级版),分享下哈。 项目视频演示 【免费】微信小程序(图书馆)自习室座位预约管理系统(SpringBoot后端Vue管理端)(高级版…...
STM32 Bootloader理解
STM32 Bootloader个人理解 stm32单片机启动时会先运行一个引导程序Bootloader,该程序可以判断单片机的启动方式,例如stm32f103单片机会利用 boot0 、boot1 两个引脚判断启动模式。判断完启动模式后,设置 SP地址 以及 PC 指针指向对应的地址。…...
