跳到正文

更多文章

数据周刊|Spark 4.2 把 CDC 写进内核,补丁也要先过 SQL 新同事 3 周做出分析助手,真正说明的不是他会写 Prompt AI 问数成本守门清单:限制查询风暴、重复试探和高价重跑 AI 查一次数跑上千条 SQL,数据库扛得住吗? 把数据湖换成 Iceberg 前,先找出最值得迁的 3 张表
一个 MCP 工具有 14 个参数,AI 为什么越用越糊涂?

有一种接口,程序员看了会沉默,AI 看了会努力。

它有 14 个参数,名字都来自数据库:disciplinemedia_typecontent_bucket。说明只有一句:“执行全局搜索。”合法值没有列,空结果也不解释原因。

人遇到这种接口,会去找文档,找不到就问写它的人。

AI 不太好意思打电话。它会猜。

第一次把“quiz”传给 media_type,接口其实只认“Assessment”;第二次把“math”传进去,系统要求首字母大写的“Math”。每次都返回空结果,模型只能换一种猜法再来一次。

看起来它很勤奋。实际上,上下文和调用次数正在一点点烧掉。

十四个内部参数把一次搜索变成猜谜

MCP 没让旧 API 自动变得适合 AI

Model Context Protocol 解决了模型如何发现和调用工具的问题,却不会替我们重新设计工具。

这就像给一间旧仓库装了自动门。门是新的,里面的箱子仍然没有标签。

AWS 最近用同一个模拟搜索后端做了 6 个 MCP 版本,从“原样暴露旧 API”一路改到“由服务端 Agent 接管整个搜索过程”。这个实验最有用的地方,是它没有只讲原则,而是把同一组问题放到不同接口上跑。

最初版本有 14 个可筛选字段,参数名采用内部术语,没有合法值,也没有有效的错误提示。模型传错值时,只得到空结果。

这种设计对普通程序也不友好,对 AI 更糟。因为空结果有两种完全不同的含义:真的没有内容,或者参数写错了。接口不说明,模型就只能用重试来买答案。

所以,给内部 API 加 MCP 的第一步,不应该是把所有参数写进 tool schema,而是问一句:这里面有多少东西,本来就只有老同事才知道?

参数名应该贴近问题,不是贴近表结构

数据库字段名常常忠实记录了系统的历史。

它可能为了兼容十年前的代码叫 content_bucket,在业务里实际表示“资源类型”;discipline 在表里没有错,但老师和模型更习惯说“subject”。

AWS 的第三个版本把参数改成更接近用户语言的名字,并通过枚举列出合法值。discipline 变成 subjectcontent_bucket 变成 resource_class。常见场景还设置默认值。

这不是讨好 AI,而是减少翻译。

从内部字段名到业务语言和合法值

如果你正在给一个数据查询、指标检索或元数据搜索接口接 MCP,可以先做三件事:

  1. 把参数名翻译成业务会说的话;
  2. 有限取值使用枚举,不让模型自由发挥;
  3. 常见情况设置默认值,并在响应里告诉模型默认值已经生效。

第三点很容易漏。默认值能减少参数,但如果模型不知道系统替它补了什么,后续解释可能出现偏差。

一个工具最好只做一件容易说清的事

很多旧 API 追求“大而全”。一个搜索接口既能列列表,又能查详情,还能按十几个条件过滤。程序员可以根据文档组合参数,模型面对的却是一团可能性。

AWS 的示例后来把“搜索”和“查看详情”拆成两个工具。搜索返回简洁结果,详情按资源 ID 单独读取。

这类拆分有三个好处:

  • 工具描述更短,模型更容易选对;
  • 响应不必每次携带大量无用字段;
  • 权限和审计可以按动作区分。

但也不能把每个参数都拆成一个工具。工具太多,Agent 仍然要在一长串名字里做选择。

比较实用的判断是:如果两个动作的输入、权限、返回结果或失败处理明显不同,就值得拆开;如果只是同一个动作的常见筛选条件,优先留在 schema 里。

做 Forge 这类本地 AI 数据工具,或者给内部分析 Agent 接工具时,这个原则尤其重要。工具边界越清楚,后面的审计、确认和失败恢复越容易做。

不是所有说明都要一直塞在上下文里

合法值一多,另一个问题又出现了。

把所有字段说明、同义词和分类表都写进 tool description,准确率可能提高,但每一轮对话都要携带这些内容。模型还没开始分析,先背了一本产品目录。

AWS 的第四个版本采用按需加载:常用值留在简短提示里,完整分类由一个 get_taxonomy 工具在需要时查询。

简单问题直接搜索,模糊问题先查分类。

常用约束常驻,复杂分类按需加载

这套做法适合参数多、分类变化频繁的工具。比如指标平台有几百个业务域,没必要每次都把完整指标树塞给模型。先让它判断需要哪个业务域,再取那部分内容。

不过,按需加载也有代价:多一次调用,多一点延迟。不是所有工具都需要这套结构。三个枚举就能说清的接口,别为了显得先进再造一个分类服务。

错误信息要告诉 AI 下一步怎么做

人在页面上看到“无数据”,会换关键词、检查筛选条件。模型需要接口明确区分:

  • 查询成功但没有匹配结果;
  • 参数值不合法;
  • 权限不足;
  • 数据源暂时不可用;
  • 条件太宽,成本过高。

最好同时返回下一步建议。

例如,不要只返回 invalid parameter,而是告诉它:subject 只接受 MathScienceLiteracy;不要只返回空数组,而是说明当前筛选组合无结果,可以放宽年级或资源类型。

错误信息不是给人看的附属文案,它是 Agent 的下一条指令。

给现有 API 接 MCP 前,先做一次减法

如果你手里正好有一个准备接给 AI 的内部接口,可以先拿纸写下这五问:

  1. 哪些参数名只有数据库开发看得懂?
  2. 哪些取值可以用枚举或默认值约束?
  3. 哪些动作应该拆成独立工具?
  4. 哪些说明可以需要时再加载?
  5. 每一种失败是否告诉模型下一步怎么办?

做完以后,再写 MCP schema。

协议负责把门打开,工具设计负责让来客知道东西放在哪。要是仓库里 14 个箱子都写着内部编号,AI 越努力,可能只会把屋子翻得越乱。


我叫石头,在数据行业里摸爬滚打了十几年,见过太多接口把组织历史写进参数名。这里写的,就是这些教训——我觉得值得说出来的那部分。

来源:AWS:MCP tool design — Practical approaches and tradeoffs

Elazer (石头)
Elazer (石头)

11 年数据老兵,从分析师到架构专家。用真实经历帮数据人少走弯路。

加入免费社群

和数据从业者一起交流成长

了解详情 →

成为会员

解锁全部内容 + 知识库

查看权益 →

1v1 咨询

有具体职业困惑?一小时说清楚

预约咨询 →
← 上一篇 把数据湖换成 Iceberg 前,先找出最值得迁的 3 张表 下一篇 → AI 查一次数跑上千条 SQL,数据库扛得住吗?