PM Vibe

工具调用与 MCP

1. 运单助手改错了 40 单,卡在哪一环

一家物流企业的客服中心,一天接三千多通电话。客服高频处理两件事:查运单现在到哪了、客户要求改派送时间。企业给客服接了一个运单助手,接了两条接口,一条查运单,一条改派送。

上线第一周就出了问题。

改错单。助手判断客户的要求已经说清楚了,直接调改派送接口把时间改了,没有让客服点确认。有些客户在电话里说的「明天」其实指的是「明天同一时间」,客服本来会再确认一句。一周下来改错了 40 单。

填错参数。改派送接口要两个值:期望派送日期和期望时间段。客户说「明天上午」,助手把「明天上午」整个填进了日期字段,接口返回格式错误。助手把报错原文丢给客服看,客服也不知道该填成什么样。

超时没人管。运单查询接口在高峰时段会超时。助手回一句「系统繁忙,请稍后再试」,客服只能自己打开另一个系统再查一遍。这一步没省下时间,反倒多了一个说不清的环节。

三个毛病各在一处:一个动作该不该让它自己动手,每个参数要交代到什么程度,动作做不成的时候谁来收拾。

2. 工具调用让模型自己挑动作

2.1 模型不执行,它只发出一个调用请求

工具调用(Tool Call)指模型在回答过程中,判断需要动一下外面的系统,就输出一段结构化的调用请求,写明要调哪个工具、参数是什么;平台拿到这段请求去真正执行,把结果塞回窗口,模型接着往下写。

模型自己不碰系统。它生成的是文本,执行的是平台。这一点对产品经理有两个直接后果。

一是模型可以写出一个参数填错的调用请求,平台照样会去执行。参数的含义、格式、取值范围,得在工具的定义里写清楚,指望模型猜是不行的。

二是凡是执行动作,都要经过平台这一层,所以权限、确认、日志都有地方可加。加在哪、加到什么程度,是这一集后面几节要讲的事。

模型发出的那段调用请求,平台拿它做了什么

客服问一句

  • 客服在助手里输入帮我看看运单 SF7781234567 到哪了
  • 窗口里此刻装着系统提示词、这张工单的字段、这一句提问
  • 模型手上的东西几个工具的名字和说明,运单系统的连接不在它这一层

这时候模型只知道自己有哪些工具,碰不到运单系统。

模型写出调用请求

  • 工具名query_waybill
  • 入参{ "waybill_no": "SF7781234567", "with_route": true }
  • 模型这一轮输出只有这一段结构化请求,没有多余的解释

模型生成的是文本,它自己一个动作也没执行。

平台核完再执行,把结果塞回窗口

  • 平台这一层校验工具名存在、waybill_no 符合运单号格式、这位客服有运单查询权限
  • 工具返回{ "status": "运输中", "current": "杭州转运中心", "eta": "明天上午" }
  • 窗口里新增这一段工具返回(Tool Result)

执行发生在平台这一层,权限和日志都挂在这里。

模型接着把答复写出来

  • 客服看到这单目前在杭州转运中心,预计明天上午派送
  • 后台记下调用时间、调用人、工具名、入参、返回结果

参数写错平台也会照发,取值范围得在工具定义里写死。

模型只发请求,动手的是平台。

这一块要看懂什么:模型手上没有系统权限,它只产出一段写清工具名和参数的请求;真正碰系统的是平台,参数填错平台也会照发。
工具定义里写清每个参数的含义、格式和取值范围,执行和权限判断放在平台那一层,每一次调用都记下调用人、入参和返回结果。

2.2 一次叫一个,还是一起叫

模型可以一次只发一个工具请求,也可以在同一轮里发好几个。判断标准是这些动作之间有没有依赖。

没有依赖的可以一起发。客户问「这单现在在哪,什么时候能到,能不能改成明天下午」,查运单、查预计到达时间、查可改的时间段这三件事互不依赖,同时发出去,返回再汇总,比一件一件排队快。

有依赖的必须串着来。改派送这个动作的前提是先知道这单现在是什么状态:已经在派送途中的单子不能改,已签收的更不能改。这类动作要等前一个工具返回结果,再决定下一步发什么。

产品经理在设计需求时要把这个依赖关系写出来。写出来了,研发才好决定哪些能并行、哪些必须等;写不出来,模型自己判断,多半会把不该同时发的动作一起发出去。

2.3 同一套接口可以包成不同粒度的工具

运单系统里其实只有两条接口:一条按单号查,一条按单号改。到了智能体这边,可以包成两种工具。

包得细,就是「查运单」「查预计到达时间」「查可改时间段」「改派送时间」四个工具,每个工具只干一件事,参数少、说明短,模型不容易用错,代价是调用次数多。

包得粗,就是一个「处理运单事项」的工具,参数里带上动作类型。调用一次就能办一串事,但它对模型的要求高,参数填错的机会也大。

常见做法是两头都要一点:高频、简单的动作包细一点,跑得稳;低频、需要连着办几件事的,允许包粗一些。具体怎么切,第 5 节展开。

3. 每个工具都要交代清楚三件事

3.1 参数的三个信息写全

一个参数要写清三样:它是什么含义、必填还是选填、格式和取值范围。少写一样,模型就开始猜。

拿改派送这个工具说事。它有两个参数。

参数 含义 必填 格式与取值
expect_date 期望派送日期 必填 格式 YYYY-MM-DD,必须是今天之后的日期,最多 7 天后
time_slot 期望时间段 选填 只能填 上午 9:00-12:00、下午 13:00-18:00、晚间 18:00-21:00 三个值之一

客服中心那个「明天上午填进日期字段」的错,就出在这张表没写。写全之后有个额外好处:模型在参数不合规的时候会先追问一句,而不是硬填一个值让接口报错。

取值有范围的参数,还要写清超范围怎么办。日期超过 7 天的,是拒绝还是转人工,这是产品经理要定的,模型定不了。

3.2 超时、重试、熔断、限流各管什么

接口是会坏的。四种情况要分开处理,它们解决的不是同一个问题。

情况 说的是什么 常见做法
超时(Timeout) 接口在规定时间内没返回 设一个等待上限,运单查询这类接口按 3 秒
重试(Retry) 失败之后再试一次,很多失败是偶发的 重试 2 次,间隔 1 秒、2 秒;写操作要带幂等键,避免重试把同一件事做两遍
熔断(Circuit Breaker) 连续失败多次,先把这条路断开 连续失败到阈值就先不调了,过一段时间再试,避免把已经压垮的系统继续往上压
限流(Rate Limit) 单位时间内允许的调用次数 每个账号每秒钟 20 次;超了要排队或者拒绝,不能一直打

四个都要有默认值,不能等出故障的时候临时定。产品经理要做的是知道这四个值各是多少、超了之后用户看到什么。

同一个超时,三种设置下客服看到的不一样

四个默认值

  • 超时上限3 秒
  • 重试2 次,间隔 1 秒、2 秒
  • 熔断连续 5 次失败触发
  • 限流每个账号每秒 20 次
  • 这一次的现场运单查询接口在高峰时段变慢,第 1 次调用 3.2 秒返回,超出上限

四个值都要有默认值,出事才有地方对。

用默认值跑一遍

  • 客服看到的那一屏「这单目前在杭州转运中心,预计明天上午派送」
  • 下面一行灰字本次查询因接口超时重试过一次(只对客服可见)

故障被平台消化掉了,客户看不出刚才出过问题。

重试改成 0 次

  • 客服看到「运单系统暂时没有响应,已经帮你转人工查询」,旁边一个「转人工」

重试一归零,故障直接露到客服面前。

熔断阈值改成连续 2 次失败、限流改成每秒 2 次

  • 熔断后「运单查询已暂停,稍后自动恢复」,状态灯转黄,旁注「熔断已触发,剩余 30 秒内不再调用」
  • 限流后连跑 10 次查询前 2 次通过,后面 8 次排队,排在最长的那个标「等待 4 秒」

熔断护住被压住的系统,限流的代价是有人要等。

四个值先定默认值,出事才有地方对。

这一块要看懂什么:超时、重试、熔断、限流管的是四件事,四个值都要有默认值;少设一个,故障就原样丢到客服面前。
运单查询按超时 3 秒、重试 2 次、熔断连续 5 次失败、每账号每秒 20 次写进需求,超了之后用户看到哪句提示一起定。

3.3 接口挂了以后给什么兜底

失败处理只是把损失压小,兜底解决的是「这事还办不办得成」。三类兜底按代价从低到高排。

第一类是给替代路径。运单查询挂了,如果系统里还有一张本地缓存的运单快照,就先按快照答,并明确告诉用户这是几分钟前的数据。

第二类是降级处理。查不到实时位置,就先答「今天上午已经到达杭州转运中心」,这一步是准确的,只是不够细。

第三类是转人工,把已经收集到的信息一并交给人工。客服中心那个案子里,转人工的时候要把单号、客户说的时间、已经试过哪些动作一起带过去,不能让客服从头问一遍。

三类都要写进需求,还要写清各自在什么情况下触发。只写一句「失败要给用户反馈」,等于没写。

4. 权限给到够用为止

4.1 只读和可写分开

查运单和改派送,看起来都在同一个系统里,权限性质完全不同。前者看一眼,后者改了别人的东西。这两类工具从一开始就要分开授权。

只读的工具可以放开一点,让智能体自己判断什么时候用。可写的工具要额外加两道:调用前要有人确认,调用后要有记录。客服中心那 40 单改错,缺的就是调用前那道确认。

4.2 写操作用谁的身份

工具调用是以某个身份打出去的。用客服本人的账号,系统里留的是客服的操作记录,出了问题算在客服头上;用平台自己的服务账号,操作记录归平台,但这一步是谁要求的就查不到了。

常见做法是服务账号加上操作人。调用日志里同时记两条:实际调用用的是平台账号,发起这个动作的人是哪一位客服。出口处写清这两条,审计才查得到人。

有柜台、有窗口、有外呼的业务,还要注意一件事:智能体的账号权限和它服务的那个人的权限要一致。客户经理能看的客户,智能体才替得了他;权限放得比人还大,等于绕过了原本的授权。

4.3 一个工具能给多大范围

权限不是只有开关两档,还能按范围收。

按对象收:查运单的工具只接受本公司承运的单号,别的公司的单号直接拒绝。

按字段收:改派送只能改期望时间和期望时间段两个字段,运单号、收货地址这些改不了。

按条数收:一次只能改一单,不允许批量改。

按时间收:派送当天下午 6 点之后不接受改期,这跟业务规则一致,也顺带挡掉了一批不现实的请求。

这几条收范围的规则,都是产品经理在需求里能写清楚的,代价很小,出事的概率降得很多。

只读和可写从授权那一刻就分开,写操作再加确认、记录、范围三条。
图注:只读和可写从授权那一刻就分开,写操作再加确认、记录、范围三条。

5. 工具粒度怎么切

5.1 万能工具和碎工具都不好用

一个「万能工具」,把所有接口都塞进去,参数里带动作类型。它的问题在模型这一端:参数多、含义杂,填错的机会大,出错之后还不好定位是参数的问题还是接口的问题。

一堆「碎工具」,一个动作一个工具,模型要先在几十个选项里挑。工具多到一定程度,模型挑错的概率上升,工具定义本身也要占窗口。

切法按三条走。同一件事里的高频动作合并成一个工具,减少来回;一次调用里参数总在三个以内的,说明粒度合适;出错之后要能一眼看出是哪个动作坏的,做不到就要拆。

万能工具参数杂,碎工具挑不过来,按高频动作合并成三个左右最顺手。
图注:万能工具参数杂,碎工具挑不过来,按高频动作合并成三个左右最顺手。

5.2 高频操作要做到稳

客服中心天天要查运单,一天几千次。这类高频操作值得单独做厚一点:参数给默认值、返回结果按固定格式、常见失败都兜住。

低频操作相反,头一回用可能就是最后一次用,做个能用的版本就够,不用花大力气打磨。

判断高频还是低频,看业务量。写需求之前先去问一句:这个动作一个月跑多少次,出错一次影响多少人。答不上来的,说明需求本身还没调研清楚。

5.3 能改数据的操作先读后写

改派送这个动作,正确的顺序是先查后改。

先查这一次是为了给动作做条件判断:这单现在是什么状态、有没有已经安排好的派送任务、上一次改期是什么时候。查完再决定改不改、怎么改。中途接口返回「已签收」,就停下来,不往下走。

先读后写还有一个附带好处:出问题的时候有据可查。日志里能同时看到改之前的状态和改之后的状态,回溯改了哪一步很快。

6. MCP 把接线这件事标准化

6.1 写一次到处能用

前面的内容都在讲单个工具怎么定义。真正麻烦的是规模:一家单位里可能有五个系统、几十条接口,每个智能体平台都要重新接一遍,接口改一次,所有接过的平台都得跟着改。

MCP(Model Context Protocol,模型上下文协议)解决的就是这一段。它把「一个外部系统能提供哪些能力」写成一套标准格式,谁按这个格式实现一次,任何支持这套标准的智能体都能接上它。接口变了,改服务端那一份,客户端不用动。

对产品经理来说,判断要不要走 MCP 看两条:这套能力会不会被多个智能体用;这套接口以后会不会经常改。两条里有一条是,就值得按 MCP 接。

6.2 三类能力:工具、资源、提示词

一个 MCP 服务器对外提供三类东西,名字和用途不一样。

类别 是什么 运单系统的例子
工具(Tools) 可以被调用、会改变状态或返回结果的动作 查运单、改派送时间
资源(Resources) 只读的数据,按需取回来,不产生动作 运单的完整轨迹记录、配送网点清单
提示词(Prompts) 预先写好的模板,用来引导出更复杂的流程 「改期申请」的规范提问模板

三类里工具用得最多,资源是这几年被低估的一块:只读数据放在资源里,比包成工具更合适,因为它不产生任何动作,风险低,取用也简单。

6.3 服务器和客户端,本地和远程

MCP 这一套里有两个角色。服务器是提供能力的那一头,通常由系统方或平台方维护;客户端是使用能力的那一头,装在智能体平台里。

接法分两种。本地接法是把服务器进程装在同一台机器上,两边通过标准输入输出通信,适合开发调试,也适合数据不出本机的场景。远程接法是服务器挂在网络上,客户端通过 HTTP 连过去,适合多个客户端共用一套能力的场景。

两种接法的产品差别在两个地方:本地接法数据不出本机,远程接法要考虑网络、鉴权和跨地域;本地接法更新要挨个机器装,远程接法改一次全都生效。

本地接法把数据留在本机,远程接法让多个客户端共用一套能力。
图注:本地接法把数据留在本机,远程接法让多个客户端共用一套能力。

7. 智能体之间怎么对话

7.1 A2A 和 MCP 管的不是一件事

MCP 管的是智能体去够工具,接完就回来了。有一类活接不回来:对方本身就是另一个智能体,它有自己的模型、自己的工具、自己的判断过程。这类协作靠 A2A(Agent-to-Agent,智能体到智能体)。

A2A 里有个类似名片的做法,叫智能体名片(Agent Card),写的是这个智能体能办什么、怎么找到它、要什么凭据。主智能体拿到名片,把任务发过去,对方用自己的模型和工具办完,把结果交回来。

一句话分清:MCP 是握手,A2A 是派活。握手的对象是一套接口,派活的对象是一个能自己做判断的智能体。

往上接是接一套接口,往右接是派活给另一个能自己做判断的智能体。
图注:往上接是接一套接口,往右接是派活给另一个能自己做判断的智能体。

7.2 ANP 管的是网络里的发现

智能体多了以后会出现第三个问题:谁知道网络里有哪些智能体、谁能办什么事。ANP(Agent Network Protocol,智能体网络协议)管的就是这一段,做的是服务的注册、发现和路由。它现在还在社区讨论阶段,没有成熟生态,产品经理知道它要解决什么就够了,不急着选型。

三种协议的分工可以这么排:MCP 解决够得着工具,A2A 解决找得到合作的智能体,ANP 解决在成百上千个智能体里找到该找的那一个。

7.3 协议对产品设计的约束

用上这些协议之后,需求里要多写三件事。

身份。跨智能体调用的时候,用谁的身份发出请求、对方看到的操作人是谁,得在对端的记录里能对上。

计费。A2A 那种派活,对方用的可能是别家单位的模型,这次调用算在谁的账上、额度怎么分,要提前说清。

责任。对方智能体给出的结果错了,算谁的责任。常见做法是主智能体做最终判断,外部智能体给的结果只当参考,关键动作仍然要人确认。

8. 运单助手按什么粒度接线

运单助手最后接了两个工具,一个查询工具、一个改期工具。

查询工具只读,参数只有一个运单号,返回固定字段:当前状态、所在城市、预计派送时间、最近一次扫描时间。超时上限设 3 秒,重试 2 次,间隔 1 秒和 2 秒;三秒还没回来就先按 5 分钟前的快照答,并带一句「数据可能有几分钟延迟」;快照也没有就转人工,把单号一起带过去。

改期工具可写,参数三个,格式和取值范围在工具定义里写全。调用前必须由客服点一次确认,确认框里显示「原时间」和「新时间」两行,点完才发出。工具内部先查后改:状态不是「运输中」的直接拒绝,返回一句可读的理由。

权限收在三处:只能改本公司的单号;只能改期望日期和时间段两个字段,一次一单;派送当天下午 6 点之后不再受理。写操作的日志同时记平台账号和发起人。

后来客户在电话里说「能不能改成明天上午」,助手不再直接改,先答一句「可以改到明天上午 9 点到 12 点,确认改吗」,客服点确认,单子才动。那一周改错 40 单的事,第二周降到 0。

9. 这个工具能不能接进来

问题 答「否」的时候怎么办
这个动作有没有现成的接口? 没有接口的,先评估是走操作电脑那条路,还是推动把接口做出来
这个动作会不会改变系统里的数据? 会改数据的,必须加人工确认和操作日志,不能只做技术对接
它的参数是不是每一项都写了含义、必填和取值范围? 补全工具定义,取值范围有边界的还要写清超范围怎么办
这个动作一个月跑多少次? 跑得少的先做能用的版本,跑得多的要单独把稳定性和速度做厚
接口失败的时候用户看到什么? 写成可核对的文案,并写清什么情况下转人工
这个工具用谁的身份调用? 用服务账号的,日志里必须同时记发起人
一次能改多少条、能改哪些字段? 补上条数和字段的限制,能一次改一单就不要允许批量
这个动作有没有它必须依赖的前置条件? 有依赖的写成「先读后写」,并把判断依据写进工具说明

八条都能答「是」,这个工具可以接。

10. 三种看起来接好了、其实没接好的情况

接口接上了,参数没交代。 工具能调通,但模型不知道「明天上午」该填成什么,于是照着原话填。参数定义那一栏空着或者写着「字符串」,等于把这活儿留给了模型的运气。

给了写权限,没给确认。 只在最后加一句「请谨慎操作」没有用,模型每次的判断都不一样。写操作要卡在平台那一层:动作发出之前停下来等人点一下,这一层比写在提示词里可靠。

失败扔给用户。 接口超时就回一句「系统繁忙」,把问题原样交给用户。失败处理要按超时、重试、熔断、限流四件事各定一套,再配上快照、降级、转人工三类兜底。

11. 接口接通之后,还剩一类问题答不上来

接口这一段能带走的判断有四条:一个动作怎么描述给模型才不容易填错参数、参数写错和接口挂了分别怎么兜、权限收在哪一层、这套接口值不值得按 MCP 的标准做一次。

工厂、医院、银行这些地方,大量问题并不需要动系统,只需要找到那份文件里的一段话。工具接得再全,也答不上「这条制度怎么规定的」这类问题。下一份材料讲资料怎么进库、怎么被找回来,以及答不准的时候先怀疑哪一环。