日期:2026-11-12 GitHub Trending 日榜第 3 名;快照采集于北京时间 16:00:35。
让编码 Agent 写一个删除确认框,它很可能交出一套自定义遮罩:监听 Esc、循环处理 Tab、切换背景的 inert,再给弹窗补 ARIA 属性。代码能跑,但浏览器原生 <dialog> 已经承担了其中不少工作。更麻烦的是,直接改成原生组件,也可能漏掉取消动作、滚动穿透和旧浏览器回退。
Modern Web Guidance 处理的正是这种落差。它把网页开发建议整理成可搜索、可按主题取回的指南,让 Agent 在写实现之前先查一小段相关知识。项目值得拆开的部分,是本地检索、兼容性策略和配套评测如何连起来,而不是又多了一份"请写现代代码"的提示词。
📋 项目概览
| 项目 | 内容 |
|---|---|
| 主仓库 | GoogleChrome/modern-web-guidance-src |
| 项目名称 | Modern Web Guidance |
| 产品定位 | 面向编码 Agent 的 Web 平台指南、搜索 CLI,以及指南编写与评测工具链 |
| 分发仓库 | GoogleChrome/modern-web-guidance |
| 快照 Stars / Forks | 2,037 / 151 |
| GitHub 主语言 | TypeScript |
| 软件许可 | Apache-2.0;guides/ 下文档和指南内容另按 CC BY 4.0 授权 |
| 运行要求 | 发布 CLI 要求 Node.js 22 及以上;源码开发清单要求 Node.js 22.18.0 及以上 |
| 主要入口 | search、retrieve、legacy-scan,以及供贡献者使用的构建和评测工具 |
源码仓库和分发仓库需要分清:前者包含原始指南、宏展开、向量处理、评分器和仪表盘;后者是安装到 Agent 一侧的产物。普通使用者不必为了查一个 CSS 模式,把整个评测环境装起来。README 同时说明了两个仓库的职责,以及软件和指南内容的不同许可。
🔥 为什么值得关注
浏览器平台的变化并不等于模型知识的同步更新。旧代码在训练语料里占了很大比例,Agent 即使知道某个新 API 的名字,也未必知道它和现有页面交互时的细节。
弹窗是个好例子:用 showModal() 能获得原生模态行为,但 show() 和直接设置 open 不是同一回事;closedby 能表达关闭策略,却不能在缺少该属性支持的浏览器里独自保护未保存表单。单纯提示"使用 HTML5"对这些问题几乎没有帮助。
这个项目选择把知识取用放到工具调用里。Agent 先把业务需求转换成短英文查询,搜索结果只返回指南 ID 和描述;判断相关后再取全文。这样既不用把所有文档常驻上下文,也给"这次实现究竟参考了哪条建议"留下了可见线索。
它还有一项容易被忽略的价值:兼容性建议不必全写死在提示词里。指南构建过程会结合浏览器支持数据,运行时再根据项目的 .mwgrc 加上目标策略。不过,运行时读的是包里生成好的指南,不是每次请求都联网查询浏览器数据库。要拿到更新后的兼容性内容,仍然需要更新分发产物。
🏗️ 核心特性
按任务找指南,不把整个知识库塞进上下文
技能入口 建议使用 2---5 个词、面向动作的英文查询,例如 confirmation modal dialog。它明确要求拆开多主题任务,不要把框架名、业务页面名和几个 UI 需求混成一句搜索词。
这和底层实现有关。查询侧使用英文词表和词法分词,不是一个随时能理解任意中文长需求的对话模型。对中文用户,比较合理的分工是由 Agent 翻译并提炼查询,而不是把完整中文需求直接交给检索器。
命中后,retrieve 会返回具体实现建议、注意事项及回退方案。技能里的"按指南复核代码"仍由 Agent 执行;它不会因为安装成功,就自动变成每个项目的编译检查。
实验性能力可以被发现,但默认不能直接取回
指南可能关联 Origin Trial 或尚不稳定的单引擎特性。项目把这些元数据写入指南索引。搜索阶段保留可发现性,取回阶段则检查项目是否显式允许相应能力。
这能避免一个常见误用:搜索排序靠前,就被当作适合生产的推荐。这里的排序表示相关性,不表示兼容性承诺。真正的取回路径还要经过策略检查。
旧代码扫描只覆盖有规则的模式
legacy-scan 是另一条入口。它扫描代码中的既有模式,把发现按指南分组,输出文件、行号和判断依据。结构化结果中还能带上 keepWhen、dropWhen,供 Agent 排除误报。
例如,项目为了支持旧浏览器保留的一段 JavaScript,未必应该删除。命中旧模式只能说明"这里值得看一眼",不能说明替换一定正确。技能也把扫描限定在开放式现代化改造场景,不要求每次新增组件都先全仓扫一遍。
指南带有行为期望,评测不止检查措辞
仓库的指南目录通常不仅有 guide.md,还会有演示、行为期望和评测材料。维护者可以让 Agent 分别在有指南、无指南的条件下修改基础应用,再用 Playwright 断言生成结果。
这条链对指南作者很有用:建议写得再漂亮,如果 Agent 取不到、误解了,或者生成代码仍然失败,都应当回到内容和任务设计里修正。它测的是特定任务与断言,不是一次性证明整个前端工程质量。
🔬 技术架构深度解析
项目有两条不同的工作链:维护者生产指南,使用者搜索和取回指南。把它们混画成"用户请求经过 LLM 后生成代码",会漏掉它最有意思的实现。
text
指南作者
guide.md / 行为期望 / 演示
│
├── 构建:展开宏、解析 Web Feature、划分检索片段
│ │
│ ├── 完整指南 Markdown + guides.json
│ └── 片段文本 + 文档向量 / 量化比例
│
└── 评测:基础应用 → 有/无指南的 Agent → Playwright 断言
│
└── 结果与仪表盘
编码 Agent
短英文查询
│
▼
静态词表查询向量 ──→ 逐片段余弦匹配 ──→ 每指南取最大值
查询中的字面词 ───→ BM25 片段评分 ───→ 每指南取最大值
│
▼
RRF 合并 → 默认前 10 项
│
Agent 选择相关指南 ID
│
▼
retrieve → .mwgrc 特性门控
│
项目 Baseline 提示
│
完整指南进入上下文
1. 查询向量和文档向量并不走同一条编码路径
StaticEmbedder 的运行过程很克制:加载词表、Int8 词向量表和每行比例;对查询分词,查出已知词的向量,按权重求和后进行 L2 归一化。向量维度由 STATIC_DIMS 定为 256。
连字符也有单独处理。完整词若存在,直接使用;不存在时,才尝试把连字符连接的部分拆开,并在匹配部分之间分配权重。未知词不会触发一次远端模型调用。
文档侧不同。构建工具读取预先生成的片段向量缓存;仓库的检索说明将它描述为用教师嵌入模型生成文档向量,再与蒸馏得到的查询词表共享空间。运行时因此不必载入完整 Transformer 来处理几个查询词。
这里的取舍很明确:查询便宜、分发包可以自包含,但表达能力受词表、分词和预训练空间限制。它适合在一个限定的 Web 指南集合里找主题,不应顺手推广成通用语义搜索引擎。
构建时缺少缓存向量,也不必把整份指南丢掉。默认构建保留片段文本并使用空向量,让它仍能通过 BM25 被找到;带 failOnMissingVectors 的严格路径则会拒绝缺失。这是检索质量的降级,不是运行时自动联网补齐向量。
2. 两条检索结果按排名合并,而不是直接相加分数
search.ts 遍历片段向量,计算归一化向量的点积。同一指南可能有多个片段,最终取其中最匹配的片段作为该指南的稠密相似度。它没有在运行时接一个远端向量数据库,也不是用近似最近邻索引跳过大部分片段。
词法侧对描述和片段内容建立 BM25 索引。同一指南同样取最高片段分数,避免一份长指南只因片段多,就靠累加获得优势。API 名称、缩写等字面信息可以由这条路径补回来。
随后使用 Reciprocal Rank Fusion,默认参数 k=60。直观说,结果在任一路榜单上排名越靠前,得到的贡献就越大;两路都排得不错的指南会更有竞争力。它合并的是名次,因此不需要假定 BM25 分值与余弦相似度处于同一尺度。
还有一个重要细节:默认 0.3 是查询级门槛。只有稠密结果最高相似度低于门槛,且 BM25 也没有命中时,搜索才返回空数组。若稠密最高值不足而词法有命中,融合时会去掉稠密榜单,保留词法结果。它不是把最终每条指南都强行过滤到 similarity >= 0.3。
内部函数返回相似度等信息,CLI 对外则压缩为 {id, description},默认最多十项。这个区别对调用方很实际:不能期待命令输出里总带着完整的评分解释。
3. 量化节约分发体积,但运行时内存不是同一个数字
查询表和片段向量都使用 Int8 存储,并附有浮点比例。量化工具 对每行计算比例,解码后再归一化;零比例的文档行返回空向量,搜索会跳过它的稠密匹配。
对文档片段,loadVectors() 会把量化数据还原成 Float32 向量,并缓存语料和 BM25 索引。因此,"磁盘里是一字节整数"不能直接推导为"搜索时每个维度只占一字节内存"。冷启动还要付出读取、解压、解析和索引构建的成本。
如果把片段数量记作 C、向量维度记作 D,稠密路径每次查询仍要做约 C×D 规模的乘加;词法路径也会遍历其文档表示。这是对实现循环的成本判断,不是某台机器上的延迟测试。对于当前这种限定主题的文档集合,简单扫描换来了较少的部署部件;如果扩成大型企业知识库,不能照搬其性能预期。
4. .mwgrc 的硬门控和软提示需要分开看
retrieve.ts 先从索引中找到 ID,再读取项目配置。只要指南带有某类门控特性,而对应字段不严格等于布尔值 true,它就抛出特性门控错误。命令行会把错误写到标准错误;多 ID 取回允许已成功的指南输出,但只要其中有错误,最终退出码仍为 1。
这意味着自动化调用方不能只看到"有 Markdown 输出"就认定整次请求成功。应同时读退出码,并识别哪一个 ID 被挡住。
配置定位也比"项目文件覆盖用户文件"更具体。mwgrc.ts 从当前目录向上查找,遇到 .mwgrc 或 .git 就停止,不合并祖先配置。只有一路没有遇到项目边界,才考虑用户目录的 .mwgrc。已经位于 Git 项目内时,不能指望个人目录的允许开关自然继承进来。损坏的 JSON 会抛错,不会默默当成默认配置。
门控挡的是正常取回接口,不是安全沙箱。文件仍在本地,Agent 也可能凭自己的知识写代码;禁止绕过的文字指令,仍依赖调用方遵守。
Baseline 目标则主要改变返回文档前面的提示。默认策略以 Widely available 为基线;newly、limited 或年份目标会附加相应说明。它并不会读取你的产物,把不符合策略的 CSS 拦在编译阶段,更不会直接测试公司使用的 WebView。
5. 评测把"指南有用"拆成可检查的问题
源码仓库有指南编写、评分器生成、校准和 Agent 评测工具。按 Harness 说明,校准目标是让预期正确的修改通过、零通过率基线失败,然后再比较 guided 与 unguided 的实际生成结果。
但"校准目标"不等于每次生成出来的评分器天然可靠。评分器本身也是需要审阅的代码,覆盖范围由任务和行为期望决定。
dialog 的行为期望就很具体:原生元素是否具有可访问名称;打开时是否处于 :modal;关闭后焦点是否回到调用者;未保存内容是否得到保护;从弹窗内按下、拖到遮罩释放时是否误关闭;背景是否仍能被聚焦或滚动。这些断言比只检查源码里出现了 <dialog> 更接近用户遇到的问题。
评测配置还要和实际采用策略一起看。源码定义的 guided 默认配置会允许 Origin Trial 和 volatile 特性,这和普通项目缺省不允许的取回策略不同。因此,维护者评测里的提升不能不加条件地当成所有保守项目的预期收益。模型、任务、断言集合和允许采用的能力都应当对齐,才谈得上可比。
📖 README 核心内容摘要
README 提供了几种使用方式:通过 npm CLI 安装,或者使用不同 Agent 的插件和技能安装入口。对团队接入而言,优先看清下面几件事。
第一,技能和工具承担不同职责。技能告诉 Agent 什么时候查、怎么组织查询、何时取回,以及如何复核;CLI 则实现检索、读配置和输出。安装了技能不等于这些建议已经变成仓库 CI 的强制规则。
第二,兼容性数据存在构建时与运行时的边界。源码依赖 web-features 和 MDN 浏览器兼容性数据,用来生成具体指南。运行时取回的是本地 Markdown;想把浏览器新变化带进 Agent,需要更新指南包,而不是仅仅更换聊天模型。
第三,"本地检索"与"整个命令绝不联网"不是一回事。搜索和取回的核心算法可以本地完成;首次 npx 下载、安装子命令,以及默认启用的遥测另有网络边界。
遥测实现 会记录搜索查询、命中的指南、调用成功与否、延迟分桶、版本和 Agent 等信息。README 说明原始用户提示词不在采集范围内,但 Agent 生成的搜索查询仍可能包含业务词。企业接入不能把"离线搜索"自动理解成"没有数据外发";可按需在调用环境设置 DISABLE_TELEMETRY=1,不必为了试用修改全局 shell 配置。
最后,许可证要按内容类型看。软件代码是 Apache-2.0,指南内容是 CC BY 4.0。把指南复制到公司文档、衍生资料或其他分发物时,应保留适用的署名与许可信息,不能只看到根目录的软件许可证就忽略文档授权。
🚀 快速上手
先准备 Node.js 22 或更高版本。下面固定使用已发布的 1.0.0,先只搜索和取回,不安装 Agent 插件,也不修改项目策略。
bash
node --version
DISABLE_TELEMETRY=1 npx --yes modern-web-guidance@1.0.0 --help
DISABLE_TELEMETRY=1 npx --yes modern-web-guidance@1.0.0 search "confirmation modal dialog"
DISABLE_TELEMETRY=1 npx --yes modern-web-guidance@1.0.0 retrieve dialog
这组查询的返回结果中包含 dialog、declarative-dialog-popover-control 等指南。调用者应根据描述选相关项,不要把前十项全部取回。查询主题换成表格、动画或表单时,也应重新搜索,而不是凭印象拼一个 ID。
retrieve 的输出若超过 9,500 字节且标准输出不是普通文件,CLI 会尝试把完整内容保存到临时 Markdown 文件,并打印路径。要继续读那份文件,不能把终端里短短的路径提示误当成完整指南。若需要自己控制输出,可重定向到文件:
bash
DISABLE_TELEMETRY=1 npx --yes modern-web-guidance@1.0.0 retrieve dialog > dialog-guide.md
一个删除确认框的最小实现
下面是围绕原生模态语义组织的独立示例。可以存为 HTML 页面,用项目支持的浏览器检查交互。它使用 showModal(),没有引入额外的弹窗库,也没有依赖较新的声明式 Invoker Commands。
html
<button id="remove" type="button">删除草稿</button>
<p id="result" role="status"></p>
<dialog id="confirm" aria-labelledby="confirm-title">
<h2 id="confirm-title">确定删除草稿?</h2>
<p>此示例只显示结果,不执行真实删除。</p>
<form method="dialog">
<button value="cancel" autofocus>保留</button>
<button value="delete">删除</button>
</form>
</dialog>
<style>
dialog:modal {
overscroll-behavior: contain;
}
dialog::backdrop {
background: rgb(0 0 0 / 40%);
overflow: hidden;
overscroll-behavior: contain;
}
</style>
<script type="module">
const trigger = document.querySelector('#remove');
const dialog = document.querySelector('#confirm');
const result = document.querySelector('#result');
trigger.addEventListener('click', () => dialog.showModal());
dialog.addEventListener('close', () => {
const choice = dialog.returnValue;
dialog.returnValue = '';
result.textContent = choice === 'delete'
? '已选择删除,业务请求应在这里单独处理。'
: '已保留草稿。';
});
</script>
这里把初始焦点放在安全的"保留"按钮;form method="dialog" 负责结束对话框;close 回调读取结果后清空 returnValue,避免下一次 Esc 关闭时误用上次选择。示例没有手工重做焦点圈定,也没有给原生模态框重复加 role="dialog" 和 aria-modal。
CSS 按指南处理滚动链。它属于需要结合目标浏览器检查的行为:部分浏览器对非滚动容器的滚动约束存在差异,不能只看到 @supports 接受某个属性就断言背景不会滚动。
如果要把示例接到真实删除接口,网络失败、重复点击、服务端授权和删除成功后的页面状态都要另行设计。弹窗正确关闭,不代表业务操作已经成功。
扫描旧项目时再使用另一条入口
在已经打开的目标项目目录中,可以运行:
bash
DISABLE_TELEMETRY=1 npx --yes modern-web-guidance@1.0.0 legacy-scan . --json
它只返回规则覆盖范围里的现代化机会,不自动改写代码。先检查每项发现的保留与丢弃条件,再决定是否取回对应指南。已有兼容回退也可能再次命中,不能为了让扫描结果归零而把它删掉。
📊 增长速度与社区热度
2026-11-12 的快照中,源码仓库位于日榜第 3 名,记录到 2,037 Stars 和 151 Forks。这个量级说明它已经吸引了一批关注者,但不能从累计 Stars 推导当天增长率,也不能把排名当成采用效果的评测。
观察这类项目的维护质量,比看一个总数更有用的是:指南变更是否有行为期望,浏览器支持数据更新后是否能进入分发产物,评分器是否随需求变化重新校准。源码仓库把这些环节放在一起,贡献者可以针对某个具体错误修指南、补断言,而不只能提交一句更强硬的提示词。
下面是当天快照记录的完整榜单:
🎯 适用场景
做 Web UI 的 Agent 集成,适合从它开始。团队可以要求 Agent 在处理表单、弹窗、布局和性能任务时,先搜索相关指南,再把真正采用的规则体现在实现里。评审时要看生成代码和测试,不只看 Agent 最后是否声称"已参考"。
维护一套内部前端知识库,也值得研究它的构建方式:把原始内容、兼容性元数据、检索片段和完整文档分开,让小入口负责找路,按需取回负责提供细节。若照搬检索算法,需要重新验证自己的词表、语料规模和查询语言,不能沿用 Web 指南领域的效果预期。
有严格浏览器版本要求的产品,应先定义支持矩阵,再决定 Baseline 提示怎么使用。尤其是 Android 内嵌 WebView、老设备或专用运行环境,公开浏览器的通用支持状态未必覆盖真实用户。指南可以帮助写回退方案,不能替代目标设备上的验证。
如果团队需要的是"禁止提交不兼容代码",这套技能不够。还需要项目自己的静态规则、浏览器测试或构建约束。它能改善 Agent 获得的资料和工作顺序,却不承担最终交付的强制验收。
💡 总结
Modern Web Guidance 把浏览器知识拆成了可以按任务查询的工具:轻量查询向量负责找相关内容,BM25 补足字面匹配,取回接口落实特性开关,再由具体指南解释实现和回退。
我更看重源码仓库把指南与行为期望放在同一条维护链里。它让"建议可能有用"变成可以持续检查的工程问题。接入时也要保留这个边界:查到指南只是起点,最终仍要让真实页面、目标浏览器和业务失败路径接受测试。