☰
从裸用到工程化:Claude Code Skills与MCP开发工作流实战
2026/10/3 11:14:36 网站建设 项目流程

1. 从“裸用”到工程化:我的 AI 开发工作流重构之路

1.1 为什么“裸用”大模型写代码迟早会崩

我最开始用 Claude Code 的时候,跟大多数人一样,就是打开终端,敲一句“帮我写个用户登录接口”,然后等它吐代码。刚开始确实爽,几秒钟出结果,复制粘贴就能跑。但用了不到两周,问题就全冒出来了。

第一个坑是上下文漂移。同一个项目里,我先让它写了一个UserService,过两天再让它写OrderService,它完全不记得UserService里定义了哪些方法、用了什么命名规范、返回体是什么结构。结果就是两个 Service 各写各的,一个用Result<T>包装,一个直接返回实体类,前端对接的时候直接懵了。

第二个坑是重复劳动。每次新开一个会话,我都要重新告诉它:“这个项目用 Spring Boot 3.2,JDK 17,MyBatis-Plus,统一返回Result<T>,异常用BusinessException,日志用@Slf4j……” 说一遍两遍还行,说二十遍的时候我真的想把键盘砸了。

第三个坑是不可复现。有一次它帮我写了一个特别巧妙的 SQL 优化方案,我当时没存下来,后来想复用的时候怎么都想不起具体怎么写的。会话一关,经验就归零。

这三个坑归结起来就是一句话:我把大模型当成了一个“随叫随到的代码生成器”,而不是一个“需要配置和管理的工程系统”。裸用大模型,就像不带任何工具去修车——能拧几个螺丝,但遇到发动机大修就彻底歇菜。

1.2 Skills 和 MCP 到底解决了什么问题

后来我开始认真研究 Claude Code 的 Skills 和 MCP,才发现这两个东西本质上是在解决两个不同维度的问题。

Skills 解决的是“知识复用”问题。你可以把 Skills 理解成给 AI 写的“操作手册”或者“岗位说明书”。比如你定义一个spring-boot-conventions的 Skill,里面写清楚这个项目的包结构规范、命名规范、异常处理规范、日志规范。之后每次让 Claude Code 写代码,它都会自动加载这个 Skill,按照你定义的规范来写。不用再重复交代,不用再纠正它的风格。

MCP 解决的是“能力扩展”问题。MCP 全称是 Model Context Protocol,你可以把它类比成“AI 世界的 USB 接口”。USB 接口让电脑可以连接鼠标、键盘、打印机等各种外设;MCP 让 Claude Code 可以连接数据库、浏览器、Figma、蓝湖、Jira 等各种外部工具。没有 MCP 的时候,Claude Code 只能读写本地文件、执行终端命令;有了 MCP,它可以查数据库表结构、读 Figma 设计稿、拉 Jira 任务详情、操作浏览器做端到端测试。

这两个东西配合起来,才真正把 Claude Code 从“代码生成器”升级成了“开发工作流引擎”。Skills 负责“知道怎么做”,MCP 负责“能做什么”,两者结合,才能实现从需求到代码到验证的完整闭环。

1.3 这套工作流适合谁,不适合谁

先说适合谁。如果你满足以下任意一条,这套工作流值得你花时间搭建:

  • 你维护的是一个长期项目,不是一次性脚本。项目周期越长,Skills 和 MCP 的复利效应越明显。
  • 你的团队有明确的编码规范,但每次 Code Review 都要花大量时间纠正风格问题。
  • 你需要频繁在多个工具之间切换,比如从 Figma 看设计稿,到数据库查字段,再到 IDE 写代码,最后到浏览器验证。
  • 你希望 AI 生成的代码可以直接合并,而不是每次都要手动改半天。

再说暂时不适合谁。如果你只是偶尔写个爬虫脚本、做个数据分析,项目生命周期不超过一周,那搭建 Skills 和 MCP 的投入产出比确实不高。这种情况下,裸用大模型反而更高效。

但如果你是一个前端或后端工程师,每天的工作就是在一个成熟项目里加功能、改 Bug、做重构,那这套工作流迟早会帮你省下大量时间。我自己的实测数据是:搭建 Skills 和 MCP 花了大概两个周末,之后每周至少省下 5 到 8 小时的重复沟通和手动修正时间。一个月就回本了。

2. Skills 体系设计:把项目规范写成 AI 能读懂的“操作手册”

2.1 Skill 的文件结构和加载机制

Claude Code 的 Skill 本质上就是一个 Markdown 文件,放在项目的.claude/skills/目录下。每个 Skill 是一个独立的文件夹,文件夹名就是 Skill 的名字,里面必须有一个SKILL.md文件作为入口。

一个典型的 Skill 目录结构是这样的:

.claude/ skills/ spring-boot-conventions/ SKILL.md examples/ controller-example.md service-example.md references/ exception-codes.md vue3-frontend-conventions/ SKILL.md examples/ component-example.md

SKILL.md的格式也有讲究。它需要包含 YAML 格式的 frontmatter,用来告诉 Claude Code 这个 Skill 叫什么、什么时候该加载它。下面是一个我实际在用的例子:

--- name: spring-boot-conventions description: 当编写或修改 Spring Boot 后端代码时使用此 Skill,包含包结构、命名规范、异常处理、日志规范等约定 --- # Spring Boot 项目编码规范 ## 包结构 - Controller 放在 `controller` 包下 - Service 接口放在 `service` 包下,实现类放在 `service.impl` 包下 - Mapper 放在 `mapper` 包下 - 实体类放在 `domain.entity` 包下 - DTO 放在 `domain.dto` 包下 - VO 放在 `domain.vo` 包下 ## 命名规范 - Controller 类名以 `Controller` 结尾 - Service 接口以 `Service` 结尾,实现类以 `ServiceImpl` 结尾 - 方法名使用动词开头,如 `createUser`、`updateOrderStatus` ## 统一返回体 所有 Controller 方法必须返回 `Result<T>`,定义如下: ...

这里有个关键点:description 字段决定了 Skill 什么时候被自动加载。Claude Code 会根据你当前的任务内容,匹配 Skill 的 description,决定是否加载。所以 description 要写得既准确又宽泛,太窄了匹配不上,太宽了会误加载。

2.2 如何写出高质量的 Skill:三个核心原则

我踩过不少坑之后,总结出写 Skill 的三个核心原则。

原则一:写“约束”而不是“教程”。很多人写 Skill 的时候,喜欢把整个 Spring Boot 教程搬进去,从什么是 IoC 讲到 AOP 原理。这是完全错误的。Claude Code 本身已经懂这些基础知识,你不需要教它。你需要告诉它的是:在这个项目里,我们是怎么做的。比如“我们不用@Autowired字段注入,统一用构造器注入”,这才是它不知道的信息。

原则二:用示例代替描述。与其写“Service 层要处理业务异常并记录日志”,不如直接给一个完整的 Service 方法示例,让它照着写。我自己的经验是,一个 20 行的代码示例,比 200 字的文字描述效果好得多。Claude Code 对代码模式的模仿能力极强,你给它看什么,它就学什么。

原则三:分层组织,按需加载。不要把所有的规范都塞进一个 Skill。我现在的做法是:基础规范(命名、包结构、返回体)放在一个base-conventionsSkill 里;数据库操作规范放在database-conventions里;前端规范放在frontend-conventions里。这样 Claude Code 在写 Controller 的时候只会加载base-conventions,不会把前端规范也拉进来,节省上下文窗口。

2.3 我实际在用的 Skill 清单和配置

下面是我目前项目里在用的 Skill 清单,以及每个 Skill 的核心内容概要:

Skill 名称触发场景核心内容
base-conventions编写任何后端代码包结构、命名规范、统一返回体、异常处理
database-conventions涉及数据库操作MyBatis-Plus 用法、分页规范、SQL 编写规范
api-design设计新接口RESTful 规范、URL 命名、参数校验、Swagger 注解
frontend-conventions编写 Vue 代码组件命名、Composition API 用法、状态管理规范
test-conventions编写测试代码JUnit 5 用法、Mockito 规范、测试命名

每个 Skill 的SKILL.md我都控制在 200 行以内,超过 200 行就会拆分成多个 Skill。原因是 Claude Code 的上下文窗口是有限的,Skill 太长会挤占其他内容的加载空间。

这里分享一个实操心得:Skill 写完之后一定要测试。测试方法是新开一个会话,让它写一个简单的功能,看它是否自动加载了正确的 Skill,生成的代码是否符合规范。如果不符合,就回去改 Skill 的 description 或者内容。我前三个 Skill 改了至少五遍才稳定下来。

3. MCP 接入实战:让 Claude Code 真正“连上”你的工具链

3.1 MCP 的本质:AI 世界的 USB 协议

MCP 这个词最近很火,但很多人搞不清楚它到底是什么。我用一个类比来解释:MCP 就是 AI 世界的 USB 协议。

在 USB 出现之前,电脑连接鼠标用 PS/2 接口,连接打印机用并口,连接显示器用 VGA 接口,每种设备一个专用接口,互不兼容。USB 出现之后,所有设备统一用 USB 接口,电脑只需要提供 USB 端口,设备只需要实现 USB 协议,就能互相通信。

MCP 做的事情一模一样。在 MCP 出现之前,Claude Code 要连数据库,需要专门写一套数据库连接逻辑;要连 Figma,需要专门写一套 Figma API 调用逻辑;要连浏览器,需要专门写一套浏览器控制逻辑。每个工具都要单独适配,工作量巨大。

MCP 出现之后,所有工具只需要实现 MCP 协议,Claude Code 只需要支持 MCP 协议,就能连接所有工具。这就是为什么最近 MCP 生态爆发式增长——大家都按同一个标准来,接入成本大幅降低。

3.2 我接入的 MCP 服务清单和配置方法

目前我项目里接入了四个 MCP 服务,每个都解决了具体的痛点:

第一个是数据库 MCP。这个 MCP 让 Claude Code 可以直接查询数据库表结构、查看字段类型、甚至执行只读 SQL。以前我要写一个实体类,得先打开数据库客户端,查表结构,复制字段名,再回到 IDE 写代码。现在直接跟 Claude Code 说“根据t_user表生成实体类”,它自己就去查表结构了。

配置方法是在项目根目录的.mcp.json文件里添加:

{ "mcpServers": { "database": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-mysql"], "env": { "MYSQL_HOST": "localhost", "MYSQL_PORT": "3306", "MYSQL_USER": "readonly", "MYSQL_PASSWORD": "your_password", "MYSQL_DATABASE": "your_database" } } } }

这里有个安全注意事项:数据库 MCP 一定要用只读账号。我专门建了一个readonly用户,只给 SELECT 权限。这样即使 Claude Code 误操作,也不会把数据改坏。

第二个是浏览器 MCP。这个 MCP 让 Claude Code 可以控制浏览器,做端到端测试。比如我写完一个登录功能,直接跟它说“打开浏览器,访问登录页,输入测试账号,验证登录成功”,它就会自动操作浏览器完成测试。

浏览器 MCP 目前有两个主流选择:Browser Use MCP 和 Playwright MCP。我两个都试过,最后选了 Playwright MCP。原因是 Playwright MCP 更稳定,对复杂页面的支持更好,而且可以直接复用 Playwright 的测试脚本。Browser Use MCP 的优势是更轻量,适合简单的页面操作。

第三个是 Figma MCP。这个 MCP 让 Claude Code 可以读取 Figma 设计稿,自动生成对应的前端代码。以前前端开发最痛苦的就是对着设计稿一个像素一个像素地调,现在直接把 Figma 链接丢给 Claude Code,它就能生成 80% 相似度的代码,我再手动微调一下就行。

第四个是蓝湖 MCP。蓝湖是国内团队常用的设计协作工具,它的 MCP 和 Figma MCP 功能类似,但更贴合国内团队的使用习惯。如果你的团队用蓝湖,直接接蓝湖 MCP 就行。

3.3 MCP 配置的常见坑和排查方法

MCP 配置看起来简单,但实际接入的时候坑特别多。我整理了几个最常见的:

坑一:MCP 服务启动失败,但没有任何报错。这种情况通常是command或args写错了。排查方法是手动在终端执行一遍command和args,看能不能正常启动。比如上面数据库 MCP 的配置,你就手动执行npx -y @modelcontextprotocol/server-mysql,看有没有报错。

坑二:MCP 服务启动了,但 Claude Code 找不到。这种情况通常是配置文件路径不对。Claude Code 默认读取项目根目录的.mcp.json,如果你放在其他位置,它就读不到。另外,有些版本的 Claude Code 需要重启才能加载新的 MCP 配置,改完配置记得重启一下。

坑三:MCP 服务能连上,但调用时报权限错误。这种情况通常是环境变量没配好。比如数据库 MCP 的MYSQL_USER和MYSQL_PASSWORD如果写错了,服务能启动,但查询的时候会报权限错误。排查方法是检查.mcp.json里的env字段,确保所有必要的环境变量都配了。

坑四:多个 MCP 服务冲突。如果你同时接入了多个功能相似的 MCP,比如同时接了 Figma MCP 和蓝湖 MCP,Claude Code 可能会不知道该用哪个。我的做法是只保留一个,需要切换的时候手动改配置。

4. Skills 和 MCP 协同:构建完整的 AI 开发工作流

4.1 一个完整功能的开发流程实录

下面我以一个真实的功能开发为例,展示 Skills 和 MCP 如何协同工作。需求是:给用户模块增加一个“修改密码”功能。

第一步:需求理解。我直接跟 Claude Code 说:“给用户模块增加修改密码功能,需要旧密码验证、新密码强度校验、修改成功后发送通知。”

第二步:自动加载 Skill。Claude Code 检测到这是后端功能开发,自动加载了base-conventions和api-design两个 Skill。它知道这个项目的 Controller 要返回Result<T>,Service 要分接口和实现类,异常要用BusinessException。

第三步:通过 MCP 查数据库。Claude Code 通过数据库 MCP 查询了t_user表结构,发现已经有password字段,但缺少password_updated_at字段。它主动提醒我:“检测到缺少password_updated_at字段,是否需要生成对应的 DDL 语句?”

第四步:生成代码。它生成了完整的代码:Controller 层的changePassword接口、Service 层的changePassword方法、DTO 层的ChangePasswordRequest、以及对应的单元测试。所有代码都符合项目规范,命名、包结构、返回体全部正确。

第五步:通过 MCP 验证。它通过浏览器 MCP 启动了前端页面,模拟用户操作,验证修改密码流程是否正常。发现新密码强度校验的前端提示文案和后端不一致,主动修正了。

第六步:生成变更总结。最后它输出了一份变更总结,包括修改了哪些文件、新增了哪些文件、需要执行什么 DDL、有什么注意事项。

整个流程下来,我只需要在第一步描述需求,后面全是自动完成的。以前这个功能我至少要写半天,现在 20 分钟搞定。

4.2 工作流中的关键决策点

这套工作流能跑通,有几个关键决策点值得展开说。

决策点一:Skill 的粒度怎么定。太粗了,一个 Skill 管所有事,Claude Code 加载的时候会带入大量无关信息,浪费上下文;太细了,一个 Skill 只管一个方法,维护成本太高。我的经验是:按“关注点”划分。命名规范是一个关注点,数据库操作是一个关注点,API 设计是一个关注点。每个关注点一个 Skill,粒度刚刚好。

决策点二:MCP 的权限怎么控。MCP 给了 Claude Code 很大的能力,但能力越大风险越大。我的原则是:只给必要的权限,不给多余的权限。数据库 MCP 只给只读权限,浏览器 MCP 只给测试环境的访问权限,Figma MCP 只给读取权限。这样即使出问题,影响也可控。

决策点三:什么时候用 Skill,什么时候用 MCP。简单判断标准是:如果这件事是“知道怎么做”,用 Skill;如果这件事是“需要访问外部资源”,用 MCP。比如“怎么写 Controller”是 Skill,“查数据库表结构”是 MCP。两者配合,才能覆盖完整的开发流程。

4.3 实测效率对比:裸用 vs 工程化

我记录了自己一个月内两种模式下的效率数据,对比如下:

对比项裸用大模型Skills + MCP 工程化
单功能平均开发时间3.5 小时1.2 小时
代码规范符合率约 60%约 95%
需要手动修正的次数平均 8 次/功能平均 1.5 次/功能
跨会话上下文丢失率100%接近 0%
端到端测试覆盖率基本没有约 70%

这个数据是我自己手动记录的,样本量不大,但趋势很明显。最让我意外的是“代码规范符合率”这一项。裸用的时候,我至少要花 30% 的时间在改命名、改返回体、改异常处理上。用了 Skill 之后,这部分时间几乎降为零。

5. 常见问题与排查技巧实录

5.1 Skill 不生效的排查思路

Skill 不生效是最常见的问题,表现是 Claude Code 生成的代码不符合 Skill 里定义的规范。排查思路如下:

第一步:检查 Skill 是否被加载。在 Claude Code 里输入/skills命令,可以看到当前加载了哪些 Skill。如果列表里没有你的 Skill,说明没加载成功。

第二步:检查 description 是否匹配。如果 Skill 在列表里但没被使用,说明 description 和当前任务不匹配。比如你的 description 写的是“编写 Java 代码时使用”,但当前任务是写 SQL,那就匹配不上。解决方法是把 description 写得更宽泛,或者拆成多个 Skill。

第三步:检查 Skill 内容是否有冲突。如果加载了多个 Skill,内容有冲突,Claude Code 可能会无所适从。比如一个 Skill 说“用@Autowired注入”,另一个说“用构造器注入”,它就会随机选一个。解决方法是确保 Skill 之间没有矛盾。

第四步:检查 Skill 文件格式。SKILL.md的 frontmatter 必须是合法的 YAML,name和description字段必须存在。我遇到过因为 YAML 缩进错误导致 Skill 加载失败的情况,排查了半天才发现。

5.2 MCP 连接失败的速查表

MCP 连接失败的原因很多,我整理了一个速查表,按现象分类:

现象可能原因解决方法
MCP 服务启动失败command 或 args 错误手动执行命令验证
Claude Code 找不到 MCP配置文件路径错误确认.mcp.json在项目根目录
调用时报权限错误环境变量配置错误检查env字段
调用超时网络问题或服务未启动检查服务状态和网络
多个 MCP 冲突功能重叠只保留一个,或手动切换
配置改了不生效需要重启重启 Claude Code

5.3 我踩过的三个大坑和解决方案

大坑一:Skill 写得太长,导致上下文溢出。我一开始把整个项目的编码规范都写进一个 Skill,结果 800 多行。Claude Code 加载之后,上下文窗口被占了一大半,导致它记不住其他重要信息。解决方案是拆分成多个小 Skill,每个控制在 200 行以内。

大坑二:MCP 用了生产环境数据库。有一次我图省事,数据库 MCP 直接连了生产库。结果 Claude Code 查询的时候执行了一条全表扫描,把生产库拖慢了。虽然没造成数据损坏,但被运维警告了一次。解决方案是永远用只读账号,永远连测试库。

大坑三:Skill 和 MCP 的职责边界不清。我一开始把“查数据库表结构”也写进了 Skill,结果 Claude Code 按照 Skill 里的描述去查,但因为没有 MCP 权限,查不到。解决方案是明确边界:Skill 只写“知道怎么做”,MCP 只写“能访问什么”,两者不重叠。

5.4 进阶技巧:让 Skill 和 MCP 互相配合

最后分享一个进阶技巧:让 Skill 引用 MCP 的能力。比如在database-conventionsSkill 里,可以写这样一段:

## 生成实体类的流程 1. 通过数据库 MCP 查询目标表的结构 2. 根据表结构生成实体类,字段名使用驼峰命名 3. 主键使用 `@TableId` 注解,类型为 `Long` 4. 公共字段(create_time、update_time)使用 `@TableField(fill = FieldFill.INSERT)` 注解

这样 Claude Code 在生成实体类的时候,就会自动去调用数据库 MCP 查表结构,然后按照 Skill 里的规范生成代码。Skill 负责“怎么做”,MCP 负责“查什么”,两者配合得天衣无缝。

这个技巧的关键是:在 Skill 里明确写出“通过 XX MCP 做 XX 事”。Claude Code 看到这样的描述,就会主动去调用对应的 MCP。我实测下来,这个配合方式比单独用 Skill 或单独用 MCP 效果好得多。

6. 从工具到习惯:我的日常 AI 开发工作流

6.1 每天开工前的准备工作

我现在每天开工前会做三件事,花不了五分钟,但能让一整天的效率提升一个档次。

第一件事是检查 Skill 和 MCP 的加载状态。输入/skills看 Skill 列表,输入/mcp看 MCP 连接状态。如果有异常,第一时间排查,不要等到写代码写到一半才发现。

第二件事是同步最新的项目规范。如果昨天 Code Review 的时候发现了新的规范问题,比如“以后 DTO 命名统一用XxxRequest和XxxResponse”,我会第一时间更新到对应的 Skill 里。这样今天写的代码就不会再犯同样的错误。

第三件事是清理过期的上下文。Claude Code 的会话上下文是有限的,如果昨天开了一个很长的会话,今天继续用的时候可能会因为上下文太满而变慢。我的做法是每天开一个新会话,把必要的背景信息通过 Skill 和 MCP 自动加载,而不是靠会话历史。

6.2 开发过程中的协作节奏

开发过程中,我摸索出了一套和 Claude Code 协作的节奏。

需求描述阶段:我会尽量把需求说清楚,包括业务背景、输入输出、边界条件。但不会说太细,因为太细了反而限制了它的发挥。比如我会说“做一个用户导出功能,支持按注册时间筛选,导出 Excel”,而不会说“用 EasyExcel 的@ExcelProperty注解定义列”。

代码生成阶段:我会让它先生成核心逻辑,我审查一遍,确认方向对了,再让它生成周边代码(Controller、DTO、测试)。这样如果方向错了,改起来成本低。

验证阶段:我会让它通过浏览器 MCP 做端到端测试,同时我自己也会手动跑一遍关键路径。AI 测试覆盖的是常规路径,人工测试覆盖的是边界情况,两者互补。

提交阶段:我会让它生成 Commit Message 和变更总结,我审查后提交。这样 Commit Message 的质量比我自己写的高,而且不会漏掉变更点。

6.3 每周复盘和持续优化

每周五下午,我会花半小时做一次复盘,主要做三件事。

第一件事是回顾本周的 Skill 更新。看看哪些 Skill 被频繁修改,说明这些地方规范不稳定,需要进一步明确。哪些 Skill 从来没被修改过,说明这些规范已经稳定了。

第二件事是检查 MCP 的使用情况。看看哪些 MCP 调用频繁,哪些几乎没用。没用的 MCP 就移除,减少配置复杂度。频繁调用的 MCP 就优化配置,提升响应速度。

第三件事是整理本周踩过的坑。把新发现的坑记录到排查速查表里,把新的解决方案补充到 Skill 里。这样下周再遇到同样的问题,就能秒解决。

这套复盘机制看起来简单,但坚持下来效果惊人。我现在的 Skill 库和 MCP 配置,比三个月前完善了不止一个档次。最重要的是,这套工作流已经变成了我的肌肉记忆,不需要刻意去想,自然而然就会按照工程化的方式去用 AI。

6.4 一个真实项目的完整复盘

最后分享一个真实项目的复盘。上个月我接了一个需求:给一个 RuoYi-Vue-Pro 项目增加 MCP 功能模块,让系统可以通过 MCP 协议对外提供能力。

这个项目我全程用 Skills + MCP 工作流完成,总共花了三天。如果按以前裸用的方式,我估计至少要一周。

第一天上午,我让 Claude Code 通过数据库 MCP 分析了 RuoYi-Vue-Pro 的表结构,理清了用户、角色、权限的关系。下午,我基于分析结果写了ruoyi-conventionsSkill,把 RuoYi 的代码规范固化下来。

第二天,我让 Claude Code 按照 Skill 规范生成了 MCP 模块的核心代码,包括 MCP 服务注册、工具定义、权限校验。中间通过浏览器 MCP 做了两次端到端测试,发现并修复了三个权限相关的 Bug。

第三天,我让它生成了完整的单元测试和集成测试,覆盖率达到了 85%。然后通过 MCP 做了压力测试,确认性能达标。最后生成了变更总结和部署文档。

这个项目让我最满意的地方是:代码质量比我手写的还高。因为 Skill 里固化了最佳实践,Claude Code 生成的代码严格遵守规范,没有一处命名不一致、没有一处异常处理遗漏。Code Review 的时候,同事问我是不是找了外援,我说是 AI 写的,他一脸不信。

这个项目之后,我彻底相信了:AI 开发工作流的未来,一定是工程化的。裸用大模型的时代已经过去了,Skills 和 MCP 才是正确的打开方式。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询