From db53afbabc509d342c39d946642b66ecafa98df3 Mon Sep 17 00:00:00 2001 From: webjoin111 <455457521@qq.com> Date: Sat, 20 Sep 2025 18:13:51 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat(llm):=20=E4=B8=BA=20OpenAI=20?= =?UTF-8?q?=E5=85=BC=E5=AE=B9=E8=AF=B7=E6=B1=82=E4=BD=93=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E6=97=A5=E5=BF=97=E5=87=80=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- zhenxun/services/llm/service.py | 6 +++++- zhenxun/utils/log_sanitizer.py | 26 ++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/zhenxun/services/llm/service.py b/zhenxun/services/llm/service.py index 1b2bd6b1..4708020c 100644 --- a/zhenxun/services/llm/service.py +++ b/zhenxun/services/llm/service.py @@ -187,8 +187,12 @@ class LLMModel(LLMModelBase): logger.debug(f"🔑 API密钥: {masked_key}") logger.debug(f"📋 请求头: {dict(request_data.headers)}") + sanitizer_req_context_map = {"gemini": "gemini_request"} + sanitizer_req_context = sanitizer_req_context_map.get( + self.api_type, "openai_request" + ) sanitized_body = sanitize_for_logging( - request_data.body, context="gemini_request" + request_data.body, context=sanitizer_req_context ) request_body_str = json.dumps(sanitized_body, ensure_ascii=False, indent=2) logger.debug(f"📦 请求体: {request_body_str}") diff --git a/zhenxun/utils/log_sanitizer.py b/zhenxun/utils/log_sanitizer.py index cfafc468..b792aaf3 100644 --- a/zhenxun/utils/log_sanitizer.py +++ b/zhenxun/utils/log_sanitizer.py @@ -50,6 +50,29 @@ def _sanitize_openai_response(response_json: dict) -> dict: return response_json +def _sanitize_openai_request(body: dict) -> dict: + """净化OpenAI兼容API的请求体,主要截断图片base64。""" + try: + sanitized_json = copy.deepcopy(body) + if "messages" in sanitized_json and isinstance( + sanitized_json["messages"], list + ): + for message in sanitized_json["messages"]: + if "content" in message and isinstance(message["content"], list): + for i, part in enumerate(message["content"]): + if part.get("type") == "image_url": + if "image_url" in part and isinstance( + part["image_url"], dict + ): + url = part["image_url"].get("url", "") + message["content"][i]["image_url"]["url"] = ( + _truncate_base64_string(url) + ) + return sanitized_json + except Exception: + return body + + def _sanitize_gemini_response(response_json: dict) -> dict: """净化Gemini API的响应体,处理文本和图片生成两种格式。""" try: @@ -147,6 +170,9 @@ def sanitize_for_logging(data: Any, context: str | None = None) -> Any: elif context == "gemini_request": if isinstance(data, dict): return _sanitize_gemini_request(data) + elif context == "openai_request": + if isinstance(data, dict): + return _sanitize_openai_request(data) else: if isinstance(data, str): return _truncate_base64_string(data)