当前位置: 首页 > article >正文

[LangChain智能体本质论-01]两种视角看待Agent和ReAct循环

作为LangChain智能体的Agent采用一种被称为ReAct循环的执行流程如下图所示这是一种结合了“推理”Reasoning与“行动”Acting的交互模式旨在让Agent能像人类一样通过逻辑思考来解决复杂问题。但是从底层的执行方式来看Agent本质上是一个Pregel对象(我的系列文章“拆解LangChain执行引擎”对Pregel具有系统的介绍)是一个通过节点和通道构建的Actor模型那么两者是如何结合在一起的我希望通过这个系列文章回答这个问题。除此之外这个序列还将深入介绍Agent状态读写、结构化输出、工具和中间的设计和实现。1. 从create_agent工厂函数说起LangChain提供了不同的编程模式创建Agent其中最简单的莫过于直接使用create_agent函数所以我们不妨先来看看该函数的定义。如下面的代码片段所示这个工厂函数创建的Agent体现为一个CompiledStateGraph对象它本质上是一个Pregel对象所以此函数提供的很多参数旨在初始化这个Pregel对象。defcreate_agent(model:str|BaseChatModel,tools:Sequence[BaseTool|Callable[...,Any]|dict[str,Any]]|NoneNone,*,system_prompt:str|SystemMessage|NoneNone,middleware:Sequence[AgentMiddleware[StateT_co,ContextT]](),response_format:ResponseFormat[ResponseT]|type[ResponseT]|dict[str,Any]|NoneNone,state_schema:type[AgentState[ResponseT]]|NoneNone,context_schema:type[ContextT]|NoneNone,checkpointer:Checkpointer|NoneNone,store:BaseStore|NoneNone,interrupt_before:list[str]|NoneNone,interrupt_after:list[str]|NoneNone,debug:boolFalse,name:str|NoneNone,cache:BaseCache[Any]|NoneNone,)-CompiledStateGraph[AgentState[ResponseT],ContextT,_InputAgentState,_OutputAgentState[ResponseT]]我们有必要逐个介绍一下每个参数model智能体的“大脑”。可以传模型名称字符串需环境配置或已实例化的 BaseChatModel如 ChatOpenAI。tools赋予Agent的“工具箱”。支持 BaseTool对象、普通Python函数会自动转为工具或描述工具JSON Schema的字典。system_prompt: 定义Agent的角色、行为准则和背景知识。支持纯字符串或预定义的SystemMessage对象。response_format: 强制结构化输出。可以传入Pydantic模型、JSON Schema 或 ResponseFormat对象确保Agent返回的数据符合特定格式常用于数据提取或接口调用。state_schema: 定义Agent的内部状态结构继承自 AgentState。它决定了Agent运行过程中能“记住”哪些信息如历史对话、工具执行中间结果。context_schema: 定义外部上下文结构。与状态不同上下文通常是运行时传入的只读配置或全局信息如 user_id, session_id。middleware: 插件系统。允许在 Agent 运行前后插入自定义逻辑如日志记录、输入过滤、耗时统计。checkpointer: 持久化层。用于保存图的状态快照实现断点续传、多轮对话记忆以及“时间旅行”回溯到某一步骤。store: 长效存储。用于在不同线程或用户之间共享信息如存储用户的长期偏好不随单次对话结束而消失。cache: 缓存机制。减少模型重复调用的开销提高响应速度并节省 Token。interrupt_before/interrupt_after: 人机交互点。在进入或退出指定节点前挂起执行。这通常用于“人在回路Human-in-the-loop”场景需用户审批后再继续。debug: 开启后会打印每一轮迭代的详细状态变化和节点执行信息。name: 为生成的 Agent 图命名方便在多 Agent 协同系统Multi-agent system中进行追踪和引用。一个Agent由最为核心的Model和Tool组成所以这三个对象交互的视角来看待Agent基于ReAct循环的执行流程是最直接的。2. 以Agent、Mode和Tool三者交互视角看待ReAct循环ReAct是一个循环往复的过程直到模型得出最终答案或达到最大尝试次数。其核心逻辑可拆解为以下四个步骤Thought推理LLM 接收到用户问题及当前上下文分析当前所处的阶段并决定下一步需要采取什么行动。Action行动模型根据推理结果发出指令调用特定的工具。这包括从工具库中提取参数并向外部环境发送请求。Observation观察LangChain 接收工具返回的真实数据如网页搜索结果、数据库查询值或代码运行输出并将其反馈给模型。Loop循环模型根据新的“观察”结果再次进行“推理”。如果信息足够则输出最终答案如果信息仍不足则继续开启下一轮 Thought - Action - Observation。我们可以从一个简单的实例来体验一下LangChain的ReAct循环。这是一个经典的利用Agent获取天气信息的例子如代码片段所示我们定义了一个get_weather函数作为Agent的工具该函数根据指定的城市通过city参数表示得到以文本表示的天气信息。函数的docstring给出了基本的描述Agent将会提取此信息作为工具描述。我们创建一个Agent并初始化了通过model、tools和system_prompt字段表示的模型、注册的工具列表和系统提示符。fromlangchain.agentsimportcreate_agentfromdotenvimportload_dotenvfromlangchain_openaiimportChatOpenAIfromlangchain_core.messagesimportHumanMessage load_dotenv()defget_weather(city:str)-str:Get weather for a given city.returnfIts always sunny in{city}!agentcreate_agent(modelChatOpenAI(modelgpt-5.2-chat),tools[get_weather],system_promptYou are a helpful assistant,)messageHumanMessage(contentWhat is the weather in Suzhou?)forstepinagent.stream(input{messages:[message]},stream_modevalues):step[messages][-1].pretty_print()具体的模型是基于“gpt-5.2-chat”创建的ChatOpenAI相关的设置比如api-key和base-url等定义在.env文件通过dotenv.load_dotenv写入环境变量。我们直接将函数get_weather作为工具添加到注册的列表中。通过create_agent函数创建的Agent默认以表示状态的AgentState作为输入这是一个TypedDict其核心成员“messages”用于存储整个Agent执行过程中生成的消息。所以我们创建了这样的字典作为调用Agent的输入并在其messages列表中添加了一个用于查询天气的HumanMessage对象。我们调用Agent的stream方法并将流模式设置为“values”执行流程中的每个步骤对于Pregel的Superstep结束之后会以流的形式输出所有的状态这里我们将每个步骤维护的消息列表中的最后一条消息的内容打印出来。 Human Message What is the weather in Suzhou? Ai Message Tool Calls: get_weather (call_aCcssiCPOFyJa6dfu2dSltqD) Call ID: call_aCcssiCPOFyJa6dfu2dSltqD Args: city: Suzhou Tool Message Name: get_weather Its always sunny in Suzhou! Ai Message Right now, the weather in **Suzhou** is reported as **sunny** ☀️. If you’d like, I can also help with things like the temperature, forecast for the next few days, or weather in a specific Suzhou (there’s one in Jiangsu, China, and another in Anhui).这个例子涉及的ReAct循环体现在如上的输出中首先我们以HumanMessage的形式向模型提供查询模型经过推理确定这是“天气查询”并且自身绑定的工具列表具有一个与之匹配的工具get_weather所以模型认为完成当前任务需要先调用get_weather工具。模型不会自行调用工具服务端工具除外但是它需要将工具调用意图封装成一个TooCall对象该对象承载的信息包括包括工具的名称get_weather、标识工具调用的IDcall_aCcssiCPOFyJa6dfu2dSltqD参数列表city: Suzhou。这样一个ToolCall对象被封装成AIMessage返回给Agent。Agent接收到AIMessage之后从中提取出ToolCall提供的参数对目标工具发起调用并将结果“It’s always sunny in Suzhou!”封装成ToolMessage再次发送给模型。模型经过推理确定能够对查询做出最终的答复了于是组织文本并组织文本并以AIMessage的形式予以回复。messageHumanMessage(contentWhat is the weather in Suzhou?)resultagent.invoke(input{messages:[message]})formessageinresult[messages]:message.pretty_print()如果不使用流式输出我们也可用按照如上方式调用Agent的invoke方法并从作为结果的字典中利用“messages”作为Key得到整个“交谈”过程中生成的消息。上面这段程序也可以得到类似的输出: Human Message What is the weather in Suzhou? Ai Message Tool Calls: get_weather (call_CIUcZcYEGEbI0IJlDs19RhTd) Call ID: call_CIUcZcYEGEbI0IJlDs19RhTd Args: city: Suzhou Tool Message Name: get_weather Its always sunny in Suzhou! Ai Message The weather in Suzhou is sunny ☀️3. 以Pregel的视角看到Agent和ReAct循环既然Agent是一个Pregel对象这是一个由节点和通道构建的Actor模型我们不免会好奇它由哪些节点和通道构成呢每个通道采用何种类型通道和节点之间的订阅和读写关系是什么样子我们为此编写了如下的演示程序将上面创建的Agent作为一个Pregel对象将其所有的通道及其类型、节点包括名称、输入和驱动Channel以及Pregel对象自身的输入/输出通道以及驱动通道与对应节点的映射关系打印出来。fromlangchain.agentsimportcreate_agentfromdotenvimportload_dotenvfromlangchain_openaiimportChatOpenAIfromPILimportImageasPILImageimportio load_dotenv()defget_weather(city:str)-str:Get weather for a given city.returnfIts always sunny in{city}!agentcreate_agent(modelChatOpenAI(modelgpt-5.2-chat),tools[get_weather],system_promptYou are a helpful assistant,)print(channels:)for(name,chan)inagent.channels.items():print(f\t[{chan.__class__.__name__}]{name})print(nodes:)for(name,node)inagent.nodes.items():print(f\tname:{name})print(f\tchannels:{node.channels})print(f\ttriggers:{node.triggers}\n)print(finput_channels:{agent.input_channels})print(foutput_channels{agent.output_channels})print(trigger_to_nodes)for(name,nodes)inagent.trigger_to_nodes.items():print(f\t{name}:{nodes})payloadagent.get_graph(xrayTrue).draw_mermaid_png()PILImage.open(io.BytesIO(payload)).show()从如下的输出可以看出通过create_agent函数创建的Agent有且只有三个节点前提是没有注册中间件分别是作为启动节点的节点“start”、封装模型和工具的节点model和节点tools。也就是说注册的所有工具都封装在同一个节点tools中并由它管理并选择执行。channels: [BinaryOperatorAggregate]messages [EphemeralValue]jump_to [LastValue]structured_response [EphemeralValue]__start__ [Topic]__pregel_tasks [EphemeralValue]branch:to:model [EphemeralValue]branch:to:tools nodes: name: __start__ channels: __start__ triggers: [__start__] name: model channels: [messages, jump_to, structured_response] triggers: [branch:to:model] name: tools channels: [messages, jump_to, structured_response] triggers: [branch:to:tools] input_channels:__start__ output_channels[messages, structured_response] trigger_to_nodes __start__: [__start__] branch:to:model: [model] branch:to:tools: [tools]再来看看Agent的通道列表。三个节点具有对应的触发通道它们的名称分别是“start”、“branch:to:model”和“branch:to:tools”对应的类型均为EphemeralValue。针对Agent的调用实际上就是通过写入“start”驱动Agent从“start”节点开始执行。model节点完成模型调用后如果需要调用工具就写入“branch:to:tools”工具调用之后通过写入“branch:to:model”将工具执行的结果反馈给模型并驱动模型节点执行。model和tools节点具有相同的输入通道分别是承载消息列表的messages、用于跳转的jump_to和表示结构化输出的structured_response。messages通道的类型为BinaryOperatorAggregate其operator用于执行列表添加操作这意味着针对此通道的更新总是在做“消息追加”操作这样会将所有的消息历史保存下来上面演示的实例也证明了这一点。工具或者中间件可以通过写入jump_to通道实现“跳转”。该通道支持三个选项“model”、“tools”和“end”前两个选项实现针对model和tools节点的跳转“end”用于终止整个处理流程。结构化输出最终写入通道structured_response。演示程序的最后两行代码会将Agent的结构以可视化的形式展现出来具体呈现的结构如下所示。如果我们站在Pregel的视角审视ReAct循环将会更加接近真实的执行流程当我们调用Agent对象时指定的HumanMessage会写入messages通道中;作为入口节点model节点将其读取出来之后与绑定的系统消息通过system_prompt参数指定的系统提示词创建和工具列表一并发送给语言模型。对于我们的例子来说就是调用OpenAI API具体的请求如下所示。{messages:[{content:You are a helpful assistant,role:system},{content:What is the weather in Suzhou?,role:user}],model:gpt-5.2-chat,stream:false,tools:[{type:function,function:{name:get_weather,description:Get weather for a given city.,parameters:{properties:{city:{type:string}},required:[city],type:object}}}]}LLM经过推理决定需要调用工具并将针对工具调用的描述置于响应中。从如下所示的响应内容可以看出针对工具get_weather的调用被置于响应的choicestool_calls节点(包括调用工具的名称标识工具调用的ID和参数列表。model节点将接收到的响应内容封装成AIMessage并写入messages通道。通过分析内容确定下一步需要调用工具于是通过写入“branch:to:tools”通道驱动执行tools节点。{choices:[{content_filter_results:{},finish_reason:tool_calls,index:0,logprobs:null,message:{annotations:[],content:null,refusal:null,role:assistant,tool_calls:[{function:{arguments:{\city\:\Suzhou\},name:get_weather},id:call_cK9LgQ76xAalnjxUH1q945CM,type:function}]}}],created:1772717196,id:chatcmpl-DG30m9xH7c6ujOxbuMIJ2cid9mU30,model:gpt-5.2-chat-2025-12-11,object:chat.completion,prompt_filter_results:[...],system_fingerprint:null,usage:{...}}当tools节点开始执行的时候它从messages通道中读取最后一条AIMessage在将工具调用部分的内容读取出来后对涉及的工具实施调用并发调用。对于每个成功完成的工具调用tools节点都会根据指定的结果创建一个ToolMessage并写入messages通道。待所有工具调用完成之后它通过写入“branch:to:model”通道驱动执行model节点。model节点和之前一样从messages通道提取写入的三条消息并附加上一条系统消息和工具列表生成如下的请求第二次对作为LLM的OpenAI API发起调用。{messages:[{content:You are a helpful assistant,role:system},{content:What is the weather in Suzhou?,role:user},{content:null,role:assistant,tool_calls:[{type:function,id:call_cK9LgQ76xAalnjxUH1q945CM,function:{name:get_weather,arguments:{\city\: \Suzhou\}}}]},{content:Its always sunny in Suzhou!,role:tool,tool_call_id:call_cK9LgQ76xAalnjxUH1q945CM}],model:gpt-5.2-chat,stream:false,tools:[{type:function,function:{name:get_weather,description:Get weather for a given city.,parameters:{properties:{city:{type:string}},required:[city],type:object}}}]}经过LLM的分析此时能够对用于的查询做出答复于是它充分利用现有的语料组织文本对请求予以响应。model节点依然将响应内容封装成AIMessage写入messages通道。由于messages作为Agent的两个输出通道之一所以我们能从调用结果中的messages成员提取完整的消息历史。{choices:[{content_filter_results:{...},finish_reason:stop,index:0,logprobs:null,message:{annotations:[],content:The weather in **Suzhou** is currently **sunny** ☀️.\n\nIf you’d like more details—such as temperature, humidity, orr a multi-day forecast—just let me know!,refusal:null,role:assistant}}],created:1772719213,id:chatcmpl-DG3XJbOOkM3usPXR56MEVrlRrthMO,model:gpt-5.2-chat-2025-12-11,object:chat.completion,prompt_filter_results:[...],system_fingerprint:null,usage:{...}}

相关文章:

[LangChain智能体本质论-01]两种视角看待Agent和ReAct循环

作为LangChain智能体的Agent采用一种被称为ReAct循环的执行流程(如下图所示),这是一种结合了“推理”(Reasoning)与“行动”(Acting)的交互模式,旨在让Agent能像人类一样通过逻辑思考…...

C++手动实现共享智能指针my_shared_ptr|引用计数+删除器+完整可运行代码

1.共享智能指针的概念 共享型智能指针就是做出一个像JAVA中垃圾回收器,并且可以运用到所有资源,heap内存和系统资源都可以使用的系统。 shared_ptr实现了共享所有权(shared ownership)方式来管理资源对象,这意味没有一个特定的shared_ptr拥有资源对象。相反,这些指向同一…...

tomcat和国产web中间件区别和联系

国产中间件 宝蓝德 https://www.bessystem.com/product/e717be5b091e4e14a7339aa4be49ca80/info?p101东方通 https://www.tongtech.com/sy.html非国产tomcat tomcat的项目发布方式 将项目复制到tomcat/webapps中启动Tomcat服务器,双击 startup.bat访问项目 IDEA 中…...

Graphormer开源模型价值:替代传统QSAR方法的深度学习新范式

Graphormer开源模型价值:替代传统QSAR方法的深度学习新范式 1. Graphormer模型概述 Graphormer是微软研究院开发的基于纯Transformer架构的图神经网络模型,专门为分子图(原子-键结构)的全局结构建模与属性预测而设计。这个创新模…...

Phi-4-mini-reasoning效果展示:含单位换算、科学计数法的复合型数学题求解

Phi-4-mini-reasoning效果展示:含单位换算、科学计数法的复合型数学题求解 1. 模型能力概览 Phi-4-mini-reasoning是一款专注于推理任务的文本生成模型,特别擅长处理需要多步逻辑推导的问题。与通用聊天模型不同,它更专注于"问题输入→…...

嵌入式系统中的累加和校验算法原理与实现

1. 累加和校验算法概述在嵌入式系统开发中,数据通信的可靠性至关重要。想象一下,当你通过无线模块控制一台工业机器人时,如果传输的运动指令数据出现错误,可能导致机械臂做出完全不可预测的动作,轻则损坏产品&#xff…...

华为OD面试官最爱问的10个Python八股文,我这样答拿到了Offer

华为OD Python面试实战指南:10个高频问题的深度解析与应答策略 面试开场:如何用技术叙事打动面试官 去年冬天,我坐在华为OD的会议室里,手指不自觉地敲击着桌面。面试官推了推眼镜,抛出了第一个Python问题。那一刻我突然…...

如何通过霞鹜文楷解决中文开源字体在技术项目中的核心挑战

如何通过霞鹜文楷解决中文开源字体在技术项目中的核心挑战 【免费下载链接】LxgwWenKai An unprofessional open-source Chinese font derived from Fontworks Klee One. 一款非专业的开源中文字体,基于 FONTWORKS 出品字体 Klee One 衍生。 项目地址: https://g…...

2025届学术党必备的六大AI科研工具推荐

Ai论文网站排名(开题报告、文献综述、降aigc率、降重综合对比) TOP1. 千笔AI TOP2. aipasspaper TOP3. 清北论文 TOP4. 豆包 TOP5. kimi TOP6. deepseek AI写作软件,是人工智能技术于内容创作领域的具体运用,正一步步改变传…...

手把手教你搭建PaddleOCR开发环境:从CUDA配置到模型验证

1. 环境准备:从零搭建PaddleOCR开发环境 最近在做一个票据识别的项目,需要用到OCR技术。对比了几种开源方案后,发现PaddleOCR不仅识别准确率高,而且对中文支持特别好。但在搭建环境时踩了不少坑,特别是CUDA和cuDNN的版…...

51单片机入门-直流电机(十五)

目录:1.直流电机驱动(PWM)2.LED呼吸灯&直流电机调速1.直流电机驱动(PWM)让他转的快一些让他转2us停1us2.LED呼吸灯&直流电机调速点亮一个LED:在循环里:点亮熄灭显示暗一些:让…...

Hunyuan模型如何降本增效?1.8B边缘部署实战案例分享

Hunyuan模型如何降本增效?1.8B边缘部署实战案例分享 1. 模型介绍与核心优势 混元翻译模型1.5版本带来了两个重要更新:18亿参数的HY-MT1.5-1.8B和70亿参数的HY-MT1.5-7B。这两个模型都专注于支持33种语言之间的互译,特别包含了5种民族语言及…...

800元打造你的第一个自平衡机器人:Cubli Mini终极搭建指南

800元打造你的第一个自平衡机器人:Cubli Mini终极搭建指南 【免费下载链接】Cubli_Mini 项目地址: https://gitcode.com/gh_mirrors/cu/Cubli_Mini 想要亲手制作一个炫酷的自平衡机器人,但又担心成本太高、技术太难?Cubli Mini正是为…...

Qwen3-14B镜像部署避坑指南:RTX 4090D驱动/CUDA/内存精准匹配

Qwen3-14B镜像部署避坑指南:RTX 4090D驱动/CUDA/内存精准匹配 1. 镜像概述与核心优势 Qwen3-14B私有部署镜像是一款专为RTX 4090D显卡优化的开箱即用解决方案。这个镜像最大的特点就是解决了大模型部署中最让人头疼的环境配置问题。 想象一下,你拿到一…...

Deep-Live-Cam性能优化指南:从环境配置到实时换脸全流程解决方案

Deep-Live-Cam性能优化指南:从环境配置到实时换脸全流程解决方案 【免费下载链接】Deep-Live-Cam real time face swap and one-click video deepfake with only a single image 项目地址: https://gitcode.com/GitHub_Trending/de/Deep-Live-Cam Deep-Live-…...

VS Code 效率技巧:符号导航快速定位代码

推荐阅读 技术总监悄悄秀了一把 VS Code 神技,被我狠狠学到了! VS Code 又发布了一个 Agent 新玩具! VS Code 1.110 官宣 AI 新特性:AI 直接调试浏览器! VS Code 2026 效率秘籍:学完无敌&#xff01…...

ESLint代码规范(二)

通过配置文件来忽略对指定文件的代码检查ESLint低于7.0.0.eslintignore/config src/utils/**.prettierignore(避免代码被 Prettier 的通用规则修改).eslintcache *.lock yarn-error.log src/utils/**ESLint大于7.0.0.eslintrc.js"ignorePatterns&qu…...

一开口就聊到客户心坎里的沟通话术

先把人聊顺,事自然就顺了一位资深顾问,老客户复购和转介绍特别多。她的秘诀很简单:先聊人,再聊事。有次对接一位态度疏离的客户,她没直接问方案,而是看到客户朋友圈刚出去玩,便说:“…...

别再只会用中断了!用状态机查表法搞定AB相编码器,STM32代码实测(附防抖技巧)

状态机查表法在AB相编码器中的工程实践与优化 记得第一次在电机控制项目中使用旋转编码器时,我整整花了三天时间调试中断服务程序。每当电机转速提高,计数器就会莫名其妙地漏脉冲或跳变。直到发现状态机查表法这个"神器",才真正解决…...

Python并发安全性重构白皮书(GIL禁用场景下的原子操作黄金标准)

第一章:Python并发安全性重构白皮书(GIL禁用场景下的原子操作黄金标准)当通过 PyPy、Cython(启用 nogil)、或 Python 3.12 的实验性子解释器(PEP 684)等路径绕过全局解释器锁(GIL&am…...

C++ 网络服务端主线:从线程池到 Reactor 的完整路线图

一、为什么要写这个系列? 前面我已经把 C 并发基础和线程池完整走了一遍: std::threadstd::mutexstd::condition_variablestd::atomic手写线程池future / 拒绝策略 / 优雅关闭 但到这里,其实还只停留在: 并发组件层 也就是说&a…...

告别重复造轮子:用快马AI一键生成可配置的魔鬼面具UI组件库

作为一个经常需要处理各种UI组件的前端开发者,最近在做一个万圣节主题项目时,遇到了一个有趣的挑战:需要快速开发一套可配置的魔鬼面具组件库。传统手动编码方式不仅耗时,而且难以应对多风格需求。幸运的是,我发现了In…...

实战指南:基于快马平台与Playwright打造自动化的网站内容监测应用

今天想和大家分享一个非常实用的自动化监测方案——基于Playwright和InsCode(快马)平台搭建的新闻网站更新监测系统。这个项目特别适合需要追踪行业动态或竞品资讯的朋友,整个过程不需要复杂的服务器配置,用快马平台就能轻松实现部署和定时运行。 项目背…...

Klipper温度曲线优化终极指南:三步解决95%打印质量问题

Klipper温度曲线优化终极指南:三步解决95%打印质量问题 【免费下载链接】klipper Klipper is a 3d-printer firmware 项目地址: https://gitcode.com/GitHub_Trending/kl/klipper 你是否曾为PLA打印翘边、ABS层间开裂或PETG拉丝问题而烦恼?这些问…...

BilibiliDown:B站视频下载的完整解决方案

BilibiliDown:B站视频下载的完整解决方案 【免费下载链接】BilibiliDown (GUI-多平台支持) B站 哔哩哔哩 视频下载器。支持稍后再看、收藏夹、UP主视频批量下载|Bilibili Video Downloader 😳 项目地址: https://gitcode.com/gh_mirrors/bi/BilibiliDo…...

Awoo Installer:让Switch游戏安装像呼吸一样简单

Awoo Installer:让Switch游戏安装像呼吸一样简单 【免费下载链接】Awoo-Installer A No-Bullshit NSP, NSZ, XCI, and XCZ Installer for Nintendo Switch 项目地址: https://gitcode.com/gh_mirrors/aw/Awoo-Installer 还在为Switch游戏安装的各种繁琐步骤头…...

计算机毕业设计springboot智慧工地管理系统 基于SpringBoot的建筑施工现场数字化管理平台 SpringBoot驱动的工程现场人员考勤与薪资结算系统

计算机毕业设计springboot智慧工地管理系统 (配套有源码 程序 mysql数据库 论文) 本套源码可以在文本联xi,先看具体系统功能演示视频领取,可分享源码参考。 在当今的建筑工程领域,科技的进步正在以前所未有的速度改变着传统的工作…...

10个C语言开源项目解析与学习指南

1. 10个值得学习的C语言开源项目解析 作为一名在嵌入式领域摸爬滚打多年的开发者,我深知阅读优秀开源代码对提升编程能力的重要性。今天要分享的这10个C语言项目,每一个都是精炼而实用的典范,特别适合想要深入理解系统编程、网络协议和底层实…...

迪文串口屏通信协议详解:从5AA5帧头到变量地址,一篇看懂HEX指令怎么发

迪文串口屏通信协议逆向解析:从帧头到数据域的HEX指令全解构 第一次拿到迪文串口屏的HEX指令时,那一串5A A5 11 82 0001 BFAA C6F4...让我完全摸不着头脑。为什么有的指令长度固定,有的却变化多端?地址字段和数据字段究竟如何划分…...

为什么需要虚拟摄像头?OBS-VirtualCam 3大核心价值解析

为什么需要虚拟摄像头?OBS-VirtualCam 3大核心价值解析 【免费下载链接】obs-virtual-cam obs-studio plugin to simulate a directshow webcam 项目地址: https://gitcode.com/gh_mirrors/ob/obs-virtual-cam 在视频会议和在线教学中,你是否曾希…...