Browse Source

feat:记录原始响应

zhangwl 15 hours ago
parent
commit
5cd8c543c3
2 changed files with 96 additions and 1 deletions
  1. 52 0
      app/db/mongo.py
  2. 44 1
      app/routers/chat.py

+ 52 - 0
app/db/mongo.py

@@ -0,0 +1,52 @@
+from pymongo import MongoClient
+from datetime import datetime
+
+MONGO_URI = (
+    "mongodb://dds-2zedd8d70bde6e541.mongodb.rds.aliyuncs.com:3717,"
+    "dds-2zedd8d70bde6e542.mongodb.rds.aliyuncs.com:3717"
+)
+
+client = MongoClient(MONGO_URI, serverSelectionTimeoutMS=5000)
+db = client["arklogs"]
+chat_logs = db["chat_logs"]
+
+# 带下划线的表示私有方法(Private)
+def _ensure_index():
+    try:
+        chat_logs.create_index([("username", 1), ("asked_at", -1)])
+    except Exception:
+        pass
+
+
+def save_chat_log(
+    username: str,
+    question: str,
+    stream_mode: bool,
+    raw_response: str = None,
+    status: str = "success",
+    error: str = None,
+):
+    """
+    保存聊天原始响应日志到 MongoDB
+
+    Args:
+        username: 提问人
+        question: 提问的问题
+        stream_mode: 回答方式(流式或非流式)
+        raw_response: API 原始响应的 repr 字符串
+        status: 响应状态 success | error
+        error: 异常时的错误信息
+    """
+    try:
+        _ensure_index()
+        chat_logs.insert_one({
+            "username": username,
+            "question": question,
+            "stream_mode": stream_mode,
+            "raw_response": raw_response,
+            "status": status,
+            "error": error,
+            "asked_at": datetime.now(),
+        })
+    except Exception as e:
+        print(f"MongoDB 日志写入失败: {e}")

+ 44 - 1
app/routers/chat.py

@@ -8,6 +8,7 @@ import json
 import asyncio
 from ..config.config import Config
 from ..routers.users import get_current_active_user, User
+from ..db.mongo import save_chat_log
 
 # =====================================================
 # 全局变量和配置
@@ -251,10 +252,18 @@ async def generate_stream_response(request: ChatRequest, username: str):
                     # 异步让出控制权,避免阻塞事件循环
                     await asyncio.sleep(0.01)
 
-            # 处理响应完成事件,获取response_id
+            # 处理响应完成事件,获取response_id并记录原始响应日志
             elif event_type == 'response.completed':
                 if 'response' in chunk_dict and hasattr(chunk_dict['response'], 'id'):
                     response_id = chunk_dict['response'].id
+                # 记录原始响应日志
+                save_chat_log(
+                    username=username,
+                    question=latest_user_msg.content,
+                    stream_mode=True,
+                    raw_response=repr(chunk_dict.get('response')),
+                    status="success",
+                )
 
         # 流式响应结束后的处理
         if accumulated_content:
@@ -292,6 +301,15 @@ async def generate_stream_response(request: ChatRequest, username: str):
             "timestamp": datetime.now().isoformat()  # 错误发生时间
         }
 
+        # 记录错误日志到 MongoDB
+        save_chat_log(
+            username=username,
+            question=latest_user_msg.content if latest_user_msg else "",
+            stream_mode=True,
+            status="error",
+            error=str(e),
+        )
+
         # 发送错误信息
         yield f"data: {json.dumps(error_response)}\n\n"
 
@@ -407,6 +425,15 @@ async def chat(
                 previous_response_id=previous_response_id,
             )
 
+            # 记录原始响应日志到 MongoDB(解析前)
+            save_chat_log(
+                username=username,
+                question=latest_user_msg.content,
+                stream_mode=False,
+                raw_response=repr(response),
+                status="success",
+            )
+
             # 检查API响应是否有效
             if response.output and len(response.output) > 0:
                 # 从output中提取文本内容
@@ -444,6 +471,15 @@ async def chat(
                     # 将AI回复添加到用户的聊天历史
                     chatHistory[username].append(assistant_message)
 
+                    # 保存聊天日志到 MongoDB
+                    save_chat_log(
+                        username=username,
+                        question=latest_user_msg.content,
+                        answer=message_content,
+                        stream_mode=False,
+                        response_id=response.id,
+                    )
+
                     # 构建完整的响应对象
                     chat_response = ChatResponse(
                         message=assistant_message,  # AI回复消息
@@ -472,6 +508,13 @@ async def chat(
     except Exception as e:
         # 捕获所有其他异常并转换为HTTP异常
         error_message = f"处理聊天请求时发生错误: {str(e)}"
+        save_chat_log(
+            username=current_user.username,
+            question=request.messages[-1].content if request.messages else "",
+            stream_mode=request.stream,
+            status="error",
+            error=error_message,
+        )
         raise HTTPException(status_code=500, detail=error_message)