05-AI的外挂:自己造,真香

49 阅读14分钟

AI的外挂:自己造,真香

一句话总结:抛弃了对标准框架和第三方工具的依赖,自己动手造,才能实现真正的代码自由和开发自由。

核心观点:不要迷信标准框架和MCP工具。适合自己的才是最好的。

AI是平的 —— 直接基于协议,少堆框架,AI理解成本更低。


背景:我们需要AI能操作浏览器

2025年,我们让AI参与前端开发时遇到一个瓶颈:

AI能写代码,但不能运行验证。

比如:

  • AI:"这段代码应该能实现登录功能"
  • 我们:"怎么验证?"
  • AI:"你们手动测试一下吧"
  • 我们:"......"

我们需要一个能力:让AI能够:

  1. 操作浏览器(打开页面、输入、点击)
  2. 调试页面(抓取控制台、查看网络请求)
  3. 验证功能(截图、检查DOM)

这样AI就能自己写代码、自己测试、自己验证,形成闭环。


探索过程:我们试过的MCP工具

一开始,我们也是"拿来主义":

GitHub上有什么MCP工具,我们就试什么

  • puppeteer-mcp
  • chrome-devtools-mcp
  • browser-automation-mcp
  • playwright-mcp
  • 还有一些社区推荐的自制工具

前后试了5-6个不同的工具,每个都用了1-2周。

这些工具的优点

说句公道话,这些工具本身并不差

功能完整:基本的浏览器操作都支持 ✅ 设计良好:有规范的接口,清晰的文档 ✅ 持续维护:大多数都有活跃的社区

但在我们的场景下,遇到了问题

问题1:不可控

这是最核心的问题

我们前端自动化有个特点:需要频繁、大量地调用

比如:

  • AI写一个组件 → 启动浏览器测试 → 关闭
  • AI改一个样式 → 启动浏览器验证 → 关闭
  • AI修一个bug → 启动浏览器调试 → 关闭

一天可能启动几十次甚至上百次

别人的MCP工具:

  • 今天启动:成功 ✅
  • 明天启动:失败 ❌ (端口被占用)
  • 后天启动:成功 ✅
  • 大后天启动:失败 ❌ (Chrome进程没杀干净)

问题在哪

  • 工具内部的进程管理太复杂
  • 各种边界情况没处理好(端口冲突、权限问题、进程残留)
  • 跨平台兼容性问题(Windows、WSL、Mac各不一样)

结果

  • 不能保证每次都成功
  • 失败了不知道怎么修(源码几万行,看不懂)
  • 每次"启动失败"都要花时间调试

我们的感受

不是工具不好,而是不可控。

对于频繁使用的场景,"能用"是不够的,必须"每次都能用"。

问题2:调试困难

当工具出问题时

  • 想看日志?工具封装了一层,日志不详细
  • 想改配置?配置项太多,不知道哪个生效
  • 想看源码?几万行代码,不知道从哪看起

真实场景

某天,工具突然启动失败。
我们:查日志 → "Failed to connect to browser"
我们:什么原因?
工具:日志就这一行。
我们:......
我们:去GitHub提issue
我们:等作者回复(可能几天,可能几周)
我们:......算了,还是自己排查吧
我们:扒源码 → 找问题 → 修bug
我们:好几个小时过去了

问题

  • 工具封装太深,出了问题摸不着
  • 文档不完善,很多配置项不知道是干什么的
  • 作者可能不维护,issue没人回

我们的感受

别人的工具,就像一个黑盒子。

能用的时候很爽,不能用的时候很痛苦。

问题3:功能不够灵活

标准工具的设计哲学:覆盖80%的常见场景。

我们的需求

  • "我想复用已打开的Chrome浏览器,不要每次都启动新的" → 工具:不支持(每次都是新的实例)

  • "我想在WSL里访问Windows上的Chrome" → 工具:不支持(没考虑过这种场景)

  • "我想把截图保存到指定路径,不要用时间戳命名" → 工具:不支持(路径是固定的)

  • "我想用Chrome的特定flag启动(忽略证书错误)" → 工具:不支持(可以提feature request)

问题

  • 我们的场景比较特殊(Windows多开、WSL、开发环境复杂)
  • 标准工具为了通用性,牺牲了灵活性
  • 很多"小需求"等工具作者支持要很久

我们的感受

工具不满足需求的时候,就两个选择:

1. 等(等作者支持) 2. 改(改源码,但看不懂)


我们的决定:自己试试

当时团队里讨论了一下:

反对意见

"工具功能挺全的,只是有些小问题,修修能用?" "自己造要花多少时间?" "我们又不是做工具的团队"

支持意见

"我们已经试了5-6个工具,每个都有各种问题" "调试工具的时间,都够自己写一个了" "我们的需求很明确,做出来肯定能用"

最后决定

花2周时间试试,不行再用别人的。


我们的方案:极简设计

核心理念:脚本 + CDP协议

我们没有做"完美的工具",而是:

只用脚本

  • 每个场景一个shell脚本
  • 直接调用CDP协议(Chrome DevTools Protocol)
  • 不封装、不抽象、不做CLI

只用TOS

  • TOS = The Old School(老派做法)
  • 直接WebSocket连CDP
  • 直接发JSON-RPC命令
  • 不依赖第三方库

核心能力

  1. 会话管理:启动、复用、关闭浏览器
  2. 页面操作:导航、输入、点击、截图
  3. 调试能力:控制台、网络请求、DOM操作
  4. 产物管理:截图、日志自动归档

技术细节

启动浏览器

# 只用最简单的命令
chrome --remote-debugging-port=9222 --user-data-dir=/path/to/profile

连接CDP

# 直接用curl
curl http://localhost:9222/json
# 返回WebSocket URL

操作页面

# 直接发WebSocket JSON-RPC
{"id":1,"method":"Page.navigate","params":{"url":"https://example.com"}}

优势

  • 透明:每一步都能看到发生了什么
  • 可控:出问题了,一眼就知道在哪
  • 灵活:想改什么,直接改脚本

我们做了什么:场景驱动

每个场景一个runbook

我们不做"大而全"的工具,而是:

每个场景一个runbook(20+个):

  • 会话启动与复用
  • 调试执行脚本表达式
  • 调试抓取控制台输出
  • 调试查看网络请求
  • 调试页面截屏
  • 输入点击与键盘
  • 拖动滑块
  • 移动端手势
  • 整站抓取
  • 深度在线搜索
  • ...(20+个场景)

每个runbook都是AI帮我们写的

  1. 我们描述需求
  2. AI生成脚本
  3. 我们测试验证
  4. AI优化改进

结果

  • 代码简洁:每个runbook平均50-100行
  • 功能完整:协议支持的都能做
  • 易于维护:改需求就加个runbook,不影响其他

AI是怎么帮我们的?

为什么2周能做完?

答案:80%的脚本代码是AI写的。

场景1:我们不懂CDP协议的某个API

我们:"怎么用CDP协议点击一个按钮?"
AI:"用DOM.resolveNode获取节点ID,然后用DOM.setDescription."
我们:生成脚本。
AI:"[完整脚本,带错误处理]"
我们:一跑,成了!

场景2:我们不会处理WSL网络问题

我们:"WSL里访问Windows的浏览器端口,一直连不上。"
AI:"WSL到Windows需要用特殊IP。建议两种方案:
     1. 使用$(hostname).local访问
     2. 配置端口转发..."

我们:选方案1,生成脚本。
AI:"[完整的启动脚本,带自动检测]"
我们:搞定!

场景3:我们要实现"会话复用"

我们:"我想复用已打开的Chrome,而不是每次都启动新的。"
AI:"可以用CDP的WebSocket连接。方案:
     1. 启动Chrome时加--remote-debugging-port
     2. 访问http://localhost:9222/json获取WebSocket URL
     3. 建立WebSocket连接复用会话
     [完整实现]"

我们:太棒了,直接用!

这就是为什么快

  • 我们不懂的 → AI懂(CDP协议细节)
  • 我们不会的 → AI会(网络配置、错误处理)
  • 我们卡住的 → AI突破(跨平台兼容性)

我们得到了什么

核心优势:可控、稳定、高效

1. 极高的启动成功率

别人的工具:70-80%(经常遇到端口冲突、进程残留等问题)

我们的脚本:95%+(只有明确的几个失败场景,比如Chrome被手动关闭了)

为什么

  • 代码简单,边界情况少
  • 我们自己写的,清楚知道每个细节
  • 出问题一眼就能定位
2. 速度快

别人的工具

  • 启动:10-30秒(工具要做各种初始化、检查)
  • 操作:每次几百毫秒(多层封装)

我们的脚本

  • 启动:2-3秒(直接启动Chrome,连接CDP)
  • 操作:几十毫秒(直接发CDP命令)

对比快10倍左右

3. 完全可控

出问题时

  • 看脚本:一眼就知道执行到哪一步
  • 看日志:每个CDP命令都有返回值
  • 改配置:直接改脚本参数,不用管配置文件

调试时

  • 不用扒几万行源码
  • 不用猜工具的内部逻辑
  • 不用等作者回复issue
4. 灵活扩展

需求变化

  • "要支持新的浏览器flag" → 改启动命令,2分钟搞定
  • "要支持新的CDP功能" → 加一个脚本,AI生成,5分钟搞定
  • "要支持新的场景" → 加一个runbook,AI生成,10分钟搞定

对比

  • 别人的工具:等作者支持(可能几周、可能几个月、可能永远不支持)
  • 我们的脚本:想改就改,立刻生效

核心原则

原则1:先用标准工具,不满足再自己造

我们不是一开始就自己造的,而是:

  1. 先试别人的工具

    • GitHub上有什么MCP工具
    • 社区有什么最佳实践
    • 试用5-6个工具,每个用1-2周
  2. 判断是否满足需求

    • 功能是否满足(80%原则)
    • 稳定性是否可靠(关键指标)
    • 是否可控(出了问题能不能修)
  3. 决定是"用"还是"自己造"

    • 如果80%满足,且稳定可控 → 用别人的
    • 如果不满足,或者不可控 → 自己造

我们的建议

不要一开始就想"我要自己造",也不要迷信"别人的工具最好"。

先试,试了不行再自己造。


原则2:协议是基础,框架是参考

MCP/CDP协议本身就很强大

  • 协议支持的,都能做
  • 协议不支持的,AI能生成

框架只是别人的一种封装

  • 适合别人的,不一定适合你
  • 别人的封装,你可能看不懂
  • 别人的设计决策,你可能不认同

我们的选择

  • 直接用CDP协议
  • 不封装、不抽象、不依赖第三方库
  • 保持简单、透明

结论

掌握协议,超越框架。


原则3:场景驱动,不做"大而全"

不要:一开始就想做"完美的工具"

  • 支持所有场景
  • 支持所有平台
  • 有完整的CLI和配置

:从具体场景出发

  • 这个场景需要什么功能
  • 实现这个功能
  • 测试、验证、迭代

我们的做法

  • 第一个场景:"打开浏览器,访问页面"
  • 第二个场景:"输入文字,点击按钮"
  • 第三个场景:"截图保存"
  • ...逐步增加

结论

小步快跑,快速迭代。


原则4:AI是你的开发伙伴

我们不懂的

  • CDP协议的细节? → 问AI
  • Linux网络配置? → 问AI
  • 跨平台兼容性? → 问AI

我们不会的

  • 脚本写不出来? → 让AI写
  • Bug修不好? → 让AI修
  • 性能优化? → 让AI优化

结论

AI能帮你做80%的工作。

你只需要做那20%的关键决策。


实践总结

我们的成果

时间成本

  • 预期:自己做一个工具,至少2-3个月
  • 实际:2周(AI帮我们写了80%的脚本)

核心指标

指标别人的MCP工具我们的脚本
启动成功率70-80%95%+
启动速度10-30秒2-3秒
稳定性经常出问题很少出问题
可控性出问题了看不懂一眼就知道在哪
灵活性不支持特殊需求想改就改
调试难度很难调试容易调试

总结

  • 成功率:提升20%+
  • 速度:快10倍
  • 可控性:完胜

完全满足前端自动化需求

AI现在的能力

  1. 写代码
  2. 启动浏览器(自动)
  3. 测试验证(自动)
  4. 抓取日志(自动)
  5. 截图保存(自动)
  6. 修复bug(循环)

形成完整闭环

AI写代码 → 启动浏览器测试 → 验证功能 → 发现bug → 修复bug → 再测试

效率提升

  • 以前:AI写代码,我们手动测试(半天)
  • 现在:AI写代码+测试+验证(10分钟)

持续优化中

当前状态

  • ✅ 基础能力完善(20+个runbook)
  • ✅ 启动成功率95%+
  • ✅ 基本满足前端自动化开发需求

未来规划

  • 🔄 增加更多场景(移动端模拟、性能测试)
  • 🔄 优化错误处理(进一步提升成功率)
  • 🔄 完善产物管理(截图、日志的组织)
  • 🔄 集成到AI工作流(让AI自动调用这些runbook)

我们的理念

不做"完美的工具",只做"够用的工具"。

先做能用,再做好用。


给你的建议

建议1:先试标准工具,判断清楚再决定

第一步:看看别人做了什么

  • GitHub上有什么MCP工具
  • 社区有什么最佳实践
  • 团队里有什么现成的

第二步:认真试用(至少1-2周)

  • 功能是否满足需求(80%原则)
  • 稳定性是否可靠(这是关键!)
  • 是否可控(出问题了能修吗?)
  • 调试是否容易(日志是否详细?)

第三步:决定是"用"还是"自己造"

  • 如果80%满足,且稳定可控 → 用别人的
  • 如果不满足,或者不可控、调试困难 → 自己造

建议2:自己造,就从场景开始

不要:一开始就想做"完美的工具"

  1. 从最小场景开始

    • 第一个场景:"打开浏览器,访问这个页面"
    • 第二个场景:"输入文字,点击按钮"
    • 第三个场景:"截图保存"
  2. 让AI帮你写脚本

    • 描述需求(说清楚要做什么)
    • AI生成脚本(让它解释为什么这么做)
    • 你测试验证(实际运行看看)
    • AI优化改进(发现问题就改)
  3. 逐步迭代

    • 这个场景能用了 → 再加下一个场景
    • 遇到问题 → 修bug
    • 需要新功能 → 加runbook

建议3:记住"AI是平的"

什么是"平的"

  • 不堆框架、不封装、不抽象
  • 代码 → 协议 → 功能
  • 简单、直接、高效

为什么"平的"很重要

  • AI理解成本低(直接协议,AI天生懂)
  • 调试成本低(出问题了,一眼看到底)
  • 维护成本低(自己写的,一看就懂)
  • 定制化成本低(协议不支持的,一句话生成)

结论

别再往代码上堆框架了。

AI理解不了那么多层。

你也理解不了那么多层。


总结

我们的经历

  1. 先试别人的工具(5-6个MCP工具,每个用1-2周)
  2. 发现不满足需求(不可控、不稳定、不灵活)
  3. 决定自己造(花2周时间,AI帮写80%代码)
  4. 完全满足需求(95%+启动成功率,快10倍)

核心原则

  1. 先用标准工具,不满足再自己造
  2. 协议是基础,框架是参考
  3. 场景驱动,不做"大而全"
  4. AI是你的开发伙伴
  5. AI是平的,少堆框架

给你的建议

  • 不要迷信标准框架和MCP工具
  • 先试,试了不行再自己造
  • 记住"AI是平的",保持简单

相关章节

返回序章 | 继续阅读


📖 在线阅读juejin.cn/post/758830…