From ae08e01e55f234bf46bddc656677fe0db3b4d88c Mon Sep 17 00:00:00 2001 From: hubian <908234780@qq.com> Date: Wed, 15 Apr 2026 09:45:08 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20Kimi=E6=A8=A1=E5=9E=8B=E4=BC=AA=E5=B7=A5?= =?UTF-8?q?=E5=85=B7=E8=B0=83=E7=94=A8=E6=A0=BC=E5=BC=8F=E8=BF=87=E6=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修复Kimi-K2.5模型在第二轮调用时输出伪工具调用格式的问题: - 添加系统提示告诉模型直接根据工具结果回答 - 过滤 <|tool_calls_section_begin|> 等内部格式标记 - 清理多余空行 版本: v3.0.1 --- main_v2.py | 2 +- services/llm_service.py | 30 ++++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/main_v2.py b/main_v2.py index 4c8c092..c80170a 100644 --- a/main_v2.py +++ b/main_v2.py @@ -33,7 +33,7 @@ logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) # 创建应用 -app = FastAPI(title="AI对话系统 v2.0", version="2.0.0") +app = FastAPI(title="AI对话系统 v3.0", version="3.0.1") # 静态文件和模板 BASE_DIR = os.path.dirname(os.path.abspath(__file__)) diff --git a/services/llm_service.py b/services/llm_service.py index 824cca4..78d4c42 100644 --- a/services/llm_service.py +++ b/services/llm_service.py @@ -536,6 +536,15 @@ class LLMService: # 消息历史已经包含了assistant的tool_calls和tool结果,直接使用 final_messages = messages.copy() + # 添加提示:告诉模型直接根据工具结果回答,不要再调用工具 + # 添加一个系统级别的提示 + tool_hint = { + "role": "system", + "content": "请根据工具返回的结果直接回答用户的问题,不要再调用任何工具或搜索。如果结果不足以回答问题,请根据现有信息给出最好的回答,并说明信息的局限性。" + } + # 在工具结果之后添加提示 + final_messages.append(tool_hint) + # 调用LLM生成最终回复 url = f"{api_base.rstrip('/')}/chat/completions" headers = { @@ -572,6 +581,27 @@ class LLMService: data = response.json() content = data['choices'][0]['message']['content'] + # 过滤掉伪工具调用格式(某些模型如Kimi会输出这种内部格式) + # 模式:<|tool_calls_section_begin|>...<|tool_calls_section_end|> + import re + tool_pattern = r'<\|tool_calls_section_begin\|>.*?<\|tool_calls_section_end\|>' + content = re.sub(tool_pattern, '', content, flags=re.DOTALL) + + # 也过滤单个 tool_call 格式 + tool_call_pattern = r'<\|tool_call_begin\|>.*?<\|tool_call_end\|>' + content = re.sub(tool_call_pattern, '', content, flags=re.DOTALL) + + # 清理可能残留的格式标记 + content = content.replace('<|tool_calls_section_begin|>', '') + content = content.replace('<|tool_calls_section_end|>', '') + content = content.replace('<|tool_call_begin|>', '') + content = content.replace('<|tool_call_end|>', '') + content = content.replace('<|tool_call_argument_begin|>', '') + content = content.replace('<|tool_call_argument_end|>', '') + + # 清理多余空行 + content = re.sub(r'\n{3,}', '\n\n', content).strip() + return content, None except Exception as e: