feat(expression_selector): 添加温度采样功能以优化表达选择
feat(official_configs): 新增模型温度配置项以支持表达模型采样 chore(bot_config_template): 更新版本号并添加模型温度说明
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import asyncio
|
||||
import hashlib
|
||||
import math
|
||||
import random
|
||||
import time
|
||||
from typing import Any
|
||||
@@ -76,6 +77,45 @@ def weighted_sample(population: list[dict], weights: list[float], k: int) -> lis
|
||||
|
||||
|
||||
class ExpressionSelector:
|
||||
@staticmethod
|
||||
def _sample_with_temperature(
|
||||
candidates: list[tuple[Any, float, float, str]],
|
||||
max_num: int,
|
||||
temperature: float,
|
||||
) -> list[tuple[Any, float, float, str]]:
|
||||
"""
|
||||
对候选表达按温度采样,温度越高越均匀。
|
||||
|
||||
Args:
|
||||
candidates: (expr, similarity, count, best_predicted) 列表
|
||||
max_num: 需要返回的数量
|
||||
temperature: 温度参数,0 表示贪婪选择
|
||||
"""
|
||||
if max_num <= 0 or not candidates:
|
||||
return []
|
||||
|
||||
if temperature <= 0:
|
||||
return candidates[:max_num]
|
||||
|
||||
adjusted_temp = max(temperature, 1e-6)
|
||||
# 使用与排序相同的打分,但通过 softmax/temperature 放大尾部概率
|
||||
scores = [max(c[1] * (c[2] ** 0.5), 1e-8) for c in candidates]
|
||||
max_score = max(scores)
|
||||
weights = [math.exp((s - max_score) / adjusted_temp) for s in scores]
|
||||
|
||||
# 始终保留最高分一个,剩余的按温度采样,避免过度集中
|
||||
best_idx = scores.index(max_score)
|
||||
selected = [candidates[best_idx]]
|
||||
remaining_indices = [i for i in range(len(candidates)) if i != best_idx]
|
||||
|
||||
while remaining_indices and len(selected) < max_num:
|
||||
current_weights = [weights[i] for i in remaining_indices]
|
||||
picked_pos = random.choices(range(len(remaining_indices)), weights=current_weights, k=1)[0]
|
||||
picked_idx = remaining_indices.pop(picked_pos)
|
||||
selected.append(candidates[picked_idx])
|
||||
|
||||
return selected
|
||||
|
||||
def __init__(self, chat_id: str = ""):
|
||||
self.chat_id = chat_id
|
||||
if model_config is None:
|
||||
@@ -517,12 +557,21 @@ class ExpressionSelector:
|
||||
)
|
||||
return []
|
||||
|
||||
# 按照相似度*count排序,选择最佳匹配
|
||||
# 按照相似度*count排序,并根据温度采样,避免过度集中
|
||||
matched_expressions.sort(key=lambda x: x[1] * (x[2] ** 0.5), reverse=True)
|
||||
expressions_objs = [e[0] for e in matched_expressions[:max_num]]
|
||||
temperature = getattr(global_config.expression, "model_temperature", 0.0)
|
||||
sampled_matches = self._sample_with_temperature(
|
||||
candidates=matched_expressions,
|
||||
max_num=max_num,
|
||||
temperature=temperature,
|
||||
)
|
||||
expressions_objs = [e[0] for e in sampled_matches]
|
||||
|
||||
# 显示最佳匹配的详细信息
|
||||
logger.debug(f"模糊匹配成功: 找到 {len(expressions_objs)} 个表达方式")
|
||||
logger.debug(
|
||||
f"模糊匹配成功: 找到 {len(expressions_objs)} 个表达方式 "
|
||||
f"(候选 {len(matched_expressions)},temperature={temperature})"
|
||||
)
|
||||
|
||||
# 转换为字典格式
|
||||
expressions = [
|
||||
|
||||
@@ -10,11 +10,6 @@ CoreSink 统一管理器
|
||||
3. 使用 MessageRuntime 进行消息路由和处理
|
||||
4. 提供统一的消息发送接口
|
||||
|
||||
架构说明(2025-11 重构):
|
||||
- 集成 mofox_wire.MessageRuntime 作为消息路由中心
|
||||
- 使用 @runtime.on_message() 装饰器注册消息处理器
|
||||
- 利用 before_hook/after_hook/error_hook 处理前置/后置/错误逻辑
|
||||
- 简化消息处理链条,提高可扩展性
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
@@ -213,6 +213,12 @@ class ExpressionConfig(ValidatedConfigBase):
|
||||
default="classic",
|
||||
description="表达方式选择模式: classic=经典LLM评估, exp_model=机器学习模型预测"
|
||||
)
|
||||
model_temperature: float = Field(
|
||||
default=1.0,
|
||||
ge=0.0,
|
||||
le=5.0,
|
||||
description="表达模型采样温度,0为贪婪,值越大越容易采样到低分表达"
|
||||
)
|
||||
expiration_days: int = Field(
|
||||
default=90,
|
||||
description="表达方式过期天数,超过此天数未激活的表达方式将被清理"
|
||||
@@ -1009,4 +1015,3 @@ class KokoroFlowChatterConfig(ValidatedConfigBase):
|
||||
default_factory=KokoroFlowChatterProactiveConfig,
|
||||
description="私聊专属主动思考配置"
|
||||
)
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
[inner]
|
||||
version = "7.9.8"
|
||||
version = "7.9.9"
|
||||
|
||||
#----以下是给开发人员阅读的,如果你只是部署了MoFox-Bot,不需要阅读----
|
||||
#如果你想要修改配置文件,请递增version的值
|
||||
@@ -134,6 +134,8 @@ compress_identity = false # 是否压缩身份,压缩后会精简身份信息
|
||||
# - "classic": 经典模式,随机抽样 + LLM选择
|
||||
# - "exp_model": 表达模型模式,使用机器学习模型预测最合适的表达
|
||||
mode = "classic"
|
||||
# model_temperature: 机器预测模式下的“温度”,0 为贪婪,越大越爱探索(更容易选到低分表达)
|
||||
model_temperature = 1.0
|
||||
|
||||
# expiration_days: 表达方式过期天数,超过此天数未激活的表达方式将被清理
|
||||
expiration_days = 1
|
||||
|
||||
Reference in New Issue
Block a user