主动开聊

This commit is contained in:
zihanjian
2025-10-23 14:07:57 +08:00
parent ac5f10a342
commit e16c80416d
4 changed files with 115 additions and 13 deletions

View File

@@ -170,6 +170,22 @@ GROUP_MODELS:
max_history: 50 # 回顾最近50条消息
```
#### 群聊随机闲聊回复
如果希望机器人在群聊中偶尔主动开聊,可在 `groups.models.mapping` 中为群添加 `random_chitchat_probability`
```yaml
groups:
models:
mapping:
- room_id: "12345678@chatroom"
model: 2
max_history: 30
random_chitchat_probability: 0.3 # 0-10 表示关闭
```
未设置该字段的群默认关闭;写入 0 可以显式禁用。
#### 功能开关
您可以启用或禁用各种功能:

View File

@@ -62,9 +62,11 @@ groups:
- room_id: example12345@chatroom
model: 2
max_history: 30 # 回顾最近30条消息
random_chitchat_probability: 0.2 # 群聊随机闲聊概率0-10 表示关闭
- room_id: example12345@chatroom
model: 7
max_history: 30 # 回顾最近30条消息
random_chitchat_probability: 0.0 # 可单独覆盖默认概率
# 私聊映射
private_mapping:
- wxid: filehelper

View File

@@ -13,6 +13,21 @@ class Config(object):
def __init__(self) -> None:
self.reload()
@staticmethod
def _normalize_random_chitchat_probability(entry, fallback_probability=0.0):
if isinstance(entry, (int, float)):
probability = entry
elif isinstance(entry, dict):
probability = entry.get("probability", fallback_probability)
else:
probability = fallback_probability
try:
probability = float(probability)
except (TypeError, ValueError):
probability = fallback_probability
probability = max(0.0, min(1.0, probability))
return probability
def _load_config(self) -> dict:
pwd = os.path.dirname(os.path.abspath(__file__))
try:
@@ -33,6 +48,42 @@ class Config(object):
self.GROUPS = yconfig["groups"]["enable"]
self.WELCOME_MSG = yconfig["groups"].get("welcome_msg", "欢迎 {new_member} 加入群聊!")
self.GROUP_MODELS = yconfig["groups"].get("models", {"default": 0, "mapping": []})
legacy_random_conf = yconfig["groups"].get("random_chitchat", {})
legacy_default = self._normalize_random_chitchat_probability(
legacy_random_conf.get("default", 0.0) if isinstance(legacy_random_conf, dict) else 0.0,
fallback_probability=0.0,
)
legacy_mapping = {}
if isinstance(legacy_random_conf, dict):
for item in legacy_random_conf.get("mapping", []) or []:
if not isinstance(item, dict):
continue
room_id = item.get("room_id")
if not room_id:
continue
legacy_mapping[room_id] = self._normalize_random_chitchat_probability(
item,
fallback_probability=legacy_default,
)
random_chitchat_mapping = {}
for item in self.GROUP_MODELS.get("mapping", []) or []:
if not isinstance(item, dict):
continue
room_id = item.get("room_id")
if not room_id:
continue
if "random_chitchat_probability" in item:
rate = self._normalize_random_chitchat_probability(
item["random_chitchat_probability"],
fallback_probability=legacy_default,
)
random_chitchat_mapping[room_id] = rate
elif room_id in legacy_mapping:
random_chitchat_mapping[room_id] = legacy_mapping[room_id]
self.GROUP_RANDOM_CHITCHAT_DEFAULT = legacy_default
self.GROUP_RANDOM_CHITCHAT = random_chitchat_mapping
self.NEWS = yconfig["news"]["receivers"]
self.CHATGPT = yconfig.get("chatgpt", {})
self.DEEPSEEK = yconfig.get("deepseek", {})

View File

@@ -52,7 +52,32 @@ class Robot(Job):
self.wxid = self.wcf.get_self_wxid() # 获取机器人自己的wxid
self.allContacts = self.getAllContacts()
self._msg_timestamps = []
self.group_random_reply_rate = 0.3
default_random_prob = getattr(self.config, "GROUP_RANDOM_CHITCHAT_DEFAULT", 0.0)
try:
self.group_random_reply_default = float(default_random_prob)
except (TypeError, ValueError):
self.group_random_reply_default = 0.0
self.group_random_reply_default = max(0.0, min(1.0, self.group_random_reply_default))
mapping_random_prob = getattr(self.config, "GROUP_RANDOM_CHITCHAT", {})
self.group_random_reply_mapping = {}
if isinstance(mapping_random_prob, dict):
for room_id, rate in mapping_random_prob.items():
try:
numeric_rate = float(rate)
except (TypeError, ValueError):
numeric_rate = self.group_random_reply_default
numeric_rate = max(0.0, min(1.0, numeric_rate))
self.group_random_reply_mapping[room_id] = numeric_rate
if self.group_random_reply_default > 0:
self.LOG.info(
f"群聊随机闲聊默认开启,概率={self.group_random_reply_default}"
)
for room_id, rate in self.group_random_reply_mapping.items():
self.LOG.info(
f"群聊随机闲聊设置: 群={room_id}, 概率={rate}"
)
try:
db_path = "data/message_history.db"
@@ -335,18 +360,20 @@ class Robot(Job):
# 调用handle_chitchat函数处理闲聊传递完整的上下文
self._handle_chitchat(ctx, None)
else:
can_auto_reply = (
not msg.from_self()
and ctx.text
and (msg.type == 1 or (msg.type == 49 and ctx.text))
)
if can_auto_reply:
rand_val = random.random()
if rand_val < self.group_random_reply_rate:
self.LOG.info(
f"触发群聊主动闲聊回复: 概率阈值={self.group_random_reply_rate}, 随机值={rand_val:.2f}"
)
self._handle_chitchat(ctx, None)
rate = self._get_group_random_reply_rate(msg.roomid)
if rate > 0:
can_auto_reply = (
not msg.from_self()
and ctx.text
and (msg.type == 1 or (msg.type == 49 and ctx.text))
)
if can_auto_reply:
rand_val = random.random()
if rand_val < rate:
self.LOG.info(
f"触发群聊主动闲聊回复: 群={msg.roomid}, 概率阈值={rate}, 随机值={rand_val:.2f}"
)
self._handle_chitchat(ctx, None)
# 7.4 私聊消息,未被命令处理,进行闲聊
elif not msg.from_group() and not msg.from_self():
@@ -618,6 +645,12 @@ class Robot(Job):
}
return mapping.get(model_id)
def _get_group_random_reply_rate(self, room_id: str) -> float:
mapping = getattr(self, 'group_random_reply_mapping', {})
if room_id and isinstance(mapping, dict) and room_id in mapping:
return mapping[room_id]
return getattr(self, 'group_random_reply_default', 0.0)
def _select_model_for_message(self, msg: WxMsg) -> None:
"""根据消息来源选择对应的AI模型