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

BrowserGym:基于LLM的浏览器自动化智能体开发实战指南

1. 项目概述当浏览器自动化遇上大语言模型最近在探索大语言模型LLM与真实世界应用交互的边界时我深度体验了ServiceNow开源的BrowserGym项目。这不仅仅是一个简单的网页自动化工具它更像是一个为LLM量身定制的“浏览器沙盒健身房”。想象一下你有一个强大的AI大脑但它被困在文本的牢笼里无法点击按钮、填写表单、浏览网页。BrowserGym要做的就是为这个大脑装上“眼睛”和“手”让它能像真人一样操作浏览器完成复杂的多步骤任务。这个项目的核心价值在于它为评估和开发基于LLM的智能体Agent提供了一个标准化、可复现的基准测试环境。无论是研究机构想测试自家模型在网页任务上的表现还是开发者想构建一个能自动处理工单、查询信息的AI助手BrowserGym都提供了一个绝佳的起点。它抽象了底层浏览器操作的复杂性将网页状态转化为LLM易于理解的文本和视觉表征并将LLM的决策翻译成具体的浏览器操作指令。我花了几周时间深入研究其架构并尝试复现了几个任务发现其设计理念非常贴合实际需求尤其是在处理现代Web应用如ServiceNow ITSM平台本身的复杂交互时展现出了强大的潜力。2. BrowserGym的核心架构与设计哲学2.1 环境抽象将网页世界翻译给AIBrowserGym最精妙的设计在于它对浏览器环境的抽象。它没有让LLM直接去解析原始的HTML DOM树——那对模型来说过于冗长和嘈杂。相反它构建了一个多模态的“观察空间”。首先是文本观察。它通过一套精心设计的提取器从网页中抽取出对任务执行最关键的信息所有可交互元素按钮、输入框、链接及其可访问名称accessible name、角色role、状态关键的文本内容如标题、列表项、表格数据以及当前页面的URL和标题。这些信息被组织成结构化的文本大大减少了无关信息的干扰。其次是视觉观察。对于某些任务纯文本可能丢失关键的布局和视觉上下文。因此BrowserGym可以捕获网页的屏幕截图并辅以关键元素的边界框坐标。这为基于视觉的模型如多模态大模型提供了输入。在我的测试中对于图标按钮、基于图片的导航或是复杂的数据可视化界面视觉观察往往能提供文本无法涵盖的线索。最后是辅助信息。环境还会提供任务目标描述、历史操作记录、以及上一步操作的结果成功、失败、错误信息。这形成了一个完整的“状态-动作”循环非常符合强化学习或规划型AI智能体的训练范式。2.2 动作空间定义AI能做什么光有观察还不够必须定义AI能执行的动作。BrowserGym定义了一套丰富且贴近人类操作的动作空间点击通过元素的XPath或辅助功能ID进行精准点击。输入文本向输入框填充内容支持模拟键盘事件。悬停将鼠标移动到某个元素上可能触发下拉菜单或提示信息。导航前进、后退、刷新、跳转到指定URL。滚动在页面内上下滚动。等待等待特定元素出现或等待一段时间这对处理动态加载的页面至关重要。提取信息主动从指定元素中获取文本用于验证或决策。每个动作都需要具体的参数比如click(xpath“//button[id‘submit’]”)。设计的关键在于这些动作既要足够原子化以便精确控制又要能组合成高级任务比如“填写这张表单并提交”。BrowserGym通过“子任务”Subtask的概念来支持这种组合允许将复杂的端到端指令如“创建一个高优先级 incident 工单”分解为一系列基础动作。2.3 奖励与任务完成判定如何告诉AI它做得好不好这是智能体训练的核心。BrowserGym采用了多层次的奖励和完成判定机制。任务成功判定这是最终目标。通常通过一个“成功检测器”来实现它可能检查特定文本是否出现在页面上如“创建成功”某个URL是否被访问或者一个特定的DOM元素状态是否改变。例如在“重置密码”任务中成功条件可能是检测到包含“密码重置邮件已发送”的确认信息元素。稀疏奖励最简单的方式是只在任务成功时给予一个大的正奖励如1失败或超时给予负奖励如-1。但这对于学习复杂的多步骤任务非常困难。稠密奖励为了更有效地引导学习BrowserGym支持设计中间奖励。例如每成功填写一个表单字段给予一个小奖励导航到正确的页面给予奖励。这能帮助智能体更快地理解任务结构。在实践中设计一个好的稠密奖励函数本身就是一个挑战需要深入理解具体任务。惩罚机制无效操作如点击一个不可点击的元素、重复操作、或偏离任务路径的操作会被给予小的负奖励防止智能体陷入无效循环。实操心得在自定义任务时成功判定逻辑的设计至关重要。过于宽松可能导致AI“蒙混过关”过于严格则可能让AI因微小差异而失败。我建议采用“主条件多个辅助验证点”的方式。例如判定“工单创建成功”不仅要看成功提示最好还能通过API或检查列表页验证新工单确实以正确的属性存在于系统中。3. 实战部署与自定义任务创建3.1 环境搭建与快速启动BrowserGym的安装相对 straightforward。它主要依赖Playwright作为浏览器自动化引擎因此第一步是确保Playwright及其浏览器驱动安装正确。# 克隆仓库 git clone https://github.com/ServiceNow/BrowserGym.git cd BrowserGym # 创建并激活虚拟环境推荐 python -m venv venv source venv/bin/activate # Linux/Mac # venv\Scripts\activate # Windows # 安装依赖 pip install -e . # 安装Playwright浏览器 playwright install chromium安装完成后可以通过其命令行工具快速测试一个示例任务。最经典的例子是“Chrome Dino Game”断网时Chrome浏览器里的小恐龙游戏。这个任务直观地展示了智能体如何通过观察像素视觉观察和分数文本观察来学习玩游戏。# 运行一个简单的演示使用随机动作 browser-gym-play --task play_chrome_dino --num_episodes 3你会看到一个浏览器窗口弹出小恐龙开始随机跳跃因为动作是随机的所以很快就会撞到仙人掌。但这验证了环境本身可以正常运行。3.2 深入核心配置文件理解任务定义要创建自定义任务必须理解其任务定义文件通常是YAML格式。这是BrowserGym的“任务蓝图”。我们以一个简化的“在ServiceNow演示实例中搜索知识库文章”任务为例拆解其核心部分。# search_kb_article.yaml task_name: search_service_now_kb start_url: https://demo.service-now.com/kb goal: 在知识库中搜索关键词‘password reset’并打开第一篇相关文章。 observations: - type: accessibility_tree # 获取可访问性树包含交互元素 - type: screenshot # 获取屏幕截图 - type: url # 获取当前URL actions: - type: click - type: type - type: press_enter - type: wait reward: type: sparse # 使用稀疏奖励 success_reward: 1.0 failure_reward: -0.1 timeout: 60 # 任务超时时间秒 success_criteria: - type: url_contains # 成功条件URL包含文章详情页的路径模式 value: /kb_view.dogoal用自然语言清晰描述任务目标。这是给LLM看的提示词的一部分必须明确无歧义。observations定义了智能体能看到什么。accessibility_tree是核心它比原始HTML更干净。screenshot对于有复杂UI的任务很有用。actions定义了智能体在当前任务中可用的动作类型。这里只开放了必要的几种。reward和success_criteria定义了“成功”是什么以及如何奖励。url_contains是一个简单的检测器在实际中你可能需要组合多个条件甚至编写自定义的Python函数来检测更复杂的状态。3.3 编写自定义任务一个完整的例子假设我们要创建一个“在GitHub上为BrowserGym项目点Star”的任务。这涉及导航、搜索、点击等多个步骤。第一步创建任务定义文件star_browsergym.yamltask_name: star_github_repo start_url: https://github.com goal: 导航到ServiceNow/BrowserGym仓库页面并点击‘Star’按钮收藏该仓库。 observations: - type: accessibility_tree options: iframe_roots: all # 重要GitHub部分内容在iframe中 - type: url actions: - type: click - type: type - type: press_enter - type: wait_for_element # 等待元素出现 reward: type: sparse success_reward: 1.0 failure_reward: -0.2 step_penalty: -0.01 # 每一步的小惩罚鼓励高效完成 timeout: 120 success_criteria: - type: element_present # 自定义条件检测“Unstar”按钮出现 xpath: //button[aria-labelUnstar this repository]第二步创建自定义成功检测器可选但推荐对于复杂条件需要在Python中实现。在任务文件同目录下创建custom_detectors.pyfrom browsergym.core import AbstractDetector class ElementPresentDetector(AbstractDetector): def __init__(self, xpath: str): self.xpath xpath def __call__(self, obs, infoNone): # obs 是当前的观察字典 # 检查 accessibility_tree 中是否存在该XPath元素 # 这里简化处理实际需要解析obs中的accessibility tree # 假设我们有一个辅助函数 if element_exists_in_obs(obs, self.xpath): return True, 检测到目标元素 # (是否成功, 消息) return False, 未找到目标元素然后在YAML中引用type: custom并指定类路径。第三步运行并测试任务编写一个简单的测试脚本test_task.pyimport gymnasium as gym import browsergym env gym.make( browsergym/webarena, task_namestar_github_repo, task_config_path./star_browsergym.yaml, headlessFalse, # 显示浏览器以便调试 ) obs, info env.reset() print(f初始目标: {info[goal]}) done False steps 0 # 手动模拟一个简单策略搜索仓库 - 进入 - 点Star # 这里仅为演示实际应由LLM或智能体产生动作 actions_to_try [ type(selectorinput[aria-label\Search GitHub\], textServiceNow/BrowserGym), press_enter(), wait_for_element(xpath//a[href\/ServiceNow/BrowserGym\], timeout10), click(xpath//a[href\/ServiceNow/BrowserGym\]), wait_for_element(xpath//button[aria-label^\Star\], timeout10), click(xpath//button[aria-label^\Star\]), ] for action_str in actions_to_try: if done: break obs, reward, terminated, truncated, info env.step(action_str) done terminated or truncated steps 1 print(fStep {steps}: Reward{reward}, Done{done}, Info{info.get(message, )}) env.close()运行这个脚本你会看到浏览器自动执行一系列操作。通过观察每个步骤的obs和reward你可以验证任务设计是否合理。注意事项现代网站如GitHub、ServiceNow大量使用动态加载和iframe。确保在observations配置中启用iframe_roots: “all”并善用wait_for_element动作。XPath的稳定性是关键尽量使用aria-label、>问题现象可能原因排查与解决思路LLM输出的动作无法执行报“元素未找到”1. XPath不稳定随页面动态变化。2. 元素在iframe内未被观察到。3. 页面尚未加载完成。1.优先使用aria-label、name、>可访问性树过于庞大导致提示词超长页面元素太多全部塞入上下文。1.实现观察过滤只提取与当前任务可能相关的元素类型如按钮、输入框、链接。2.基于位置过滤只提取视口viewport内的元素。3.使用LLM进行摘要先用一个小模型对原始观察进行总结再将总结放入主提示词。动作执行成功但页面状态未按预期变化1. 页面有JavaScript拦截或异步更新。2. 需要与原生浏览器交互如下拉文件选择。1. 增加wait时间或使用wait_for_element等待特定状态出现。2. BrowserGym基于Playwright支持文件上传等复杂交互需使用对应的Playwright API封装自定义动作。任务成功率波动大LLM行为不一致1. 提示词不够精确。2. LLM温度temperature参数过高。3. 观察信息中存在歧义。1.精炼提示词明确指令格式提供更多上下文示例少样本学习。2.降低温度参数如设为0使输出更确定。3. 在观察中增加唯一性标识如为相似按钮添加索引“[1] 提交按钮” “[2] 提交按钮”。5.2 提升智能体性能的策略动作分块与宏动作对于非常复杂的任务不要让LLM一次只做一个原子动作。可以定义一些“宏动作”如fill_form(field1value1, field2value2)或navigate_to_kb_search()。这降低了LLM的规划难度。可以在BrowserGym中通过封装多个基础动作来实现宏动作。分层观察不要总是给LLM完整的细节。在高层规划阶段只提供页面标题、主要区域、链接列表等摘要信息。当需要具体操作时如填写某个表单再提供该区域的详细观察。这模仿了人类的注意力机制。自我反思与重试当动作失败或陷入死胡同时让LLM分析错误信息环境通常会返回并重新规划。可以在提示词中加入“如果上一步失败请分析原因并尝试另一种方法”的指令。利用视觉观察对于纯文本模型难以处理的UI如图标、验证码、图表可以接入多模态模型如GPT-4V。将屏幕截图和需要关注的元素坐标框一起输入让模型“看到”界面并做出决策。6. 从实验到应用BrowserGym的潜力与扩展经过一段时间的实践我认为BrowserGym的价值远不止于学术研究。它为构建实用的、基于LLM的自动化流程提供了坚实的基础框架。在企业内部应用场景IT服务管理自动化这正是ServiceNow的老本行。可以训练智能体自动处理常见工单如密码重置、软件安装申请。智能体能登录ITSM平台根据工单描述执行标准操作流程。数据录入与迁移将纸质表格或旧系统的数据通过智能体操作新系统的Web界面进行录入。智能体能理解表格内容并导航到正确的页面字段进行填写。内部系统巡检与报告自动登录多个内部监控或业务系统抓取关键指标生成综合日报。扩展方向多标签页与跨应用流程当前BrowserGym主要针对单页任务。真实的业务流程往往涉及在多个标签页、甚至不同网站间切换如从邮箱打开链接登录另一个系统。扩展其支持多标签页环境将极大提升实用性。更强大的观察表征探索如何用向量数据库存储历史观察让智能体具备“记忆”避免重复操作。或者引入对页面DOM结构的更高级语义理解。与人协作设计“人机回环”机制。当智能体不确定时例如遇到从未见过的弹窗可以截图并生成问题向人类求助将人类的反馈作为学习信号。BrowserGym将一个复杂的现实问题——网页自动化——标准化成了一个AI可学习的游戏环境。它降低了LLM智能体研发的门槛。最大的体会是成功的关键往往不在模型本身有多大而在于环境设计得是否合理观察是否有效、奖励是否精准、动作是否得当。这更像是一门“环境工程”的艺术。如果你正在考虑将LLM的能力延伸到真实的浏览器交互中BrowserGym是一个非常值得深入研究和定制的起点。从运行一个demo开始尝试创建一个属于自己的简单任务你会对整个智能体系统的运作有更深刻的理解。

相关文章:

BrowserGym:基于LLM的浏览器自动化智能体开发实战指南

1. 项目概述:当浏览器自动化遇上大语言模型最近在探索大语言模型(LLM)与真实世界应用交互的边界时,我深度体验了ServiceNow开源的BrowserGym项目。这不仅仅是一个简单的网页自动化工具,它更像是一个为LLM量身定制的“浏…...

【收藏级】2026年大模型入门指南:小白程序员必看,告别AI焦虑,轻松切入AI行业

这篇文章想聊清楚一个很现实的问题:在2026年AI热潮愈演愈烈的今天,小白和程序员到底该怎么低成本进入AI行业? 如果你最近也在焦虑、在内耗,刷到各种AI热点就心慌,不知道该学什么、不知道该怎么开始,甚至担心…...

构建本地优先的代码片段管理工具:从设计到实践

1. 项目概述:一个为开发者量身定制的代码片段管理工具如果你和我一样,是个每天和代码打交道的开发者,那你肯定遇到过这样的场景:为了解决一个特定的问题,你花了半天时间在网上搜索、调试,终于写出了一段堪称…...

Flutter for OpenHarmony 中 webview_flutter 适配实战指南

Flutter for OpenHarmony 中 webview_flutter 适配实战指南 欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net 摘要 本文基于真实项目实践,完整介绍了在 Flutter for OpenHarmony(以下简称 FOH)工程中&…...

LangGraph 终极解析:从 “玩具 Agent“ 到 “生产级智能体“ 的核心武器

目录 LangGraph 终极解析:从 "玩具 Agent" 到 "生产级智能体" 的核心武器 一句话定位 为什么必须学 LangGraph?(LangChain 的致命缺陷) LangGraph 四大核心概念(一张图搞懂) 1. S…...

python系列【仅供参考】:js2py模块--python中执行js

js2py模块--python中执行js js2py 1. 在python中执行js代码 2. js代码翻译 3. 在js中调用Python函数 4. 在js中调用Python模块 js2py Python中执行JS代码,通常用两个库:js2py,pyexecjs。当网页使用 js 加密时我们可以使用这些库来分析 js 的实现逻辑,获取加密信息。 js2p…...

下载安装 Temurin® JDK JDK 21 - LTS 速度很慢,有办法加速吗?

下载 Temurin JDK JDK 21 - LTS 速度很慢,有办法加速吗? 加速下载 Temurin JDK 21 的方法 方法一:清华大学 TUNA 镜像(推荐 ⭐⭐⭐⭐⭐) 这是目前最快、最稳定的国内镜像,速度可以跑满带宽。 直接访问目…...

Godot XR Tools:加速VR/AR开发的模块化工具集与实战指南

1. 项目概述:Godot XR Tools 是什么? 如果你正在用 Godot 引擎捣鼓 VR 或 AR 项目,大概率会遇到一些“通用但繁琐”的问题:怎么让虚拟手自然地抓取物体?怎么实现一个稳定可靠的传送移动机制?UI 界面在 3D …...

python系列【仅供参考】:JS的解析与Js2Py使用

JS的解析与Js2Py使用 JS的解析与Js2Py使用 简介: JS的解析 事件监听器 搜索关键字 请求关联JS文件 Js2Py Js2Py的简单使用 安装Js2Py 执行JavaScript代码 调用JavaScript函数 Js2Py的应用示例 创建JavaScript文件 使用JavaScript JS的解析与Js2Py使用 简介: Js2Py是一个Pyt…...

基于工作流的低代码AI应用开发:Flock平台核心架构与实战指南

1. 项目概述:Flock,一个为AI应用构建者准备的“乐高积木”如果你正在寻找一个工具,能够让你像搭积木一样,快速构建出功能强大的聊天机器人、智能客服,甚至是能自主协作的多智能体系统,那么Flock很可能就是你…...

深入Android Framework:构建稳定、高效的无人售卖机系统

摘要: 本文聚焦于Android Framework框架层,探讨其在无人售卖机系统开发中的核心价值与应用实践。区别于常规应用层开发,无人售卖机因其特殊的运行环境(如弱网、断电风险、多外设交互)及业务需求(如交易安全、设备状态监控、离线能力),对Android系统的底层能力提出了更高…...

如何在华为HarmonyOS设备上部署microG服务:解决签名验证的完整技术指南

如何在华为HarmonyOS设备上部署microG服务:解决签名验证的完整技术指南 【免费下载链接】GmsCore Free implementation of Play Services 项目地址: https://gitcode.com/GitHub_Trending/gm/GmsCore microG Services是一个开源免费的Google Play服务替代框架…...

#81_闲谈语言的分类

机器语言是二进制指令,CPU可直接执行; 低级语言通常指机器语言和汇编语言,与硬件紧密相关; 高级语言则接近自然语言,独立于具体硬件,需编译/解释才能运行; 中级语言并非严格分类,有时…...

golang如何实现桌面应用热更新_golang桌面应用热更新实现攻略

Go桌面应用无法真正热更新,只能通过go-selfupdate实现无缝重启:下载校验新二进制、替换并重启,需适配各平台签名与自启机制,插件机制不可行,核心难点在于更新时机判断与状态快照恢复。Go 桌面应用热更新无法真正“热”…...

5分钟快速上手!Calibre豆瓣插件终极安装指南,轻松获取中文图书元数据

5分钟快速上手!Calibre豆瓣插件终极安装指南,轻松获取中文图书元数据 【免费下载链接】calibre-douban Calibre new douban metadata source plugin. Douban no longer provides book APIs to the public, so it can only use web crawling to obtain da…...

为什么很多人 DFS 写得飞起,一到「矩阵最长递增路径」就彻底懵了?

为什么很多人 DFS 写得飞起,一到「矩阵最长递增路径」就彻底懵了? 有一类算法题,非常容易让人产生错觉。 看起来只是: 矩阵 + DFS结果一写。 不是超时。 就是死循环。 再不然: 明明逻辑没错 结果性能直接爆炸而「矩阵中的最长递增路径(Longest Increasing Path in a…...

欧拉回路(一笔画)

欧拉回路是图论中的一个经典概念,指一条经过图中每条边恰好一次并且起点和终点相同的闭合路径。通俗地讲,就是一笔画问题中能够不重复地走完所有边并回到起点的画法。 基本定义 欧拉回路:经过图中每条边恰好一次且闭合的回路。 欧拉通路&am…...

吃透C++ STL map/set:从入门到实战,新手也能轻松上手

文章目录 前言 一、先搞懂:map和set是什么?核心区别在哪? 二、set使用详解:去重排序,一键搞定 三、map使用详解:键值映射,高效查找 四、map和set的常见避坑点(新手必看&#xff…...

Dify插件开发实战:Python SDK快速构建AI工作流扩展工具

1. 项目概述与核心价值如果你正在为 Dify 构建自定义插件,并且厌倦了从零开始处理复杂的协议、序列化和生命周期管理,那么langgenius/dify-plugin-sdks这个项目就是你一直在找的“脚手架”。简单来说,它是一套官方维护的软件开发工具包&#…...

私有化部署ChatGPT Web应用:从架构解析到实战部署指南

1. 项目概述与核心价值最近在折腾一个挺有意思的开源项目,叫“ChatGPTwebV15”。这名字听起来有点技术范儿,但说白了,就是一个让你能自己部署、完全掌控的类ChatGPT网页应用。它基于OpenAI的API,但把整个交互界面、对话管理、甚至…...

如何在手机上3步完成Android内核刷入:Horizon Kernel Flasher终极指南

如何在手机上3步完成Android内核刷入:Horizon Kernel Flasher终极指南 【免费下载链接】HorizonKernelFlasher A simple app that can flash AnyKernel flashable zips on android 项目地址: https://gitcode.com/gh_mirrors/ho/HorizonKernelFlasher 还在为…...

2026.5.7@霖宇博客制作中遇见的问题

倒数2个知识点没看 记得看下1. one 前端网页的验证码如何修改为后端的验证码 将前端生成的验证码修改为后端生成,核心目的是为了解决安全性问题。如果验证码只在前端生成和校验,恶意攻击者可以轻松绕过登录页面直接发起请求,导致验证码完全失…...

国家医疗保障webpack

开始逆向 定位到signature的位置 发现是webpack模块 要找到入口位置 这一块是加载器的位置 先把这个扣下来 再扣自执行函数 不要里面的函数 会报环境错误 然后报这个错误 把加载器函数调用注释 o函数挂载到全局去调用 代码全拉 然后注释掉 这一块是 类ob 然后报t is not define…...

C语言实现精简Smalltalk运行时:探索面向对象与消息传递的本质

1. 项目概述:当“小结构”遇上“小对话”如果你在开源社区里混迹过一段时间,可能会发现一个有趣的现象:很多项目的名字,乍一看不知所云,但一旦你理解了它的设计哲学,就会觉得无比贴切。tinystruct/smalltal…...

终极健康办公指南:Stretchly科学休息管理工具完全解析

终极健康办公指南:Stretchly科学休息管理工具完全解析 【免费下载链接】stretchly The break time reminder app 项目地址: https://gitcode.com/gh_mirrors/st/stretchly 在数字时代,长时间面对电脑屏幕已成为现代职场人士的日常。Stretchly作为…...

WarcraftHelper:魔兽争霸III终极优化工具3步快速配置指南

WarcraftHelper:魔兽争霸III终极优化工具3步快速配置指南 【免费下载链接】WarcraftHelper Warcraft III Helper , support 1.20e, 1.24e, 1.26a, 1.27a, 1.27b 项目地址: https://gitcode.com/gh_mirrors/wa/WarcraftHelper 还在为魔兽争霸III在现代电脑上运…...

AI智能体驱动TDD:agent-flow-tdd框架实战与优化指南

1. 项目概述:当AI智能体遇上测试驱动开发 如果你和我一样,在软件开发领域摸爬滚打了十几年,肯定对测试驱动开发(TDD)又爱又恨。爱的是它那套“红-绿-重构”的严谨流程,确实能产出健壮、可维护的代码&#x…...

WarcraftHelper:魔兽争霸3终极兼容性修复与性能增强方案

WarcraftHelper:魔兽争霸3终极兼容性修复与性能增强方案 【免费下载链接】WarcraftHelper Warcraft III Helper , support 1.20e, 1.24e, 1.26a, 1.27a, 1.27b 项目地址: https://gitcode.com/gh_mirrors/wa/WarcraftHelper 还在为魔兽争霸3在现代电脑上运行…...

蓝桥杯单片机决赛避坑指南:从“高位熄灭”到“双键长按”的实战代码优化

蓝桥杯单片机决赛代码优化实战:从数码管显示到双键检测的进阶技巧 参加蓝桥杯单片机竞赛的同学们都知道,决赛环节往往会在基础功能上设置诸多"陷阱",考验选手对细节的掌控能力。本文将针对数码管高位熄灭、温度传感器小数处理、双键…...

前端响应式设计:最佳实践

前端响应式设计:最佳实践 前言 响应式设计是现代前端开发的核心概念之一,它确保网站和应用在不同设备上都能提供良好的用户体验。随着移动设备的普及,响应式设计变得越来越重要。今天,我就来给大家讲讲响应式设计的最佳实践&#…...