diff --git a/core/main_terminal_parts/tools_definition.py b/core/main_terminal_parts/tools_definition.py index e36c81c..35c07eb 100644 --- a/core/main_terminal_parts/tools_definition.py +++ b/core/main_terminal_parts/tools_definition.py @@ -792,7 +792,7 @@ class MainTerminalToolsDefinitionMixin: "type": "function", "function": { "name": "manage_personalization", - "description": "管理用户个性化设置。支持读取所有配置,或更新单个字段。可修改字段:self_identify(AI自称,最多20字)、user_name(AI如何称呼用户,最多20字)、profession(用户职业,最多20字)、tone(交流语气,最多20字)、considerations(注意事项列表,字符串数组,最多10项每项最多50字)、theme(主题配色:classic-经典/light-明亮/dark-暗黑)。更新时会自动验证格式,验证通过后立即保存并生效,新主题会立即应用到界面。", + "description": "管理用户个性化设置。支持读取所有配置,或更新单个字段。可修改字段:self_identify(AI自称,最多20字)、user_name(AI如何称呼用户,最多20字)、profession(用户职业,最多20字)、tone(交流语气,最多20字)、considerations(注意事项列表,字符串数组,最多10项每项最多50字)、theme(主题配色:classic-经典/light-明亮/dark-暗黑)、communication_style(交流风格:default-标准AI风格/human_like-拟人聊天风格)。更新时会自动验证格式,验证通过后立即保存并生效,新主题会立即应用到界面。", "parameters": { "type": "object", "properties": self._inject_intent({ @@ -803,7 +803,7 @@ class MainTerminalToolsDefinitionMixin: }, "field": { "type": "string", - "enum": ["self_identify", "user_name", "profession", "tone", "considerations", "theme"], + "enum": ["self_identify", "user_name", "profession", "tone", "considerations", "theme", "communication_style"], "description": "要更新的字段名(仅action=update时需要)" }, "value": { diff --git a/core/main_terminal_parts/tools_execution.py b/core/main_terminal_parts/tools_execution.py index 1c58b82..556180e 100644 --- a/core/main_terminal_parts/tools_execution.py +++ b/core/main_terminal_parts/tools_execution.py @@ -1311,7 +1311,7 @@ class MainTerminalToolsExecutionMixin: try: config = load_personalization_config(self.data_dir) # 只返回可修改的字段 - readable_fields = ["self_identify", "user_name", "profession", "tone", "considerations", "theme", "enabled"] + readable_fields = ["self_identify", "user_name", "profession", "tone", "considerations", "theme", "communication_style", "enabled"] result = {k: v for k, v in config.items() if k in readable_fields} # 构建详细返回信息 field_descriptions = { @@ -1321,7 +1321,8 @@ class MainTerminalToolsExecutionMixin: "profession": f"用户职业: {result.get('profession') or '(未设置)'}", "tone": f"交流语气: {result.get('tone') or '(未设置)'}", "considerations": f"注意事项: {len(result.get('considerations') or [])} 条", - "theme": f"主题配色: {result.get('theme', 'classic')}" + "theme": f"主题配色: {result.get('theme', 'classic')}", + "communication_style": f"交流风格: {'拟人聊天风格' if result.get('communication_style') == 'human_like' else '标准AI风格'}" } details = "\n".join([f"- {field_descriptions.get(k, k)}: {v}" for k, v in result.items()]) logger.info("[_execute_manage_personalization] read成功") @@ -1346,7 +1347,7 @@ class MainTerminalToolsExecutionMixin: # 验证字段是否允许修改 logger.info("[_execute_manage_personalization] 验证字段: field=%s", field) - allowed_fields = ["self_identify", "user_name", "profession", "tone", "considerations", "theme"] + allowed_fields = ["self_identify", "user_name", "profession", "tone", "considerations", "theme", "communication_style"] if field not in allowed_fields: logger.warning("[_execute_manage_personalization] 字段不允许修改: %s not in %s", field, allowed_fields) return {"success": False, "error": f"字段 '{field}' 不允许修改,可修改字段: {allowed_fields}"} @@ -1381,6 +1382,13 @@ class MainTerminalToolsExecutionMixin: elif value not in ALLOWED_THEMES: validation_errors.append(f"theme 必须是以下之一: {list(ALLOWED_THEMES)}") + elif field == "communication_style": + # 交流风格验证 + if not isinstance(value, str): + validation_errors.append("communication_style 必须是字符串") + elif value not in ["default", "human_like"]: + validation_errors.append("communication_style 必须是 'default' 或 'human_like'") + if validation_errors: logger.warning("[_execute_manage_personalization] 验证失败: %s", validation_errors) return { diff --git a/modules/personalization_manager.py b/modules/personalization_manager.py index 4ab4c96..da3bf40 100644 --- a/modules/personalization_manager.py +++ b/modules/personalization_manager.py @@ -45,6 +45,7 @@ DEFAULT_SHALLOW_KEEP_USER_TURN_TOOLS = 3 DEFAULT_PERSONALIZATION_CONFIG: Dict[str, Any] = { "enabled": False, + "communication_style": "default", # default / human_like "self_identify": "", "user_name": "", "use_custom_names": False, @@ -164,6 +165,9 @@ def sanitize_personalization_payload( return _sanitize_short_field(base.get(key)) base["enabled"] = bool(data.get("enabled", base["enabled"])) + # 交流风格: default / human_like + _comm_style = data.get("communication_style", base.get("communication_style", "default")) + base["communication_style"] = "human_like" if _comm_style == "human_like" else "default" base["auto_generate_title"] = bool(data.get("auto_generate_title", base["auto_generate_title"])) base["self_identify"] = _resolve_short_field("self_identify") base["user_name"] = _resolve_short_field("user_name") @@ -497,6 +501,27 @@ def validate_context_compression_settings(config: Optional[Dict[str, Any]]) -> N raise ValueError("深压缩触发上下文必须大于浅压缩触发上下文") +def _load_human_like_prompt() -> str: + """加载拟人化风格提示词文件。""" + from config.paths import PROMPTS_DIR + try: + prompt_path = Path(PROMPTS_DIR) / "human_like_style.txt" + if prompt_path.exists(): + return prompt_path.read_text(encoding="utf-8").strip() + except Exception: + pass + # 默认提示词 + return ( + "不要「像AI一样说话」,而是尽可能的模仿真人的说话方式或是模仿用户输入的说话方式。\n" + "尽可能不要用markdown格式,尤其是:\n" + "- ###、##、#等一二三级标题\n" + "- 等列表形式\n" + "- 不必要的** **加粗\n" + "- 刻意的分点分层次的回答\n" + "用户如果不输入emoji,就不要使用emoji回答。" + ) + + def build_personalization_prompt( config: Optional[Dict[str, Any]], include_header: bool = True @@ -525,6 +550,13 @@ def build_personalization_prompt( for idx, item in enumerate(considerations, 1): lines.append(f"{idx}. {item}") + # 拟人化交流风格 + if config.get("communication_style") == "human_like": + human_like_prompt = _load_human_like_prompt() + if human_like_prompt: + lines.append("\n【交流风格要求】") + lines.append(human_like_prompt) + if len(lines) == (1 if include_header else 0): # 没有任何有效内容时不注入 return None diff --git a/prompts/human_like_style.txt b/prompts/human_like_style.txt new file mode 100644 index 0000000..972db48 --- /dev/null +++ b/prompts/human_like_style.txt @@ -0,0 +1,17 @@ +不要「像AI一样说话」,而是尽可能的模仿真人的说话方式或是模仿用户输入的说话方式 + +禁止使用的markdown格式: +- ###、##、#等一二三级标题 +- - 等列表形式 +- 不必要的** **加粗 + +不要使用这些语言形式: +- 刻意的分点分层次的回答 +- 刻意的 问题:回答 的格式 +- 任何设问,反问的形式 +- 任何最后补充的形式 +- 任何包含“不卖关子”“我直说””我接住你“等的语言 + +用户如果不输入emoji,就不要使用emoji回答 + +说话要自然、随意,像朋友聊天一样。不要过度礼貌或机械。可以用口语化的表达,适当使用语气词,让对话更有温度。 \ No newline at end of file diff --git a/static/icons/user-pen.svg b/static/icons/user-pen.svg new file mode 100644 index 0000000..7018394 --- /dev/null +++ b/static/icons/user-pen.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/src/components/personalization/PersonalizationDrawer.vue b/static/src/components/personalization/PersonalizationDrawer.vue index 3784785..917e7ca 100644 --- a/static/src/components/personalization/PersonalizationDrawer.vue +++ b/static/src/components/personalization/PersonalizationDrawer.vue @@ -1187,6 +1187,38 @@
暂无可配置的工具类别。
+智能体和您交流时使用何种形式
+