本文最后更新于 2026-05-10,文章内容可能已经过时。

调用API是在用工具,搭建Skills是在设计意图——Perplexity这份手册,把开发者的升级路径写明白了

Perplexity的Agent Skills开发手册里有这么一句话:

"Skills需要新的开发者思维(Skills require a new developer mindset)。"

大多数开发者扫一眼就跳过了。毕竟,这种话听起来像是产品文案里的套话——哪家公司不说自己"需要新思维"?

但我把这份手册反复读了几遍之后,发现这句话背后藏着三个真实的设计陷阱。不是理论上的,是那种你照着老习惯写完代码、部署上线、然后发现Skill从来不被触发、或者模型开始自己编答案的那种陷阱。

这篇文章就是把这三个陷阱拆开来给你看。

---

第一个陷阱:你以为你在写触发条件,其实你在写一段自我介绍

传统API的世界是确定性的

在普通的API调用逻辑里,触发入口是开发者定义的。逻辑大概长这样:

# 传统API调用方式

def handle_user_input(user_input):

if "天气" in user_input:

return call_weather_api(parse_city(user_input))

elif "翻译" in user_input:

return call_translation_api(user_input)

else:

return default_response()

规则是你写的,条件是你定的,什么情况下调哪个API,完全在你的掌控之内。这套逻辑是闭合的、可预测的,出了问题你能顺着代码一行一行找。

Skills的世界是意图驱动的

但在Perplexity的Skills体系里,触发逻辑不是你写的——是模型读懂的。

Agent在决定"要不要调用这个Skill"的时候,它看的不是你的if-else,而是你在description字段里写的那段话。模型会把用户的自然语言意图,和你写的description做语义匹配,然后自己决定"这个Skill该不该上"。

# Skills的注册方式(伪代码)

skill = {

"name": "weather_query",

"description": "当用户询问某个城市或地点的天气情况时使用此技能,

包括当前天气、未来几天预报、温度、降雨概率等。",

"parameters": {

"city": {"type": "string", "description": "城市名称"}

}

}

你的代码入口,从main()变成了一段自然语言。

这意味着什么?

意味着description写烂了,Skill永远不会被调用——而且这个Bug比代码Bug更难debug。

举个真实场景:假设你写了一个查询股票价格的Skill,description是这样的:

"查询金融数据。"

用户问:"帮我看看今天苹果股价怎么样?"

模型很可能不会触发这个Skill。因为"金融数据"这个描述太模糊,模型无法确信这个Skill能回答"股价"这类问题。它可能直接用自己的知识库给你一个过时的答案,甚至编一个。

正确的写法应该是:

"当用户询问股票价格、涨跌幅、市值或某只股票的实时行情时,使用此技能。支持A股、港股、美股的股票代码或公司名称查询。"
核心转变:你不再写触发条件,你要写Skill的自我描述,让模型读懂"我能干什么、什么时候该叫我"。

---

第二个陷阱:你的错误信息现在有两个读者——用户和AI

传统的错误处理链路

在传统开发里,错误处理是这样的:API调用失败→抛出异常→开发者捕获→返回错误码→前端展示友好提示。链路清晰,责任分明。

# 传统错误处理

try:

result = call_external_api(params)

return {"status": "success", "data": result}

except APIException as e:

return {"status": "error", "code": e.code, "message": "服务暂时不可用"}

这里的message是写给用户看的,目标是"让用户理解出了什么问题"。

Skills失败后,模型会自己做决定

但在Skills体系里,失败之后发生的事情超出了你的控制范围。

模型在拿到你的错误返回之后,会自行决定下一步:它可能重试、可能切换到另一个Skill、也可能——这是最危险的情况——直接用自己的知识库编一个答案

Perplexity手册里对这一点有明确要求:你必须在返回结构里定义fallback语义,告诉模型"失败时你应该怎么理解这个结果"。

这意味着你的error_message字段,不再只是给用户看的提示,而是给模型读的提示词

# Skills的错误返回(伪代码)

def handle_skill_error(error_type):

if error_type == "city_not_found":

return {

"status": "error",

# 给用户看的

"user_message": "未找到该城市的天气数据",

# 给模型读的——告诉它下一步该怎么办

"model_instruction": "城市名称可能有误,请向用户确认具体城市名称,

不要自行猜测或使用历史数据作为当前天气。"

}

你需要同时写两个版本的错误信息:一个让用户明白发生了什么,一个让模型知道它下一步应该怎么行动。

为什么这很重要?

因为如果你不告诉模型失败时该怎么做,模型会自己找出路。而模型找出路的方式,有时候是"幻觉"——它会用一种自信的语气告诉用户一个完全错误的答案,用户还以为是你的Skill返回的结果。

你的错误处理逻辑,现在是AI行为的一部分。

---

第三个陷阱:你设计的不是函数,是在对话流里漂流的能力单元

传统API是无状态的

传统API调用是无状态的。每次请求都是独立的,上下文管理是开发者自己的事。你要传什么参数,就在请求里显式地带上什么参数,API不会"记得"你上次说了什么。

Skills活在对话的上下文里

但Skills的每次调用,都处于一段对话的"中间"。模型会把前文的信息带进来,自动填充Skill的输入参数。

来看一个具体的场景:

用户:上海今天天气怎么样?

>

Agent:上海今天晴,气温28℃……

>

用户:那明天呢?

第二句话里,用户根本没提"上海"。但模型会从上下文里理解,city参数应该是"上海",然后用这个值去调用你的天气Skill。

听起来很智能,对吧?但问题来了:

用户:帮我查一下刚才那个城市的天气。

你的Skill的city参数,该从哪里来?

如果你在设计Skill的时候没有考虑这种情况——没有在description里说明"city参数可以从上下文中获取"——模型可能会:

1. 直接报错说"缺少城市参数"

2. 随便猜一个城市

3. 向用户重新确认(这是最好的情况,但体验很差)

Perplexity手册里有一个隐含要求:Skill的参数设计必须考虑"模型可能用上下文自动填充哪些字段",并在description里明确说明哪些参数可以从对话历史推断,哪些必须用户显式提供。

这是一个思维方式的根本转变:你不是在设计一个函数签名,你是在设计一个能在对话流里自主定位自己输入的能力单元。

---

综合对比:三个维度,一张表看清楚

| 维度 | 传统API调用 | Perplexity Skills | | 触发逻辑 | 开发者用代码定义(if-else、路由规则) | 模型根据用户意图 + Skill描述动态匹配 | | 错误处理 | 抛异常→捕获→返回错误码,读者是用户 | 返回fallback语义,同时服务用户和模型 | | 状态管理 | 无状态,每次调用独立,参数显式传入 | 有隐式状态,模型从对话上下文自动填充参数 |

三个维度,每一个都要求你把"开发者视角"切换成"模型协作者视角"。

---

实战建议:写完一个Skill,用这3个问题自查

✅ Skills开发者思维检查清单

问题一:如果模型只读了我的description,它能准确判断"什么时候该调我"吗?

检查方法:把description单独拿出来,给一个没看过你代码的同事读,让他判断"这个Skill适合回答哪类用户问题"。如果他说不清楚,模型也说不清楚。

问题二:我的错误返回,有没有告诉模型"失败后该怎么做"?

检查方法:想象模型拿到你的error response之后,它的下一步行动是什么。如果答案是"不知道",你需要补一个model_instruction字段。

问题三:我的参数里,哪些可能由模型从上下文推断,哪些必须用户显式提供?

检查方法:设计一个多轮对话场景,在第三轮或第四轮调用你的Skill,看看参数还能不能正确填充。

---

横向视角:这不只是Perplexity的问题

这套思维不是Perplexity独有的。

如果你用过Claude的Function Calling,你会发现function description字段的设计哲学完全一致——写得好不好,直接决定模型会不会调用这个函数。GPT的Tool Calling同理。MCP(Model Context Protocol)在工具定义规范里,也在走同一条路:把工具的"自我描述"作为一等公民来设计。

这是Agent时代的一个底层共识:当AI成为调用方,开发者的工作重心从"写调用逻辑"转移到"写能力说明书"。

你写的不再是代码逻辑,而是AI能力的使用说明书。

---

如果你想直接上手测试这套设计逻辑,或者对比GPT / Claude的Function Calling在这三个维度上的实际表现——

👉 [api.884819.xyz](https://api.884819.xyz) 聚合了主流模型的API接入,可以用同一套代码框架横向对比不同Agent能力的设计逻辑。新用户注册即送体验token,国产模型(Deepseek / 千问等)完全免费,没有月租,按量付费,省去多平台注册的麻烦。

---

这篇我们拆的是Perplexity Skills的设计哲学——触发逻辑、错误处理、状态管理,三个维度各有一个认知陷阱。

但有一个问题我一直没回答:如果同样的"新开发者思维",放到Anthropic的MCP协议里,设计逻辑会不会完全不同?

下一篇,我们把MCP的工具定义规范拿来和Perplexity Skills并排放——看看两家对"AI调用能力"这件事,到底在哪里达成了共识,又在哪里产生了根本分歧。MCP有一个设计决策,我第一次看到的时候觉得"这不对吧",但越想越觉得它比Skills更彻底。

敬请期待。

---

本文由8848AI原创,转载请注明出处。关注8848AI,带你从零开始学AI。

#AI开发 #Perplexity #AgentSkills #FunctionCalling #MCP #大模型应用 #8848AI #AI工程师