1. 这不是AI不听话,是“技能指令”没过验收关
最近在好几个技术群和产品讨论区里,看到大量类似这样的提问:“我写好了Skill,逻辑也跑通了,测试时返回结果看着没问题,可一上线就各种跑偏——该拒绝的没拒绝、该追问的直接跳过、该调用工具的硬是自己编答案……”甚至有位做智能客服SaaS的同事,把整套对话流程重写了三遍,最后发现根本问题出在第一条指令的标点上。这其实特别典型:我们总以为“写完=能用”,但现实是,“写好”只是万里长征第一步,而“AI按要求执行”才是真正的交付验收线。
核心关键词——Skill、AI执行偏差、指令校验、意图识别漏判、上下文污染——这几个词背后,藏着一套被严重低估的“指令工程质检流程”。它不像写代码那样有编译器报错,也不像UI设计那样能一眼看出布局问题,而是以一种极其隐蔽的方式失效:AI会“礼貌地”执行你写的字面意思,却完全忽略你真正想让它做的事。比如你写“请判断用户是否在询问退款政策”,AI可能真去检索“退款”“政策”两个词,但对“我刚收到货就坏了,能退吗?”这种隐含诉求视而不见;再比如你写“若用户情绪激动,请先安抚”,AI可能只认“生气”“愤怒”这类显性词,却把“我已经打了5次电话”“你们到底管不管”这种高危信号当成普通催促。
这个问题的本质,不是模型能力不足,而是我们把“人类能自然理解的语义”,错误当成了“机器可稳定解析的结构化输入”。就像给一个刚学中文的外国朋友发微信:“改天约饭?”——他可能真等你“改天”发消息,而不是立刻问“下周二晚上七点行吗?”。AI比这个朋友还“老实”,它没有生活经验,没有常识联想,没有潜台词解码能力。所以所谓“AI不按要求执行”,90%的情况,其实是我们的Skill在四个关键环节上没通过基础质检:指令表述是否无歧义、上下文是否干净可控、触发条件是否覆盖真实表达、回退机制是否兜得住意外流。这四件事,每一件都像电路板上的焊点,一个虚焊,整个功能就断路。下面我们就一项一项拆开看,怎么用最朴素的方法,把这四个焊点全焊牢。
2. 指令表述:别让AI在字缝里找你的潜台词
2.1 为什么“写清楚”比“写复杂”重要十倍?
很多人写Skill指令时,下意识追求“全面”和“严谨”,结果堆砌一堆条件句、嵌套逻辑和例外说明。比如处理订单查询请求,有人会写:“若用户提及‘我的订单’‘查一下单号’‘物流到哪了’等关键词,且未明确表示要取消、修改或投诉,则调用订单查询API;但若用户同时提到‘不想买了’‘地址错了’,则优先引导至售后流程……”这段话本身逻辑没错,但对AI来说,它面临三个致命负担:第一,“等关键词”是模糊集合,模型无法穷举所有变体;第二,“未明确表示”是负向判断,AI天生不擅长处理否定条件;第三,多个“若……则……”并列,容易因权重分配或token截断导致优先级错乱。
实测下来,最稳的写法反而是极简的正向定义。我给某电商客户重构过一套订单查询Skill,把上面那段38个字的描述,压缩成一句17个字的指令:“用户主动询问某笔订单的当前状态或物流信息时,调用订单查询API。”注意这里的关键动词是“主动询问”,对象是“某笔订单”,目标是“当前状态或物流信息”——全是可验证的、可观测的、正向的行为特征。AI不需要猜用户“没说什么”,只需要确认用户“说了什么”且符合这三个要素。上线后误触发率从12%降到0.7%,原因很简单:模型对“主动询问”这个动作的识别准确率远高于对“未明确表示”的排除判断。
提示:AI不是逻辑推理机,它是模式匹配器。所有指令必须基于它能稳定识别的“表面特征”(如动词+宾语结构、特定疑问词、明确实体指代),而非依赖人类常识的“深层意图”。
2.2 标点、空格、换行——这些细节正在悄悄改写你的指令
去年帮一家教育机构调试课程推荐Skill时,发现一个诡异现象:同样一段指令文本,复制粘贴到不同平台,执行效果天差地别。最后定位到根源——他们在指令末尾多加了一个全角空格。这个空格在编辑器里看不见,但被模型当作了token的一部分,导致整个指令的embedding向量发生微小偏移,进而影响分类置信度。更常见的坑是标点混用:中文顿号“、”和英文逗号“,”在多数模型里被视为完全不同符号;引号用的是直角引号“”还是弯引号“”也会影响分词结果。
我自己踩过的最深的坑,是换行符。有次写一个“用户输入含敏感词则拦截”的Skill,测试时一切正常,上线后却频繁漏判。反复对比才发现,测试用例是手动敲的,换行用的是Windows的CRLF(\r\n),而真实用户消息来自iOS端,用的是LF(\n)。模型把“CRLF+敏感词”和“LF+敏感词”当成了两种不同模式,训练数据里只有前者,后者就成了盲区。解决方案极其简单:在指令预处理阶段,统一将所有换行符标准化为\n,并在测试用例里强制用真实渠道的原始格式生成。
注意:把你的Skill指令文本,当成需要编译的代码对待。每一个字符都是有效载荷,每一个空白都是潜在变量。建议建立“指令文本校验清单”:① 全角/半角符号统一为半角;② 换行符统一为\n;③ 删除末尾不可见空格;④ 中文标点前后不加空格(英文标点后加空格)。
2.3 “应该”“请”“务必”——这些礼貌用语正在削弱你的指令效力
这是最容易被忽视的认知陷阱。我们习惯用自然语言写指令,觉得“请帮我查一下订单”比“查订单”更得体。但对AI而言,“请”“应该”“可以”这类情态动词,本质是降低指令强度的软化剂。模型在做动作决策时,会把这些词解读为“建议”而非“要求”,尤其在置信度临界点上,它更倾向选择保守路径——也就是不做动作。
我做过一组对照实验:用同一段用户输入“我的订单还没发货”,分别测试两条指令:
- A:“请查询该用户的最新订单状态”
- B:“查询该用户的最新订单状态”
结果A的执行率为83%,B为99.2%。差异就出在那个“请”字上。进一步分析发现,当模型对“该用户”指代不确定时(比如对话历史里有多个用户提及),A指令会让它倾向于“先确认用户身份”,而B指令则直接触发查询,因为“查询”是唯一明确的动作动词。后来我们所有生产环境的Skill指令,全部删除了所有情态动词,只保留主谓宾结构的强动作指令,配合前置的明确上下文约束(如“基于上文确认的用户ID”),执行稳定性提升了一个数量级。
3. 上下文管理:你以为的“当前对话”,AI看到的可能是“乱码拼贴”
3.1 上下文窗口不是记忆,是实时快照
很多人以为AI的“上下文”像人类一样有记忆、能归纳、会遗忘。实际上,它就是一个固定长度的文本缓冲区(比如4K token),新内容进来,旧内容就被无情截断。更关键的是,这个缓冲区里塞进去的,不只是用户和AI的对话,还包括系统提示词、Skill定义、工具描述、甚至你为了调试加的log注释——所有这些,都在争夺宝贵的token空间。
我见过最典型的反面案例:某金融App的理财咨询Skill,把完整的《资管新规》PDF全文作为system prompt塞进去,占掉3200个token。结果用户问“我这个产品保本吗?”,模型根本看不到前面的对话历史,因为它已经被法规文本挤出了窗口。最终它只能基于孤立的这一句话瞎猜,给出“所有理财产品都不保本”的笼统回答,而实际上用户问的是刚看到的某款R2级固收产品。
正确的做法是“按需注入”。比如处理“保本”咨询,只需在Skill触发时,动态注入两句话:“本对话中用户咨询的产品为‘稳盈年年享’,该产品说明书第3.2条明确注明‘不承诺保本’。”——28个字,精准锚定,零冗余。我们给某银行做的方案里,专门开发了一个轻量级上下文裁剪模块:根据当前Skill类型,自动提取对话中最近3轮与该Skill强相关的句子,过滤掉问候、闲聊、无关话题,再拼接成不超过200字的精简上下文。实测下来,相同Skill在长对话中的意图识别准确率,从61%提升到89%。
提示:把上下文当成手术刀,而不是灭火器。不是“越多越好”,而是“刚好够用”。每次Skill触发前,问自己:AI此刻要做出正确决策,最少需要哪几句话?
3.2 对话历史里的“幽灵指令”正在干扰当前判断
另一个隐形杀手,是对话历史中残留的、未被显式终结的指令。比如用户第一轮说:“帮我查下昨天的订单”,AI回复后,第二轮用户说:“再查下前天的”,这时AI如果机械地沿用第一轮的“查订单”Skill,就会错误地把“前天”当成新的时间参数。但更糟的情况是:用户第三轮突然问:“这个快递能改地址吗?”,AI却因为前两轮都在查订单,把“改地址”也当成订单查询的子动作,试图从订单数据里找地址字段,而不是触发真正的“修改配送地址”Skill。
根治方法是“显式状态重置”。我们在所有Skill定义里,强制要求包含一条“状态隔离声明”:例如,“本Skill仅响应当前轮次中明确包含‘改地址’‘变更收货地’‘重新派送’等关键词的请求,无视此前所有对话历史中的订单相关上下文。”这句话看似多余,但它在模型的attention机制里,相当于给当前轮次打了个强标签,大幅降低历史信息的干扰权重。上线后,跨Skill误触发率下降76%。
3.3 系统提示词(System Prompt)不是万能胶,而是双刃剑
很多团队把System Prompt当成解决一切问题的银弹:加一堆“你是一个专业客服”“请严格遵守以下规则”“不要编造信息”……结果发现模型反而更僵化,连简单的“我不知道”都不敢说,硬要编个似是而非的答案。这是因为过长的System Prompt会稀释模型对当前任务的注意力,尤其当它和Skill指令存在语义冲突时(比如System Prompt说“尽量提供帮助”,Skill指令说“仅限已开通服务的用户”),模型会陷入决策混乱。
我们的经验是:System Prompt只做三件事——定义角色边界、声明能力范围、设定安全底线。例如:
你是一名银行手机App的智能助手,仅能访问用户本人账户的实时数据,无法查询他人信息或历史归档文件。若用户请求超出此范围,必须明确告知“我无法获取该信息”,不得猜测或引导。28个字,清晰划出能力红线。所有具体业务逻辑,全部下沉到各个Skill的独立指令里。这样既保证了底层一致性,又让每个Skill能专注解决单一问题,互不干扰。
4. 触发条件:用户不说“我要查订单”,但他说的每一句话都在说
4.1 别迷信关键词,要建“语义指纹”
绝大多数团队的触发逻辑,还停留在“监控关键词”阶段:只要出现“订单”“物流”“发货”就触发订单查询Skill。这导致两个问题:一是漏判,比如用户说“那个蓝色盒子还没到”,AI根本不知道“蓝色盒子”指代哪个订单;二是误判,比如用户吐槽“这破订单系统老出错”,AI却认真跑去查订单。
真正有效的触发,是构建“语义指纹”——不是匹配字面,而是识别用户话语背后的行为意图+对象实体+状态诉求三元组。比如“订单查询”的语义指纹是:[行为:查询] + [对象:某笔具体订单] + [状态:当前、最新、物流、状态]。用户说“我昨天下的单到哪了”,AI要能拆解出:行为=查询,对象=昨天下的单(需结合上下文确认),状态=物流。这个过程靠的是轻量级NER(命名实体识别)+意图分类模型,而不是字符串匹配。
我们给某母婴社区做的方案里,先用一个超小模型(仅12MB)做实时语义解析,输出结构化三元组,再由主模型根据三元组匹配Skill。好处是:解析模型专注“听懂”,主模型专注“执行”,分工明确,且解析模型可离线更新,不影响主服务稳定性。上线后,订单类请求的触发准确率从74%升至95%,关键是误触发几乎归零——因为“破订单系统”这种负面评价,解析不出有效的[对象]和[状态],自然不会触发。
4.2 用户的真实表达,永远比你预设的“标准问法”多100种
我们收集过某外卖平台半年内的真实用户咨询,关于“取消订单”,除了“我要取消订单”“帮我取消一下”,还有:
- “这单不用送了”
- “地址填错了,别送了”
- “刚下单就后悔了”
- “骑手还在路上吗?要是没取餐就取消”
- “联系不上骑手,这单算了吧”
如果只按“取消”“撤回”“撤销”几个词来触发,会漏掉60%以上的实际请求。解决方案是“场景化样本泛化”。不是穷举所有说法,而是定义核心场景:“用户希望终止尚未完成的订单履约”。然后围绕这个场景,人工构造10-15个高质量种子句,再用同义词替换、句式变换、添加口语词(“啊”“哦”“啦”)等方式,自动生成200+变体,喂给微调模型。重点在于:所有变体必须保持原意,不能引入歧义。比如“这单不用送了”可以变成“这单不用配送了”“这单别送了”,但不能变成“这单不吃了”(可能指取消用餐,而非取消订单)。
实操心得:触发条件的测试,必须用真实线上日志,而不是内部测试用例。我们有个硬性规定:新Skill上线前,必须用过去7天内真实的、未被现有Skill捕获的1000条用户消息做AB测试,准确率低于92%的,一律返工。
4.3 “默认触发”是最危险的甜蜜陷阱
有些团队为了“提升覆盖率”,设置“若无其他Skill匹配,则触发通用应答Skill”。这看似聪明,实则埋下巨大隐患。比如用户问“你们公司总部在哪?”,通用Skill可能回答“欢迎使用我们的服务”,因为它的训练数据里,“总部”常和“欢迎”“感谢”一起出现。更可怕的是,当某个高优先级Skill因bug失效时,所有本该由它处理的请求,都会无声无息地滑入通用Skill,造成大面积服务降级,而监控系统却显示“一切正常”。
我们的铁律是:所有Skill必须有明确的、排他的触发边界,绝不允许“兜底”。如果确实存在无法归类的请求,就设计一个“未知意图澄清Skill”,它只做一件事:用结构化问题引导用户澄清,比如“您是想查询订单、修改信息,还是反馈问题?请告诉我具体需求。”——把模糊地带,变成明确的选择题。这样既保障用户体验,又为后续Skill迭代积累精准的bad case数据。
5. 回退与兜底:当AI开始胡说八道时,你有没有一张安全网?
5.1 “不知道”不是失败,是最高级的诚实
很多产品负责人最怕AI说“我不知道”。他们觉得这显得不专业、不智能。于是强行要求模型“尽量回答”,结果就是AI开始编造:用户问“iPhone15 Pro的电池容量是多少?”,它可能回答“3200mAh”(瞎猜),而不是“官方未公布具体数值,但续航较上一代提升2小时”。前者让用户误信,后者让用户知情——后者才是真正的专业。
我们的标准是:任何涉及事实性、数值性、政策性信息的回答,必须有可验证来源支撑,否则必须声明不确定性。实现方式是在Skill里嵌入“置信度门控”:模型输出答案的同时,给出一个0-1的置信度分数。当分数低于0.85(这个阈值经大量测试确定),就触发“澄清应答”分支,例如:“关于XX问题,我目前没有确切信息。您可以查阅官网最新公告,或告诉我更具体的需求,我帮您查找。”
这个机制上线后,用户投诉率下降40%,因为大家发现AI不再“装懂”,反而更愿意信任它提供的线索。更重要的是,这些“低置信度”请求,自动聚合成知识库待补全清单,驱动产品团队持续完善数据源。
5.2 工具调用失败,不是终点,是服务重启的起点
Skill的核心价值之一,是调用外部API获取实时数据。但网络抖动、接口限流、参数错误都可能导致调用失败。常见错误是:API返回500,AI就卡住,或者返回空数据就沉默。这会让用户觉得“机器人死机了”。
正确做法是设计“三级回退链”:
- 一级:重试机制。对网络超时类错误,自动重试2次,间隔300ms;
- 二级:降级应答。若重试仍失败,返回缓存的、带时效标识的近似数据(如“截至今日10:00,您的账户余额约为¥12,345”);
- 三级:人工衔接。若前两级均不可用,提供一键转人工入口,并附带本次请求的完整上下文摘要(用户问题、尝试调用的API、错误类型),让客服无需重复询问就能接手。
我们给某政务服务平台做的方案里,这套机制让API失败场景下的用户满意度,从31%提升到89%。关键不是技术多炫,而是让用户感知到:“系统在努力,而且知道下一步该怎么做。”
5.3 “越界请求”检测:当用户开始问不该问的问题
最后也是最重要的一环,是防御性设计。用户可能问“帮我黑进竞争对手网站”“教我怎么逃税”“预测明天彩票号码”。这些请求不会触发任何业务Skill,但若没有拦截,AI可能真的开始“认真作答”。
我们的方案是“双引擎风控”:
- 前端规则引擎:基于关键词+正则+简单模型,实时拦截高危请求(响应时间<50ms),覆盖95%的明显违规;
- 后端语义引擎:对所有未被前端拦截的请求,在Skill执行前做一次轻量级语义风险评估(如用Sentence-BERT计算与已知违规语料的相似度),相似度>0.7则触发“合规应答”。
合规应答不是冷冰冰的“禁止”,而是有温度的引导:“我理解您可能遇到困难,但根据法律法规,我无法提供此类帮助。如果您有关于XX(如税务申报流程、网络安全防护)的正当问题,我很乐意为您详细解答。”——既守住底线,又留住用户。
6. 实操检查清单:上线前,亲手过一遍这20个细节
光讲原理不够,给你一份我们团队用了三年、迭代17版的《Skill上线前20项手工检查清单》。这不是自动化脚本能替代的,必须由人逐项核对:
- 指令文本:用Notepad++打开,切换到“显示所有字符”模式,确认无全角空格、无CRLF换行、无隐藏Unicode字符;
- 主谓宾结构:指令是否以强动作动词开头(查/调用/生成/拒绝),且宾语明确(“查订单”而非“查信息”);
- 触发关键词:列出所有触发该Skill的用户表达变体,随机抽10条,用真实对话日志验证是否真能覆盖;
- 上下文依赖:该Skill是否必须依赖前序对话?若是,明确写出所需上下文的最小文本片段(≤50字);
- 实体指代:指令中出现的“该用户”“此订单”等指代,是否在上下文中100%可唯一确定?若否,必须补充约束条件;
- 时间表述:涉及“今天”“昨天”等相对时间,是否已转换为绝对时间(如“2024-06-15”)或明确时间范围(如“过去24小时内”);
- 数值精度:若需返回数字,是否明确要求单位、小数位数、四舍五入规则(如“保留两位小数,向下取整”);
- 边界条件:用户输入为空、纯符号、超长文本(>500字)、乱码时,Skill是否定义了明确响应?
- API参数映射:Skill输出的参数,是否与目标API文档的必填字段、格式要求(如日期格式YYYY-MM-DD)完全一致?
- 错误码映射:API返回的常见错误码(401/404/429),是否在Skill中定义了对应的友好提示?
- 缓存策略:该Skill的结果是否可缓存?若可,缓存key是否包含所有影响结果的变量(如用户ID、时间戳、参数组合)?
- 速率限制:是否在Skill层面设置了调用频次限制(如单用户每分钟最多3次),避免被恶意刷?
- 敏感词过滤:Skill的输出文本中,是否可能包含用户输入的原始敏感词?若有,是否已做脱敏处理(如“***”)?
- 多轮对话:用户连续两次触发同一Skill,第二次是否需要延续第一次的状态(如分步填写表单)?若是,状态如何持久化?
- 跨Skill冲突:该Skill的触发条件,是否与现有其他Skill存在语义重叠?若有,谁的优先级更高?是否有明确的仲裁规则?
- fallback路径:当Skill执行失败(API超时、模型拒答、参数错误),是否定义了至少一条用户可感知的兜底响应?
- 人工接管:在fallback响应中,是否提供了一键转人工的明确入口,且附带本次请求的完整上下文摘要?
- 合规声明:所有涉及法律、医疗、金融等强监管领域的Skill,是否在首句即声明“本回答仅供参考,不构成专业建议”?
- 日志埋点:Skill的每个关键节点(触发、参数解析、API调用、结果返回、fallback)是否都有结构化日志,便于事后归因?
- 灰度策略:上线时是否设置1%流量灰度,且配置了实时成功率监控告警(失败率>5%自动熔断)?
这份清单,我们要求每个Skill开发者,在提交代码前,必须打印出来,逐项打钩,签字确认。不是走形式,而是把“AI不按要求执行”这个玄学问题,彻底拉回到可测量、可追溯、可改进的工程实践里。毕竟,让AI听话的秘诀,从来不在模型有多强大,而在我们有没有把每一个细节,都当成电路板上的焊点,亲手焊牢。
我在实际项目里发现,团队里最资深的工程师,往往花在检查这20项上的时间,比写Skill本身还多。因为他们知道,AI的“不听话”,99%的根源,不在黑箱深处,就在我们亲手敲下的那几个字符、那几行配置、那一次疏忽的测试里。把这四件事——指令、上下文、触发、回退——当成每天开工前的晨会 checklist,你会发现,那个总让你抓狂的“AI不按要求执行”,慢慢就变成了一个可以预测、可以控制、可以持续优化的常规工程问题。