资讯详情 从一键检测到 AI 修复:用 TaoToken 把无障碍检查做进研发流程
📅 2026/10/9 6:19:45
1. 为什么无障碍检查总在提测后才暴露前端团队做无障碍最怕的不是规则多而是问题发现得太晚。组件写完、页面联调、测试提 Bug才发现某个图标按钮没有可访问名称或者对比度不达标。这时候改代码牵一发动全身回归成本高排期还得往后挪。我观察过几个团队的实际流程无障碍问题通常散落在三个阶段编码阶段靠人肉记忆联调阶段靠 Chrome 插件抽查真机阶段靠测试同学手动过一遍。三个阶段各管各的没有统一入口也没有统一的修复建议。结果就是同一个问题在 Web 端修了H5 端又冒出来Vue 组件里改了Android 真机上还是老样子。更麻烦的是修复环节。很多开发者知道要加alt、要补aria-label但具体加到哪个标签、用什么措辞、会不会影响现有布局心里没底。于是要么拖着不改要么改完引入新问题。无障碍检查变成了一种“知道重要但总被推迟”的专项工作。这篇内容想解决的就是把检测和修复这两件事从“专项”变成“日常”。具体来说我会带你走一遍在 VS Code 里配置无障碍检测脚本用 TaoToken 统一调用 AI 修复能力再通过提交前校验和 CI 步骤让无障碍问题在进入代码仓库之前就被拦住。整套链路不需要你改现有构建工具也不需要额外部署服务核心就是几个配置文件加一段提示词模板。适合谁看前端开发者、技术负责人、以及正在把无障碍纳入质量体系的团队。如果你已经在用 ESLint、Prettier 这类工具这套思路可以直接叠加进去。如果你还没开始做无障碍那正好从编码阶段就把它做进流程比后期补票轻松得多。核心检索词先明确无障碍检测工具链、AI 修复、VS Code 插件、研发流程集成。这四个词贯穿全文后面每个步骤都会围绕它们展开。2. TaoToken 前置准备统一 Key 与模型接入在讲具体配置之前先把 TaoToken 的接入方式说清楚。你可以把它理解成一个统一的模型调用入口不管底层用的是哪个模型前端只需要维护一个 Base URL 和一个 API Key切换模型时改一个 Model ID 就行。对于无障碍修复这种场景好处很明显——修复提示词模板不用跟着模型变团队里每个人拿到的修复建议风格也一致。2.1 获取 API Key 与确认 Base URL第一步打开 TaoToken 的控制台在 API Keys 页面创建一个新的 Key。建议按项目或按环境命名比如a11y-vscode-dev方便后续排查问题时定位来源。创建完成后你会拿到一串以sk-开头的 Key。这个 Key 只显示一次记得先复制到安全的地方。Base URL 固定为https://taotoken.net/api注意这里不要加任何路径后缀也不要加 UTM 参数。后面在 VS Code 配置和 CI 脚本里都直接用这个地址。2.2 确认可用模型与 Model IDTaoToken 支持多种模型无障碍修复场景建议选代码理解能力较强的模型。你可以在模型对话页面先试一下输入一段缺少alt的图片标签看模型能不能给出合理的修复建议。确认可用后记下对应的 Model ID。这个 ID 后面会出现在三个地方VS Code 的 settings.json、修复脚本的环境变量、以及 CI 的校验步骤里。三处必须保持一致否则会出现“本地能修、CI 报错”的情况。2.3 环境变量与本地安全存放不要把 Key 硬编码在代码里。推荐做法是在本地建一个.env.local文件加入.gitignore内容如下TAOTOKEN_API_KEYsk-你的Key TAOTOKEN_BASE_URLhttps://taotoken.net/api TAOTOKEN_MODEL_ID你的ModelID然后在 VS Code 的 settings.json 里通过${env:TAOTOKEN_API_KEY}这种方式引用。这样既方便本地调试又不会把 Key 提交到仓库。如果你在团队里推广可以把这个.env.local的模板放到项目文档里新同学 clone 下来填自己的 Key 即可。注意每个开发者用自己申请的 Key不要共用方便后续按人排查调用量。2.4 验证 Key 是否可用在正式配置之前先用一条 curl 命令确认 Key 能通curl -X POST https://taotoken.net/api/v1/chat/completions \ -H Content-Type: application/json \ -H Authorization: Bearer $TAOTOKEN_API_KEY \ -d { model: $TAOTOKEN_MODEL_ID, messages: [ {role: user, content: 回复 OK 两个字母} ] }如果返回内容里包含OK说明 Key、Base URL、Model ID 三者都对上了。如果返回 401先检查 Key 有没有复制完整如果返回 model not found检查 Model ID 拼写。这一步看起来简单但实际排障时能省很多时间。我见过不少情况是 VS Code 插件报错最后发现是 Key 里多了一个空格。3. 可复制配置VS Code 检测脚本与 AI 修复模板这一节是整篇的核心。我会给出可以直接复制到项目里的配置文件包括 VS Code 的 settings 片段、检测脚本、以及 AI 修复的提示词模板。你不需要全部照搬按自己项目的技术栈调整路径和规则即可。3.1 VS Code settings.json 配置片段在项目根目录的.vscode/settings.json里加入以下内容。这段配置做了三件事指定无障碍检测脚本的路径、把 TaoToken 的环境变量注入、以及设置保存时自动检测。{ a11yCheck.scriptPath: ${workspaceFolder}/scripts/a11y-check.js, a11yCheck.autoRunOnSave: true, a11yCheck.include: [src/**/*.vue, src/**/*.jsx, src/**/*.tsx], a11yCheck.exclude: [**/node_modules/**, **/dist/**], a11yCheck.taotoken.baseUrl: https://taotoken.net/api, a11yCheck.taotoken.apiKey: ${env:TAOTOKEN_API_KEY}, a11yCheck.taotoken.modelId: ${env:TAOTOKEN_MODEL_ID}, a11yCheck.fixPromptTemplate: ${workspaceFolder}/scripts/a11y-fix-prompt.md }注意a11yCheck.taotoken.baseUrl这里写的是完整地址不要加/v1后缀脚本内部会自己拼接。apiKey和modelId都通过环境变量读取避免明文泄露。如果你用的是 Cline 或类似插件做 MCP 集成配置方式略有不同但三件套不变Base URL、Key、Model ID。Cline 的 MCP 配置里把 TaoToken 作为一个 provider 写进去Model ID 填同一个值即可。3.2 检测脚本 a11y-check.js在scripts/目录下新建a11y-check.js。这个脚本的作用是读取当前打开的文件抽取模板内容跑一遍无障碍规则把问题输出到控制台和 VS Code 的 Problems 面板。const fs require(fs); const path require(path); // 简化版规则集实际项目可替换为 axe-core const RULES [ { id: img-alt, test: (node) node.tag img !node.attrs.alt, message: 图片缺少 alt 属性, severity: error }, { id: button-name, test: (node) node.tag button !node.attrs[aria-label] !node.text, message: 按钮缺少可访问名称, severity: error }, { id: color-contrast, test: (node) node.style node.style.color node.style.background, message: 颜色对比度可能不足建议检查, severity: warning } ]; function parseTemplate(content) { // 简易解析实际项目建议用 vue/compiler-sfc const match content.match(/template([\s\S]*?)\/template/); if (!match) return []; const template match[1]; const nodes []; const tagRegex /(\w)([^]*)/g; let m; while ((m tagRegex.exec(template)) ! null) { const tag m[1]; const attrStr m[2]; const attrs {}; const attrRegex /(\w[\w-]*)(?:([^]*))?/g; let a; while ((a attrRegex.exec(attrStr)) ! null) { attrs[a[1]] a[2] || true; } nodes.push({ tag, attrs, text: }); } return nodes; } function checkFile(filePath) { const content fs.readFileSync(filePath, utf-8); const nodes parseTemplate(content); const issues []; nodes.forEach((node, index) { RULES.forEach((rule) { if (rule.test(node)) { issues.push({ file: filePath, line: index 1, ruleId: rule.id, message: rule.message, severity: rule.severity }); } }); }); return issues; } const target process.argv[2]; if (!target) { console.error(请传入要检测的文件路径); process.exit(1); } const issues checkFile(path.resolve(target)); if (issues.length 0) { console.log(无障碍检测通过未发现问题); process.exit(0); } issues.forEach((issue) { console.log(${issue.file}:${issue.line} [${issue.severity}] ${issue.message} (${issue.ruleId})); }); process.exit(1);这个脚本是简化版实际项目里建议直接引入axe-core把解析后的 DOM 传进去跑。但结构是一样的解析模板、跑规则、输出问题。你可以把它挂到 VS Code 的保存事件上也可以单独在命令行跑。3.3 AI 修复提示词模板 a11y-fix-prompt.md在scripts/目录下新建a11y-fix-prompt.md。这个模板会被修复脚本读取把问题代码和上下文一起发给 TaoToken。你是一个前端无障碍修复专家。请根据以下信息给出最小改动的修复方案。 ## 问题信息 - 规则 ID{{ruleId}} - 问题描述{{message}} - 文件路径{{filePath}} - 行号{{line}} ## 原始代码片段 html {{codeSnippet}}修复要求只修改与无障碍相关的属性或标签不要改动业务逻辑。如果缺少 alt根据图片上下文给出合理描述无法判断时用空 alt。如果缺少 aria-label用简洁的中文描述控件用途。如果涉及颜色对比度给出符合 WCAG AA 的色值建议。输出格式先给出修复后的完整代码片段再用一句话说明改动原因。输出示例button aria-label关闭弹窗×/button改动原因为图标按钮补充可访问名称屏幕阅读器可正确朗读。这个模板的关键是“最小改动”和“输出格式固定”。前者避免模型大改代码后者方便脚本解析。你可以在模板里加更多规则比如要求保留原有缩进、不引入新依赖等。 ### 3.4 修复脚本 fix-with-ai.js 再写一个脚本把检测结果和提示词模板拼起来调用 TaoToken 拿修复建议。 javascript const fs require(fs); const path require(path); const https require(https); const API_KEY process.env.TAOTOKEN_API_KEY; const BASE_URL process.env.TAOTOKEN_BASE_URL || https://taotoken.net/api; const MODEL_ID process.env.TAOTOKEN_MODEL_ID; async function callTaoToken(prompt) { const url new URL(${BASE_URL}/v1/chat/completions); const body JSON.stringify({ model: MODEL_ID, messages: [{ role: user, content: prompt }], temperature: 0.2 }); return new Promise((resolve, reject) { const req https.request( { hostname: url.hostname, path: url.pathname, method: POST, headers: { Content-Type: application/json, Authorization: Bearer ${API_KEY} } }, (res) { let data ; res.on(data, (chunk) (data chunk)); res.on(end, () { try { const json JSON.parse(data); resolve(json.choices[0].message.content); } catch (e) { reject(new Error(解析响应失败: ${data})); } }); } ); req.on(error, reject); req.write(body); req.end(); }); } async function fixIssue(issue, codeSnippet) { const template fs.readFileSync( path.resolve(__dirname, a11y-fix-prompt.md), utf-8 ); const prompt template .replace({{ruleId}}, issue.ruleId) .replace({{message}}, issue.message) .replace({{filePath}}, issue.file) .replace({{line}}, issue.line) .replace({{codeSnippet}}, codeSnippet); return callTaoToken(prompt); } module.exports { fixIssue };这个脚本不直接改文件而是把修复建议返回给调用方。在 VS Code 插件里你可以把返回内容展示在 Diff 视图里让开发者确认后再应用。这样既用了 AI 的效率又保留了人工审核的环节。3.5 提交前校验husky lint-staged在package.json里加入{ scripts: { a11y:check: node scripts/a11y-check.js, a11y:fix: node scripts/fix-with-ai.js }, lint-staged: { *.{vue,jsx,tsx}: [ node scripts/a11y-check.js ] } }配合 husky 的 pre-commit 钩子每次提交前自动跑检测。如果有 error 级别的问题直接拦住提交并在终端输出问题列表和修复建议。开发者可以选择手动改也可以调用 AI 修复脚本生成建议。这样一套下来无障碍检查就从“想起来才做”变成了“提交前必过”。而且因为检测脚本和修复脚本共用同一套规则和提示词团队里每个人的修复风格也趋于一致。4. 验证请求与成功结果修复前后评分对比配置写完得验证它真的能跑通。这一节我会用一个真实的 Vue 组件例子走一遍从检测到修复再到复检的完整流程并给出修复前后的无障碍评分变化。4.1 准备一个有问题组件新建src/components/UserCard.vue内容如下template div classuser-card img :srcavatar classavatar button classclose-btn clickclose×/button a href/profile classprofile-link点击这里/a input typetext placeholder请输入昵称 /div /template script export default { props: [avatar], methods: { close() { this.$emit(close); } } }; /script style .user-card { background: #f0f0f0; color: #999; } .close-btn { color: #ccc; background: #f0f0f0; } /style这个组件有几个典型问题图片没有alt、关闭按钮没有可访问名称、链接文案“点击这里”含义不清、输入框没有关联标签、颜色对比度不足。4.2 运行检测脚本在终端执行node scripts/a11y-check.js src/components/UserCard.vue输出类似src/components/UserCard.vue:3 [error] 图片缺少 alt 属性 (img-alt) src/components/UserCard.vue:4 [error] 按钮缺少可访问名称 (button-name) src/components/UserCard.vue:6 [warning] 颜色对比度可能不足建议检查 (color-contrast)如果配置了 VS Code 插件保存文件时 Problems 面板也会出现对应提示点击可以跳转到具体行。4.3 调用 AI 修复把检测结果传给修复脚本或者直接在 VS Code 里点击 Quick Fix。以图片为例发给 TaoToken 的提示词会包含规则 IDimg-alt 问题描述图片缺少 alt 属性 文件路径src/components/UserCard.vue 行号3 原始代码片段img :srcavatar classavatar模型返回的修复建议类似img :srcavatar classavatar alt用户头像改动原因为图片补充描述性 alt屏幕阅读器可正确朗读。按钮的修复建议button classclose-btn clickclose aria-label关闭用户卡片×/button链接文案的修复建议a href/profile classprofile-link查看个人资料/a输入框的修复建议label fornickname昵称/label input idnickname typetext placeholder请输入昵称颜色对比度的修复建议.user-card { background: #f0f0f0; color: #333; } .close-btn { color: #333; background: #f0f0f0; }4.4 应用修复并复检把上述修改应用到组件里再次运行检测脚本node scripts/a11y-check.js src/components/UserCard.vue输出无障碍检测通过未发现问题如果用 axe-core 跑完整规则集修复前的评分通常在 60-70 分左右修复后可以到 95 分以上。具体分数取决于规则集和页面复杂度但趋势是一致的常见问题被消除后评分会明显上升。4.5 在 CI 里加一道校验在.github/workflows/a11y.yml里加入name: Accessibility Check on: [pull_request] jobs: a11y: runs-on: ubuntu-latest steps: - uses: actions/checkoutv4 - uses: actions/setup-nodev4 with: node-version: 20 - run: npm ci - run: node scripts/a11y-check.js src/components/UserCard.vue env: TAOTOKEN_API_KEY: ${{ secrets.TAOTOKEN_API_KEY }} TAOTOKEN_BASE_URL: https://taotoken.net/api TAOTOKEN_MODEL_ID: ${{ secrets.TAOTOKEN_MODEL_ID }}这样每次 PR 都会跑一遍无障碍检测。如果有 error 级别的问题CI 会失败PR 无法合并。开发者可以在本地先用 AI 修复脚本生成建议改完再提交。注意 CI 里的环境变量通过 GitHub Secrets 注入不要明文写在 workflow 文件里。Base URL 固定用https://taotoken.net/api不要加 UTM 参数。5. 本篇常见错排查401、local proxy failed、reading choices、OAuth配置过程中最容易卡在几个报错上。这一节把常见错误和排查路径列出来你遇到时可以直接对照。5.1 401 Unauthorized报错原文{error:{message:Invalid API key,type:invalid_request_error}}原因通常是 Key 不对。排查顺序第一检查.env.local里的TAOTOKEN_API_KEY有没有多余空格或换行。复制 Key 时容易带上首尾空白。第二确认 VS Code 的 settings.json 里引用的是${env:TAOTOKEN_API_KEY}而不是写死的字符串。如果写死改 Key 时容易漏改。第三确认 CI 里的 Secret 名称和 workflow 文件里引用的一致。GitHub Secrets 区分大小写。第四如果用的是 Cline 或 MCP 集成检查配置文件里的 provider 字段是否指向 TaoTokenBase URL 是否填的https://taotoken.net/api。5.2 local proxy failed报错原文Error: local proxy failed to connect这个错误通常出现在本地开发环境。原因可能是第一本地网络无法直接访问https://taotoken.net/api。检查一下能不能用 curl 通。第二如果公司网络有代理设置需要在环境变量里配置HTTPS_PROXY。注意这里说的是正常的网络代理配置不是任何特殊工具。第三VS Code 的代理设置和终端不一致。可以在 VS Code 的 settings.json 里加http.proxy字段值和你终端里的HTTPS_PROXY保持一致。5.3 reading choices of undefined报错原文TypeError: Cannot read properties of undefined (reading choices)这个错误说明 API 返回的结构和脚本预期的不一致。排查第一打印完整响应体看返回的 JSON 里有没有choices字段。如果返回的是错误信息先解决错误。第二确认 Model ID 拼写正确。Model ID 错误时有些接口会返回错误对象而不是标准响应。第三检查请求体里的messages格式。必须是数组每个元素有role和content。第四如果用的是流式响应需要按 SSE 格式解析不能直接JSON.parse。5.4 OAuth 相关报错报错原文OAuth token expired or invalid如果你用的是 Claude Code 或类似工具可能会遇到 OAuth 报错。排查第一确认你用的是 API Key 方式而不是 OAuth 方式。TaoToken 的接入用 API Key 即可不需要走 OAuth 流程。第二如果工具默认走 OAuth在配置里切换为 API Key 模式。具体字段名看工具文档通常是authType或credentialType。第三检查 Key 是否过期。在控制台重新生成一个替换环境变量里的值。5.5 修复建议不生效有时候 AI 返回了修复建议但应用到代码后检测仍然报错。原因可能是第一修复建议只改了模板没改样式。比如对比度问题需要同时改 CSS。第二Vue 的动态绑定语法没被正确解析。比如:altdynamicAlt在检测脚本里可能被当成没有 alt。需要在解析逻辑里处理:前缀。第三修复后的代码没有保存检测脚本读的是旧文件。第四缓存问题。VS Code 插件有时会缓存检测结果重启窗口或手动触发一次检测。5.6 CI 里 Key 不生效CI 报 401但本地正常。排查第一确认 GitHub Secrets 里加了TAOTOKEN_API_KEY和TAOTOKEN_MODEL_ID。第二确认 workflow 文件里的env字段拼写正确大小写一致。第三确认 Secret 的值没有多余空格。在 GitHub 界面里重新粘贴一次。第四如果用的是其他 CI 平台检查环境变量注入方式是否一致。6. 把无障碍检查变成日常研发习惯整套链路跑通之后你会发现无障碍检查不再是一个需要专门排期的任务。它变成了保存文件时的一次提示、提交前的一道校验、CI 里的一个步骤。开发者不需要记住所有规则只需要在问题出现时看一眼修复建议确认后应用即可。如果你想把这件事在团队里推下去建议从一个小项目开始。先配好 VS Code 的检测脚本和 AI 修复模板让一两个同学试用一周。收集他们的反馈调整提示词模板和规则集。等流程稳定了再推广到更多项目。几个实用技巧第一把.env.local的模板放到项目 README 里新同学 clone 下来填自己的 Key 即可。不要共用 Key方便按人排查调用量。第二修复提示词模板里加上“保留原有缩进”和“不引入新依赖”这两条能减少很多格式上的返工。第三CI 里先只拦 error 级别的问题warning 先放行。等团队适应了再逐步收紧。第四定期回顾检测结果把高频问题沉淀成团队的无障碍编码规范。比如“所有图片必须有 alt”“所有图标按钮必须有 aria-label”写进 Code Review 清单。第五如果你在用 Coding Plan 做长期编码或 Agent 任务可以把无障碍检测脚本挂到 Agent 的工作流里让它在生成代码后自动跑一遍检测。这样从生成到校验形成闭环减少人工介入。需要提醒的是AI 修复建议不是万能的。对于复杂的交互组件比如自定义下拉框、模态框、拖拽排序模型可能给不出完全正确的方案。这时候还是需要开发者结合业务场景判断。AI 的作用是处理那些重复性高、规则明确的问题把人的精力留给真正需要思考的部分。最后如果你还没开始用 TaoToken可以先从模型对话页面试一下修复提示词的效果。确认模型能给出合理建议后再接入到 VS Code 和 CI 里。接入文档里有完整的配置说明API Keys 页面可以创建和管理 Key。长期做编码和 Agent 任务的团队可以看看 Coding Plan 的额度方案比按次调用更划算。整套流程的核心就一句话让无障碍问题在写代码的时候被发现在提交之前被修复在合并之前被验证。做到这三点无障碍就不再是负担而是研发流程里自然的一部分。