十年前我刚入行那会儿,公司里有个老大哥,特别爱写文档。那时候大家都觉得代码才是王道,文档那是给外人看的玩意儿,能省则省。有一次项目上线前,接口文档写得含糊不清,参数定义模棱两可,结果前端和后端扯皮了整整三天。那时候我就明白了一个道理,机器不懂人情世故,你给它的指令稍微有点歧义,它就能给你跑出个十万八千里。
现在做 AI Agent 开发,其实跟当年写接口文档是一个道理。很多人觉得调个大模型接口,传个 prompt 就算完事了。其实真正难的不是调用,而是给 AI 造技能。也就是所谓的 Skill 或者 Function Calling。你定义不好这个技能,模型就像那个当年看不懂文档的前端,明明手里有刀,却不知道怎么切菜。今天咱们不聊虚的,就聊聊怎么给 AI 造个趁手的技能。
你可能会问,不就是写个函数给 AI 调用吗,有什么难的。我当年也是这么想的,觉得把参数列清楚,返回个 JSON 不就完了。结果在实际项目里踩了大坑。模型要么不调用,要么调用错了参数,甚至有时候胡乱编造参数。后来我复盘了很久,才发现问题的根源不在代码逻辑,而在你对技能的理解上。这不仅仅是技术实现,更是一种思维模型的转换。
咱们得先搞清楚,AI Agent 里的 Skill 到底是什么。别被那些新名词吓唬住,它本质上就是以前我们说的 RPC 接口,只不过调用者从另一个程序变成了一个大语言模型。以前我们设计接口,是给人看的,开发者会读文档,会看示例。现在设计 Skill,是给模型看的,模型没有眼睛,它只看你的描述文本。所以,写的规范能不能让模型读懂,比你代码写得漂不漂亮更重要。
我记得历史上有个事儿,特别有意思。早年间的 SOAP 协议,规定得特别严格,xml 层层嵌套,看似规范,实则繁琐。后来 RESTful 火了,为什么,因为简单直观,符合人的直觉。现在的 AI Skill 设计也是这个趋势。你如果把技能定义写得像当年的 SOAP 一样复杂,模型大概率会晕。它需要的是清晰、直接、符合自然语言逻辑的描述,而不是冷冰冰的类型定义。
我去年做一个智能客服 Agent 的时候,一开始定义了一个查询订单的技能。我写了十几个参数,什么开始时间、结束时间、订单状态、用户等级,恨不得把数据库字段都搬上去。结果测试的时候,模型经常漏传参数,或者把状态字段传成字符串。后来我简化了,只保留了最核心的订单号和时间范围,其他的让模型通过多轮对话去确认。效果立马就好了很多。这说明什么,说明技能要原子化,不要贪大求全。
这里有个很关键的认知,你要明白模型的能力边界。它擅长理解意图,不擅长做复杂计算或者逻辑判断。所以你的 Skill 设计,应该是把模型不擅长的事情封装起来。比如查询数据库、调用外部 API、执行复杂计算,这些交给 Skill。而意图识别、参数补全、结果润色,这些留给模型本身。分工明确,才能各司其职。很多新手容易犯的错误,就是想让模型在一个技能里把所有事都干了。
再说个生产环境里的真实取舍。有时候为了稳定性,我们不得不牺牲一些灵活性。比如有的技能可能需要联网查询,但网络波动怎么办。我在设计的时候,会给每个技能加上超时处理和重试机制,并且在描述里告诉模型,如果这个技能失败了,可以尝试另一个备选方案。这就好比当年我们做系统架构时的熔断降级,只不过现在这个决策者变成了 AI。你得教它怎么面对失败,而不是假定一切顺利。
还有一个容易被忽略的点,就是技能的副作用。以前的函数式编程讲究无状态,现在的 AI Skill 最好也遵循这个原则。如果一个技能会修改数据库状态,一定要在描述里写清楚。比如“创建订单”和“查询订单”要分开定义。曾经有个项目,因为把修改操作和查询操作混在一个技能里,模型有时候只是想查个数据,结果误触发了修改逻辑,造成了线上事故。这种坑,踩一次就够了。
写到这里,你可能觉得有点繁琐。确实,给 AI 造技能比单纯调接口要累得多。但你想啊,十年前我们会写接口的人,和只会调包的人,现在的差距有多大。技术浪潮一波接一波,底层逻辑其实没变。谁能更好地理解机器与人协作的边界,谁能设计出更清晰规范的交互协议,谁就能在这一波 AI 红利里走得更远。这不是卷,这是基本功。
最后想跟你聊聊心态。别急着把所有功能都做成 Skill。先从一个小的痛点开始,比如帮用户查个天气,或者算个汇率。把这一个技能的描述打磨到极致,让模型调用得丝滑顺畅。这种成就感,比你堆砌一百个半成品的技能要有价值得多。编程是这样,做 AI 也是这样,慢就是快。希望今天的分享,能让你在下一次定义 Skill 的时候,多一分思考,少一分迷茫。
