我过去用的方式,其实很"裸":打开 Claude Code,甩一段需求描述,它理解为啥就干啥,我像个给 AI 传话的实习生,一遍一遍提醒它"注意项目结构""别动那个配置文件""用项目里已有的工具函数"。短期内好像也能跑,但换一个项目、换一台机器、换一个人,一切归零。后来我把 Skills 和 MCP 引入工作流,把 AI 从"对话里的临时工"变成了"带着工具箱和项目规范进场的正式员工",整个开发节奏和交付质量都上了一个台阶。这篇文章就把我这段时间的工程化实践,从思路到配置再到踩坑,一次性讲清楚。
1. 为什么我会从"裸用"转向工程化
1.1 "裸用"阶段我遇到的真问题
先说清楚什么叫"裸用"。我的理解是:你没有给 AI 任何持久化的上下文,没有固定的工具集,也没有跨会话保留的约定,每次开工都是"新开一个会话,从零解释需求"。这套方式的典型表现有几种。
第一种是重复解释。项目里明明有一个统一的请求封装,AI 第一次会乖乖用,但换一个会话,它可能自己fetch一把,你不得不重新把项目里的目录结构、依赖关系、代码风格粘贴一遍。稍微复杂一点的项目,光"进入状态"就要花掉十分钟。
第二种是工具不可达。让 AI 去查数据库、读线上日志、看某个服务的返回结果,它做不了,因为它没有相应的接口。你只能自己手动查完,再把结果贴给它。一次两次还行,次数多了你会发现:我到底是来写代码的,还是来给 AI 跑腿的?
第三种是上下文丢失。聊到一半,会话超时,重新进来,AI 对刚才讨论的决策一无所知。你可能还记得当时为什么放弃了方案 A 选择方案 B,但 AI 不记得,于是它可能再次给你推荐方案 A,你又要花时间解释。
这些问题本质上是同一个:AI 的工作环境太单薄了。它只有对话窗口,没有"项目上下文",没有"工具调用能力",没有"长期记忆"。让一个只有对话能力的助手去参与工程级开发,当然会觉得它"不聪明""不听话"。后来我才意识到,问题不全在模型身上,在我没有给它搭好环境。
1.2 MCP 和 Skills 分别解决什么问题
MCP(Model Context Protocol,模型上下文协议)和 Claude Code Skills 是两条不同的补强路线,理解它们的边界很重要,不然容易混在一起不知道什么时候该用哪个。
MCP 解决的是**"AI 能触达什么"**的问题。它定义了一套标准化的接口,让 AI 可以调用外部工具、读取外部数据。比如通过 PostgreSQL MCP,AI 能直接查询数据库;通过 GitHub MCP,AI 能查看仓库、创建 Issue、发起 Pull Request;通过文件系统 MCP,AI 能管理本地文件。相当于给 AI 接上了"手"和"眼睛"。
Skills 解决的是**"AI 知道怎么做、按什么规范做"**的问题。它是一份结构化的提示词和示例集合,告诉 AI 在特定任务里应该遵循什么流程、用什么代码风格、有什么必须遵守的项目约定。相当于给 AI 发了"员工手册"。
我用一个类比来理解:MCP 是工具柜,里面摆着螺丝刀、电钻、水平仪;Skills 是操作规范,写着"打孔前要先划线""电线必须走线槽""完工后要清理现场"。只有工具柜,AI 有力气但不知道怎么干;只有操作规范,AI 知道怎么干但没工具。两者结合,AI 才是一个"带工具、懂规矩"的施工队。
想清楚这一点之后,我开始动手给工作流做工程化改造,核心就两件事:建好工具柜,写好员工手册。
2. MCP 基础选型与配置实操
2.1 用大白话理解 MCP 的运作方式
在写配置之前,先把 MCP 的运作方式说透。MCP 分三个角色:宿主(比如 Claude Code)、MCP 服务器(提供能力的服务)、MCP 客户端(连接两者的桥梁)。当 AI 在对话中决定"我需要查询数据库"时,它会通过 MCP 协议向服务器发出请求,服务器执行操作并返回结果,AI 再把结果纳进自己的思考继续生成代码。
这个设计的精髓在于标准化。过去的做法是每个工具都有自己的调用方式,AI 要接十个工具就得适配十种接口。MCP 把这一切统一成一套协议,等价于给 AI 的工具调用做了一个"USB-C 接口"。不同服务器只要遵循同一协议,就能无缝接入。
从配置角度看,MCP 服务器的接入通常就是一段 JSON 配置。以claude_desktop_config.json或者在 Claude Code 里的settings.json为例,核心字段包括:name(服务器名)、transport(传输方式,通常是stdio或sse)、args(启动命令和参数)、env(环境变量)。配置方式不算复杂,关键在于掌握 .mcp 文件与依赖管理。
我实际在项目里优先使用的 MCP 服务器如下:
| MCP 服务器 | 用途 | 类型 |
|---|---|---|
| filesystem | 本地读写、文件搜索、目录树 | 官方示例 |
| PostgreSQL | 执行查询、查看表结构、数据行采样 | stdio |
| GitHub | 仓库读取、Issue/PR 操作、代码检索 | HTTP/SSE |
| Memory | 跨会话记忆用户偏好与项目决策 | stdio |
| Context7 | 实时获取第三方库最新文档 | stdio |
| Puppeteer | 浏览器自动化、页面内容提取 | stdio |
这个清单是我在实际项目里的"基础款",足够覆盖大部分日常开发场景。重点不是装得多,而是装得准,每个工具都要对应真实需要。装一堆用不上的工具,既增加系统请求开销,也让 AI 在决策时更容易选错。
2.2 几个高性价比 MCP 服务器的配置示范
PostgreSQL MCP是我所有项目里最常用的一个。AI 能直接连上本地开发库,天然知道有哪些表,也能执行带条件的查询。配置示例如下:
{ "mcpServers": { "postgres": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-postgres"], "env": { "DATABASE_URI": "postgresql://user:password@localhost:5432/mydb" } } } }配置完成后,你可以在对话里直接说"看一下 orders 表最近一周的订单量趋势",AI 会自己生成 SQL、执行查询、把结果整理成可读的总结。这里要注意:不要给 AI 配上生产环境的写权限,我一开始图省事直接指向了生产库的只读账号,结果 AI 在分析时把只读当成常规,遇到写入需求时报错才发现配置里少了权限层级。给 MCP 的最小权限原则,和给人类开发者的最小权限原则完全一致。
Memory MCP的价值在于把"跨会话记忆"变成一种基础能力。之前"裸用"时的老大难——AI 不记得上一次的决策——由它来兜底。它内部维护了一份知识图谱式的记忆库,当 AI 发现对话里出现"我们决定后端用 FastAPI""用户反馈里 E 开头的订单号是异常数据"这类信息时,可以主动写入记忆。下次会话里,这些问题就不再需要重复解释。
Memory MCP 不用特意配置复杂参数,它默认会在本地维护一个记忆文件。我要强调的其实是另一个点:记忆是有噪音的。AI 写入记忆的门槛很低,什么"用户喜欢蓝色主题"这类临时偏好也会被记下来,积累多了反而干扰判断。我每周会清理一次记忆文件,只保留真正对项目有长期影响的决策。这就像给 AI 做大扫除,把脑子里没用的东西清出去,免得它做事的时候想太多。
GitHub MCP比较适合团队协作场景。它让 AI 能直接读取仓库里的文件结构、查看分支状态、创建 Issue,甚至发起 PR。配置上通过环境变量传入 Personal Access Token 即可。我用它来替代"把代码粘贴到对话框里"的笨办法:直接在对话里说"看看 feature/user-auth 分支上改了哪些文件",AI 自己去拉取信息,比人肉复制粘贴准确得多。
2.3 Claude Code Skills 的编写规范
Skills 的核心是一组带说明的 Markdown 文件,放在项目的.claude/skills目录下。每个 Skill 有一个名字、一段说明、一段脚本和若干示例。Claude Code 在启动时会加载这些文件,并在对话中把相关内容作为上下文的一部分提供。
我自己写 Skill 的模板如下:
--- name: 后端接口开发规范 description: 新增或修改后端 API 接口时使用。强制统一响应格式、错误码规范、日志埋点要求。 --- ## 使用场景 当需要新增一个 HTTP 接口,或者修改已有接口的签名/返回值时,请遵循本规范。 ## 响应结构 所有接口返回统一结构: { "code": 0, "message": "success", "data": {} } ## 错误码 - 1000: 参数错误 - 1001: 未登录 - 1002: 无权限 - 2000: 业务异常 ## 注意事项 - 必须在入口处记录请求日志,包含 request_id - 参数校验使用 pydantic,不允许手写 if 判断 - 所有时间字段统一为 ISO8601 格式编写 Skill 的要点在于具体化。写得越具体,AI 的执行越稳定。你说"要遵守好的代码风格",AI 不知道该听谁的;你说"函数命名用 snake_case,禁止用缩写",AI 就能给出符合预期的结果。
我还会给团队公共的 Skill 加上版本号,方便知道当前用的是哪一版。如果发现某个 Skill 让 AI 频繁做错事,那不是 AI 的问题,是 Skill 写得不够清楚,我会先修订它,再重新跑一次典型场景验证。
3. 把工作流改造成工程化链路
3.1 项目启动:上下文注入与目录约定
工程化和"裸用"的第一个明显分水岭,在项目启动阶段。裸用是你人肉把项目背景灌给 AI;工程化是你把项目背景沉淀成文件,让 AI 自己读取。
我在每个新项目里固定做三件事:
- 写一个
CLAUDE.md项目说明,内容包括项目简介、技术栈、目录结构、常用命令、关键业务约定。Claude Code 会自动把它作为项目级上下文进行加载。 - 写
.claude/skills/目录下的业务型 Skill,把那些"只可意会只可经验"的编码规范沉淀下来。 - 把 MCP 配置写进项目级配置文件,让团队里每个开发者 clone 后只需一条命令就能把工具链拉起来。
CLAUDE.md的内容不用追求面面俱到,但要有优先级。我的习惯是开头先写三句话以内的项目定位,然后是"如果你要改这个项目,必须先知道的五件事"——这五件事往往才是 AI 最容易踩雷的地方。例如某个模块用了全局单例,改之前必须先了解它的生命周期;某个表的删除用的是软删除;某条链路绕过了统一异常处理。这些都放进CLAUDE.md,AI 从一开始就带着避雷清单进场。
3.2 开发过程:技能绑定与工具协同
项目运行起来之后,工程化工作流给我的体验是:AI 从"被动答题"变成"主动干活"。过去我描述一个需求,AI 给我一段代码;现在我会说"按后端接口开发规范实现用户资料更新接口",它能自动按规范里的响应结构、错误码、日志要求去写,不再需要我把规范一步步贴给它。
演示一个实际开发场景,假设有个需求:给用户模块加一个"修改昵称"的接口。我的实际使用方式是这样一句话:
给用户模块新增修改昵称的接口。请先阅读 CLAUDE.md 了解项目结构,再按用户接口开发规范实现,完成后运行该接口的单测。
AI 的执行链路是:读取CLAUDE.md→ 了解项目模块位置 → 加载"用户接口开发规范"Skill → 通过 PostgreSQL MCP 查看用户表字段 → 生成接口代码 → 用文件系统 MCP 确认目标文件 → 写入代码 → 运行测试命令验证。
这条链路里,AI 不是在"写一段代码",而是在"完成一个工程任务"。我节省了来回确认的时间,AI 的输出也更接近团队规范。自动化意识一旦建立,我就能把更多精力放在设计决策上,而不是类型标注和命名。
3.3 交付检查:自动化验证与文档生成
工程化带来的另一个好处是交付质量可控。原来 AI 写完代码我人肉审查,现在一部分审查可以交给工具。
我的做法是在 Skill 里内置一个"交付检查清单",让 AI 每次完成任务后,按清单逐项确认:是否有遗漏文件?变量名是否符合规范?是否有调试日志残留?是否补充了测试?是否更新了相关文档?AI 按清单检查,输出一个完成情况报告,我再重点看它标注"未完成"或"不确定"的项。
CLAUDE.md和 Skills 的引入,也让"生产文档"从负担变成了副产品。项目里有一个"接口文档生成"的 Skill,AI 在写完接口后,可以自动更新 OpenAPI 格式的文档文件;有"变更日志"Skill,AI 在每次完成需求后,把变更内容追加到 CHANGELOG。文档和代码是同一次行为产生的,就不容易出现"代码改了文档没改"的常见病。
4. 踩坑记录与排查技巧
4.1 权限与配置同步问题
MCP 接入后的第一坑,永远是权限。我给 PostgreSQL MCP 单独建了一个最小权限账号,只给SELECT和必要的INSERT权限,不给DROP、TRUNCATE。一开始觉得"开发库而已无所谓",直到有一次 AI 在会话里把一张临时表DROP了,我才意识到:开发库也是库,也要按生产标准对待。最小权限不是针对 AI 的不信任,而是对任何自动化流程的基本防护。
第二个坑是配置不同步。团队里如果有人改了 MCP 配置或者新增了 Skill,其他人拉代码后不会自动生效,就会出现"你那边 AI 能查数据库,我这边报找不到工具"的混乱。后来我把 MCP 配置和 Skills 全部纳入版本控制,并在CLAUDE.md里写上"更新配置后请重启 Claude Code"。这不是什么高明技巧,但能减少大部分困扰。
通过 .mcp 文件管理项目级工具时,同样建议把依赖的 package 版本写清,注释写清每个工具的用途。目录权限上,若团队成员共享同一台机器,要注意个人仓库与全局仓库的隔离——不共享 HOME 目录配置,不覆盖他人的全局工具列表,是避免"改了个人的配置,影响别人环境"的基本觉悟。
4.2 工具输出超时与请求量过大
MCP 工具不是没有成本。AI 每次调用工具都有一次网络开销,调用链一旦密密麻麻排起来,整个会话会变得很慢,严重时工具直接超时。我遇到过一次 AI 写一段前端代码,为了查一个组件库的 API,连续调用 Context7 查了七八次,每次都在等待网络返回,体验极差。
应对方式有两个。一是在提示词里明确约束:例如在 Skill 中写"Context7 仅在不确定 API 时使用,同一会话内最多使用两次"。二是给工具调用做缓冲:像 GitHub 类工具,AI 可以先把仓库信息汇总,一次性读完需要的文件,而不是逐个单独请求。
4.3 常见问题速查表
| 现象 | 可能原因 | 处理方式 |
|---|---|---|
| AI 调用工具后报"connection refused" | MCP 服务器未启动或端口冲突 | 检查配置文件端口,重启服务 |
| AI 无法写入文件 | 文件系统 MCP 未授予对应目录权限 | 在配置中补上该目录 |
| AI 频繁使用不必要的工具 | Skills 缺少工具使用约束 | 在 Skill 中写明工具使用边界 |
| 跨会话不记得项目决策 | 未配置 Memory MCP,或记忆文件过期 | 接入 Memory,更新记忆内容 |
| 更新配置后不生效 | 宿主进程未重启 | 重启 Claude Code |
| AI 生成了不符合项目规范的代码 | 缺少业务型 Skill | 编写对应场景 Skill |
| 团队成员工具版本不一致 | 配置未纳入版本控制 | 工具与配置入仓库同步 |
排查方法与人类新员工上岗类似:先看它有没有权限,再看它有没有工具,最后看它懂不懂规矩。这三个维度对照排查,大部分问题都能定位。
我还有一个习惯,是让 AI 在工具调用前先说明"我要用哪个工具、用来做什么"。这样我能看到它的意图,在它走偏之前拦下来,而不是等它执行完才发现结果不对。实测下来,会话的可控性提升尤其明显。
5. 工程化实践的几个进阶心得
5.1 用自定义 Skill 沉淀团队规范
比起一堆写在 wiki 里没人看的规范文档,我把团队规范逐步改写成 Skills。新成员加入后,与其让他读三天文档,不如让他直接和配好 Skills 的 Claude Code 一起工作,AI 会在实际任务里隐形地执行规范。这个转变不是技术上的,而是知识管理上的:把"知道怎么写"变成了"运行时会自动遵守"。
但 Skill 也不是越多越好。每个 Skill 都会增加上下文长度,装得太多,AI 反而抓不住重点。我现在的原则是:只保留那些"出错成本高"或"反复犯过错误"的规范。比如统一响应格式、错误码规范、日志埋点这类必守红线,值得写;像"函数要写注释"这种软性追求,写了用处也不大,AI 会为写注释而写注释。
5.2 定期审查 AI 的工具使用日志
Claude Code 会记录会话中所有工具调用情况。我每隔一段时间会把日志翻出来看一眼,重点做两个分析:一是哪些工具被高频调用,说明是核心依赖;二是哪些工具调用了但结果没被使用,说明这个工具可能是个干扰项,削弱了 AI 的执行效率。
这就像是看程序的 profiler 报告——不加分析时一切正常,分析完总能找到几个可以优化的热点。我之前发现自己装了某个翻译工具,AI 偶尔会去翻它,但翻完并不能帮助写代码,反而拖慢节奏。移除之后,会话速度提升明显,AI 的执行路径也干净了。
5.3 把这些方法迁移到其他工具和场景
一旦理解了 MCP 和 Skills 的思路,你会发现这套方法论并不局限于某个特定工具。只要支持 MCP 协议的客户端,或者任何支持"工具集+上下文注入"的 AI 工具,都能套用同样的框架。业务系统的接入也越来越多,像禅道这类项目管理工具都已提供 MCP 接口,AI 可以直接读取需求、更新任务状态;地图、行情、办公协作等领域也在逐步开放。
MCP 的意义在于它把 AI 和真实系统之间的连接方式做成了开放式标准。今天我接数据库、接代码仓库、接浏览器,明天接内部系统、接业务平台,不用重写所有集成代码。工程化不是一次性的改造,而是一种可以不断复用的思维框架:给 AI 建工具柜,给 AI 发员工手册,让 AI 在一个有结构、有规范的环境里工作。
对于正准备开始改造工作流的朋友,我的建议是从小处入手:先给一个你最有痛感的工具链配好 MCP,再挑一个最容易违反的规范写成 Skill。跑顺了,再逐步加码。我自己也还在迭代这套流程,毕竟 AI 开发工具更新得太快,唯一稳妥的做法就是把"持续调整"本身也工程化。