diff --git a/src/chat/message_manager/context_manager.py b/src/chat/message_manager/context_manager.py index 61c5f0440..b26e660b4 100644 --- a/src/chat/message_manager/context_manager.py +++ b/src/chat/message_manager/context_manager.py @@ -118,7 +118,7 @@ class SingleStreamContextManager: # 三层记忆系统集成:将消息添加到感知记忆层 try: - if global_config.three_tier_memory and global_config.three_tier_memory.enable: + if global_config.memory and global_config.memory.enable: unified_manager = _get_unified_memory_manager() if unified_manager: # 构建消息字典 diff --git a/src/chat/replyer/default_generator.py b/src/chat/replyer/default_generator.py index 0f1ab2c26..9e6b19a32 100644 --- a/src/chat/replyer/default_generator.py +++ b/src/chat/replyer/default_generator.py @@ -575,7 +575,7 @@ class DefaultReplyer: str: 记忆信息字符串 """ # 检查是否启用三层记忆系统 - if not (global_config.three_tier_memory and global_config.three_tier_memory.enable): + if not (global_config.memory and global_config.memory.enable): return "" try: diff --git a/src/config/config.py b/src/config/config.py index add8f562f..833fca481 100644 --- a/src/config/config.py +++ b/src/config/config.py @@ -39,7 +39,6 @@ from src.config.official_configs import ( ReactionConfig, ResponsePostProcessConfig, ResponseSplitterConfig, - ThreeTierMemoryConfig, ToolConfig, VideoAnalysisConfig, VoiceConfig, @@ -382,7 +381,6 @@ class Config(ValidatedConfigBase): emoji: EmojiConfig = Field(..., description="表情配置") expression: ExpressionConfig = Field(..., description="表达配置") memory: MemoryConfig | None = Field(default=None, description="记忆配置") - three_tier_memory: ThreeTierMemoryConfig | None = Field(default=None, description="三层记忆系统配置") mood: MoodConfig = Field(..., description="情绪配置") reaction: ReactionConfig = Field(default_factory=ReactionConfig, description="反应规则配置") chinese_typo: ChineseTypoConfig = Field(..., description="中文错别字配置") diff --git a/src/config/official_configs.py b/src/config/official_configs.py index f324433bd..7a98d76f7 100644 --- a/src/config/official_configs.py +++ b/src/config/official_configs.py @@ -434,8 +434,6 @@ class MemoryConfig(ValidatedConfigBase): search_top_k: int = Field(default=10, description="默认检索返回数量") search_min_importance: float = Field(default=0.3, description="最小重要性阈值") search_similarity_threshold: float = Field(default=0.5, description="向量相似度阈值") - search_max_expand_depth: int = Field(default=2, description="检索时图扩展深度(0-3)") - search_expand_semantic_threshold: float = Field(default=0.3, description="图扩展时语义相似度阈值(建议0.3-0.5,过低可能引入无关记忆,过高无法扩展)") enable_query_optimization: bool = Field(default=True, description="启用查询优化") # 路径扩展配置 (新算法) @@ -453,30 +451,6 @@ class MemoryConfig(ValidatedConfigBase): enable_memory_deduplication: bool = Field(default=True, description="启用检索结果去重(合并相似记忆)") memory_deduplication_threshold: float = Field(default=0.85, description="记忆相似度阈值(0.85表示85%相似即合并)") - # 检索权重配置 (记忆图系统) - search_vector_weight: float = Field(default=0.4, description="向量相似度权重") - search_graph_distance_weight: float = Field(default=0.2, description="图距离权重") - search_importance_weight: float = Field(default=0.2, description="重要性权重") - search_recency_weight: float = Field(default=0.2, description="时效性权重") - - # 记忆整合配置 - consolidation_enabled: bool = Field(default=False, description="是否启用记忆整合") - consolidation_interval_hours: float = Field(default=2.0, description="整合任务执行间隔(小时)") - consolidation_deduplication_threshold: float = Field(default=0.93, description="相似记忆去重阈值") - consolidation_time_window_hours: float = Field(default=2.0, description="整合时间窗口(小时)- 统一用于去重和关联") - consolidation_max_batch_size: int = Field(default=30, description="单次最多处理的记忆数量") - - # 记忆关联配置(整合功能的子模块) - consolidation_linking_enabled: bool = Field(default=True, description="是否启用记忆关联建立") - consolidation_linking_max_candidates: int = Field(default=10, description="每个记忆最多关联的候选数") - consolidation_linking_max_memories: int = Field(default=20, description="单次最多处理的记忆总数") - consolidation_linking_min_importance: float = Field(default=0.5, description="最低重要性阈值") - consolidation_linking_pre_filter_threshold: float = Field(default=0.7, description="向量相似度预筛选阈值") - consolidation_linking_max_pairs_for_llm: int = Field(default=5, description="最多发送给LLM分析的候选对数") - consolidation_linking_min_confidence: float = Field(default=0.7, description="LLM分析最低置信度阈值") - consolidation_linking_llm_temperature: float = Field(default=0.2, description="LLM分析温度参数") - consolidation_linking_llm_max_tokens: int = Field(default=1500, description="LLM分析最大输出长度") - # 遗忘配置 (记忆图系统) forgetting_enabled: bool = Field(default=True, description="是否启用自动遗忘") forgetting_activation_threshold: float = Field(default=0.1, description="激活度阈值") @@ -500,26 +474,13 @@ class MemoryConfig(ValidatedConfigBase): node_merger_context_match_required: bool = Field(default=True, description="节点合并是否要求上下文匹配") node_merger_merge_batch_size: int = Field(default=50, description="节点合并批量处理大小") - -class MoodConfig(ValidatedConfigBase): - """情绪配置类""" - - enable_mood: bool = Field(default=False, description="启用情绪") - mood_update_threshold: float = Field(default=1.0, description="情绪更新阈值") - - -class ThreeTierMemoryConfig(ValidatedConfigBase): - """三层记忆系统配置类""" - - enable: bool = Field(default=False, description="启用三层记忆系统(实验性功能)") - data_dir: str = Field(default="data/memory_graph/three_tier", description="数据存储目录") - + # ==================== 三层记忆系统配置 (Three-Tier Memory System) ==================== # 感知记忆层配置 perceptual_max_blocks: int = Field(default=50, description="记忆堆最大容量(全局)") perceptual_block_size: int = Field(default=5, description="每个记忆块包含的消息数量") perceptual_similarity_threshold: float = Field(default=0.55, description="相似度阈值(0-1)") perceptual_topk: int = Field(default=3, description="TopK召回数量") - activation_threshold: int = Field(default=3, description="激活阈值(召回次数→短期)") + perceptual_activation_threshold: int = Field(default=3, description="激活阈值(召回次数→短期)") # 短期记忆层配置 short_term_max_memories: int = Field(default=30, description="短期记忆最大数量") @@ -532,10 +493,12 @@ class ThreeTierMemoryConfig(ValidatedConfigBase): long_term_decay_factor: float = Field(default=0.95, description="衰减因子") long_term_auto_transfer_interval: int = Field(default=60, description="自动转移间隔(秒)") - # Judge模型配置 - judge_model_name: str = Field(default="utils_small", description="用于决策的LLM模型") - judge_temperature: float = Field(default=0.1, description="Judge模型的温度参数") - enable_judge_retrieval: bool = Field(default=True, description="启用智能检索判断") + +class MoodConfig(ValidatedConfigBase): + """情绪配置类""" + + enable_mood: bool = Field(default=False, description="启用情绪") + mood_update_threshold: float = Field(default=1.0, description="情绪更新阈值") class ReactionRuleConfig(ValidatedConfigBase): diff --git a/src/main.py b/src/main.py index c6a02e1a7..62386001b 100644 --- a/src/main.py +++ b/src/main.py @@ -479,7 +479,7 @@ MoFox_Bot(第三方修改版) # 初始化三层记忆系统(如果启用) try: - if global_config.three_tier_memory and global_config.three_tier_memory.enable: + if global_config.memory and global_config.memory.enable: from src.memory_graph.manager_singleton import initialize_unified_memory_manager logger.info("三层记忆系统已启用,正在初始化...") await initialize_unified_memory_manager() diff --git a/src/memory_graph/manager.py b/src/memory_graph/manager.py index 5bc0c55d1..8ddd8a0b4 100644 --- a/src/memory_graph/manager.py +++ b/src/memory_graph/manager.py @@ -138,20 +138,24 @@ class MemoryManager: ) # 检查配置值 - expand_depth = self.config.search_max_expand_depth - expand_semantic_threshold = self.config.search_expand_semantic_threshold - search_top_k = self.config.search_top_k + # 兼容性处理:如果配置项不存在,使用默认值或映射到新配置项 + expand_depth = getattr(self.config, "path_expansion_max_hops", 2) + expand_semantic_threshold = getattr(self.config, "search_similarity_threshold", 0.5) + search_top_k = getattr(self.config, "search_top_k", 10) + # 读取权重配置 - search_vector_weight = self.config.search_vector_weight - search_importance_weight = self.config.search_importance_weight - search_recency_weight = self.config.search_recency_weight + search_vector_weight = getattr(self.config, "vector_weight", 0.65) + # context_weight 近似映射为 importance_weight + search_importance_weight = getattr(self.config, "context_weight", 0.25) + search_recency_weight = getattr(self.config, "recency_weight", 0.10) + # 读取阈值过滤配置 - search_min_importance = self.config.search_min_importance - search_similarity_threshold = self.config.search_similarity_threshold + search_min_importance = getattr(self.config, "search_min_importance", 0.3) + search_similarity_threshold = getattr(self.config, "search_similarity_threshold", 0.5) logger.info( - f"📊 配置检查: search_max_expand_depth={expand_depth}, " - f"search_expand_semantic_threshold={expand_semantic_threshold}, " + f"📊 配置检查: expand_depth={expand_depth}, " + f"expand_semantic_threshold={expand_semantic_threshold}, " f"search_top_k={search_top_k}" ) logger.info( @@ -422,7 +426,7 @@ class MemoryManager: "query": query, "top_k": top_k, "use_multi_query": use_multi_query, - "expand_depth": expand_depth or global_config.memory.search_max_expand_depth, # 传递图扩展深度 + "expand_depth": expand_depth or getattr(global_config.memory, "path_expansion_max_hops", 2), # 传递图扩展深度 "context": context, "prefer_node_types": prefer_node_types or [], # 🆕 传递偏好节点类型 } diff --git a/src/memory_graph/manager_singleton.py b/src/memory_graph/manager_singleton.py index 1abc51df4..f07804e65 100644 --- a/src/memory_graph/manager_singleton.py +++ b/src/memory_graph/manager_singleton.py @@ -139,29 +139,29 @@ async def initialize_unified_memory_manager(): from src.memory_graph.unified_manager import UnifiedMemoryManager # 检查是否启用三层记忆系统 - if not hasattr(global_config, "three_tier_memory") or not getattr( - global_config.three_tier_memory, "enable", False + if not hasattr(global_config, "memory") or not getattr( + global_config.memory, "enable", False ): logger.warning("三层记忆系统未启用,跳过初始化") return None - config = global_config.three_tier_memory + config = global_config.memory # 创建管理器实例 _unified_memory_manager = UnifiedMemoryManager( - data_dir=Path(getattr(config, "data_dir", "data/memory_graph/three_tier")), + data_dir=Path(getattr(config, "data_dir", "data/memory_graph")), # 感知记忆配置 perceptual_max_blocks=getattr(config, "perceptual_max_blocks", 50), perceptual_block_size=getattr(config, "perceptual_block_size", 5), perceptual_activation_threshold=getattr(config, "perceptual_activation_threshold", 3), - perceptual_recall_top_k=getattr(config, "perceptual_recall_top_k", 5), - perceptual_recall_threshold=getattr(config, "perceptual_recall_threshold", 0.55), + perceptual_recall_top_k=getattr(config, "perceptual_topk", 5), + perceptual_recall_threshold=getattr(config, "perceptual_similarity_threshold", 0.55), # 短期记忆配置 short_term_max_memories=getattr(config, "short_term_max_memories", 30), short_term_transfer_threshold=getattr(config, "short_term_transfer_threshold", 0.6), # 长期记忆配置 long_term_batch_size=getattr(config, "long_term_batch_size", 10), - long_term_search_top_k=getattr(config, "long_term_search_top_k", 5), + long_term_search_top_k=getattr(config, "search_top_k", 5), long_term_decay_factor=getattr(config, "long_term_decay_factor", 0.95), long_term_auto_transfer_interval=getattr(config, "long_term_auto_transfer_interval", 600), # 智能检索配置 diff --git a/src/memory_graph/perceptual_manager.py b/src/memory_graph/perceptual_manager.py index a0fd2a694..e914a2be2 100644 --- a/src/memory_graph/perceptual_manager.py +++ b/src/memory_graph/perceptual_manager.py @@ -279,6 +279,28 @@ class PerceptualMemoryManager: logger.error(f"生成向量失败: {e}", exc_info=True) return None + async def _generate_embeddings_batch(self, texts: list[str]) -> list[np.ndarray | None]: + """ + 批量生成文本向量 + + Args: + texts: 文本列表 + + Returns: + 向量列表,与输入一一对应 + """ + try: + if not self.embedding_generator: + logger.error("嵌入生成器未初始化") + return [None] * len(texts) + + embeddings = await self.embedding_generator.generate_batch(texts) + return embeddings + + except Exception as e: + logger.error(f"批量生成向量失败: {e}", exc_info=True) + return [None] * len(texts) + async def recall_blocks( self, query_text: str, @@ -528,11 +550,29 @@ class PerceptualMemoryManager: logger.info("重新生成记忆块向量...") - for block in self.perceptual_memory.blocks: - if block.embedding is None and block.combined_text: - block.embedding = await self._generate_embedding(block.combined_text) + blocks_to_process = [] + texts_to_process = [] - logger.info(f"✅ 向量重新生成完成({len(self.perceptual_memory.blocks)} 个块)") + for block in self.perceptual_memory.blocks: + if block.embedding is None and block.combined_text and block.combined_text.strip(): + blocks_to_process.append(block) + texts_to_process.append(block.combined_text) + + if not blocks_to_process: + logger.info("没有需要重新生成向量的块") + return + + logger.info(f"开始批量生成 {len(blocks_to_process)} 个块的向量...") + + embeddings = await self._generate_embeddings_batch(texts_to_process) + + success_count = 0 + for block, embedding in zip(blocks_to_process, embeddings): + if embedding is not None: + block.embedding = embedding + success_count += 1 + + logger.info(f"✅ 向量重新生成完成(成功: {success_count}/{len(blocks_to_process)})") async def shutdown(self) -> None: """关闭管理器""" diff --git a/src/memory_graph/short_term_manager.py b/src/memory_graph/short_term_manager.py index 52e4a878a..673e71b41 100644 --- a/src/memory_graph/short_term_manager.py +++ b/src/memory_graph/short_term_manager.py @@ -492,6 +492,28 @@ class ShortTermMemoryManager: logger.error(f"生成向量失败: {e}", exc_info=True) return None + async def _generate_embeddings_batch(self, texts: list[str]) -> list[np.ndarray | None]: + """ + 批量生成文本向量 + + Args: + texts: 文本列表 + + Returns: + 向量列表,与输入一一对应 + """ + try: + if not self.embedding_generator: + logger.error("嵌入生成器未初始化") + return [None] * len(texts) + + embeddings = await self.embedding_generator.generate_batch(texts) + return embeddings + + except Exception as e: + logger.error(f"批量生成向量失败: {e}", exc_info=True) + return [None] * len(texts) + def _parse_json_response(self, response: str) -> dict[str, Any] | None: """解析 LLM 的 JSON 响应""" try: @@ -684,11 +706,29 @@ class ShortTermMemoryManager: """重新生成记忆的向量""" logger.info("重新生成短期记忆向量...") - for memory in self.memories: - if memory.embedding is None and memory.content: - memory.embedding = await self._generate_embedding(memory.content) + memories_to_process = [] + texts_to_process = [] - logger.info(f"✅ 向量重新生成完成({len(self.memories)} 条记忆)") + for memory in self.memories: + if memory.embedding is None and memory.content and memory.content.strip(): + memories_to_process.append(memory) + texts_to_process.append(memory.content) + + if not memories_to_process: + logger.info("没有需要重新生成向量的短期记忆") + return + + logger.info(f"开始批量生成 {len(memories_to_process)} 条短期记忆的向量...") + + embeddings = await self._generate_embeddings_batch(texts_to_process) + + success_count = 0 + for memory, embedding in zip(memories_to_process, embeddings): + if embedding is not None: + memory.embedding = embedding + success_count += 1 + + logger.info(f"✅ 向量重新生成完成(成功: {success_count}/{len(memories_to_process)})") async def shutdown(self) -> None: """关闭管理器""" diff --git a/template/bot_config_template.toml b/template/bot_config_template.toml index 80cb7476e..ec3910f9a 100644 --- a/template/bot_config_template.toml +++ b/template/bot_config_template.toml @@ -1,5 +1,5 @@ [inner] -version = "7.8.1" +version = "7.8.2" #----以下是给开发人员阅读的,如果你只是部署了MoFox-Bot,不需要阅读---- #如果你想要修改配置文件,请递增version的值 @@ -251,49 +251,10 @@ vector_db_path = "data/memory_graph/chroma_db" # 向量数据库路径 (使用 search_top_k = 10 # 默认检索返回数量 search_min_importance = 0.3 # 最小重要性阈值 (0.0-1.0) search_similarity_threshold = 0.6 # 向量相似度阈值 -search_expand_semantic_threshold = 0.3 # 图扩展时语义相似度阈值(建议0.3-0.5,过低可能引入无关记忆,过高无法扩展) # 智能查询优化 enable_query_optimization = true # 启用查询优化(使用小模型分析对话历史,生成综合性搜索查询) -# === 记忆整合配置 === -# 记忆整合包含两个功能:1)去重(合并相似记忆)2)关联(建立记忆关系) -# 注意:整合任务会遍历所有记忆进行相似度计算,可能占用较多资源 -# 建议:1) 降低执行频率;2) 提高相似度阈值减少误判;3) 限制批量大小 -consolidation_enabled = true # 是否启用记忆整合 -consolidation_interval_hours = 1.0 # 整合任务执行间隔 -consolidation_deduplication_threshold = 0.9 # 相似记忆去重阈值 -consolidation_time_window_hours = 2.0 # 整合时间窗口(小时)- 统一用于去重和关联 -consolidation_max_batch_size = 100 # 单次最多处理的记忆数量 - -# 记忆关联配置(整合功能的子模块) -consolidation_linking_enabled = true # 是否启用记忆关联建立 -consolidation_linking_max_candidates = 10 # 每个记忆最多关联的候选数 -consolidation_linking_max_memories = 20 # 单次最多处理的记忆总数 -consolidation_linking_min_importance = 0.5 # 最低重要性阈值(低于此值的记忆不参与关联) -consolidation_linking_pre_filter_threshold = 0.7 # 向量相似度预筛选阈值 -consolidation_linking_max_pairs_for_llm = 5 # 最多发送给LLM分析的候选对数 -consolidation_linking_min_confidence = 0.7 # LLM分析最低置信度阈值 -consolidation_linking_llm_temperature = 0.2 # LLM分析温度参数 -consolidation_linking_llm_max_tokens = 1500 # LLM分析最大输出长度 - -# === 记忆遗忘配置 === -forgetting_enabled = true # 是否启用自动遗忘 -forgetting_activation_threshold = 0.1 # 激活度阈值(低于此值的记忆会被遗忘) -forgetting_min_importance = 0.8 # 最小保护重要性(高于此值的记忆不会被遗忘) - -# === 记忆激活配置 === -activation_decay_rate = 0.9 # 激活度衰减率(每天衰减10%) -activation_propagation_strength = 0.5 # 激活传播强度(传播到相关记忆的激活度比例) -activation_propagation_depth = 1 # 激活传播深度(最多传播几层,建议1-2) - -# === 记忆检索配置 === -search_max_expand_depth = 2 # 检索时图扩展深度(0=仅直接匹配,1=扩展1跳,2=扩展2跳,推荐1-2) -search_vector_weight = 0.4 # 向量相似度权重 -search_graph_distance_weight = 0.2 # 图距离权重 -search_importance_weight = 0.2 # 重要性权重 -search_recency_weight = 0.2 # 时效性权重 - # === 路径评分扩展算法配置(实验性功能)=== # 这是一种全新的图检索算法,通过路径传播和分数聚合来发现相关记忆 # 优势:更精确的图结构利用、路径合并机制、动态剪枝优化 @@ -308,6 +269,48 @@ path_expansion_path_score_weight = 0.50 # 路径分数在最终评分中的权 path_expansion_importance_weight = 0.30 # 重要性在最终评分中的权重 path_expansion_recency_weight = 0.20 # 时效性在最终评分中的权重 +# 🆕 路径扩展 - 记忆去重配置 +enable_memory_deduplication = true # 启用检索结果去重(合并相似记忆) +memory_deduplication_threshold = 0.85 # 记忆相似度阈值(0.85表示85%相似即合并) + +# === 记忆遗忘配置 === +forgetting_enabled = true # 是否启用自动遗忘 +forgetting_activation_threshold = 0.1 # 激活度阈值(低于此值的记忆会被遗忘) +forgetting_min_importance = 0.8 # 最小保护重要性(高于此值的记忆不会被遗忘) + +# === 记忆激活配置 === +activation_decay_rate = 0.9 # 激活度衰减率(每天衰减10%) +activation_propagation_strength = 0.5 # 激活传播强度(传播到相关记忆的激活度比例) +activation_propagation_depth = 1 # 激活传播深度(最多传播几层,建议1-2) + +# === 记忆激活配置(强制执行)=== +auto_activate_base_strength = 0.1 # 记忆被检索时自动激活的基础强度 +auto_activate_max_count = 10 # 单次搜索最多自动激活的记忆数量 + +# === 三层记忆系统配置 === +# 感知记忆层配置 +perceptual_max_blocks = 50 # 记忆堆最大容量(全局) +perceptual_block_size = 5 # 每个记忆块包含的消息数量 +perceptual_similarity_threshold = 0.55 # 相似度阈值(0-1) +perceptual_topk = 3 # TopK召回数量 +perceptual_activation_threshold = 3 # 激活阈值(召回次数→短期) + +# 短期记忆层配置 +short_term_max_memories = 30 # 短期记忆最大数量 +short_term_transfer_threshold = 0.6 # 转移到长期记忆的重要性阈值 +short_term_search_top_k = 5 # 搜索时返回的最大数量 +short_term_decay_factor = 0.98 # 衰减因子 + +# 长期记忆层配置 +long_term_batch_size = 10 # 批量转移大小 +long_term_decay_factor = 0.95 # 衰减因子 +long_term_auto_transfer_interval = 180 # 自动转移间隔(秒) + +# 节点去重合并配置 +node_merger_similarity_threshold = 0.85 # 节点去重相似度阈值 +node_merger_context_match_required = true # 节点合并是否要求上下文匹配 +node_merger_merge_batch_size = 50 # 节点合并批量处理大小 + # === 性能配置 === max_memory_nodes_per_memory = 10 # 每条记忆最多包含的节点数 max_related_memories = 5 # 激活传播时最多影响的相关记忆数 @@ -317,29 +320,6 @@ max_related_memories = 5 # 激活传播时最多影响的相关记忆数 # 1. 感知记忆层 (Perceptual Memory) - 消息块的短期缓存,自动收集 # 2. 短期记忆层 (Short-term Memory) - 结构化的活跃记忆,模型格式化 # 3. 长期记忆层 (Long-term Memory) - 持久化的图结构记忆,批量转移 -[three_tier_memory] -enable = false # 是否启用三层记忆系统(已经是核心系统,建议启用) -data_dir = "data/memory_graph/three_tier" # 数据存储目录 - -# --- 感知记忆层配置 --- -perceptual_max_blocks = 50 # 记忆堆最大容量(全局) -perceptual_block_size = 5 # 每个记忆块包含的消息数量 -perceptual_similarity_threshold = 0.55 # 相似度阈值(0-1) -perceptual_topk = 5 # TopK召回数量 -perceptual_activation_threshold = 3 # 激活阈值(召回次数达到此值→转为短期记忆) - -# --- 短期记忆层配置 --- -short_term_max_memories = 30 # 短期记忆最大数量(达到上限触发批量转移) -short_term_transfer_threshold = 0.6 # 转移到长期记忆的重要性阈值(0.0-1.0) -short_term_search_top_k = 5 # 搜索时返回的最大数量 - -# --- 长期记忆层配置 --- -long_term_batch_size = 10 # 批量转移大小(每次转移多少条短期记忆) -long_term_search_top_k = 5 # 长期记忆二次检索返回数量 - -# --- 记忆检索配置 --- -enable_judge_retrieval = true # 启用智能检索判断(裁判模型评估是否需要二次检索) -judge_confidence_threshold = 0.7 # 裁判模型置信度阈值 [voice] enable_asr = true # 是否启用语音识别,启用后MoFox-Bot可以识别语音消息,启用该功能需要配置语音识别模型[model.voice]