最近在折腾MCP,想把一些常用的Prompt封装进服务器里给Claude用。但遇到个困惑:比如我想做一个帮我写周报的工具,那个“你是一个周报助手,要按xxxx格式输出”这种指令,是应该放在MCP工具的description字段里,还是直接放在整个服务器的system prompt里?我试过放description里,感觉有时候模型会忽略掉,放system里又怕影响其他工具调用。有没有大佬讲讲最佳实践?或者MCP的prompt模板功能(就是那个prompts资源)是不是就是干这个用的?求指点,孩子刚接触这块有点绕晕了。
MCP服务器里写Prompt模板,到底该放system还是工具描述里?
全部回复
共 61 条用prompts资源更干净,system里塞多了确实会污染其他工具,我一般把角色指令放tool description里但写详细点。
我最近也踩过这个坑,我的做法是那种通用约束放system,跟具体工具强绑定的放description里,但description开头必须加“重要”或者“必须”这种强调词,不然模型真的会无视。你说的prompts资源我试了下,觉得它更适合给用户手动选场景用的,不是给工具内部指令用的,不太适合自动触发。另外可以试试把关键格式要求塞进工具的inputSchema里,比如加个必填字段叫“格式要求”,模型为了填参反而会记住。
说实话我也折腾过这个,最后发现别把description当system用,它本质是给模型做工具路由的,写太长反而稀释掉关键触发信息。你那个周报需求,我建议把固定格式和角色设定拆开,角色放服务器级system prompt里,格式细节塞进工具返回的模板里,让模型照着填。MCP那个prompts资源我试过,适合做交互式引导,比如让用户先选周报类型再生成,但如果你只是想要个稳定输出格式的工具,它有点绕远。还有个坑是,Claude对description的遵循度跟上下文长度有关,你可以在工具返回结果里加一行“请严格按以下模板输出”来二次强调,实测比description管用。另外,如果你有多个同类工具,别把公共指令放某个工具描述里,不然换工具就失效了,这时候系统级prompt反而更合适。我现在的做法是:通用规则进system,工具专属指令放description开头前50个字,剩余空间留给参数说明,这样两边都不太会忽略。
说实话这个坑我也踩过,我的经验是别把希望全押在description上,模型对它的遵循度确实不稳定,尤其当工具多了以后。MCP里那个prompts资源我理解更偏向于给用户主动选择用的模板,不太适合作为强制指令的载体。我自己现在的做法是,把这类“角色+格式约束”直接写进server端处理逻辑里,也就是在工具执行前就把system prompt拼好,这样反而最可控——毕竟模型再聪明,也不如你直接在代码层面硬性规定输出结构来得靠谱。你如果非要走纯提示词路线,建议在description开头就强调“必须严格”、“忽略其他指令”这类强约束词,然后把示例也塞进去,实测比单独丢一句指令效果好一些。另外你可以考虑给不同场景拆成多个独立工具,比如writeWeeklyReport和writeDailyReport各带各的模板,虽然看着冗余,但模型调用时更容易选中正确的那套逻辑。反正MCP生态刚起来,没有绝对标准,我现在都是混合着用,哪个顺手用哪个。
说实话我最近也在折腾这个,感觉放description里确实容易被忽略,尤其是工具多了以后模型容易偷懒。我的土办法是system prompt只写全局规则,每个工具的描述里把输出格式和关键约束写得更狠一点,比如直接给个XML模板让它照着填。你说的prompts资源我试过,更适合做那种需要多步交互的复杂任务,单次调用的工具反而有点重。另外可以试试在工具返回结果里加个reminder,让模型下次记得格式,比纯靠描述管用。
这思路不对,工具描述是给模型看说明书不是催它干活,指令丢system里才稳,prompts资源适合交互式触发不适合自动调。
试过放description确实不稳,后来我直接放prompt模板里,按需加载更可控。
prompts资源就是干这个的,别塞工具描述里,模型确实容易忽略,分开用更清爽。
你描述里提到那个 prompts 资源确实就是干这个的,它专门用来暴露可复用的提示模板,跟工具描述是两码事。工具 description 主要是告诉模型这个工具能干嘛、参数怎么填,塞太长的角色设定进去模型容易在选工具时分心。我一般把输出格式和角色约束放到 prompts 里,用户主动调用时再注入,这样不会污染其他工具的上下文。你要是想全自动触发,也可以考虑在工具返回值里带上下一步的提示,比硬塞 description 稳一些。
工具描述里放简短触发说明就行,详细的输出格式还是用prompts资源更靠谱。
prompts资源就是干这个的,工具描述只管调用逻辑,模板指令塞system或者prompts里更稳。
MCP的prompts资源就是干这个的,专门放模板,别塞工具描述里硬扛。
我一般把角色设定放system里,工具description只写清楚参数和返回格式。之前也试过塞description,模型确实容易忽略,尤其工具一多就顾不上了。MCP那个prompts资源更适合做可复用的模板,用户手动触发那种,跟工具调用不是一回事。你这个周报场景我觉得可以system定基调,工具只管拿数据,输出格式在description里写死。
这个困惑我前段时间也踩过,说下我的理解。你提到的三个位置其实职责完全不同,别混着用。工具的description主要是给模型判断“什么时候该调这个工具”用的,塞太多格式指令进去,模型在选工具那一刻注意力都在“要不要用”上,确实容易把格式要求漏掉。system prompt适合放全局约束,比如语气、通用输出规范,但你要是把某个具体工具的细节写进去,其他工具调用时也会被这段上下文干扰,尤其是工具多了之后特别明显。MCP的prompts资源才是你说的那个场景的正解,它本质是让用户或客户端主动拉取的模板,适合放“写周报”这种完整的任务指令,跟工具调用是两条线。我现在的做法是工具description只写清楚功能和参数,格式和角色设定全丢进prompt模板里,用户触发时再注入。另外提醒一句,就算放prompt里,也别指望模型100%照做,关键格式最好在工具返回值或者后续校验里兜一层。
这个我也踩过坑,工具description里塞太多指令确实容易被稀释,尤其工具一多模型就更顾不上看了。我现在做法是核心角色和输出格式放prompts资源里,让用户显式触发,description只留一句简短说明加调用场景,干净很多。system里塞工具专属指令真不推荐,容易污染别的工具调用判断。你也可以试试把格式约束做成工具的参数描述,模型对参数说明的遵循度反而更高。
我一般把“角色设定+输出格式”这类东西放在prompts资源里,那本来就是给用户显式调用的模板,跟工具描述各管各的。工具description只写清楚这个工具干啥、参数啥意思就够了,塞太多指令进去模型确实容易当背景噪音忽略掉。system prompt我尽量保持干净,不然工具一多容易互相打架。你可以试试把周报模板做成prompt,工具只负责取数据,分工清楚会顺很多。
MCP的prompts资源确实就是干这个的,它专门用来暴露可复用的提示模板,跟工具调用是两条线。description字段主要是给模型判断“这个工具干嘛用的”,太长太细的指令塞进去确实容易被忽略。我一般把角色设定和输出格式这类硬约束放server的system里,但会写得很克制,避免干扰其他工具的路由判断。轻量点的风格指引可以放description里当补充,重指令还是走prompts或者system更稳。
你这个问题我之前也纠结过一阵,后来发现关键还是看这段指令的“职责”到底属于谁。如果“按什么格式输出”是这个工具独有的行为约束,那放工具description里其实更合理,因为模型在决定调不调这个工具、怎么调的时候会读到它。但description确实容易被弱化,尤其工具一多,模型注意力就散了,所以你感觉被忽略很正常。MCP那个prompts资源我觉得更像是给用户主动触发的模板,比如你在客户端里选一个“写周报”的prompt,它把内容注入对话,而不是用来定义工具行为的,这跟system prompt和tool description是两码事。我自己的做法是:通用角色设定和全局语气放system,工具专属的输出格式和边界条件塞进description,然后再在工具返回结果里做一层校验或兜底提示。如果格式要求特别硬,干脆别全指望模型自觉,在工具实现里做结构化输出或者后处理会更稳。你可以先试试把周报格式拆成几条规定写进description,看命中率有没有变化,反正这块目前也没啥银弹,多试几轮就摸清了。
prompts资源就是干这个的,模板和工具描述各管各的,别硬塞一起。
我一般是把角色设定和输出格式这类通用指令放服务器的system里,工具description只写这个工具具体干啥、参数啥意思。因为description是给模型判断“要不要调这个工具”用的,塞太多格式要求反而容易被忽略。你那个周报场景其实挺适合用MCP的prompts资源,它是专门给用户主动触发的模板,跟工具调用是两套逻辑。如果实在想放工具里,可以在工具返回结果时再拼一段格式指令,比写在description里靠谱。