今天想聊一个特别让人头疼的问题。你有没有遇到过这种情况——你在维护一个Agent系统,改了某个Skill的描述,结果另一个完全没碰过的Skill突然就不正常了?
太经典了,我觉得做过Agent开发的人多多少少都踩过这个坑。Perplexity专门给这种现象起了个名字,叫Action at a Distance,翻译过来就是「超距作用」。这其实是个物理学术语,最早是牛顿提出万有引力的时候引发的争论——两个天体之间没有任何可见的东西连接,引力怎么就能传过去呢?牛顿自己都觉得不安,爱因斯坦后来也用「鬼魅般的超距作用」来吐槽量子纠缠。
这个类比确实精准。但在Agent系统里,这不是什么鬼魅,其实是有明确原因的对吧?
对,一点都不玄学。核心原因是这样的:大模型在做路由决策的时候,它是把所有Skill的名称和描述拼在一起看的。所有Description共享同一个上下文窗口,模型的注意力机制会在这些描述之间建立关联权重。你新增一个Skill,或者改了某个旧Skill的一个关键词,本质上就是在重新分配大模型的全局注意力。原来井水不犯河水的业务边界,可能因为你加的一句话就乱套了。
嗯,这就解释了为什么传统软件工程里「模块独立性」的直觉在这里会失效。你以为两个Skill互不相关,但在模型的语义空间里它们可能是近邻。
没错,这是很多团队踩坑的根本原因。而且很多团队维护Skill的方式特别粗暴——失败了就改描述、改主体指令,下次又错了再改一次。短期好像修好了,长期来看就是在不断诱发超距作用,整个路由体系越改越乱。
那Perplexity的思路是什么?先诊断再下药?
对,他们的核心理念就是:不要凭感觉大刀阔斧地改。每一次失败先分类型,不同类型用不同修法。他们把失败分成了三大类。
我们一类一类来聊。第一类是什么?
第一类是路由问题。就是Skill不该加载的时候加载了,或者该加载的时候没加载。这个问题出在Description上,Description本质上就是路由触发器。你可以把大模型做路由理解成一个多分类任务——给定用户输入,从N个Skill里选最匹配的。它不是用if-else做硬匹配,而是通过语义相似度做软匹配。所以两个Skill的描述在语义空间里距离太近,模型就容易搞混。
那修的时候怎么办?
Perplexity的规则很明确:改Description必须配Eval。不该加载却加载了,你就收紧描述,同时立刻加负向评测,证明你没抢别人的流量。该加载却没加载,你就补关键词,同时加正向评测,证明它能被正确唤醒。改Description不配Eval,就是在埋雷。
好,第二类呢?
第二类是执行问题。路由对了,Skill正确加载了,但输出结果不对。这时候Perplexity提出了一个很克制的原则,叫Append Mostly——追加为主。不是去改主干指令,而是追加Gotcha。Gotcha就是真实失败留下来的坑点,那些看起来理所当然可以这么做、实际上不应该这么做的特例。
能举个例子吗?
比如说「当遇到X报错时,不要重试,立刻报警」。就这么一条极简的负面特例,追加到专门的附件里,不污染主干指令。这背后的洞察是:大模型对指令的敏感度是非线性的,主干指令的微小改动可能引发全局行为漂移,但在末尾追加具体的边界条件相对安全。这其实跟软件工程里的开放封闭原则很像——对扩展开放,对修改封闭。
所以这就是他们说的Gotcha飞轮机制?每次失败变成一条边界,Skill靠追加边界越用越稳。
对,从80%的成功率提升到99.9%,靠的不是把Instructions写得更厚,而是把失败边界收得更紧。这个思路转变其实挺重要的。
第三类呢?我猜这个最隐蔽。
你猜对了。第三类是全局Prompt变更。你的Skill一行没动,Description也没问题,路由也对,但系统Prompt——那个定义Agent底层行为逻辑的东西——被别的团队改了。比如你的Skill假设模型会先确认再执行,但新的系统Prompt要求默认执行事后报告。你的Skill没变,但脚底下的地基在动。
而且不同模型对System Prompt和Skill指令的优先级处理还不一样,这就更难预判了。
是的,有些模型严格遵循System Prompt,有些更容易被后出现的Skill指令覆盖。所以Perplexity的处理方法就是立刻排查,检查当前Skill是否跟新设定产生了逻辑冲突。虽然是被动防御,但必须做到位。
说完三类修法,接下来就是怎么验证修改没改坏别的地方了。Perplexity提了一个四层评测体系?
对。第一层是路由测试,该加载的加载了没有,不该加载的有没有误触发,这是基础。第二层是路径测试,Skill加载了不代表模型真的读了该读的内容,比如附件里的参考资料有没有被正确使用。第三层是端到端测试,跑完整流程,然后用LLM-as-Judge来打分。不过这里要注意,LLM做裁判也有偏差,比如倾向于给更长的回答打高分,所以评分标准要尽可能具体可量化。
第四层呢?
第四层是跨模型测试,这是很多人忽略的。GPT和Claude在处理同一个Prompt时行为差异很大。有些模型对上下文靠前的内容更敏感,有些对靠后的更敏感,这直接影响你追加的Gotcha在不同位置的生效概率。所以跨模型测试不是锦上添花,是生产环境的刚需。
最后Perplexity还给了三条忠告,我觉得都挺实在的。
嗯,第一条是用Skill自动化你自己的日常工作,见得越多用得越多,才知道边界在哪。第二条是评估前置,写Skill之前先写Eval,尤其是针对相邻Skill的负面测试,这跟TDD的思路一脉相承。第三条是少即是多,Skill一开始就应该是一张薄薄的纸,别预想模型会怎么犯错,让它在真实环境里跑,失败了再通过Gotcha飞轮自然生长出厚度。
总结一下,修Skill不是写作文,是做手术——每一刀要精准,每一刀都要有检查。一个好的Agent Skill不是一气呵成写出来的,而是在评测体系的保护下,在真实失败里一点点追加出来的。这个思路其实适用于所有做Agent开发的团队。
对,核心就一句话:把每一次失败压缩成一个精准的Gotcha,在评测套件的保护下谨慎迭代。Skill才能从一堆指令真正变成稳定可靠的系统资产。