最近在搭一个MCP服务器,打算把几个内部API封装成工具给Claude用。问题是我在系统Prompt里写了很长的工具使用说明,结果模型经常选错工具或者参数传得乱七八糟。试过把工具描述写详细点,但Prompt太长又影响响应速度。也试过让模型先“思考”再调用,但效果不稳定。想知道大家有没有比较实用的做法?比如工具描述的结构、Prompt里该强调什么,或者有没有办法让模型在调用前先确认一下意图?求实战经验,别甩官方文档。
MCP服务器里写Prompt模板,怎么优雅地让LLM自己选择工具?
全部回复
共 46 条我之前也踩过这个坑,后来发现把工具描述改成“动词+对象+场景”的格式会好很多,比如“查询订单状态:当用户询问物流时调用”,模型命中率明显上来了。另外别在系统Prompt里堆说明,把关键约束塞到工具描述本身,Prompt只留一句“优先用工具解决,不确定就问”。还有个偏方:给每个工具加个“confirmation”参数,让模型先返回意图让用户确认再执行,虽然多一步但稳得很。你试过把参数设计成枚举值吗?我感觉这比让模型自由发挥强多了。
试试把工具描述改成“场景+输入+输出”三段式,模型选错率能降不少,参数校验放MCP端做兜底就行。
工具描述里加一行“何时不该用我”反而比强调功能更管用,我这边试过模型误调用少了一半多。
试试把工具描述改成“触发条件+反例”,再在prompt里加一句“不确定就选tool_a”,比长篇说明管用。
描述里直接写“当用户想xx时用这个”,比列参数有效得多,实测能少错一半。
我之前也踩过这个坑,后来发现把工具描述改成“触发条件+输入示例”的结构会好用很多,比如写清楚“当用户提到A或B场景时,用这个工具,输入长这样”。另外别把说明都堆在系统Prompt里,MCP工具描述本身就是给模型看的,精简到关键参数比写长篇大论有效。还有个土办法,就是在工具里加一个必填的“意图确认”字段,让模型先输出它理解的用户需求,再传实际参数,这样乱传的情况少了一大半。不过响应速度确实会慢点,看你能不能接受了。
工具描述里直接塞一个“何时用”的触发示例,比写一堆参数说明好用,我试下来准确率提升挺明显。
把高频调用场景做成独立的小工具,比一个万能大工具强,模型选错概率低很多。
工具描述里把参数示例和边界条件写死,比写一堆说明管用,我试过效果好很多。
我之前也踩过这个坑,后来发现最有效的不是把描述写长,而是给每个工具加一个“适用场景”和“反例”字段,模型判断起来快很多。另外你可以试试在系统Prompt里写一句“如果用户需求不明确,先调用一个意图确认工具”,比让模型自己瞎猜稳。参数乱传的话,可以在工具定义里把必填参数和可选参数分得很清楚,再给个默认值兜底。不过说实话,MCP这种动态工具选择,目前还是得靠多轮测试调描述,别指望一次性完美。
我之前也踩过这个坑,后来发现工具描述里别堆砌功能,把关键参数和典型使用场景写成“if you need X, use tool Y with parameter Z”这种条件句式,模型命中率高很多。另外可以让MCP在返回结果时带上工具调用的置信度,低于阈值就主动反问一句“你确定要查的是XX吗”,比让模型自己思考靠谱。
我之前也踩过这个坑,后来发现把工具描述改成“触发条件+关键参数示例”的结构会好很多,比如写明“当用户提到X时用这个”,比单纯罗列功能管用。另外可以试试在Prompt里加一句“不确定时先问用户再选工具”,虽然会多一轮对话,但能明显减少乱调用。还有个野路子是给每个工具故意加一个“前置必填参数”让模型填,比如传个task_type,填错了就让它自己纠正,相当于逼它先理解意图。你那个“思考”步骤不稳定,可能因为模型对内部推理没约束,不如把“思考”换成“让模型输出一段简短的调用理由”,再用代码校验这个理由和工具是否匹配。
工具描述里把“何时用”放最前面,参数给默认值并写清边界,比堆细节管用。
我现在的做法是把工具描述拆成“什么时候用”和“怎么用”两段,前者写触发场景,后者只放参数格式,模型选错的概率明显低了。另外别指望模型自己确认意图,不如在MCP层加个轻量校验,参数不对就直接返回错误提示让它重试,比在prompt里反复强调管用。
工具描述别写小作文,我一般就三行:干啥用、啥时候用、参数怎么填。关键是给每个工具起个动词开头的名字,比如get_user_profile比user_info清晰多了,模型选错的概率能降不少。另外你可以在MCP里加个"确认意图"的中间工具,让模型先调它复述一遍要干啥,虽然多一轮但比乱传参强。Prompt里少写"你必须",多写"如果用户想X就调Y",条件式描述比命令式管用。
工具描述这块我踩过类似的坑,后来发现关键不是写得多,而是写得“可判别”。每个tool的description里最好明确写出什么场景该用它、什么场景不该用,尤其是几个功能相近的工具,把边界条件直接怼进去,模型选错的概率会明显下降。参数乱传很多时候是因为schema里字段名太抽象,改成带业务语义的命名,再配上enum约束,比在prompt里反复强调管用得多。系统prompt我一般只留全局规则和工具之间的路由逻辑,具体用法全塞进tool自己的描述里,这样也方便单独迭代。让模型先确认意图这招我也试过,说实话在Claude上不太稳,后来换成在返回里强制带一个reasoning字段,反而更容易排查它到底哪步理解歪了。另外别忽视工具数量,超过七八个之后选择准确率会断崖式下跌,该合并的就合并,或者做个二级路由工具先分流。
工具描述别光堆功能,重点写清楚“什么时候该用”和“什么情况别用”,边界比细节管用。我一般会把参数拆成必填和可选,再给一两个典型调用示例,模型照着抄比读一堆说明靠谱。另外系统prompt里别重复工具描述,那玩意儿本来就会自动注入,你写太长反而稀释注意力。让模型先确认意图可以试试在工具里加个dry-run参数,先返回解析结果让它自己检查,比硬让它“思考”稳多了。
可以试试把工具描述拆成“什么时候用”和“怎么用”两段,前者用一句话讲清适用场景,后者只放最关键的参数约束,别把所有细节都塞进主prompt。我现在的做法是把详细说明挂在工具自己的description里,主prompt只留一句“先判断意图再选工具,不确定就反问”,反而稳了不少。还有个坑是参数类型尽量用enum收窄,模型乱传多半是因为可选值太开放。你那个先确认意图的思路我觉得对,但别让它自由发挥,给它固定几个澄清话术可能更靠谱。
工具描述别写小作文,把每个工具的名字和参数命名得自解释一点,模型光看签名就能猜个八九不离十。我一般会在系统Prompt里塞个两三行的决策树,只写“什么场景用哪个”,具体参数交给工具schema去约束。还有个野路子是加个confirm工具,让模型调之前先输出意图摘要,你这边拦截确认再放行,稳很多。
工具描述别整套API文档塞进去,把每个工具压成一句话说清“干啥+关键参数”,剩下的细节让模型调用后自己看返回。我这边试过在描述里加一句“拿不准就先问用户确认”,比硬写一堆规则管用。还有个偏方是用few-shot塞两三个正反例进system prompt,比纯文字说明稳不少,不过token得控制住。你们内部API如果参数格式统一,其实可以考虑做成一个入口工具再内部分发,模型选择压力会小很多。
工具描述里把每个参数的枚举值和边界写清楚,比堆一大段说明管用多了。
把工具描述写短反而更稳,我现在的做法是每个工具只留一句“什么场景用”,参数说明塞进JSON schema的description里。Prompt里专门加一句“不确定就先用tool_search问一句再动手”,Claude调用前会自己确认下。另外工具名用动词开头比名词堆叠好认很多,选错率能降不少。