Prompt、Skill、MCP 到底该写什么?用一次订单退款任务讲清三层边界
Prompt、Skill、MCP 到底该写什么?用一次订单退款任务讲清三层边界
你明明把退款政策写进了 Prompt,又复制到技能文件里,还在 MCP 工具说明中强调了一遍。原以为这是“三重保险”,结果 Agent 换了一个用户,仍引用上笔订单;没有查询订单状态,就直接发起退款;工具明明返回失败,它却回复用户“退款已办理”。
更麻烦的是,运营刚修改一条退款规则,你发现三个地方都要改,而且内容已经悄悄变成了三个版本。
AI 配置不是写得越多越安全,重复指令往往是在制造三个互相打架的真相源。
问题不在模型“够不够聪明”,而在于我们没有分清三层职责:
- Prompt 管这一次要做什么
- 技能文件管这类任务通常怎么做
- MCP 工具说明管外部能力是什么、何时调用、参数怎么传
下面用一条完整的订单退款链路,把这件事讲透。
同一个退款任务,写在三个地方为什么会得到三种结果?
先看一个电商售后中的典型任务:
1. 获取用户订单号;
2. 查询订单状态;
3. 判断退款资格;
4. 满足条件时创建退款;
5. 不满足条件时解释原因或转人工;
6. 根据工具结果生成客服回复。
这是一个很适合观察分层问题的案例:订单号和用户诉求是动态信息,退款规则是稳定流程,查询与退款则依赖外部工具。
实践中最常见的翻车方式,是把整段任务同时塞进三个地方。
Prompt:
用户要退款。请查询订单,判断退款资格,符合条件就退款,
失败则转人工,回复要礼貌。退款政策如下……
Skill:
收到退款请求后查询订单,判断退款资格,符合条件就退款……
当前订单号为 A20250318,用户因为重复购买申请退款……
MCP description:
该工具用于退款。客服应先安抚用户,再查询订单,
按照退款政策判断,符合条件时创建退款,最后使用礼貌语气回复……
表面上,每一层都“写得很完整”,实际上出现了三类冲突:
- Prompt 每轮重复携带整套流程,浪费上下文;
- Skill 混入当前订单号,换用户后可能残留旧数据;
- MCP 描述被客服 SOP 淹没,模型反而看不清工具边界。
get_order,直接调用 create_refund;工具拒绝后,最终回复仍声称退款成功。
图中为流程示意,不代表真实平台评测结果。真正需要观察的不是最终回答,而是模型为什么调用、传了什么参数、工具返回了什么。
这种错误很反常识:规则写了三遍,系统却没有更稳定。原因是模型面对的不是“三重保险”,而是三份来源不同、寿命不同、可能互相冲突的指令。
三层各管什么:任务、方法与能力
最容易记住的分法,是把整个 Agent 看成一家餐厅:
- Prompt 像顾客这次点的菜;
- Skill 像后厨的标准菜谱;
- MCP 工具说明像设备操作手册;
- API 服务端则是燃气阀、门禁和食品安全制度。
你不会把顾客桌号写进永久菜谱,也不会把整套餐厅服务话术印在烤箱说明书上。
| 维度 | Prompt | 技能文件 | MCP 工具说明 | | 核心问题 | 这次做什么 | 这类任务怎么做 | 这个工具怎么用 | | 内容寿命 | 单次会话或短期 | 长期复用 | 随工具版本存在 | | 典型内容 | 用户诉求、临时上下文、输出格式 | SOP、规则、异常分支、示例 | 功能、参数、返回值、调用限制 | | 不该放什么 | 完整长期 SOP | 用户隐私与当次订单数据 | 整套业务流程、客服人设 | | 主要风险 | Token 浪费、指令冲突 | 规则污染、版本过期 | 误选工具、误传参数 |判断一段内容应该放在哪里,最实用的依据不是文件名,而是信息生命周期:
- 只对当前对话有效:放入 Prompt;
- 换一批用户仍然成立:放入技能文件;
- 必须绑定某个具体工具:写入 MCP 工具说明。
不同 Agent 产品对“技能文件”的命名和加载方式可能不同,有的叫 Skill,有的叫 Workflow、Playbook 或 Knowledge,但任务层、流程层、能力层的分工基本不变。
放错位置后,六类故障会一起出现
| 症状 | 可能原因 | 修复方向 | | 每轮都输入大段退款流程 | SOP 被塞进 Prompt | 迁移到技能文件 | | 换一个用户仍引用旧订单 | 动态数据写进技能文件 | 移回会话 Prompt | | 模型频繁选错相似工具 | 工具说明缺少调用边界 | 补充适用与禁止场景 | | 工具描述长达数千字 | 业务流程塞进 MCP 说明 | 将流程迁移到 Skill | | 模型声称退款成功,但工具失败 | 技能缺少结果校验规则 | 增加“以工具返回为准” | | 提示词禁止越权,接口却仍能执行 | 把安全控制寄托于自然语言 | 服务端强制鉴权与校验 |其中最隐蔽的问题是版本分叉。
假设退款政策发生变化。如果政策分别存在于 Prompt 模板、Skill 和 MCP 描述中,就需要修改三个位置。只要漏改一个,Agent 就可能在不同入口执行不同规则。
而正确分层后,政策通常只需要修改技能文件;除非接口参数或能力发生变化,否则 MCP 工具定义无需调整。
现场重构:把一坨客服指令拆回正确三层
Prompt:只保留本次任务
用户希望申请订单退款。
本次上下文:
- order_id: {{order_id}}
- 用户诉求: {{user_request}}
- 回复语言: 简体中文
- 回复风格: 简洁、礼貌,不承诺尚未确认的退款结果
请使用“订单退款处理”技能完成任务。
这里不再重复退款政策和完整操作步骤。Prompt 只回答四件事:谁、什么订单、要解决什么、如何输出。
技能文件:保存稳定 SOP
# 订单退款处理
适用场景
用户询问或申请订单退款。
执行流程
1. 确认订单号是否完整。
2. 查询订单状态。
3. 根据退款政策判断是否符合条件。
4. 符合条件时,征得必要确认后创建退款。
5. 不符合条件时,说明具体原因。
6. 遇到高风险订单、工具失败或政策冲突时转人工。
回复要求
- 不得在工具返回成功前声称退款已经完成。
- 不向用户展示内部风控字段。
Skill 负责的是“退款任务通常怎么处理”。即使查询订单的底层接口将来被替换,这套业务流程依然可能成立。
MCP 说明:只描述工具调用契约
查询工具:
{
"name": "get_order",
"description": "根据订单号查询订单当前状态、支付状态和可退款信息。仅用于已有明确订单号的场景;不得猜测订单号。",
"inputSchema": {
"type": "object",
"properties": {
"order_id": {
"type": "string",
"description": "用户提供或系统上下文中已确认的订单号"
}
},
"required": ["order_id"]
}
}
退款工具:
{
"name": "create_refund",
"description": "为符合退款条件的订单创建退款。调用前必须已查询订单,并确认订单当前允许退款。本工具只负责提交退款,不负责判断业务政策。",
"inputSchema": {
"type": "object",
"properties": {
"order_id": {
"type": "string"
},
"reason": {
"type": "string",
"description": "经过确认的退款原因"
}
},
"required": ["order_id", "reason"]
}
}
最后一句非常关键:
工具负责执行,不负责决定业务政策。
否则一旦退款政策变化,你就不得不修改接口描述,把业务版本和工具版本错误地绑在一起。
重构后,模型应该怎样执行?
正确的信息流应该是:
用户请求
↓
Prompt:读取本次订单号、诉求与输出要求
↓
技能文件:采用订单退款 SOP
↓
get_order:查询订单状态与退款资格
↓
技能规则:根据查询结果判断
↓
create_refund:满足条件时提交退款
↓
工具结果:确认成功、失败或待处理
↓
生成客服回复
图2:正确版执行过程——先采用退款技能,再调用 get_order;确认 refundable=true 后调用 create_refund,最终回复与工具返回保持一致。
注意,“调用成功”和“退款到账”也不是一回事。如果工具只返回 submitted,客服只能说“退款申请已提交”,不能擅自升级为“退款已经到账”。
完整架构中,还要再补一层真正的安全边界:
图3:订单退款 Agent 的三层信息流。用户请求
↓
Prompt:本次目标与上下文
↓
技能文件:选择并执行退款 SOP
↓
MCP 工具说明:发现工具、理解参数与边界
↓
真实 API:鉴权、校验、执行
↓
工具结果
↓
生成客服回复
MCP 说明不是安全边界。权限、退款金额、订单归属和订单状态,必须由 API 服务端强制校验。
自然语言可以告诉模型“不要越权”,却不能阻止攻击者绕过模型直接请求接口。
不要凭感觉:用同一批请求做小型对照测试
为了避免虚构胜率,可以准备一组 24 条客服请求,按六类场景各取四条:
- 正常可退款;
- 已退款或退款处理中;
- 缺少订单号;
- 不符合退款条件;
- 工具返回失败;
- 疑似越权或订单归属不一致。
建立三组配置:
- A:所有内容集中写在 Prompt;
- B:业务流程塞进 MCP 描述;
- C:按 Prompt、Skill、MCP 正确分层。
测试时固定模型版本、温度、工具集合与样本顺序,逐条记录:
| 指标 | 记录方法 | | 正确工具选择率 | 是否先选择了符合场景的工具 | | 参数一次填写正确率 | 首次调用是否包含全部必填参数 | | 条件不满足时误调用率 | 不可退款场景是否调用了退款工具 | | 回复与工具结果一致率 | 最终措辞是否忠于工具返回 | | 平均输入 Token | 由调用日志记录 | | 政策变更改动位置数 | 修改一次规则需要编辑几个文件 |本文不填入未经实际运行的“漂亮数字”。你可以将模型名称、版本、温度、24 条逐项结果和原始日志一起保存,避免把一次偶然成功包装成普遍结论。
想验证分层是否有效,最好的方法不是继续争论定义,而是让同一测试集在不同模型上跑一遍。你可以把文中的 Prompt、技能文件和 MCP 定义保存为固定配置,通过 api.884819.xyz 接入模型,记录工具选择、参数错误、Token 消耗和回复一致性。
平台使用用户名和密码即可注册,无需邮箱验证;内置 AI 对话,注册后可以直接使用。国产模型如 Deepseek、千问等完全免费,没有月租和订阅,其他模型按量付费。
新用户注册即送体验token。建议同时保存一份自己的“退款客服测试包”:
- Prompt 模板;
- 技能文件示例;
- 两个 MCP 工具定义;
- 24—30 条客服测试问题;
- 模型配置与评测记录表。
四问法:一段内容究竟应该放在哪?
以后遇到任何 Agent 配置,先问四个问题:
1. 换一个用户,这段内容还成立吗?
不成立,通常属于 Prompt。
2. 换一个工具,这段流程还成立吗?
成立,通常属于技能文件。
3. 不调用外部工具,这条规则还需要吗?
需要,通常是业务规则,而不是 MCP 描述。
4. 它描述的是目标、方法,还是接口能力?
目标进 Prompt,方法进 Skill,接口能力进 MCP。
最终可以压缩成一条迁移规则:
动态上下文进入 Prompt,稳定 SOP 进入技能文件,参数与能力边界进入 MCP;权限与最终业务校验留在服务端。
Prompt 工程的终点,从来不是写出一个包罗万象的“超级提示词”,而是为不同信息建立清晰的职责、版本和唯一真相源。
Prompt 负责下任务,Skill 负责教方法,MCP 负责报能力,API 负责守底线。
但位置分清后,还有一个更棘手的问题:如果退款政策已经更新,Skill 仍是旧版本,而工具返回又与 Prompt 预期冲突,模型究竟应该听谁的?
下一篇,我们将通过一次“新政策、旧 Skill、真实工具结果互相打架”的事故,拆解 Agent 的指令优先级、版本管理与冲突处理。
下一篇:《Prompt、Skill 和工具结果互相打架时,AI 应该听谁的?一文讲清 Agent 的指令优先级》 本文由8848AI原创,转载请注明出处。关注8848AI,带你从零开始学AI。#Prompt技巧 #MCP #AISkills #Agent开发 #AI客服 #人工智能 #8848AI