ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Agent Skill: react-best-practices 实战大纲:把 React 最佳实践封装成可复用技能

Agent Skill: react-best-practices 实战大纲:把 React 最佳实践封装成可复用技能 1. 为什么要把 react-best-practices 封装成 Agent SkillReact 项目的性能问题有个很讨厌的特点它不会在编译时报错也不会在测试里挂掉只会在用户点开页面时悄悄多等 600ms。等团队发现时往往已经积累了几十个页面的性能债。Vercel 开源的 react-best-practices 把十余年 React/Next.js 优化经验整理成了结构化规则集但规则集本身只是文档真正让它产生价值的方式是把它变成一个 Agent Skill让 AI 在写代码和做 Code Review 时自动调用。Agent Skill 和普通 Prompt 的区别我用一个类比说明Prompt 像是你临时跟同事口头交代帮我看看这段代码有没有性能问题每次说法不同、标准不同Skill 则像是一份写进团队 Wiki 的检查清单有明确的触发条件、输入输出约定和约束规则。在工程化 Agent 系统里Skill 更接近函数或子代理——它定义了 Agent 能做什么、在什么条件下做、做到什么程度。react-best-practices 这套规则的设计思路很值得借鉴它按影响优先级排序从 CRITICAL 到 LOW 分级强制先解决对用户体验影响最大的问题。比如消除异步瀑布流和客户端 Bundle 体积优化被标为 CRITICAL而重渲染优化、JS 性能属于 MEDIUM-LOW。这个优先级逻辑如果只放在文档里开发者大概率还是会先花时间调 useMemo但封装成 Skill 后AI 会按规则等级输出问题清单把请求瀑布流排在重渲染前面。我试过把类似规则集直接塞进系统提示词效果并不好——规则一多模型就开始选择性遗忘或者把不同等级的规则混在一起输出。后来改成 Skill 结构把触发条件、规则文件、输出模板分开管理稳定性明显提升。这篇文章就按这个思路带你从目录结构开始一步步把 react-best-practices 沉淀成一个可复用的 Agent Skill并用一段真实的 React 组件代码验证它的检查与修复建议能力。2. TaoToken 前置准备给 Skill 一个稳定的模型入口Skill 本身是规则和提示词的封装但它最终要调用模型来执行检查。如果你用的是 Claude Code、Cursor 或 Codex 这类编码智能体模型入口的稳定性直接决定了 Skill 能不能在团队里长期跑下去。TaoToken 在这里扮演的角色是统一的 API 接入层让你不用在每个工具里分别配置不同的模型供应商。先明确三个核心要素后面配置里会反复用到要素值说明Base URLhttps://taotoken.net/api所有请求的统一入口不加 UTM 参数API Key在控制台创建形如sk-开头的字符串注意保密Model ID按需选择代码审查建议用长上下文模型如claude-sonnet-4-20250514获取 Key 的路径是登录官网后进入控制台在 API Keys 页面创建新密钥。这里有个容易踩的坑创建后 Key 只显示一次务必立刻复制到安全的地方页面刷新后就看不到了。如果你用的是 Claude Code它读取的是环境变量或 settings 文件如果用 Cline 或 Cursor配置方式又不一样。为了后面演示方便我建议先把 Key 存到环境变量里export TAOTOKEN_API_KEYsk-你的密钥 export TAOTOKEN_BASE_URLhttps://taotoken.net/api验证 Key 是否可用最直接的方式是发一个最小请求curl -s https://taotoken.net/api/v1/messages \ -H x-api-key: $TAOTOKEN_API_KEY \ -H anthropic-version: 2023-06-01 \ -H content-type: application/json \ -d { model: claude-sonnet-4-20250514, max_tokens: 64, messages: [{role: user, content: 回复 OK 两个字母}] }返回里能看到content字段带OK说明 Key 和 Base URL 都通了。这一步别跳过后面 Skill 报错时你才能快速判断是模型入口问题还是规则配置问题。对于长期做代码审查和 Agent 任务的场景Coding Plan 比按量计费更划算尤其是团队多人共用时。你可以先按量跑通流程确认 Skill 效果后再切到套餐。模型对话入口可以用来单独测试某条规则对一段代码的判断方便调试提示词。3. Skill 目录结构与可复制配置把 react-best-practices 封装成 Skill核心是把规则和执行逻辑分离。规则文件保持和上游仓库一致的结构执行逻辑用一份配置文件描述触发条件和输出格式。下面是我实际用的目录结构skills/ └── react-best-practices/ ├── SKILL.md # 技能主文件定义触发条件与输出约定 ├── rules/ # 规则文件按类别前缀命名 │ ├── async-parallel.md │ ├── async-defer-await.md │ ├── bundle-dynamic-import.md │ └── rerender-memo.md ├── templates/ │ └── review-output.md # 输出模板约束问题清单格式 └── skill.config.json # 技能元数据与模型参数SKILL.md是触发入口它决定了 Agent 什么时候调用这个技能。内容要写得足够具体避免代码审查这种宽泛描述导致误触发--- name: react-best-practices description: 审查 React/Next.js 代码的性能问题按 CRITICAL 到 LOW 优先级输出问题清单与修复建议。当用户提交 .tsx/.jsx 文件、要求 Code Review、或提到性能优化时触发。 --- # React 最佳实践审查技能 ## 触发条件 - 用户提供 React 组件代码并要求审查 - 用户提到性能卡顿首屏慢请求瀑布流 - 代码变更涉及 useEffect、数据获取、动态导入 ## 执行步骤 1. 读取 rules/ 下所有规则文件 2. 按影响等级分组CRITICAL HIGH MEDIUM LOW 3. 对每段代码逐条匹配规则记录违规位置 4. 按 templates/review-output.md 格式输出 ## 约束 - 不修改代码只输出问题与建议 - 每条问题必须引用具体规则文件名 - 无问题的规则不输出避免噪音skill.config.json里放模型参数和规则路径这样换模型时不用改 SKILL.md{ name: react-best-practices, version: 1.0.0, model: claude-sonnet-4-20250514, baseUrl: https://taotoken.net/api, rulesDir: ./rules, outputTemplate: ./templates/review-output.md, maxTokens: 4096, temperature: 0.2 }temperature设成 0.2 是有意的——代码审查需要稳定输出太高的随机性会让同一段代码两次审查结果不一致团队协作时很难对齐。规则文件沿用上游的模板格式每条规则必须包含影响等级、标签和错误/正确示例。以async-parallel.md为例--- impact: CRITICAL tags: [async, waterfall, performance] --- # 并行化无关请求 ## 问题 多个不相互依赖的异步请求被串行 await总耗时等于各请求之和。 ## 错误示例 ts const user await fetchUser(id); const posts await fetchPosts(user.id); const settings await fetchSettings(user.id);正确示例const user await fetchUser(id); const [posts, settings] await Promise.all([ fetchPosts(user.id), fetchSettings(user.id) ]);修复建议识别无数据依赖的请求用 Promise.all 并行执行。输出模板 review-output.md 约束了问题清单的格式让不同人跑出来的结果结构一致 markdown ## 审查结果 ### CRITICAL - [规则名] 文件:行号 — 问题描述 - 修复建议... ### HIGH ... ### 统计 - 检查规则数N - 发现问题数M这套结构的好处是规则可以独立增删不影响主流程输出格式固定方便接入 CI 或生成报告模型参数集中管理换供应商只改一个文件。如果你团队用 Cline 的 MCP 模式可以把skill.config.json里的 Base URL、Key、Model ID 三件套直接映射到 MCP 配置里保持和 Skill 一致。4. 验证请求对一段 React 组件执行检查配置写完后必须验证否则你不知道 Skill 是真的在按规则检查还是模型在自由发挥。我准备了一段故意埋了三个问题的组件代码覆盖请求瀑布流、Bundle 膨胀和重渲染三类问题// UserDashboard.tsx import HeavyChart from ./HeavyChart; import { useEffect, useState } from react; export function UserDashboard({ userId }: { userId: string }) { const [user, setUser] useState(null); const [posts, setPosts] useState([]); const [settings, setSettings] useState(null); useEffect(() { async function load() { const u await fetch(/api/user/${userId}).then(r r.json()); setUser(u); const p await fetch(/api/posts/${u.id}).then(r r.json()); setPosts(p); const s await fetch(/api/settings/${u.id}).then(r r.json()); setSettings(s); } load(); }, [userId]); return ( div h1{user?.name}/h1 HeavyChart data{posts} / span{settings?.theme}/span /div ); }这段代码的问题很典型三个请求串行执行形成瀑布流HeavyChart静态导入导致首屏 Bundle 膨胀settings变化会触发整个组件重渲染。现在把代码和 Skill 一起发给模型curl -s https://taotoken.net/api/v1/messages \ -H x-api-key: $TAOTOKEN_API_KEY \ -H anthropic-version: 2023-06-01 \ -H content-type: application/json \ -d { model: claude-sonnet-4-20250514, max_tokens: 4096, temperature: 0.2, system: 你是 react-best-practices 技能执行器。读取 rules/ 下规则按 CRITICAL 到 LOW 输出问题清单每条引用规则文件名。, messages: [{ role: user, content: 审查以下代码\n\ntsx\nimport HeavyChart from \./HeavyChart\;\nimport { useEffect, useState } from \react\;\n\nexport function UserDashboard({ userId }: { userId: string }) {\n const [user, setUser] useState(null);\n const [posts, setPosts] useState([]);\n const [settings, setSettings] useState(null);\n\n useEffect(() {\n async function load() {\n const u await fetch(/api/user/${userId}).then(r r.json());\n setUser(u);\n const p await fetch(/api/posts/${u.id}).then(r r.json());\n setPosts(p);\n const s await fetch(/api/settings/${u.id}).then(r r.json());\n setSettings(s);\n }\n load();\n }, [userId]);\n\n return (\n div\n h1{user?.name}/h1\n HeavyChart data{posts} /\n span{settings?.theme}/span\n /div\n );\n}\n }] }预期输出应该包含三条 CRITICAL/HIGH 级别的问题每条都引用具体规则文件。实际返回的content里问题清单大致长这样### CRITICAL - [async-parallel.md] UserDashboard.tsx:12-16 — 三个请求串行 await形成请求瀑布流 - 修复建议user 请求完成后posts 和 settings 无依赖关系用 Promise.all 并行 ### CRITICAL - [bundle-dynamic-import.md] UserDashboard.tsx:2 — HeavyChart 静态导入进入首屏 Bundle - 修复建议改用 React.lazy Suspense 动态导入 ### MEDIUM - [rerender-memo.md] UserDashboard.tsx:26 — settings 变化触发整个组件重渲染 - 修复建议将 settings 消费逻辑拆到子组件或用 useMemo 隔离验证成功的标志有三个问题按优先级排序、每条引用规则文件名、修复建议具体到代码行。如果输出只是泛泛而谈建议优化性能说明 Skill 的规则文件没被正确读取需要检查rulesDir路径和 SKILL.md 里的执行步骤。修复后的代码可以再跑一次验证确认问题清零import { lazy, Suspense, useEffect, useState } from react; const HeavyChart lazy(() import(./HeavyChart)); export function UserDashboard({ userId }: { userId: string }) { const [user, setUser] useState(null); const [posts, setPosts] useState([]); const [settings, setSettings] useState(null); useEffect(() { async function load() { const u await fetch(/api/user/${userId}).then(r r.json()); setUser(u); const [p, s] await Promise.all([ fetch(/api/posts/${u.id}).then(r r.json()), fetch(/api/settings/${u.id}).then(r r.json()) ]); setPosts(p); setSettings(s); } load(); }, [userId]); return ( div h1{user?.name}/h1 Suspense fallback{div加载图表.../div} HeavyChart data{posts} / /Suspense span{settings?.theme}/span /div ); }第二次审查应该只输出未发现 CRITICAL 问题或者只剩 MEDIUM 级别的重渲染建议。这个前后对比就是 Skill 有效性的直接证据。5. 常见报错排查401、local proxy failed 与 reading choicesSkill 跑不起来时报错信息往往指向配置问题而不是规则问题。下面是我和团队实际遇到过的几类按出现频率排序。401 Unauthorized是最常见的。返回体通常是{error:{type:authentication_error,message:invalid x-api-key}}。原因有三个Key 复制时带了空格、Key 已过期或被删除、请求头字段名写错。Anthropic 格式用x-api-keyOpenAI 格式用Authorization: Bearer两者不能混。排查时先用第 2 节的 curl 最小请求验证 Key确认通了再查 Skill 配置。local proxy failed一般出现在 Cline 或 Cursor 这类工具里报错形如Error: connect ECONNREFUSED 127.0.0.1:xxxx。这说明工具在尝试走本地代理端口但代理没启动。检查工具的 settings 里是否残留了http.proxy配置或者环境变量里有HTTP_PROXY。把 Base URL 直接设成https://taotoken.net/api不要经过任何中间层。如果团队统一用 MCP 模式确认 MCP server 的启动命令里没有多余的代理参数。reading choices这个报错很有迷惑性完整信息通常是Cannot read properties of undefined (reading choices)。它意味着工具按 OpenAI 格式解析响应但实际返回的是 Anthropic 格式或者反过来。根源在skill.config.json里的模型和接口格式不匹配。用claude-sonnet-4-20250514就要走/v1/messages接口返回体是content数组用 GPT 系列走/v1/chat/completions返回体才是choices。检查你的请求路径和模型 ID 是否对应。OAuth 相关报错比如OAuth token expired或invalid_grant通常出现在 Claude Code 的登录态失效时。如果你是用 API Key 接入不应该出现 OAuth 报错一旦出现说明工具还在走账号登录模式。需要在 Claude Code 的 settings 里显式配置 API Key 和 Base URL覆盖掉默认的 OAuth 流程。Codex 的auth.json也是同理里面如果存的是 OAuth token 而不是 API Key就会报这个错。正确做法是把auth.json改成{ apiKey: sk-你的密钥, baseUrl: https://taotoken.net/api }规则文件读取失败表现为模型输出未找到规则或直接忽略规则自由发挥。检查rulesDir是相对路径还是绝对路径相对路径的基准是 SKILL.md 所在目录。另外确认规则文件的 frontmatter 格式正确impact字段值必须是 CRITICAL/HIGH/MEDIUM/LOW 之一写错会导致该规则被跳过。排查顺序建议固定下来先验证 Key 和 Base URLcurl 最小请求再验证接口格式模型 ID 与路径匹配最后验证规则加载单独发一条规则文件内容让模型复述。这样能把问题范围快速缩小到某一层不用在配置里大海捞针。6. 把 Skill 接入你的日常工作流Skill 配好之后真正的价值在于让它进入日常流程而不是每次手动发 curl。三种接入方式按投入从低到高排列。最轻的方式是把它做成一个 shell 脚本接收文件路径作为参数输出审查报告#!/bin/bash # review.sh FILE$1 CODE$(cat $FILE) curl -s https://taotoken.net/api/v1/messages \ -H x-api-key: $TAOTOKEN_API_KEY \ -H anthropic-version: 2023-06-01 \ -H content-type: application/json \ -d { \model\: \claude-sonnet-4-20250514\, \max_tokens\: 4096, \temperature\: 0.2, \system\: \$(cat skills/react-best-practices/SKILL.md)\, \messages\: [{\role\: \user\, \content\: \审查\n$CODE\}] } | jq -r .content[0].text配合 git hook在 pre-commit 阶段对改动的.tsx文件跑一遍问题清单直接打印到终端。这样性能问题在提交前就被拦住不用等到 Code Review。中等投入是接入 CI。在 GitHub Actions 里加一个 job对 PR 里改动的 React 文件执行审查把结果作为评论贴到 PR 上。关键是把temperature压到 0.2 以下保证同一份代码在不同 CI 运行里输出一致否则评论会反复变化团队会失去信任。最重但收益最大的是做成团队共享的 Skill 仓库。把skills/react-best-practices/作为独立 git 仓库维护规则文件按上游更新同步团队成员的编码工具统一从这个仓库拉取。新人入职时不用背规则AI 会在他们写代码时按统一标准提示。规则编号如async-parallel还能作为 Code Review 的引用依据避免我觉得这样更好的主观争论。一个实用技巧定期用pnpm validate或类似脚本扫描项目代码统计各类问题的出现次数做成趋势图。如果 CRITICAL 问题数在下降说明 Skill 在起作用如果某类问题反复出现说明对应规则的提示词需要加强或者团队需要针对性培训。这比单纯看AI 有没有报错更能反映 Skill 的实际效果。最后提醒一点Skill 的输出是建议不是命令。模型偶尔会误报比如把有依赖关系的请求判成可并行。修复建议落地前人工确认一遍数据依赖关系。把 Skill 当成一个不知疲倦的初级审查员而不是最终决策者这样用起来最稳。
返回列表