给 AI Agent 接工具:MCP 实战 4 个坑

先说结论

很多人接完 MCP 会发现一件事:工具明明调通了,Agent 还是干不成活。问题往往不在模型,而在工具这一层——描述怎么写、暴露几个、返回什么、能不能写。下面 4 个坑,是把内部系统接给 Agent 时最容易反复踩的。

坑一:工具描述按 API 文档写

模型选工具,靠的是描述文本,不是函数签名。把 query_order(sql: string) 写成「执行 SQL 查询」,模型根本不知道什么时候该用它,要么不用,要么乱用。

描述里至少要写清四件事:什么时候该用、什么时候别用、返回什么、有什么限制。比如改成:「当用户询问订单状态、退款进度、物流异常等结构化业务数据时使用;只支持 SELECT,禁止 JOIN 超过两张表;最多返回 50 行,超出需加筛选条件;涉及用户隐私字段时改用 get_order_summary。」

同一个工具,改完描述后选择准确率往往比换模型提升更明显。这是投入产出比最高的一步,先做这个。

坑二:一次暴露几十个工具

每个工具的定义都占上下文。挂 40 个工具,光定义就可能吃掉几千 token,而且选项一多,模型选错概率直线上升。实践中的经验值是:单轮对话里暴露 8~12 个工具比较稳,超过就该分组。

常见做法有三种:按业务域拆成多个 MCP Server,按会话场景动态挂载(用户问财务就别挂运维工具),或者加一层路由——先给模型一个「找工具」的元工具,让它描述意图,再由路由返回 3~5 个候选。第三种最灵活,但要多维护一层,团队小的话先做前两种。

判断标准很简单:如果一个工具一周都没被调用过,就别默认挂着。

坑三:返回值把上下文冲掉

这是最隐蔽的坑。工具返回 200KB 的 JSON,模型上下文当场被塞满,后面的推理全乱。更糟的是,它可能只用到其中三个字段。

正确做法是把「取数据」和「看数据」分开:工具默认返回结构化摘要——总数、关键字段、少量样例行,再附一个资源 ID;模型需要细节时,用另一个 read 工具按 ID 分页取。这和 MCP 里 resources 的思路一致:引用优先,内容按需加载。

另外两个细节:错误返回值也要设计,别直接抛 500 堆栈,要返回「哪一步失败、能不能重试、下一步建议」;长列表加默认分页,别让模型一次拿到一万条。

坑四:写操作没有闸门

只读工具出错顶多是答错,写工具出错是删数据、发错邮件、下错单。三个基本闸门:

  • 默认只读。写操作单独成组,不随会话默认挂载。
  • 先 dry-run。所有写操作支持预览模式,模型必须先展示「将要做什么」,再由用户确认。
  • 幂等键。Agent 重试很常见,没有幂等键的接口会重复下单、重复发消息。

还有一个容易忽略的点:权限要按真实用户身份透传,不要用服务账号的超级权限跑所有请求。否则任何一次提示注入,影响的都是全量数据。

上线前做一件小事:工具选择评测

别用「聊两句感觉还行」来判断。建一个 20~30 条的小评测集,用真实用户的问法(别写「调用 xxx 工具」,要写「我上周那笔退款到哪了」),统计三个指标:工具选对率、参数填对率、多余调用次数。

再打开 trace 看调用链。多数问题一眼就能看出来:要么没选对工具,要么选对了但参数缺字段,要么在中途反复横跳。每周回归一次,改完工具描述就重跑——这比事后猜「是不是模型不行」高效得多。

接工具这件事,本质上不是接 API,是给一个不懂你业务的同事写说明书。说明书写得越清楚,它干活越靠谱。

© 版权声明

相关文章

暂无评论

您必须登录才能参与评论!
立即登录
none
暂无评论...