🤖 在 MCP(Model Context Protocol)逐渐成为 AI 应用连接外部工具、数据源和业务系统的标准接口后,一个很现实的问题出现了:工具调用结果是否每次都要重新获取?答案并不总是“是”。合理的缓存与复用策略,可以降低延迟、减少重复请求,并让模型上下文更稳定。
一、为什么 MCP 场景需要缓存?
MCP 的核心价值,是让 AI 模型能够发现并调用外部工具,例如查询数据库、访问 API、读取资源或执行计算。根据 MCP 工具规范,服务器可以通过 tools/list 暴露可用工具,客户端再根据上下文决定是否调用工具 官方工具规范。如果每次会话、每次推理前都重新拉取工具列表或资源内容,就可能带来额外网络开销、接口限流压力和用户等待时间。
缓存的意义不只是“省一次请求”。在 AI Agent 场景中,工具列表、资源模板、提示词列表等内容经常会进入模型上下文。若这些内容顺序和内容保持稳定,既有助于客户端复用结果,也有助于上游模型获得更稳定的提示上下文。MCP 规范也建议服务器在工具未变化时返回确定性顺序,以便客户端可靠缓存工具列表 MCP Tools。
二、哪些结果适合缓存?
📦 MCP 缓存规范明确提到,一些 resultType 为 complete 的结果可以携带缓存提示,例如 server/discover、tools/list、prompts/list、resources/list、resources/templates/list 和 resources/read MCP 缓存规范。这说明缓存更适合“发现类、列表类、资源读取类”结果,而不是所有工具调用都应该缓存。
- 适合缓存:工具列表、提示词列表、资源模板、公开配置、低频变化的文档片段。
- 谨慎缓存:用户权限相关资源、个性化查询结果、会随时间快速变化的数据。
- 不建议缓存:写操作结果、支付状态、库存扣减、权限校验、带有一次性状态的多轮交互结果。
三、缓存键:不要只看工具名
🔑 一个常见误区是:只用工具名作为缓存键。MCP 缓存规范强调,缓存响应应由请求方法以及影响结果的请求参数共同识别;如果方法或参数不同,客户端不能直接复用旧响应 Cache Key。这对工具调用结果复用非常关键。
例如,同样是 resources/read,读取的 uri 不同,结果自然不同;同样是分页 tools/list,cursor 不同,对应的页面也不同。实践中可以把缓存键设计为:协议版本、服务器标识、方法名、工具名、参数哈希、授权上下文、分页游标、租户 ID 等字段的组合。这样能降低“错用缓存”的风险。
四、TTL:缓存不是永久有效
⏱️ MCP 使用 ttlMs 表达结果的新鲜度提示,语义类似 HTTP Cache-Control 的 max-age;如果 ttlMs 为正数,客户端可以在对应毫秒数内认为结果新鲜;如果为 0,则应视为立即过期 TTL 说明。需要注意,TTL 是提示,不是保证。服务器可能在 TTL 到期前就发生数据变化。
在实际系统中,TTL 可以分层设置:工具列表通常变化较慢,可以给较长 TTL;资源读取取决于业务数据更新频率;用户相关数据建议短 TTL 或不缓存。对于频繁失败的远程工具,还可以配合“失败短缓存”,例如在短时间内避免重复请求同一个不可用接口,但不能把失败结果当作长期事实。
五、cacheScope:区分 public 与 private
🔐 MCP 的 cacheScope 用于表达缓存作用域,可为 public 或 private。public 表示结果不包含用户特定数据,可以被共享缓存复用;private 表示结果包含私有信息,只能在相同授权上下文中复用 Cache Scope。
这对企业 AI 应用尤其重要。比如“公开天气查询工具列表”可能适合 public;而“读取某员工可访问的内部知识库资源”通常应为 private。即使工具端点需要认证,也不能默认把结果视为私有或公开,服务端应根据结果内容和权限模型明确标注缓存范围。
六、复用策略:先判断,再命中
🧠 工具调用结果复用不能只追求命中率,更要保证语义正确。推荐采用“三步判断”:先判断请求是否可缓存,再判断缓存是否新鲜,最后判断当前授权与上下文是否匹配。
- 可缓存性判断:只缓存明确安全、幂等、可复用的结果。
- 新鲜度判断:根据 ttlMs 和接收时间计算是否过期。
- 上下文判断:校验用户、租户、权限、参数、分页游标和协议版本是否一致。
对于工具列表,可以在应用启动、会话开始或首次需要工具时加载,并在 TTL 内复用。对于资源读取,可以采用按 URI 和权限上下文缓存。对于真实工具调用,例如查询订单状态、生成报表、调用搜索接口,则要根据业务语义决定是否缓存,不能仅因为“入参相同”就复用。
七、失效机制:TTL 之外还要有通知
📣 MCP 规范指出,TTL 与变更通知可以互补使用;当收到相关变更通知时,即使缓存仍在 TTL 内,也应立即视为失效 通知与缓存。这让系统既能减少轮询,又能在工具列表或资源发生变化时快速更新。
建议服务端在工具新增、删除、权限变更、资源模板更新时发出通知;客户端收到通知后,删除对应缓存项,而不是简单等待 TTL 到期。对分页列表,还要注意每一页都是独立缓存;如果游标失效,应丢弃相关分页缓存并从第一页重新拉取。
八、工程实践建议
✅ 好的 MCP 缓存策略,不是“缓存所有结果”,而是“只缓存可证明安全、可复用、可失效的结果”。
- 为缓存键加入方法、参数、授权上下文和服务器标识,避免串用结果。
- 默认私有数据使用 private,不确定时不要使用 public。
- 对写操作、强实时查询、一次性流程结果默认不缓存。
- 对工具列表和资源模板优先使用 TTL 加通知失效。
- 缓存命中时也要保留审计能力,记录结果来源是实时调用还是缓存复用。
- 出现权限变化、工具调用报错或参数 schema 不匹配时,主动刷新相关缓存。
总结
🚀 MCP 协议中的缓存与复用,本质上是在“性能、成本、实时性和安全性”之间做平衡。工具列表、资源模板和稳定资源适合通过 ttlMs、cacheScope、确定性排序和变更通知来优化;而用户敏感数据、写操作和强实时结果则必须谨慎处理。
对开发者而言,最实用的落地原则是:先定义哪些结果能缓存,再设计严格的缓存键,然后用 TTL 控制新鲜度,用 cacheScope 控制共享范围,用通知机制处理即时失效。这样既能提升 AI 应用响应速度,也能避免因错误复用工具结果带来的安全和业务风险。👏