AI Coding 装了一堆 Skills 反而更难用:Prompt、Skill、MCP、Agent 到底该放哪一层?

13 阅读13分钟

这段时间 AI Coding 有个趋势挺明显。

以前大家比的是:

哪个模型写代码强?

后来开始比:

谁的 Agent 强?

再后来整个东西越来越多:

Prompt
Skill
MCP
Tool
Agent
AGENTS.md
Memory
Plugin

我自己刚开始接触这些东西的时候,也有一个很直接的反应:

能装的先装上。

Skill 多一点。

MCP 多接几个。

项目规则写详细一点。

Agent 权限开全一点。

感觉这样 AI 应该会越来越强。

结果用了一段时间以后,我反而发现:

很多 AI Coding 工作流,不是能力不够,是东西塞太多了。

你本来只是想问:

这条 SQL 为什么慢?

结果 Agent 开始:

扫描项目
↓
读取几十个文件
↓
加载项目规则
↓
加载 Skills
↓
调用数据库工具
↓
分析 ORM
↓
继续追调用链

最后烧了一大堆上下文。

而你真正需要的可能只是:

SQL
+
表结构
+
EXPLAIN

然后聊 5 分钟。

所以我现在越来越觉得:

AI Coding 真正需要学的,不是把所有东西都装上,而是知道什么时候根本不该用它。


我后来给自己定了一个特别简单的规则

碰到一个任务,我先不想:

用哪个 AI?

先想:

这个任务到底需要 AI 获得多大的能力?

我现在大概拆成四层:

第 1 层:Prompt
        ↓
告诉 AI“这一次怎么做”

第 2 层:Skill
        ↓
告诉 AI“这类事情以后都怎么做”

第 3 层:MCP / Tool
        ↓
给 AI“获取信息或执行动作的能力”

第 4 层:Agent
        ↓
让 AI 自己规划、多步执行、验证结果

这四层看起来很像。

但解决的问题完全不同。

搞混以后,最常见的结果就是:

本来一句 Prompt 能解决的问题
↓
硬是启动了 Agent
↓
Agent 又加载 Skill
↓
Skill 又要求调用 MCP
↓
最后为了改一行代码
跑了一大圈

第一层:Prompt 解决的是“这一次我要你怎么干”

比如我现在有一段代码:

async function getUser(id: string) {
  const response =
    await fetch(`/api/users/${id}`);

  const data = response.json();

  return data;
}

我只是想知道:

为什么这里返回的不是真正的用户对象?

这种事情完全不需要:

Skill
MCP
Agent

一个 Prompt 就够了。

甚至我会主动限制:

下面这段代码有 Bug。

不要重构。
不要修改无关代码。
不要引入新的库。

只回答:

1. 根因是什么
2. 最小修改是什么
3. 为什么
4. 怎么验证

代码:

[代码]

答案其实就是:

const data =
  await response.json();

这种任务的特点是:

输入已经在当前对话里
+
目标非常明确
+
不需要访问外部系统
+
不需要连续执行动作

那么:

别启动 Agent。

有时候 AI 工具最容易犯的一个错,就是:

因为我有锤子,所以什么都想当钉子。


第二层:Skill 解决的是“我不想每次重新教你”

假设刚才不是偶尔 Review 一次。

而是你们团队每次 Review 后端接口,都要求检查:

鉴权
参数验证
事务边界
幂等
日志
超时
重试
SQL
错误码
测试

如果每次都复制一大段 Prompt:

检查鉴权……
检查事务……
检查幂等……
检查……

就开始烦了。

这种东西才比较像 Skill。

OpenAI 现在对 Skill 的定位,本身就是把重复工作方式封装成可复用工作流,可以包含步骤、示例、代码和资源,而不是每次从头重新解释。(OpenAI Academy)

比如我可能写一个:

backend-api-review

里面表达的不是:

帮我 Review 代码

而是一套稳定流程:

触发条件:
用户要求 Review 后端接口

检查顺序:

1. 先确认接口职责
2. 检查鉴权
3. 检查参数边界
4. 检查事务范围
5. 检查幂等
6. 检查外部调用超时
7. 检查重试是否安全
8. 检查数据库操作
9. 构造失败路径
10. 给出验证方式

要求:

无法构造真实失败路径的问题,
不要标成高风险 Bug。

代码风格问题最后单独列。

这样下一次就不用重新写几十行。

所以我现在区分 Prompt 和 Skill,主要看一句话:

这套规则,下周还会不会再用?

只用一次:

Prompt

反复使用:

考虑 Skill

这比看到什么都做成 Skill 简单很多。


但 Skill 也不是越多越好

这个问题现在其实挺容易出现。

比如你装了 40 个 Skill:

React Review
TypeScript Review
API Review
SQL Review
Security Review
Testing
Refactor
Git
Documentation
Performance
……

每一个单独看都不错。

问题是模型开始面临另一个任务:

这次到底应该用哪几个?

如果 Skill 自己没有提供项目特有的信息、固定流程、脚本或者真正有价值的检查标准,只是在重复:

先理解需求
再修改代码
最后跑测试

那随着模型本身越来越强,这种 Skill 的收益可能并没有想象中大。

最近掘金上已经开始出现“很多基础 Skill 是否还值得保留”的讨论,本质上说的也是这件事:Skill 应该提供额外约束和工作流,而不是单纯把模型本来就会做的动作重新写一遍。(掘金)

所以我现在判断一个 Skill 要不要留,会问:

删掉它以后,
模型到底失去了什么?

如果答案是:

基本没失去什么

我可能直接删。


第三层:MCP / Tool 解决的是“AI 光靠嘴已经做不了了”

这个区别特别重要。

比如你问:

我们线上 orders 表现在有哪些索引?

模型不知道。

因为答案根本不在上下文里。

你可以手动复制给它:

SHOW INDEX FROM orders;

也可以给 AI 一个:

数据库查询工具

让它自己读取。

这才进入 Tool / MCP 这一层。

MCP 本身不是“更高级的 Prompt”。

官方协议里非常明确:MCP Server 可以暴露 prompts、resources 和 tools;其中 tool 是可以让模型执行动作或获取信息的能力。(Model Context Protocol)

说人话就是:

Prompt:
告诉 AI 怎么想

Skill:
告诉 AI 这类工作按什么流程想

Tool / MCP:
让 AI 有手和眼睛

比如:

读数据库 schema
查 issue
读取 Git 历史
调用内部 API
获取监控指标
创建文件
执行某个服务

这些不是再写 500 字 Prompt 可以解决的。

AI 根本需要:

真实世界的数据 / 能力

举个最典型的 SQL 例子

你给 AI:

SELECT *
FROM orders
WHERE user_id = 10086
  AND status = 'paid'
ORDER BY created_at DESC
LIMIT 20;

然后问:

怎么优化?

如果没有其他信息。

它很容易回答:

CREATE INDEX ...

问题是它根本不知道:

orders 有多少数据?

现在有哪些索引?

status 有几个值?

数据怎么分布?

EXPLAIN 是什么?

实际扫描了多少行?

这种时候真正需要的不是:

更强 Prompt

而是给它:

真实数据

例如一个数据库 Tool 可以让它读取:

SHOW CREATE TABLE
SHOW INDEX
EXPLAIN ANALYZE

这时候答案质量提升的原因,不一定是:

模型突然聪明了。

而是:

它终于看见现场了。


但我这里又会卡一道权限

能让 AI:

SELECT

不代表我要让它:

DROP TABLE

能让它:

读取生产日志

也不代表我要让它:

修改线上配置

所以 Tool / MCP 一旦进来,问题已经从:

模型聪不聪明

变成了:

权限到底给多少

这个变化特别大。

因为 Prompt 写错了,最多回答难看一点。

一个拥有写权限的工具调用错了:

可能真改东西。

所以我现在很反感这种思路:

为了让 Agent 更强
把能开的权限全部开了

我的习惯反而是:

默认只读

确实需要修改
↓
再给最小写权限

危险操作
↓
人工确认

第四层:什么时候才真的需要 Agent?

这是最容易过度使用的一层。

假设任务变成:

用户列表搜索偶发显示旧数据,帮我在这个项目里找到原因并修掉。

这时候就不再是一段代码了。

AI 可能需要:

找到页面入口
↓
找到搜索组件
↓
找到 Hook
↓
找到请求封装
↓
理解状态流
↓
复现 Bug
↓
修改代码
↓
跑测试
↓
发现测试失败
↓
再次修改
↓
验证

这时候 Agent 就有意义了。

因为任务已经不是:

回答一个问题

而是:

完成一串依赖前一步结果的动作

我现在判断要不要上 Agent,最简单的标准就是:

它需要“做事”,还是只需要“思考”?

如果只是:

解释代码
分析 Bug
写 SQL
讨论架构
Review 方案
检查正则
分析日志

我大概率先用普通对话。

如果是:

跨文件改代码
搜索整个仓库
实际执行命令
跑测试
根据测试继续修改
更新配置
真正完成一个需求

那才值得启动 Agent。


举一个更真实的例子:产品让我改用户搜索

需求:

用户列表增加搜索。

输入需要防抖。
服务端分页。
不能让旧请求覆盖新请求。

如果我还在方案阶段。

我可能只问普通模型:

先别写代码。

请帮我拆出这个需求里所有可能产生
请求竞态和状态不同步的地方。

尤其考虑:

1. 连续输入
2. 快速切页
3. 请求返回乱序
4. keyword 改变时 page 怎么处理
5. 组件卸载
6. 请求失败

这时候:

Prompt 就够了。

如果以后公司所有列表页面都要按这个规范检查。

那么:

做成 Skill。

如果 AI 还需要读取:

接口文档
项目规范
设计系统
测试环境 API

那开始需要:

Resources / Tools / MCP

如果最终目标变成:

把这个需求直接实现
并跑完测试

这才轮到:

Agent

所以同一个需求。

不是永远属于某一层。

它会随着你希望 AI 做到什么程度往上走。


我现在甚至会故意把“分析”和“执行”分开

这是最近用 AI Coding 以后,我自己比较明显的一个变化。

以前是:

发现 Bug
↓
直接开 Agent
↓
让它自己看
自己改
自己测

现在很多问题我会先停在:

普通对话层

先找两个模型讨论。

一个给方案。

另一个找漏洞。

确认方向以后,才把最终任务交给 Agent。

大概是:

模型 A
↓
分析

模型 B
↓
攻击 A 的方案

我
↓
确认方向

Agent
↓
真正修改项目

为什么要多一道?

因为我不太喜欢:

一个 Agent
既负责提出假设
又负责根据这个假设改代码
最后还负责证明自己改对了

很容易一路沿着第一个错误判断跑到底。

sru19ojb9esibFjhrYOCh6.png

我自己这种“先分析,再决定要不要执行”的阶段,平时就会在 chathao.com 里直接切模型。

对我真正有用的不是:

一个页面有多少模型

而是:

这个问题根本不用动仓库的时候
我就别启动 Agent

只想:

看 Bug
看 SQL
Review 方案
让第二个模型找第一份答案的漏洞

就在普通模型里解决。

等方向明确,确实需要:

读项目
改文件
跑测试
执行命令

再切执行型工具。

这套分层以后,我自己最大的感觉就是:

很多问题根本用不到最重的武器。


同样是 Claude,我也不会每次都拿同一种任务去问

比如有时候只是:

这段 TypeScript 的泛型为什么推断错了?

这种问题本身不需要整个项目上下文。

我甚至不想让 AI:

扫描仓库

单纯把最小代码贴出来,让模型分析就好了。

如果我对第一次答案没把握。

直接换模型复核。

gEzpnjyGvFBZz1IVPjYlsM.png

我现在特别喜欢一个 Prompt:

下面是另一个 AI 给出的技术分析。

不要默认它正确。

你的任务不是重新回答。

只做三件事:

1. 找出它依赖但没有证明的假设
2. 构造能让这个方案失败的场景
3. 告诉我哪些结论必须通过代码、
   日志或测试验证

如果第一份答案没有明显问题,
也直接告诉我。
不要为了反驳而反驳。

这个对:

Debug
SQL
并发
缓存
架构
线上排障

特别有用。

有时候第二个模型确实什么都补不出来。

那也没关系。

至少比让第一个模型:

自己检查自己

多一道独立视角。


我最后把这四层压成了一张判断表

现在碰到一个 AI Coding 任务,我脑子里基本这样判断:

问题 1:

信息是不是已经都在我手上?
        │
        ├─ 是
        │
        ↓
        │   问题 2:
        │   这是一次性要求,
        │   还是会反复出现?
        │
        │   一次性
        │     ↓
        │   Prompt
        │
        │   反复出现
        │     ↓
        │   Skill
        │
        └─ 否
            ↓
        AI 是否需要读取外部信息
        或执行一个动作?
            │
            ├─ 是
            │   ↓
            │ Tool / MCP
            │
            └─ 还需要连续规划、
               执行、验证、继续修改
                ↓
              Agent

当然真实系统不会永远这么干净。

很多 Agent 自己也会加载 Skills、调用 Tools/MCP。

它们不是互斥的。

真正重要的是:

别把四个东西当成四种“AI 更强的等级”。

它们解决的是四个不同问题。


一个我现在很不喜欢的架构

比如:

用户:
解释这个正则为什么会超时
↓
Agent 启动
↓
加载整个 repo
↓
加载 12 个 Skills
↓
连接 Git MCP
↓
读取项目历史
↓
运行搜索
↓
最后告诉你:

存在 catastrophic backtracking

问题不在于答案错。

而在于:

为了回答一个 30 秒的问题,启动了一支施工队。

真正合理的可能就是:

正则
+
测试字符串
+
一个普通模型

结束。


反过来也一样

还有另一种极端。

一个需求明明是:

找到整个项目里所有旧版 API
↓
分析调用关系
↓
升级
↓
修测试
↓
重新跑测试
↓
输出修改摘要

你还在普通聊天框里:

我复制第一个文件给你

然后:

再复制第二个

第三个。

第四个。

聊到后面上下文已经一锅粥。

这种任务继续坚持 Prompt,也不合理。

应该承认:

这已经是 Agent 任务了。

所以我现在真正关心的不是“哪个功能最强”

而是:

有没有用最小的能力解决问题。

能 Prompt 解决:

别开 Agent。

重复流程明显:

再做 Skill。

缺真实信息:

接 Tool / MCP。

确实需要操作整个项目:

再上 Agent。

这样还有一个额外好处:

权限特别容易管。

因为一个只负责:

分析 SQL

的模型。

压根没必要获得:

生产数据库写权限。

一个只负责:

Code Review

的模型。

可能根本不需要:

Shell 权限。

一个只负责:

解释错误日志

的模型。

更没必要:

修改仓库。

权限不给。

它自然也做不了那些离谱的事。


最后

以前看到 AI Coding 新功能,我第一反应经常是:

这个我得装。

现在反而变成:

这个东西到底解决了我哪一个原来解决不了的问题?

Skill 很好。

MCP 很好。

Agent 也很好。

但:

更多能力

从来不自动等于:

更好的工程结果

能力越往上走。

其实意味着 AI 可以接触的东西也越来越多:

更多上下文
更多文件
更多工具
更多权限
更多状态
更多失败路径

所以现在如果有人问我:

Prompt、Skill、MCP、Agent 应该怎么选?

我不会先解释四个名词。

我会先反问:

你到底只是想让 AI 想一下,还是准备真的让它动手?

这个问题回答完。

后面的选择其实已经解决一半了。