diff --git a/main_v2.py b/main_v2.py index b42ee53..4c8c092 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对话系统 v3.0", version="3.0.6") +app = FastAPI(title="AI对话系统 v2.0", version="2.0.0") # 静态文件和模板 BASE_DIR = os.path.dirname(os.path.abspath(__file__)) diff --git a/services/llm_service.py b/services/llm_service.py index 2c8286c..f5de31b 100644 --- a/services/llm_service.py +++ b/services/llm_service.py @@ -519,9 +519,6 @@ class LLMService: """ 第二阶段调用:使用包含工具调用和结果的完整消息历史 - 注意:SiliconFlow 等平台不支持标准 tool 消息类型, - 需要将工具结果转换为普通用户消息格式。 - Args: messages: 已包含assistant tool_calls和tool结果的完整消息历史 provider_config: LLM Provider配置 @@ -536,43 +533,8 @@ class LLMService: max_tokens = provider_config.get('max_tokens', 4096) temperature = agent_config.get('temperature_override') or provider_config.get('temperature', 0.7) - # 转换消息格式:将 tool 相关消息转为普通消息格式 - # 因为很多 API 平台(如 SiliconFlow)不支持 tool 消息类型 - converted_messages = [] - tool_results_content = [] - - for msg in messages: - role = msg.get('role') - - if role == 'system': - converted_messages.append(msg) - elif role == 'user': - converted_messages.append(msg) - elif role == 'assistant': - # 如果有 tool_calls,跳过这个消息(不发送给不支持的平台) - if msg.get('tool_calls'): - # 记录工具调用信息(可选) - pass - else: - converted_messages.append(msg) - elif role == 'tool': - # 收集工具结果,后面合并成一个用户消息 - tool_results_content.append(msg.get('content', '')) - - # 如果有工具结果,添加为一个特殊的用户消息 - if tool_results_content: - combined_results = "\n\n".join([ - f"【搜索结果 {i+1}】\n{result}" - for i, result in enumerate(tool_results_content) - ]) - - # 添加工具结果作为用户消息 - converted_messages.append({ - "role": "user", - "content": f"以下是搜索工具返回的结果:\n\n{combined_results}\n\n请根据以上搜索结果回答我之前的问题,不要再说\"让我搜索一下\",直接给出回答。如果搜索结果不足以回答,请说明。" - }) - - final_messages = converted_messages + # 消息历史已经包含了assistant的tool_calls和tool结果,直接使用 + final_messages = messages.copy() # 调用LLM生成最终回复 url = f"{api_base.rstrip('/')}/chat/completions" @@ -588,16 +550,6 @@ class LLMService: } logger.info(f"工具结果返回LLM: url={url}, model={model}, 消息数={len(final_messages)}") - # 打印消息内容(调试) - for i, msg in enumerate(final_messages): - role = msg.get('role') - content_preview = str(msg.get('content', ''))[:100] if msg.get('content') else 'None' - if role == 'tool': - logger.info(f"消息[{i}] role={role}, tool_call_id={msg.get('tool_call_id')}, content长度={len(msg.get('content',''))}") - elif role == 'assistant' and msg.get('tool_calls'): - logger.info(f"消息[{i}] role={role}, tool_calls={len(msg['tool_calls'])}") - else: - logger.info(f"消息[{i}] role={role}, content={content_preview}...") try: async with httpx.AsyncClient(timeout=60.0) as client: @@ -610,27 +562,6 @@ 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: