From 8be1acb9f2862be8ddfbad6f5e0d58d75ea03210 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=B1=E6=BD=AE?= Date: Mon, 1 Dec 2025 19:22:59 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0PREAMBLE=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- routes/chat.py | 2 +- utils/fastapi_utils.py | 18 ++++++++++-------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/routes/chat.py b/routes/chat.py index 112a9e2..8f5bb29 100644 --- a/routes/chat.py +++ b/routes/chat.py @@ -297,7 +297,7 @@ async def enhanced_generate_stream_response( preamble_text = await preamble_task # 只有当preamble_text不为空且不为""时才输出 if preamble_text and preamble_text.strip() and preamble_text != "": - preamble_content = get_content_from_messages([{"role": "assistant","content": preamble_text + "\n"}], tool_response=tool_response) + preamble_content = get_content_from_messages([{"role": "preamble","content": preamble_text + "\n"}], tool_response=tool_response) chunk_data = create_stream_chunk(f"chatcmpl-preamble", model_name, preamble_content) yield f"data: {json.dumps(chunk_data, ensure_ascii=False)}\n\n" logger.info(f"Stream mode: Generated preamble text ({len(preamble_text)} chars)") diff --git a/utils/fastapi_utils.py b/utils/fastapi_utils.py index 1316eb6..bf12736 100644 --- a/utils/fastapi_utils.py +++ b/utils/fastapi_utils.py @@ -101,9 +101,9 @@ def get_content_from_messages(messages: List[dict], tool_response: bool = True) TOOL_RESULT_S = '[TOOL_RESPONSE]' THOUGHT_S = '[THINK]' ANSWER_S = '[ANSWER]' + PREAMBLE_S = '[PREAMBLE]' for msg in messages: - if msg['role'] == ASSISTANT: if msg.get('reasoning_content'): assert isinstance(msg['reasoning_content'], str), 'Now only supports text messages' @@ -128,6 +128,8 @@ def get_content_from_messages(messages: List[dict], tool_response: bool = True) elif msg['role'] == FUNCTION: if tool_response: content.append(f'{TOOL_RESULT_S} {msg["name"]}\n{msg["content"]}') + elif msg['role'] == "preamble": + content.append(f'{PREAMBLE_S}\n{msg["content"]}') else: raise TypeError @@ -156,8 +158,8 @@ def process_messages(messages: List[Dict], language: Optional[str] = None) -> Li # 确定当前ASSISTANT消息在所有ASSISTANT消息中的位置(从0开始) assistant_position = assistant_indices.index(i) - # 使用正则表达式按照 [TOOL_CALL]|[TOOL_RESPONSE]|[ANSWER] 进行切割 - parts = re.split(r'\[(TOOL_CALL|TOOL_RESPONSE|ANSWER)\]', msg.content) + # 使用正则表达式按照 [THINK|TOOL_CALL]|[TOOL_RESPONSE]|[ANSWER] 进行切割 + parts = re.split(r'\[(THINK|PREAMBLE|TOOL_CALL|TOOL_RESPONSE|ANSWER)\]', msg.content) # 重新组装内容,根据消息位置决定处理方式 filtered_content = "" @@ -198,7 +200,7 @@ def process_messages(messages: List[Dict], language: Optional[str] = None) -> Li elif current_tag == "ANSWER": # 所有ASSISTANT消息都保留ANSWER数据 filtered_content += f"[ANSWER]\n{text}\n" - elif current_tag != "THINK": + elif current_tag != "THINK" and current_tag != "PREAMBLE": filtered_content += text + "\n" else: # 标签 current_tag = parts[i] @@ -213,13 +215,13 @@ def process_messages(messages: List[Dict], language: Optional[str] = None) -> Li else: processed_messages.append({"role": msg.role, "content": msg.content}) - # 逆运算:将包含 [TOOL_RESPONSE] 的消息重新组装回 msg['role'] == 'function' 和 msg.get('function_call') + # 逆运算:将包含 [THINK|TOOL_RESPONSE] 的消息重新组装回 msg['role'] == 'function' 和 msg.get('function_call') # 这是 get_content_from_messages 的逆运算 final_messages = [] for msg in processed_messages: - if msg["role"] == ASSISTANT and "[TOOL_RESPONSE]" in msg["content"]: + if msg["role"] == ASSISTANT: # 分割消息内容 - parts = re.split(r'\[(TOOL_CALL|TOOL_RESPONSE|ANSWER)\]', msg["content"]) + parts = re.split(r'\[(THINK|PREAMBLE|TOOL_CALL|TOOL_RESPONSE|ANSWER)\]', msg["content"]) current_tag = None assistant_content = "" @@ -257,7 +259,7 @@ def process_messages(messages: List[Dict], language: Optional[str] = None) -> Li "arguments": arguments } }) - elif current_tag != "THINK": + elif current_tag != "THINK" and current_tag != "PREAMBLE": final_messages.append({ "role": ASSISTANT, "content": text