无框架数据驱动:用WebDriver+CSV快速实现UI自动化回归
刚开始接触WebDriver做UI自动化的时候很多人的第一反应是先选一个测试框架。我也走过这条弯路项目还没跑通先花了一整天折腾依赖安装、配置监听器、设计页面对象模型最后被一堆“与业务无关的复杂度”卡住自动化进展几乎为零。后来我换了个完全相反的策略不引入任何测试框架只靠Selenium WebDriver本身的能力加一个简单的循环去读CSV文件把每条数据都当成一条用例来执行。结果这套最朴素的做法反而在公司内部系统上稳定运行了大半年每次版本回归都能靠它兜底。这里说的“无框架数据驱动”核心思路就是输入数据、操作步骤、预期结果三者分离。写代码的人维护步骤不懂代码的同事也能直接改数据文件来调整用例。如果你正被“UI自动化要不要上框架”这个问题困扰或者用例量在一两百条以内、团队没有专职测试开发这套方案会是一个非常省心的起点。下面我把当时怎么设计、怎么写引擎、踩了哪些坑一步步完整讲清楚。1. 从“装框架”到“先跑起来”无框架方案的形成过程1.1 数据驱动到底驱动的是什么很多人听到“数据驱动”就觉得一定要上什么高级框架其实这个词的本质非常简单。我把UI自动化比作做菜操作步骤相当于菜谱里的流程不管做红烧肉还是清蒸鱼“切菜、下锅、调味”这个流程大体不变变的只是食材和调料的配比。数据驱动就是把这段“不变的操作流程”留在代码里把“会变的数据”全部放到CSV、Excel或者JSON文件里。用WebDriver来描述这个思路会更直接。一个网页上的登录动作永远是打开页面、输入用户名、输入密码、点击登录、检查结果这五步但用户名和密码的组合是千变万化的。如果每测一组数据就复制粘贴一段代码那本质上还是在用代码堆用例维护成本很高。数据驱动的做法是让WebDriver的代码只写一遍然后循环读取数据文件每读一行就跑一遍同样的操作。这个方案的核心不是“用了什么工具”而是“分界线画在哪”。把容易变化的内容移到数据文件里把不容易变化的内容沉淀成引擎。只要这个分界线画得好哪怕没有框架也能做到新增用例时一行代码都不用改。1.2 框架解决的问题中小规模项目里根本不存在成熟测试框架确实解决了很多问题用例组织、失败重跑、多线程并发、复杂报告、依赖管理、数据隔离。但如果团队只有一两个人用例总数不到两百条这些能力中的大部分根本用不上。这个问题我当时想得很清楚的跨浏览器并行执行听起来很专业但内部系统就只用Chrome多出来的能力全都是负债。框架带来的通常是额外的学习成本和配置成本。我见过不止一个团队花了一两周时间搭框架最后写用例的时间反而被压缩原因就在于他们一直在处理框架本身的语法和规则。而CSV加WebDriver的方案半小时就能跑通第一条用例这个“先跑起来”的即时反馈对建立自动化信心非常重要。我在实际项目里做过一次粗算把一套测试框架从零配置到能跑一条用例大约需要半天而用CSV加一个for循环从写代码到出结果最多半小时。在用例量小于两百的区间这种简单方案在速度上的优势是碾压性的。等到用例量真正大到需要框架的时候再迁移也不迟而不是一开始就背着一个重型武器跑步。1.3 为什么标题强调WebDriver而不是框架WebDriver是浏览器自动化的底层标准它的核心能力是让代码能够模拟真实用户去操作浏览器。而测试框架是建立在WebDriver之上的上层建筑用来管理用例、输出报告、组织断言。标题里强调WebDriver是想把注意力拉回到最底层的“驱动浏览器”这件事上。无框架方案并不是说完全没有自己的封装而是说不依赖TestNG、pytest这类现成测试框架。我自己写了一个很小的调度循环这个循环负责读数据、执行WebDriver操作、记录结果。它虽然简陋但在项目早期足够实用而且每一行代码都是我完全能掌控的。这里也提示一点无框架不意味着可以忽略稳定性。浏览器进程回收、显式等待、异常处理这些基本功一个都不能少。不要把“无框架”理解成“代码随便写”它的本质是用最少的外部依赖跑出稳定可靠的结果。2. 文件结构、数据格式与最简引擎设计2.1 目录结构怎么摆才能让同事一眼看懂无框架方案没有框架约定俗成的目录规范所以目录结构必须靠自己去设计。我的原则是看目录就能知道去哪里改数据、去哪里看结果、引擎代码在哪里。一套典型的目录结构长这样project/ ├── cases/ │ ├── login.csv │ ├── search.csv │ └── audit.csv ├── drivers/ │ └── chromedriver ├── lib/ │ └── engine.py ├── logs/ └── reports/每个文件夹的职责非常单一cases放测试数据一个CSV文件对应一个业务模块的用例集合drivers放浏览器驱动lib放唯一的调度引擎reports放每次执行的结果表logs放WebDriver的日志和异常堆栈。这样设计的好处是哪怕一个完全没接触过自动化的人看到这个目录也能猜个八九不离十。维护用例的人根本不需要打开引擎代码只要直接在cases里新增或修改CSV行数据。我当时和团队里兼职负责验证业务的同事协作他只需要知道“改CSV、跑脚本、看reports”这个协作模式比任何框架都顺畅。2.2 CSV为什么是最好的起点团队里不是每个人都熟悉JSON语法也不是每个人都愿意装数据库客户端但几乎所有人都会用Excel打开表格。CSV的亲和力就在这里。它本质上是一个纯文本表格既可以用Excel编辑也可以直接用文本编辑器打开而且因为它是纯文本进版本控制库之后每次改动都可以通过diff清晰地看到。这一点在无框架方案里尤其重要。没有框架提供的隔离和校验机制数据文件就是最重要的“车间现场”要保证现场足够直观。CSV还带来一个额外好处Python的csv.DictReader可以直接把第一行表头变成字典的键代码里可以用case[username]的方式读字段语义非常清晰。如果你担心CSV表达能力不够其实大部分UI用例的根本不需要复杂结构。每一行就是一条完整用例每一列就是一个输入参数或预期值。真遇到某个字段需要保存多行文本也可以先在CSV里放一个标识符具体内容再解析。但我在实际项目中尽量不这么复杂保持简单才是无框架方案的生命线。2.3 最简引擎只有三个动作读文件、执行用例、写结果无框架引擎的骨架非常短一个函数读数据一个函数跑用例一个函数写报告。我甚至不建议一开始就把引擎写得特别抽象等真的出现重复逻辑再抽也不迟。import csv from selenium import webdriver def read_cases(path): with open(path, encodingutf-8-sig) as f: return list(csv.DictReader(f)) def run_case(case): driver webdriver.Chrome() try: driver.get(case[url]) # WebDriver操作定位元素、输入数据、点击按钮、检查结果 # 每一步都要用显式等待避免页面还没加载完就操作 return True, 执行成功 except Exception as e: return False, f{type(e).__name__}: {str(e)} finally: driver.quit() def write_report(report, pathreports/result.csv): with open(path, w, newline, encodingutf-8-sig) as f: writer csv.writer(f) writer.writerow([case_no, result, detail]) writer.writerows(report) def main(): cases read_cases(cases/login.csv) report [] for case in cases: ok, detail run_case(case) report.append((case[case_no], PASS if ok else FAIL, detail)) write_report(report)三个动作之间耦合度很低随便替换其中一个都不会影响另外两个。尤其是run_case内部因为每条用例独立打开浏览器、执行操作、最后关闭浏览器天然实现了用例隔离。如果后期要求速度可以再考虑复用浏览器进程但第一步先保证隔离别为了性能牺牲稳定性。3. 一个真实用例的完整落地过程3.1 用一份CSV描述登录模块的十组场景空谈原理不如直接跑一个具体例子。我选登录模块因为它是几乎每个Web系统都有的功能也是UI自动化最经典的入门场景。当时我创建了一个cases/login.csv里面大致是这个结构case_no,url,username,password,expected CASE001,http://localhost:8080/login,admin,123456,操作台 CASE002,http://localhost:8080/login,admin,123455,密码不正确 CASE003,http://localhost:8080/login,normal_user,123456,个人中心 CASE004,http://localhost:8080/login,user_expired,123456,账号已过期 CASE005,http://localhost:8080/login,blocked_user,123456,账号已被锁定每一行代表一条完整的UI交互验证。expected列是执行完操作后页面上应该出现的文本它既是回归的基准也是对业务需求的显式表达。最左侧的case_no是唯一标识它会在后续的日志、报告、失败排查中被反复引用。设计这份CSV的时候有个小原则宁可每个文件少放几条用例也不要在一个文件里堆太多不同业务的场景。文件职责单一以后出了问题才能快速定位。当时我把登录、查询、审批、导出分别放在四个CSV文件里跑回归时逐个执行看着也清晰。3.2 从数据到执行、断言、落盘一套完整代码有了CSV后就得把run_case里的逻辑补完整。登录场景的WebDriver代码大概长这样from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC def run_case(case): driver webdriver.Chrome() try: driver.get(case[url]) WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.ID, username)) ) driver.find_element(By.ID, username).send_keys(case[username]) driver.find_element(By.ID, password).send_keys(case[password]) driver.find_element(By.ID, loginBtn).click() WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.CLASS_NAME, message)) ) actual driver.find_element(By.CLASS_NAME, message).text return case[expected] in actual, f实际结果: {actual} except Exception as e: return False, f{type(e).__name__}: {str(e)} finally: driver.quit()这段代码有几个细节值得展开。第一等待条件用的是WebDriverWait而不是time.sleep因为页面加载快慢受网络环境影响很大固定睡三秒既浪费又容易误判。第二点击登录按钮后等待的是一个业务层面的结果元素也就是提示消息而不是随便等待某个通用元素。第三断言时用case[expected] in actual判断预期文本是否出现在实际结果中这就是无框架方案最轻量的断言方式。到这里整条链路就闭环了CSV提供数据、WebDriver执行操作、Python断言判断结果、报告文件记录每次执行情况。整个过程没有TestNG、没有pytest、没有复杂配置但已经完全可以承担日常回归的任务。3.3 一次真实执行后结果长什么样跑完python lib/engine.py之后我通常在reports/result.csv里看到类似下面的输出case_no结果失败详情CASE001PASS实际结果: 欢迎进入操作台CASE002PASS实际结果: 密码不正确CASE003PASS实际结果: 欢迎进入个人中心CASE004FAILTimeoutException: 等待元素超时CASE005FAIL断言失败: 预期“账号已被锁定”但实际显示“账号已被锁定请联系管理员”不要小看这份最简单的表格它能直观回答三个问题哪些用例通过、哪些用例挂了、挂的原因大概率是什么。比如CASE004的异常是TimeoutException说明页面没有在预期时间内出现登录框优先怀疑环境或网络问题而不是业务逻辑问题而CASE005的失败是文本不完全匹配优先怀疑预期值写得太严格。这个阶段我特别提醒自己不要为了让报告好看而去写复杂的HTML报告先用CSV交付结果等真正有人需要更美观的展示时再升级。无框架的核心是先保证自动化在业务中产生价值而不是让工具链看起来很完善。4. 无框架数据驱动最容易踩的五个坑4.1 编码问题同一份CSV在不同电脑上报错无框架方案里CSV文件的编码问题几乎每个人都会碰到。Windows下用Excel另存的CSV默认可能是GBK编码而macOS和Linux环境下Python默认用UTF-8读取两边一交汇打开文件时就会出现乱码甚至UnicodeDecodeError。我当时的解决办法是两件事同时做。第一读取文件时统一指定encodingutf-8-sig让Python在解码时自动处理带BOM的UTF-8文件第二建一个标准的CSV模板模板本身也是用UTF-8-BOM编码写入的这样Excel和Python都能正常识别。with open(cases/login.csv, encodingutf-8-sig) as f: cases list(csv.DictReader(f))后来我把这个约定写到了团队协作说明里所有CSV文件统一用UTF-8-BOM编辑文件时优先用VS Code或记事本少用Excel。不是说Excel不能用而是Excel的“另存为默认编码”容易把文件改掉尤其是跨系统协作时这个坑几乎百发百中。4.2 等待策略sleep用多了慢用少了挂无框架方案没有框架提供的内置等待机制所以很多人图省事直接在代码里写time.sleep(3)。这个做法在固定环境下看着能跑但换一台性能差一点的电脑或者网络稍微波动一下用例就会随机失败。随机失败比稳定失败更可怕因为它让团队开始怀疑自动化的可信度。正确做法是全面使用WebDriver的显式等待。上面的示例里我已经用了WebDriverWait这里再补充一个细节等待条件要分层次选。打开页面后等登录框出现用presence_of_element_located点击按钮后等结果消息可见用visibility_of_element_located如果某个元素是异步加载后出现可能还要用element_to_be_clickable。把等待条件写好这套无框架方案的稳定性会有质的提升。我曾经遇到过一版代码在本地跑十分钟稳定通过放到服务器上就跑挂的情况最后定位就是固定sleep导致的。换成显式等待之后同样的脚本在两边都正常执行问题瞬间消失。4.3 失败定位没打印case_no等于没有排查入口无框架方案因为代码量少很多人会在循环里忘记打印当前正在执行的用例编号。我在项目早期就吃过这个亏一次性跑二十条用例执行到第三条时浏览器崩了日志只显示“element not found”却完全不知道是哪一行数据触发的问题。最后只能打断点重新跑白白浪费了不少时间。解决方案是在循环开始处输出当前用例信息并且在异常捕获时把案例的关键字段也一起打出来。比如for case in cases: print(f正在执行 {case[case_no]}用户: {case[username]}) ok, detail run_case(case) print(f{case[case_no]} - {PASS if ok else FAIL}{detail})这个习惯成本极低收益却很大。日志里有了CASE004这个上下文排查时就能立刻回到CSV里看这一行数据到底是什么再判断是数据写错、还是定位器失效、还是页面环境异常。排查一条失败用例的时间可以从小时级降到分钟级。4.4 CSV被Excel打开过之后格式悄悄变了这是一个特别具有代表性的坑也几乎是无框架方案逃不掉的坑。有一次团队里的业务同事要临时调整测试数据直接用Excel打开了login.csv改完保存关掉。结果再跑自动化时我检查报告发现全用例都挂了特别是用户名列很多变成了科学计数法表达。原因很典型Excel对长数字列有自动格式化逻辑比如手机号、订单号、身份证这类超过一定长度的数字会被当成数值类型处理从而显示成科学计数法。CSV一旦被Excel“清洗”过数据就不再是你原来定义的那个纯文本了。为了规避这个情况我的措施是尽量避免直接让同事用Excel修改原始CSV而是给一个独立的填写模板模板里所有列都预先设置成文本格式。如果只能用Excel那就在关键列前加一个单引号强制按文本处理。更彻底的做法是数据生成也由脚本完成比如手工维护一个固定的用例表设定好条件后自动生成CSV。这些手段都不是高深的架构设计但能极大减少无框架方案里的低级事故。4.5 断言别用整页源码结果才有价值无框架方案里断言写得太粗或太细都会带来问题。太粗的写法是assert case[expected] in driver.page_source把整个页面源码拿来做包含判断优点是写起来省事缺点是页面上任何隐藏的文本都可能干扰断言一个不起眼的备注文字就能让用例误判。太细的写法是对每一次操作都做完整断言比如校验每个输入框的值、每个提示的样式这会让用例非常脆弱页面改一个文案就挂一片。比较合理的做法是找到业务结果最集中的那个元素对它的文本做精确断言就像登录示例里对message元素的处理。message WebDriverWait(driver, 10).until( EC.visibility_of_element_located((By.CLASS_NAME, message)) ) actual message.text.strip() return case[expected] in actual, f实际结果: {actual}这样写出来的断言表达的是“用户在这个页面上能看到的真实反馈”而不是“HTML源码里是否有某段字符串”。数据驱动的结果才有业务解释价值排查故障时也更能定位到是交互层问题还是数据层问题。5. 什么情况下应该升级到框架边界与路径5.1 我从这套方案中得到的三条判断标准无框架方案适合的场景我在前面也强调了主要是用例量不大、人员少、协作简单。真正落到实际决策上我自己习惯用三条标准来判断是否该引入框架第一用例总数是否超过两百。如果持续大量增加CSV文件的维护会变得笨重框架对用例的分组、筛选和标签管理会更合适。第二是否需要多人同时维护。一个人维护时可以靠记忆和习惯多人维护时则需要框架的规范来约束代码风格。第三是否需要跨浏览器或者分布式执行。如果团队要求每种浏览器都跑一遍甚至多台机器并行无框架方案的手写成本会迅速上升。这些判断标准不是绝对真理但足够用来避开“过早框架化”和“长期了无脑坚持无框架”两个极端。在我看来工具是为业务服务的如果某一天无框架方案开始阻碍业务发展那就果断升级不要为了技术情怀硬扛。5.2 如果未来要升级从这三个点开始最平滑不少团队担心无框架方案和框架完全割裂未来推倒重来成本很大。其实不会无框架方案里的数据文件可以原封不动保留最大的改动只是引擎部分。我当时设想的三步升级路径是第一步把lib/engine.py里重复的WebDriver操作重构成页面对象但只抽高频使用的模块比如登录、导航、搜索。不要为了设计模式把所有元素都封装一遍那会让前期成本暴涨。第二步引入pytest作为用例收集器和断言库CSV数据继续沿用只是让pytest来负责组织每条用例执行。第三步如果需要更丰富的报告把result.csv渲染成HTML页面或者接入现成的报告组件。这三个步骤的特点是每一阶段都仍然能跑都保留了上一阶段的数据资产。单位不必一次性切换到完整框架可以根据团队节奏逐步推进。这样既照顾了业务稳定也不错过框架带来的长期优势。5.3 无框架方案与成熟框架的差异到底差在哪用一张表来对比会更直观。这里对比的不是谁好谁坏而是回答“各自的边界在哪里”维度无框架数据驱动成熟测试框架用例组织CSV的行记录直观但弱约束类、方法、标签结构化强数据驱动手写for循环读取内置数据提供者支持参数化断言管理Python内置assert断言库、软断言、失败重试报告输出自写简单CSV集成HTML、Allure等报表并发执行基本没有串行为主内置或插件级并发行学习成本低半天可上手较高需要专门学习适合阶段早期、中小用例量大型、多人、复杂场景无框架方案在功能完整度上显然逊色但在“快速验证”“小步跑通”“团队零基础”这类场景下它的价值极其突出。一个团队如果连自动化都还没跑起来与其讨论框架选型不如先用无框架方案感受一下数据驱动的全过程等真正理解了自动化难点在哪再决定要不要引入框架也不迟。最后分享一个我现在还在用的习惯即使后来部分流程迁移到了框架里cases目录下继续用CSV文件维护数据的做法一直没有变。它让每个新加入的同事第一天就能看懂用例结构回归之前人眼扫一遍表格也能知道哪些数据是重点。这一点反而是很多复杂框架给不了的。如果你正纠结于UI自动化到底要不要上框架我的建议是先别纠结把WebDriver加CSV这套最小的循环跑起来让它成为团队自动化的起点。

相关新闻

Rust Serde实战:JSON与TOML集成的核心技巧与踩坑指南

Rust Serde实战:JSON与TOML集成的核心技巧与踩坑指南

1. 为什么说 Serde 是 Rust 数据层的"基础设施"1.1 序列化框架要解决的根本问题先聊一个最基础的问题:我们写程序,数据在内存里是一堆结构体、枚举、Vec,但一旦要落盘、要发到网络上、要给别人消费,就必须变成一串字节或…

2026/10/9 8:58:30 阅读更多 →
tilelang昇腾组件开源:从tile描述到高效算子的编译实践

tilelang昇腾组件开源:从tile描述到高效算子的编译实践

最近开源社区里热度很高的一件事,是某头部AI团队把 tilelang 的昇腾组件开源了。作为一个常年跟算子性能较劲的人,我第一时间就把代码拉下来过了一遍。tilelang 是一个面向算子开发的 tile 级编译器框架,它的吸引力在于:你不需要手…

2026/10/9 8:58:30 阅读更多 →
P3619《魔法》题解:贪心排序与C++任务调度实现

P3619《魔法》题解:贪心排序与C++任务调度实现

打卡信奥刷题到 P3619 这道题时,我一度以为它只是普通的模拟题,结果连续提交两次都栽在同一个地方。这道名为《魔法》的 C 信奥题,表面上是让你处理一堆来源不明的咒语,剥掉那层魔法外衣之后,其实是典型的“门槛 收益…

2026/10/9 8:58:30 阅读更多 →

最新新闻

医院智能挂号系统:微信小程序+Java后端+HanLP语音挂号解析

医院智能挂号系统:微信小程序+Java后端+HanLP语音挂号解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 9:29:40 阅读更多 →
电工进阶必修:PLC品牌选择与快速上手实战指南

电工进阶必修:PLC品牌选择与快速上手实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 9:29:40 阅读更多 →
MT6236平台HI253 sensor驱动源码解析与移植实战指南

MT6236平台HI253 sensor驱动源码解析与移植实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 9:29:40 阅读更多 →
Tween.js 核心原理与工程实践:轻量时间插值引擎解析

Tween.js 核心原理与工程实践:轻量时间插值引擎解析

1. 为什么今天还要学 Tween.js?——当动画库泛滥成灾时,它凭什么还稳坐工具箱第一层“Tween.js”这四个字母出现在我电脑桌面的快捷方式栏里,已经快七年了。不是因为懒,也不是因为怀旧,而是每次打开 Figma 做交互动效预…

2026/10/9 9:29:40 阅读更多 →
工业PHM落地实战:从传感器数据到RUL预测的全流程避坑指南

工业PHM落地实战:从传感器数据到RUL预测的全流程避坑指南

简介:本资源是一份面向工业智能运维领域工程师、高校研究生及PHM方向研究者的专业技术文档,系统讲解故障预测与健康维护(PHM)算法原理与智能分析技术实践路径。内容覆盖PHM技术演进脉络、核心概念辨析(如MTBD、健康指数…

2026/10/9 9:29:40 阅读更多 →
OCA与OCR技术选型指南:从字符识别到文档结构理解

OCA与OCR技术选型指南:从字符识别到文档结构理解

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 9:28:35 阅读更多 →

日新闻

Java时间API实战:LocalDate、Date与ZonedDateTime的转换与避坑指南

Java时间API实战:LocalDate、Date与ZonedDateTime的转换与避坑指南

Java时间API这个话题,隔三差五就会在群里被翻出来讨论一次。上周还有个同事线上处理一个订单超时问题,排查到最后发现是ZonedDateTime序列化后时区丢了,用户在下单当天晚上看到的时间整整差了8个小时。这类问题几乎每个做Java开发的人都遇到过…

2026/10/9 0:00:49 阅读更多 →
EasyTier实践:从NAT穿透到子网代理的异地组网部署与排错

EasyTier实践:从NAT穿透到子网代理的异地组网部署与排错

前几个月我手头有好几台机器需要互相访问:办公室台式机、家里 NAS、还有一台云主机。如果只是偶尔传个文件倒还好,问题是工作场景经常要在几处环境之间来回切换,每次都先登录跳板机再层层代理,实在折腾。我先后试过端口映射、自建…

2026/10/9 0:00:49 阅读更多 →
AI Agent工程实战:从七要素到七个决策点的系统设计指南

AI Agent工程实战:从七要素到七个决策点的系统设计指南

AI Agent 这个词在过去一年里被反复提及,但真正动手搭过一套能跑起来的 Agent 系统的人都知道,从"知道它是什么"到"让它稳定干活"之间隔着一整套工程决策。我前后参与过几个 Agent 项目的落地,从最初用现成框架拼装&…

2026/10/9 0:01:50 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 15:26:32 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 15:26:40 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 10:10:36 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 21:13:17 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 15:26:17 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 6:17:20 阅读更多 →