🐦 第3章 扣子插件和卡片
📄 一句话概括

插件有两种接法:挂给智能体,让模型自己决定调不调;插进工作流,让图纸决定。 两种的差别不在先进与否,在「用户说要一步还是两步」这件事由谁来理解。 这一节用同一个需求跑两遍,再用一句含糊的话看它们怎么分道扬镳。

📝 本章和前面几章的关系

上一节讲插件是什么,这一节讲怎么用。 这一节的结论会一直用到第 16 章:步骤固定的插工作流,步骤看情况的挂智能体。 如果你只记一句话:有副作用的动作,一律插工作流并且加一道确认。

一、两种接法,一句话区别

挂给智能体:把插件挂到智能体的工具表里,用户说一句话,模型自己判断要不要调、调哪个。 插进工作流:在工作流里放一个插件节点,把参数接好。链走到那儿就一定调,不看模型心情。 前者灵活:用户只要其中一步,它就只走一步。后者死板:用户没要的那步也照走。

但死板有死板的好处:该走的一步都不会漏。 有副作用的动作尤其需要这个。

二、同一句需求跑两遍

需求是:「帮我看看美元汇率,再算一下 500 美元合多少人民币。」 这句话里有两个动作,用户说得很清楚。两种接法都调了两次,结果一样。 所以需求清楚的时候,两种接法没有差别。 差别出现在需求不清楚的时候。

这不是巧合:接法的选择,本质上是在赌「用户会不会把话说全」。

三、含糊的需求:两种都出问题

换成「美元现在什么情况」。 挂给智能体的:一次都没调——请求里没有「汇率」「换算」这些词,它判断不出该干什么,就凭记忆答了一句。 它没有做错,它只是不知道要做什么,又不肯问。 插进工作流的:照样查、照样算,给了一个用户没要的答案。数字是真的,但答非所问。

两种都不是「错」,是两种取舍:一个灵活但可能一步都不走,一个死板但一定走完。 第三种做法这里没演示,但实际最好用: 先追问一句「你是想查汇率,还是想换算金额」。追问属于对话流的能力,第 13 章会讲。

四、什么该挂、什么该插

步骤固定、每次都要走 → 插工作流。少一步就是漏功能。 用户可能只要其中一步 → 挂智能体。硬走完反而烦人。 有副作用的动作 → 插工作流,并且加一道「先给人看一眼」。不能让模型自己决定发不发消息。

要试很多次才知道用哪个 → 挂智能体。工作流写不出这种分支。 四条里第三条最硬。前三条是效率问题,第三条是责任问题。

五、调不通的时候查四步

第一步查地址。 直接把 URL 贴到浏览器里,看返回什么。 404 是地址错,401 是鉴权错,500 是对面挂了。 第二步查鉴权。 平台的插件配置里要填 Key 或 Token。 过期、额度用完、环境填错(测试 Key 打到生产地址)都在这步暴露。 第三步查参数。 必填的漏了、类型不对、格式不对(日期写成「明天」)。 这一步的报错通常很明确,照着改就行。

第四步查返回。 前三步都通,但下游拿不到值——那是字段名对不上。 这一步最隐蔽,因为链是通的、日志是绿的。 四步里最容易跳过的是第一步,最容易卡住的是第四步。

六、动手 Demo:同一句需求,两种接法

需求里有两个动作:查汇率、做换算。先用一句说清楚的话跑两遍,再换一句含糊的。

PLUG = {'汇率': lambda: 7.12, '换算': lambda v: v * 7.12}

def way_a(q):                      # 挂给智能体:模型看着办
    calls, out = [], None
    if '汇率' in q:                 # 这里是关键词替身
        out = PLUG['汇率'](); calls.append('汇率')
    if '算' in q and out is not None:
        out = PLUG['换算'](500); calls.append('换算')
    return calls, out

def way_b(q):                      # 插进工作流:图纸写死
    PLUG['汇率']()
    return ['汇率', '换算'], PLUG['换算'](500)

实跑输出:

--------------------------------------------------------------------
两种接法:挂给智能体,还是插进工作流
--------------------------------------------------------------------


  ① 同一个需求,两种接法
  --------------------------------------------------------------------
  需求里有两个动作:查汇率、做换算。差别在「谁决定调哪个」。

| 接法 | 调用 | 调了哪几个 | 结果 |
|---|---:|---|---|
| 挂给智能体 | 2 次 | 汇率、换算 | 3560.00 |
| 插进工作流 | 2 次 | 汇率、换算 | 3560.00 |

  这次两种接法结果一样,因为需求说得很清楚。换成含糊的问法,差别就出来了。

  ② 换一句含糊的需求
  --------------------------------------------------------------------

| 接法 | 调用 | 调了哪几个 | 结果 |
|---|---:|---|---|
| 挂给智能体 | 0 次 | 没调 | (没调工具,凭记忆答) |
| 插进工作流 | 2 次 | 汇率、换算 | 3560.00 |

  挂给智能体:一次都没调——请求里没有「汇率」「换算」这些词,它判断不出该干什么,就凭记忆答。
  插进工作流:照样查、照样算,给了一个用户没要的答案,但至少数字是真的。
  ! 两种都不是「错」,是两种取舍:一个灵活但可能一步都不走,一个死板但一定走完。

  ③ 什么该挂、什么该插
  --------------------------------------------------------------------

| 情形 | 接法 | 为什么 |
|---|---|---|
| 步骤固定、每次都要走 | 插进工作流 | 少一步就是漏功能 |
| 用户可能只要其中一步 | 挂给智能体 | 硬走完反而烦人 |
| 有副作用(发消息、下单) | 插进工作流 + 加确认 | 不能让模型自己决定发不发 |
| 要试很多次才知道用哪个 | 挂给智能体 | 工作流写不出这种分支 |

①说清楚的那句,两种接法都调了两次,结果一样。所以别以为插工作流一定更差——需求明确时它们等价。 ②含糊那句才是分水岭。挂给智能体的零次调用:它没找到「汇率」「换算」这两个词,判断不出该干什么。 ③插进工作流的还是两步,给出了三千五百六十。数字是真的,只是用户没问这个。 ④「它没有做错,它只是不知道要做什么,又不肯问」——这句话值得抄下来。这是所有智能体产品的通病。 ⑤第三张表四条判据里,第三条最硬:有副作用的动作必须插工作流加确认。前三条是效率,第三条是责任。

30 秒实验

  1. 给你的智能体数一下挂了几个插件。有三个以上的,想想你有没有在工作流里也插一遍。
  2. 找一句用户真会说的含糊话,问一句,看它是乱调还是承认不知道。
  3. 把一个有副作用的插件(发消息、写表)改成工作流加确认,再跑一次。

常见误区

  1. 「挂给智能体更聪明。」挂给智能体是把判断权交给模型,请求含糊时它会一步都不走。
  2. 「插进工作流最稳,都用它。」用户只要一半的时候,硬走完反而烦人,还多花钱。
  3. 「调通了就没问题。」链通、日志绿、答案缺个角,这是插件最常见的故障形态。第四步查返回,别跳。
自测三问(点开对答案) 1. 两种接法的本质差别是什么? —— 谁来理解「用户要几步」。挂给智能体是模型理解,插进工作流是设计者提前定死。 2. 有副作用的插件该怎么接? —— 插进工作流,并且加一道「先给人看一眼」。不能让模型自己决定发不发。 3. 调不通按什么顺序查? —— 地址、鉴权、参数、返回。第一步最容易跳过,第四步最容易卡住。

会用了,下一个问题是:平台没有的能力怎么办。 下一节从零做一个自定义插件——查股票价格,从接口到调用到解析,走一遍,也看它怎么坏。

相关笔记