让 AI 编程助手真正看懂 CSS:一个静态知识图谱 + 一个运行时探针(开源)

9 阅读5分钟

用 AI 写前端的人,大概都经历过这两种翻车现场。

引子:两个让我决定动手的场景

场景 A(静态盲区):让 AI 改 .btn-primary 的圆角。它 grep 出 6 个候选文件、逐一 Read,然后告诉你"这几处可能互相覆盖"——十几个工具调用之后,级联关系还是要你自己判断。

场景 B(运行期盲区):问 AI"为什么 .sidebar 在 1280px 宽度下会溢出",它读完一圈 CSS 给不出结论。因为溢出是运行期行为——容器宽度、滚动链、containing block 劫持——静态代码里根本没有答案。

AI 写前端已经很强,但在 CSS 这件事上,它获取信息的方式是残缺的:看不到结构(图谱),也看不到现场(渲染)

所以我做了两个开源工具,一个负责静态、一个负责运行期:

  • cssgraph — 把样式表解析成知识图谱,通过 MCP 提供给 AI Agent;
  • cssprobe-cli — 用真实浏览器做运行时探针,把"页面实际渲染成什么样"变成结构化输出。

cssgraph:给 AI 一张 CSS 地图

它索引什么

索引覆盖面:CSS / SCSS / Less / Sass (indented) / PostCSS、CSS Modules、CSS-in-JS、JSX/TSX 里的 className 引用、ERB / Haml / HTML 模板的 class 提取,以及 Tailwind v3(JS config)和 v4(CSS @theme)。

索引结果落在一个本地 SQLite 知识图谱里:每个 className、属性、变量、at-rule 都是节点,引用 / 覆盖 / 级联是边。

性能参考(来自项目 README 的实测表):

项目规模文件数首次索引耗时节点
小型项目~50~15s~16K~50K
生产级 monorepo~11K3–5 min~780K~2200万

100% 本地运行,没有网络请求,不上传任何样式代码。

MCP:13 个工具

对外接口是 MCP(Model Context Protocol),核心工具包括:

  • cssgraph_rule:精确查找某个选择器(O(1)),返回 loose / strict 两级影响范围
  • cssgraph_explore:一次拿全 —— 属性、覆盖关系、特异性、引用组件
  • cssgraph_impact:评估"改这个 className 会影响哪里"

安装与接入:

npm i -g cssgraph
cd your-project
cssgraph init --workers 8        # 建立索引(workers 控制并行解析)
cssgraph mcp-install             # 自动写入 MCP 配置 + Agent Skill

mcp-install 会自动识别并配置 Claude Code、Cursor、Codex CLI、opencode、Gemini CLI、Antigravity 等 8 种客户端,同时写入一个 Agent Skill(SKILL.md + pitfalls),教 agent 何时用哪个工具、如何串联、哪些坑不要踩。

文件监听默认开启:你改 CSS,agent 同时在查——索引永远是新的,不存在"过期索引"问题。

效果

Agent 问"哪些代码引用了 .btn-primary":

以前:grep → 6 个文件 → 逐一 Read → 手工拼级联 → 猜测。 现在:一次 cssgraph_rule 调用,返回 properties / overrides / specificity / callers / impact。


cssprobe-cli:给 AI 一双眼睛

它解决什么

溢出、滚动链、containing block 劫持、字号继承链……这些问题的答案只存在于真实渲染里。

cssprobe-cli 打开一个真实 Chromium(基于 Playwright),注入收集器读取 computed styles 和元素度量,再由纯 Node 函数分析器输出结论。每条结论都带置信度分级

  • DEFINITE:可以证明的结论
  • INDEFINITE:有证据但存在解释分支
  • UNVERIFIABLE:静态无法证明,显式标记"需要运行时验证"

这个置信度设计是我最喜欢的一部分:它诚实——不把"猜测"包装成"结论",agent 拿到之后知道哪些可以信、哪些要再验证。

用法

npm i -g cssprobe-cli

cssprobe-cli open https://example.com   # 启动 daemon 会话 + 浏览器
cssprobe-cli inspect .sidebar           # 检查:DOM 树 + 布局 + findings
cssprobe-cli layout .sidebar            # 只看 ASCII 布局图
cssprobe-cli findings .sidebar          # 只看问题清单
cssprobe-cli close                      # 关闭会话

输出支持 JSON,可以直接喂给 agent 或者用 jq 处理:

cssprobe-cli inspect body --json | jq '.findings[] | {id, confidence, message}'

需要登录的页面也能处理:

cssprobe-cli open https://mysite.com --headed   # 手动登录
cssprobe-cli state-save --name mysite           # 保存会话状态
cssprobe-cli open https://mysite.com --state state.json   # 之后免登录复用

一起用:一静一动的完整链路

AI Agent
   │
   ├─ "这个 className 的样式从哪来?"  ──▶ cssgraph(静态图谱)
   │     一次调用:属性 / 覆盖 / 特异性 / callers / impact
   │
   └─ "页面实际渲染成什么样?"        ──▶ cssprobe-cli(运行时探针)
         真实 Chromium:布局 / 溢出 / 滚动链 / 置信度分级结论

典型修复流程:

  1. 要改 .card 的样式 → cssgraph 一次调用拿全定义与影响面
  2. 改完验证渲染 → cssprobe-cli inspect .card 看实际布局与 findings
  3. 修复后对照 findings 确认问题消除

静态管线管"改得对",运行时管线管"跑得对"。


为什么不用现成的东西

  • 为什么不用 grep / Read:不是慢一点的问题——CSS 的答案(覆盖关系、特异性)需要跨文件重建,这恰好是模型最不擅长、token 花得最多的地方。
  • 为什么不用 DevTools:DevTools 是给人看的,交互式面板对 agent 不可读;cssprobe 的输出是结构化的、带置信度的、可以直接进上下文的。
  • 为什么坚持本地:样式表是私有资产,不适合拉到云端做索引。两个工具都 100% 本地,无账号、无 API key、无遥测负担。

开源信息

两个项目都是 MIT 协议,欢迎 issue、PR 和 star:

cssgraph 已发布到官方 MCP Registryio.github.mack-peng/cssgraph),在 Claude Code / Cursor / Codex 里都可以直接接入。

如果你也在用 AI 写前端,并且受够了"跟 AI 争论 CSS 到底谁覆盖了谁",这两个工具应该能省下你不少时间。用起来有任何问题,评论区见——有问必回。