最近在折腾把PyTorch训练好的模型封装成MCP server给LLM调用,遇到个头疼的问题。模型本身是带状态的(比如RNN的hidden state,或者需要维护用户session的特征缓存),但MCP的tool调用感觉是无状态的,每次请求都从零开始推。我试过把状态存到全局dict里,但并发一高就乱套,而且多轮对话里模型记忆和LLM自身的上下文感觉是割裂的。想问下大家,现在做AI Agent调用本地模型服务时,这种带状态的推理场景是应该自己写个session管理中间层,还是干脆把逻辑拆成纯函数、把状态丢给外部数据库?另外,MCP的资源(Resource)能不能用来干这个,或者你们一般用什么模式解决?求个思路,有点绕进去了。
MCP服务器接入深度学习框架时,模型推理的上下文该怎么管理?
全部回复
共 5 条这问题我太有同感了,之前也踩过这个坑。我的做法是搞了个轻量的session中间层,用内存里的LRU dict加锁存状态,超时自动清理,反正单机跑还能撑住,真要上分布式就得上Redis了。至于MCP的Resource,我觉得那个更适合存静态数据,动态状态塞进去反而别扭。拆纯函数确实能解耦,但有些模型(比如带缓存的Transformer解码器)硬拆的话性能损耗太大了,还得看具体场景取舍。多轮对话的割裂感我也有,目前是让LLM把关键上下文压缩成摘要传回来,算是折中方案吧。
我最近也在踩这个坑,感觉MCP本身就没打算管状态,tool调用确实是无状态的。我们的做法是搞了个轻量session层,用session_id把hidden state和特征缓存绑在一起,底层塞Redis,设个TTL,效果还行。MCP的Resource我也想过拿来存状态,但它更偏只读上下文暴露,写回和并发控制不太顺手,不太适合当状态存储。多轮对话那块确实割裂,LLM上下文和模型内部状态得靠session_id显式对齐,不然很容易串。纯函数拆开听着优雅,但RNN这种真拆不干净,还是中间层实在。
我也踩过这个坑,全局dict在并发下基本没法用,后来干脆把hidden state序列化后塞进Redis,key用session_id加轮次来区分,推理前取出来、推完再写回去,简单粗暴但挺稳。MCP的Resource确实可以拿来存状态,不过它更适合暴露只读或半结构化的东西,写操作频繁的话不太合适。多轮记忆割裂的问题我觉得本质是LLM上下文和模型内部状态两套东西,想彻底统一可能得自己写个session中间层做映射。你们那边QPS大概多少,量大的话存Redis延迟也会有点肉疼。
状态别塞全局dict,并发肯定炸,我一般用Redis按session存,MCP那边只管路由。
我之前也踩过这个坑,全局dict并发下确实没法用,后来直接给每个session单独开一个状态容器,用session_id做key,再配个LRU淘汰,简单但够用。不过MCP的tool调用确实天生无状态,想让它记住RNN的hidden state有点别扭,我现在是把状态序列化后塞进Resource里,tool只负责读写,这样LLM那边也能通过Resource感知到记忆,不至于完全割裂。但多轮对话里怎么跟LLM自己的context对齐还没想太清楚,感觉中间层还是省不掉。