ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

MCP、Skill、Agent、Prompt:AI应用开发四大概念解析与协同实践

MCP、Skill、Agent、Prompt:AI应用开发四大概念解析与协同实践

1. 从一堆混乱概念说起:为什么这四个词总被混着用

刚接触AI应用开发那会儿,我最怕别人问我"你那个Agent和Prompt到底啥区别"。不是答不上来,是每次答完对方眼神里都写着"你确定?"。后来我发现,问题不在我,在于这四个词——MCP、Skill、Agent、Prompt——它们压根不在一个层面上,却被无数文章塞进同一句话里讲,越讲越糊。

举个我常打的比方。把AI应用想象成一家餐厅:Prompt是你写给厨师的点菜单,写清楚要什么菜、什么口味、忌口什么;Skill是厨师练过的专项手艺,比如颠勺、刀工、调酱汁,是能被反复调用的能力单元;Agent是那个能自己看单、决定先炒哪个菜、发现食材不够主动去冰箱翻的服务员兼调度;MCP则是厨房和外部供应商之间的标准接口协议,让厨师能按统一格式向菜市场下单,而不用为每个供应商单独学一套黑话。

这四个东西解决的是完全不同的问题:Prompt解决"怎么把话说清楚",Skill解决"能力怎么复用",Agent解决"任务怎么自主推进",MCP解决"工具怎么标准化接入"。混着讲,就像把"菜谱""厨艺""服务员""采购协议"揉成一团,谁也说不清。

这篇内容我打算按我实际踩坑的顺序来拆:先讲Prompt为什么不是"随便写写",再讲Skill怎么把重复劳动变成资产,然后讲Agent的自主性到底自主在哪,最后讲MCP为什么是让前三者真正跑起来的那根管子。全程用我做过的一个数据分析场景串起来——让AI自动完成"读取销售数据、清洗、算同比环比、生成结论"这条链路。这个场景足够典型,四个概念都能落地。

适合谁看?如果你已经用过ChatGPT或类似工具,但一到"搭个能自己干活的系统"就卡壳,这篇就是写给你的。不需要你懂底层模型训练,但需要你愿意动手试。

2. Prompt:不是"会说话"就行,而是结构化表达工程

2.1 为什么"你是个数据分析专家"这种开场几乎没用

我早期写Prompt,最爱开头来一句"你是一位资深数据分析专家"。写了几十次之后发现,这句话对输出质量的提升微乎其微。原因很简单:模型不知道"资深"具体指什么行为。它不会因为你夸它"资深"就突然学会用同比环比而不是只算个平均值。

真正起作用的是约束和示例。我后来把数据分析的Prompt改成三段式:角色只占一句,重点放在"输出必须包含哪些字段""遇到缺失值怎么处理""结论必须引用具体数字"。改完之后,同一个模型输出的稳定性肉眼可见地提升。

这里有个反直觉的点:Prompt的长度和效果不是正相关。我试过把Prompt写到两千字,结果模型开始"抓不住重点",把次要约束当主要约束执行。后来我固定在一个原则——核心约束不超过7条,超过就拆成多轮。

2.2 一个能跑的数据分析Prompt长什么样

下面是我实际在用的一个Prompt骨架,用于让模型对一份销售明细做分析。注意它不是"求你了帮我分析",而是像给一个初级分析师下brief:

任务:对输入的销售明细表做月度分析。 输入格式:CSV,字段为 date, region, product, sales_amount, quantity。 必须输出: 1. 按月汇总的销售额与销量 2. 环比增长率(本月 vs 上月),保留两位小数 3. 销售额Top3的地区及其占比 4. 一段不超过150字的结论,结论中必须引用至少3个具体数字 约束: - 缺失的 sales_amount 按0处理,并在结论中说明缺失条数 - 不要输出任何图表代码,只输出文字和表格 - 如果某月数据少于5条,标注"样本不足"并跳过环比计算 输出格式:先给汇总表格,再给结论段落。

这个Prompt里,"必须输出"是硬约束,"约束"是边界条件,"输出格式"是结构约定。三者缺一不可。我踩过的坑是只写"必须输出"不写"约束",结果模型遇到缺失值直接编了个数填进去,分析结论全错。

2.3 Prompt的复用与版本管理:别把好Prompt弄丢了

我吃过最大的亏,是某次调出一个效果特别好的Prompt,随手改了几笔想"再优化一下",结果效果崩了,想回退却发现没存。从那以后我养成了一个习惯:每个正式使用的Prompt都存成独立文件,带版本号和一句话说明。

prompts/ sales_analysis_v1.txt # 基础版,仅汇总 sales_analysis_v2.txt # 加入环比与Top3 sales_analysis_v3.txt # 加入缺失值处理与样本不足判断

版本管理的好处不只是回退。当你后面要接Agent时,Agent需要调用不同的Prompt,有版本号才能精确指定"这一步用v3,那一步用v1"。没有版本管理,Agent的调试会变成一场灾难。

提示:Prompt里的示例(few-shot)比形容词有用十倍。与其写"要专业",不如给一个专业输出的样例。

3. Skill:把"每次都要重写"变成"一次封装反复调用"

3.1 Skill的本质是能力单元,不是更长的Prompt

很多人第一次听到Skill,以为是"高级Prompt"。不准确。Prompt是一次性的指令,Skill是可被反复调用的能力封装。区别在于:Prompt用完就散了,Skill有名字、有输入输出约定、能被别的流程引用。

还是用数据分析场景。我最初每次分析都要在Prompt里重新描述"怎么算环比"。后来我把"算环比"抽成一个Skill:输入是两列数字,输出是增长率,内部固定了"除数为0时返回空值"这类边界处理。之后任何分析流程要算环比,直接调这个Skill,不用再重复描述。

这就是Skill的核心价值:把领域知识固化下来,让调用方不需要懂细节。调用方只需要知道"这个Skill叫calc_mom_growth,给它两列数,它给我增长率",至于它内部怎么处理除零、怎么保留小数,调用方不用管。

3.2 一个Skill的完整定义包含哪些部分

我总结下来,一个能用的Skill至少要有五部分:名称、用途描述、输入约定、输出约定、边界处理。缺任何一部分,调用时都会出问题。下面是我给"数据清洗"写的一个Skill定义:

部分内容
名称clean_sales_data
用途对原始销售明细做标准化清洗
输入原始CSV文本
输出清洗后的结构化数据 + 清洗日志
边界处理金额为负视为退货单独标记;日期格式不统一时尝试三种常见格式;无法解析的行记入日志不丢弃

注意"边界处理"这一栏。这是Skill和普通Prompt最大的分水岭。普通Prompt遇到脏数据可能直接崩或者瞎编,Skill因为提前定义了边界,行为是可预期的。我在实际项目里,80%的调试时间都花在补边界处理上,而不是写主逻辑。

3.3 Skill的粒度怎么定:太粗和太细都是坑

我一开始把"整个数据分析"做成一个Skill,结果发现它太粗,任何一个小环节要调整都得动整个Skill,牵一发动全身。后来我又走向另一个极端,把"读一行""判断是否为空"都做成Skill,结果调用链长得像面条,维护成本爆炸。

摸索下来,我的经验是:一个Skill对应一个"人能一句话说清职责"的单元。"清洗销售数据"是一句话,"计算环比增长率"是一句话,"生成分析结论"是一句话。而"读取CSV第三行第二列"不是一句话,它是实现细节,不该独立成Skill。

按这个粒度,我的数据分析链路拆成了四个Skill:清洗、汇总、算增长、写结论。每个都能单独测试,单独替换。比如后来我想把"写结论"从模板式换成模型生成,只改那一个Skill,其他三个纹丝不动。

注意:Skill的输入输出约定要写死。我见过有人把输入写成"一段数据",结果调用方传了JSON、传了CSV、传了纯文本,Skill内部要写一堆判断。约定越具体,调用越省心。

4. Agent:自主性的边界在哪里,别把它当万能

4.1 Agent和"带Skill的Prompt链"差在哪

如果只是把Skill按顺序串起来跑,那叫工作流,不叫Agent。工作流是我提前定好"先清洗、再汇总、再算增长、最后写结论",一步接一步。Agent的区别在于:它自己决定下一步做什么。

举个具体差异。工作流遇到"数据里没有region字段"会直接报错停下。Agent遇到同样情况,可能自己判断"那我先看看有哪些字段,也许地区信息藏在别的列名里",然后调整策略继续。这个"自己判断"就是自主性。

但我要泼盆冷水:自主性不是越多越好。我做过一个Agent,让它自由决定分析步骤,结果它有时候跳过清洗直接汇总,得出错误结论还振振有词。后来我给它加了硬约束——"清洗步骤不可跳过",它才稳定下来。所以Agent的自主性应该限定在你允许它自由的那部分,而不是全放开。

4.2 Agent的决策循环:观察、思考、行动、再观察

一个Agent跑起来,本质是个循环。我用数据分析Agent举例:

  1. 观察:拿到任务"分析这份销售数据",先看数据长什么样
  2. 思考:判断需要哪些Skill,顺序是什么
  3. 行动:调用清洗Skill
  4. 再观察:看清洗日志,有没有异常
  5. 思考:异常是否影响后续,要不要补处理
  6. 行动:继续调用汇总Skill……

这个循环里,"再观察"是最容易被忽略但最关键的一步。很多Agent失败不是因为不会行动,而是行动完不看结果,闷头往下走。我在实现时强制要求:每个Skill调用后必须读取其输出或日志,再决定下一步。这一条加上之后,Agent的出错率降了一大截。

4.3 给Agent设"护栏":哪些事它绝对不能做

Agent越自主,越需要护栏。我在数据分析Agent里设了三类护栏:

  • 数据护栏:不允许修改原始数据文件,只能读和生成新文件
  • 步骤护栏:清洗和校验步骤不可跳过,即使Agent认为"数据很干净"
  • 输出护栏:结论中出现的每个数字必须能追溯到某个Skill的输出,不允许"估算"

第三类护栏特别重要。模型有编造数字的倾向,如果不强制追溯,它会写出"销售额约为120万"这种没有依据的话。我的做法是要求结论里的数字必须带来源标记,比如"环比增长8.3%(来源:calc_mom_growth)"。

护栏类型具体规则违反时的处理
数据护栏只读原始数据拒绝执行并记录
步骤护栏清洗不可跳过强制插入清洗步骤
输出护栏数字可追溯剔除无来源数字并告警

这三类护栏不是限制Agent的能力,而是让它的行为可预期、可审计。没有护栏的Agent,跑十次给你十个不同结果,你根本不敢用。

5. MCP:让Skill和Agent不再"各接各的线"

5.1 没有MCP时,工具接入有多痛

在MCP出现之前,我每接一个外部工具都要写一套适配代码。读数据库写一套,调文件系统写一套,连个天气接口又写一套。每套的调用方式、错误处理、参数格式都不一样。Agent要调用它们,就得记住每个工具的"脾气"。

这就像家里每个电器插头形状都不同,你得备一堆转换头。MCP要做的,就是统一插头标准。它定义了一套通用的工具描述和调用协议,任何工具只要按这个协议暴露自己,Agent就能用统一方式调用,不用为每个工具单独写适配。

5.2 MCP的三方角色:宿主、客户端、服务端

MCP的架构里有两个关键角色。服务端是提供能力的一方,比如一个封装了数据库查询的服务,它按MCP协议声明"我能做query,输入是SQL,输出是结果集"。客户端是调用方,通常是Agent所在的运行环境,它按协议去发现服务端有哪些能力,然后调用。

我实际用下来,最大的好处是工具发现自动化。以前我要手动告诉Agent"有个工具叫X,参数是Y",现在Agent可以自己去问服务端"你有哪些能力",然后自动适配。这在工具多的时候省事太多。

5.3 把数据分析链路用MCP串起来

回到我的数据分析场景。我把"读数据"做成一个MCP服务端,暴露一个read_data能力;把"写报告"做成另一个服务端,暴露write_report能力。Agent作为客户端,启动时先发现这两个服务,然后按需调用。

这样做的直接收益是:换数据源不用改Agent。原来数据从本地文件读,后来要改成从某个数据接口读,我只改read_data服务端的实现,Agent那边完全不动。因为Agent只认MCP协议,不认具体实现。

环节传统做法MCP做法
接入新工具写专属适配代码服务端按协议暴露即可
工具发现手动配置自动发现
替换实现改调用方只改服务端
错误处理每个工具各写一套协议层统一

提示:MCP的价值在工具多、变化快的时候才明显。如果整个项目就一两个固定工具,硬上MCP反而增加复杂度。别为了用而用。

6. 四者协同:一条完整的数据分析链路是怎么跑通的

6.1 从任务下达到报告产出,每一步谁在干活

把四个概念放进同一条链路,职责就清楚了。用户下达任务"分析本月销售数据",这是Prompt层面的输入,定义了目标和约束。Agent接收任务,规划步骤。它调用Skill完成清洗、汇总、算增长。这些Skill要读写数据,通过MCP接入的数据服务完成。最后Agent调用写结论的Skill,产出报告。

我实际跑这条链路时,会在每个环节打日志。日志格式统一为"时间 | 环节 | 动作 | 结果"。这样出问题时能快速定位是Prompt没写清、Skill有bug、Agent决策错、还是MCP连接断。没有日志,调试就是盲人摸象。

6.2 一次真实排错:结论数字对不上

有次跑完,报告说"环比增长15%",但我手算明明是8%。排查过程是这样的:

先看Agent日志,发现它调用了calc_mom_growth两次,一次用清洗前数据,一次用清洗后数据,结论里引用的是清洗前那次。问题出在Agent的决策——它没意识到清洗会改变数据,应该只用清洗后的结果。

修复方案不是改Skill,而是给Agent加一条规则:涉及计算的Skill,必须使用最近一次清洗后的数据。这条规则写进Agent的约束里,问题解决。

这个案例说明:四个概念里任何一个出问题,表现都可能是"结果不对",但根因位置完全不同。会看日志、会分层排查,比会写代码更重要。

6.3 什么场景该用全套,什么场景杀鸡不用牛刀

不是所有任务都值得上全套。我的判断标准很简单:

  • 任务一次性、数据干净、结论要求不高:一个Prompt搞定,别折腾
  • 任务会重复、步骤固定:Prompt + Skill,把重复部分封装
  • 任务步骤不固定、需要根据中间结果调整:加Agent
  • 工具多、变化频繁、需要跨系统:加MCP

我见过有人做个简单的文本分类也上Agent加MCP,结果调试成本远超收益。复杂度要匹配问题复杂度,这是我在这个领域踩得最深的坑。

7. 我踩过的几个典型坑,以及后来怎么绕开

7.1 Prompt写太满,模型反而"看不见"重点

前面提过,但值得展开。我曾经写过一个Prompt,把十几条约束全塞进去,结果模型只执行了前三条,后面的当没看见。后来我改成分层:核心约束放最前,次要约束放后面,并且用空行隔开。模型对位置的敏感度比我想的高,重要的往前放,这条经验屡试不爽。

7.2 Skill边界没定义,脏数据直接让流程崩

有次数据里混进一行日期是"2024年13月",清洗Skill没处理,直接抛异常,整个Agent停摆。后来我在所有Skill里强制加一条:遇到无法解析的输入,不抛异常,记日志并跳过。流程的健壮性比"严格报错"更重要,因为Agent场景下没人盯着,崩了就是崩了。

7.3 Agent自主性给太多,它开始"自作主张"

我一度让Agent自由决定用哪些Skill,结果它为了"省事"跳过了校验步骤。后来我把关键步骤设为不可跳过,Agent只能在非关键环节自主。自主性要像放风筝,线得攥在手里。

7.4 MCP服务端版本不一致,调用报错查半天

MCP服务端升级了能力描述,但Agent那边的客户端缓存还是旧的,导致调用参数对不上。后来我规定:服务端任何变更都要带版本号,客户端启动时校验版本。版本不一致直接拒绝启动,比跑到一半报错好排查得多。

8. 给想上手的人几条实在建议

如果你现在想把这套东西用起来,我的建议是别一上来就四个一起上。先用Prompt把单个任务跑通,确认输出稳定;再把重复的部分抽成Skill,感受复用的好处;然后试着让Agent串两个Skill,体会自主决策的边界;最后在工具确实多起来的时候,再引入MCP。

这个顺序不是教条,是我自己走弯路走出来的。跳过前面直接上Agent和MCP,大概率会在调试里迷失,因为出问题时你分不清是哪一层的问题。

另外,日志和版本管理从第一天就要做。我早期嫌麻烦不写日志,后来每次排错都像考古。现在我的每个项目都有统一的日志格式和Prompt/Skill版本目录,看起来是额外工作,实际省下的时间远超投入。

最后说个心态上的事。这四个概念本身不难,难的是它们组合起来后的不确定性。模型有随机性,Agent有决策自由,工具接入有环境差异,三者叠加,同一个输入两次跑出不同结果是常态。接受这个常态,把精力放在"让结果可追溯、可复现"上,比追求"每次都完美"实际得多。我到现在也不敢说自己的Agent百分百稳定,但我能做到出问题时十分钟内定位到是哪一层,这就够用了。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进