🐛 fix: 修复 Mem0 连接池耗尽和 LLM 参数透传问题

- mem0_manager: 添加 _cleanup_mem0_instance 方法,在缓存移除实例时显式释放数据库连接,避免等待 GC 导致连接池耗尽
- deep_assistant: 根据 model_provider 过滤不支持的参数,Anthropic 不支持 OpenAI 特有参数如 n、presence_penalty 等

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
朱潮 2026-03-04 10:11:44 +08:00
parent b3b6dd85d9
commit 9215f8236d
2 changed files with 68 additions and 3 deletions

View File

@ -166,7 +166,38 @@ async def init_agent(config: AgentConfig):
"api_key": config.api_key
}
if config.generate_cfg:
model_kwargs.update(config.generate_cfg)
# 内部使用的参数,不应传给任何 LLM
internal_params = {
'tool_output_max_length',
'tool_output_truncation_strategy',
'tool_output_filters',
'tool_output_exclude',
'preserve_code_blocks',
'preserve_json',
}
# Anthropic 不支持的 OpenAI 特有参数
openai_only_params = {
'n', # 生成多少个响应
'presence_penalty',
'frequency_penalty',
'logprobs',
'top_logprobs',
'logit_bias',
'seed',
'suffix',
'best_of',
'echo',
'user',
}
# 根据提供商决定需要过滤的参数
params_to_filter = internal_params.copy()
if model_provider == 'anthropic':
params_to_filter.update(openai_only_params)
filtered_cfg = {k: v for k, v in config.generate_cfg.items() if k not in params_to_filter}
model_kwargs.update(filtered_cfg)
llm_instance = init_chat_model(**model_kwargs)
# 创建新的 agent不再缓存

View File

@ -218,6 +218,38 @@ class Mem0Manager:
"""
return self._sync_pool
def _cleanup_mem0_instance(self, mem0_instance: Any) -> None:
"""清理 Mem0 实例,释放数据库连接
Mem0 PGVector 实现在初始化时获取连接并持有
只有在 __del__ 时才归还Python GC 不保证 __del__ 立即被调用
可能导致连接池耗尽此方法显式释放连接
Args:
mem0_instance: Mem0 Memory 实例
"""
try:
# Mem0 Memory 实例有一个 vector_store 属性,类型是 PGVector
if hasattr(mem0_instance, 'vector_store'):
vector_store = mem0_instance.vector_store
# PGVector 有 conn 和 connection_pool 属性
if hasattr(vector_store, 'conn') and hasattr(vector_store, 'connection_pool'):
if vector_store.connection_pool is not None:
try:
# 先关闭游标
if hasattr(vector_store, 'cur') and vector_store.cur:
vector_store.cur.close()
# 归还连接到池
vector_store.connection_pool.putconn(vector_store.conn)
# 标记为已清理,防止 __del__ 重复释放
vector_store.conn = None
vector_store.connection_pool = None
logger.debug("Successfully released Mem0 database connection back to pool")
except Exception as e:
logger.warning(f"Error releasing Mem0 connection: {e}")
except Exception as e:
logger.warning(f"Error cleaning up Mem0 instance: {e}")
async def get_mem0(
self,
user_id: str,
@ -249,8 +281,10 @@ class Mem0Manager:
# 检查缓存大小,超过则移除最旧的
if len(self._instances) >= self._max_instances:
removed_key, _ = self._instances.popitem(last=False)
logger.debug(f"Mem0 instance cache full, removed oldest entry: {removed_key}")
removed_key, removed_instance = self._instances.popitem(last=False)
# 显式释放连接,避免等待 GC 导致连接池耗尽
self._cleanup_mem0_instance(removed_instance)
logger.debug(f"Mem0 instance cache full, removed and cleaned: {removed_key}")
# 创建新实例
mem0_instance = await self._create_mem0_instance(