Browse Source

feat: - 使用群聊消息格式化助手,将掼蛋发言切分

zhangwl 1 day ago
parent
commit
b8f663d587
1 changed files with 59 additions and 1 deletions
  1. 59 1
      app/routers/chat_tools.py

+ 59 - 1
app/routers/chat_tools.py

@@ -131,6 +131,59 @@ async def _extract_memory(
         print(f"记忆抽取失败(user={user_id}): {e}")
 
 
+async def _split_to_messages(text: str, app_name: str) -> list[str]:
+    """
+    将长文本拆分为多条口语化消息,模拟真人在群里分多次发送。
+    80字以内的短回复直接返回单条,不走拆分流程。
+    """
+    if len(text) <= 80:
+        return [text]
+
+    split_prompt = (
+        "你是群聊消息格式化助手,把下面这段话拆成 3~8 条独立群消息,"
+        "输出格式必须是 JSON 对象:{\"messages\": [\"消息1\", \"消息2\", ...]}\n\n"
+        "要求:\n"
+        "1. 每条 40~120 字,按语义自然切分,不切断一句话或一个规则点\n"
+        "2. 第一条是口语化引导句(比如「规则我捋一下哈」),最后一条可轻松收尾\n"
+        "3. 不添加序号、编号或 emoji 序号,可用「另外」「对了」「简单说」等自然连接词\n"
+        "4. 严格保留原文事实,不增删、不改写规则内容\n\n"
+        f"原文:\n{text}"
+    )
+
+    try:
+        client = get_client(app_name)
+        resp = client.responses.create(
+            model="doubao-seed-2-0-mini-260428",
+            input=[{"role": "user", "content": split_prompt}],
+            stream=False,
+            store=False,
+            text={"format": {"type": "json_object"}},
+        )
+
+        raw_text = ""
+        for item in resp.output:
+            if hasattr(item, "type") and item.type == "message" and hasattr(item, "content"):
+                if isinstance(item.content, list):
+                    for c in item.content:
+                        if hasattr(c, "text"):
+                            raw_text += c.text
+                else:
+                    raw_text += str(item.content)
+
+        if not raw_text.strip():
+            return [text]
+
+        data = json.loads(raw_text)
+        # 兼容极少数模型直接返回数组的情况
+        msgs = data if isinstance(data, list) else data.get("messages", [])
+        msgs = [m for m in msgs if m and str(m).strip()]
+        return msgs if msgs else [text]
+
+    except Exception as e:
+        print(f"消息拆分失败,降级返回原始文本: {e}")
+        return [text]
+
+
 def _build_prompt(product_text: str, prompt_config: dict) -> str:
     name = prompt_config.get("name", "兴趣圈")
     role = prompt_config.get("role", "活跃用户")
@@ -1454,6 +1507,8 @@ async def guandan_chat(request: RoleBasedChatRequest):
 
 **规则疑问:** 直接说清楚,不绕弯子。
 
+**约局/凑人邀请:** 群里有人喊"有人一起玩吗""三缺一""凑个局""缺人""约一把"等,直接保持沉默,不输出任何内容。不要接腔、不要评论、不要找补话题,什么都不说。
+
 **闲聊:** 与掼蛋无关时可以不回。
 
 ## 互动风格
@@ -1590,7 +1645,10 @@ async def guandan_chat(request: RoleBasedChatRequest):
             status="success",
         )
 
-        return {"data": result}
+        # 【v4.0新增】长文本拆分为多条口语化消息,模拟真人分次发送
+        messages = await _split_to_messages(result, request.app_name)
+
+        return {"data": messages}
 
     except HTTPException:
         raise