You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 00:45:55