🐛 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:
parent
b3b6dd85d9
commit
9215f8236d
@ -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(不再缓存)
|
||||
|
||||
@ -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(
|
||||
|
||||
Loading…
Reference in New Issue
Block a user