Flask多会话聊天机器人会话数据存储失败问题求助
Flask聊天机器人会话存储失效问题排查与解决
问题描述
使用Flask开发聊天机器人,chat()函数的GET/POST方法均正常,可在MongoDB中存储和检索数据,但chat_session()的POST方法无法将用户输入、机器人响应与对应session_id关联存储,导致会话功能失效,该问题已持续一周。
数据库集合定义
chat_messages_collection = db.chat_messages (存储chat()会话的chat_history数组) active_chat_sessions_collection = db.active_chat_sessions (存储活跃聊天会话) chat_sessions_collection = db.chat_sessions (存储活跃聊天会话及其session_history数组) chat_history_collection=db.chat_history (存储chat()会话的用户输入与机器人响应,用于历史展示) session_history_collection=db.session_history (存储各会话的用户输入与机器人响应,用于会话历史展示) session_messages_collection = db.session_messages (存储各会话的session_history数组)
完整代码
# Function to retrieve conversation history def get_chat_history(): return list(chat_history_collection.find()) @app.route('/chat', methods=['GET', 'POST']) def chat(): if request.method == 'GET': chat_history = get_chat_history() return render_template('chatbot.html', chat_history=chat_history) elif request.method == 'POST': user_input = request.json['user_input'] chat_history_collection.insert_one({'sender': 'user', 'message': user_input}) response = rag_chain.invoke(user_input) bot_response = response.split('answer: ')[1].strip() chat_history_collection.insert_one({'sender': 'bot', 'message': bot_response}) # Retrieve the last document if any exists last_chat_document = chat_messages_collection.find_one(sort=[('_id', -1)]) # Check if a document exists and extract the existing chat history if last_chat_document: chat_history = last_chat_document.get('chat_history', []) else: chat_history = [] # Append the current user input and bot response to the chat history chat_history.append({'user_input': user_input, 'bot_response': bot_response}) # Update the chat history in the database if last_chat_document: chat_messages_collection.update_one({'_id': last_chat_document['_id']}, {'$set': {'chat_history': chat_history}}) else: chat_messages_collection.insert_one({'chat_history': chat_history}) # Format the chat history formatted_chat_history = [] for entry in chat_history: formatted_entry = { 'user_input': entry['user_input'], 'bot_response': entry['bot_response'] } formatted_chat_history.append(formatted_entry) return response @app.route('/start_new_chat_session', methods=['POST']) def start_new_chat_session(): # Generate a session ID session_id = random.randint(1000, 9999) # Store the session ID in the active chat sessions collection active_chat_sessions_collection.insert_one({'session_id': session_id}) # Store an empty chat history for the session chat_sessions_collection.insert_one({'session_id': session_id, 'session_history': []}) # Return the session ID to the client return jsonify({'success': True, 'sessionId': session_id}) @app.route('/get_chat_sessions', methods=['GET']) def get_chat_sessions(): # Retrieve existing chat sessions from the active chat sessions collection sessions = list(active_chat_sessions_collection.find({}, {'_id': 0, 'session_id': 1})) session_ids = [session['session_id'] for session in sessions] # Return the list of session IDs to the client return jsonify({'success': True, 'sessions': session_ids}) @app.route('/chat/<int:session_id>', methods=['GET', 'POST']) def chat_session(session_id): if request.method == 'GET': # Retrieve chat history for the specified session ID session_history = get_session_history(session_id) return render_template('chat.html', session_history=session_history, session_id=session_id) elif request.method == 'POST': user_input = request.json['user_input'] session_messages_collection.insert_one({'session_id': session_id, 'sender': 'user', 'message': user_input}) response = rag_chain.invoke(user_input) bot_response = response.split('answer: ')[1].strip() session_messages_collection.insert_one({'session_id': session_id, 'sender': 'bot', 'message': bot_response}) # Update session history update_session_history(session_id, user_input, bot_response) return jsonify({'response': bot_response, 'success': True, 'session_id': session_id}) def get_session_history(session_id): # Retrieve chat history for the specified session ID from the session_history collection session_history = session_history_collection.find_one({'session_id': session_id}) return session_history.get('session_history', []) if session_history else [] def update_session_history(session_id, user_input, bot_response): # Retrieve session history for the specified session ID from the session_history collection session_history = session_history_collection.find_one({'session_id': session_id}) session_history = session_history.get('session_history', []) if session_history else [] session_history.append({'user_input': user_input, 'bot_response': bot_response}) # Update or insert session history in the session_history collection session_history_collection.update_one({'session_id': session_id}, {'$set': {'session_history': session_history}}, upsert=True) @app.route('/delete_chat_session/<session_id>', methods=['DELETE']) def delete_chat_session(session_id): try: # Delete the chat session with the given session_id # Perform necessary database operations here active_chat_sessions_collection.delete_one({'session_id': int(session_id)}) chat_sessions_collection.delete_one({'session_id': int(session_id)}) return jsonify({'success': True}), 200 except Exception as e: return jsonify({'error': str(e)}), 500
调试发现的现象
- 会话可正常发起,但数据未存入目标集合,反而被存入
chat_messages(chat_session()应使用session_messages和session_history) session_id仅在GET渲染页面时传递,POST请求未携带- 核心功能逻辑无报错,但无法关联
session_id存储输入输出 - 数据库中无会话相关数据
解决方案
1. 修正前端请求路径
这是核心问题:确保会话页面的POST请求发送到/chat/<session_id>接口,而非通用的/chat接口。例如前端使用axios时,应编写:
axios.post(`/chat/${sessionId}`, { user_input: userInput }) .then(response => { /* 处理响应 */ })
2. 验证session_id传递一致性
确认前端在会话全程(GET渲染、POST发送消息)均正确携带session_id,可在浏览器开发者工具的网络面板中检查POST请求的URL是否包含正确的session_id。
3. 添加调试日志定位问题
在chat_session的POST方法和update_session_history函数中添加日志,确认参数传递和数据库操作结果:
from flask import current_app @app.route('/chat/<int:session_id>', methods=['GET', 'POST']) def chat_session(session_id): if request.method == 'POST': current_app.logger.info(f"Received POST request for session {session_id}") # 原有代码... current_app.logger.info(f"Inserted message to session_messages for session {session_id}") def update_session_history(session_id, user_input, bot_response): current_app.logger.info(f"Updating session {session_id} history with input: {user_input}") session_history = session_history_collection.find_one({'session_id': session_id}) current_app.logger.info(f"Found existing session history: {session_history}") # 原有代码... result = session_history_collection.update_one({'session_id': session_id}, {'$set': {'session_history': session_history}}, upsert=True) current_app.logger.info(f"Update result - matched: {result.matched_count}, modified: {result.modified_count}, upserted: {result.upserted_id}")
4. 统一会话初始化逻辑
在start_new_chat_session中初始化session_history_collection的空记录,避免upsert第一次执行的潜在异常:
@app.route('/start_new_chat_session', methods=['POST']) def start_new_chat_session(): session_id = random.randint(1000, 9999) active_chat_sessions_collection.insert_one({'session_id': session_id}) chat_sessions_collection.insert_one({'session_id': session_id, 'session_history': []}) # 新增初始化session_history session_history_collection.insert_one({'session_id': session_id, 'session_history': []}) return jsonify({'success': True, 'sessionId': session_id})
5. 优化数据库索引
为会话相关集合的session_id字段创建索引,提升查询和更新效率:
# 在应用初始化时执行(例如与集合定义同位置) session_history_collection.create_index('session_id', unique=True) session_messages_collection.create_index('session_id')
内容的提问来源于stack exchange,提问作者Amar Dib
相关产品推荐
相关产品推荐

