同会话下聊天机器人无法检索历史数据的技术求助
问题:医疗聊天机器人同会话无法检索历史数据
自研基于OpenAI的医疗聊天机器人,同会话内无法正确检索历史数据。比如告知机器人姓名后,后续询问姓名时机器人无法识别。以下是相关代码和测试记录:
后端Flask代码
@app.route("/chat", methods=["POST"]) def chat(): try: user_input = request.json.get("message", "") session_id = request.json.get("session_id", str(uuid.uuid4())) # Generate a new session ID if not provided user_name = request.json.get("name", "User") # Extract user name if provided # Store or update the user's name in the conversation model conversation = Conversation.query.filter_by(session_id=session_id).first() if conversation: conversation.user_name = user_name conversation.user_message = user_input else: conversation = Conversation(session_id=session_id, user_name=user_name, user_message=user_input, bot_reply="") db.session.add(conversation) db.session.commit() # Retrieve conversation history conversations = Conversation.query.filter_by(session_id=session_id).all() conversation_history = [c.user_message for c in conversations] # Retrieve user name from session user_name = session.get("name", "User") # Generate response using OpenAI's API with a system message app.logger.info("Generating response with ChatGPT...") try: response = openai.ChatCompletion.create( model="gpt-3.5-turbo", messages=[ {"role": "system", "content": f"You are a medical assistant. Your name is {user_name}. Provide accurate medical information and advice. If you are unsure about a medical issue, advise the user to consult a healthcare professional."}, {"role": "system", "content": "Conversation history: " + ", ".join(conversation_history)}, {"role": "user", "content": user_input} ], max_tokens=300, temperature=0.7 ) bot_reply = response['choices'][0]['message']['content'].strip() app.logger.info(f"ChatGPT reply: {bot_reply}") except Exception as e: app.logger.error(f"Error generating response with ChatGPT: {e}") bot_reply = "Error: Unable to generate response." # Update and store the conversation in the database app.logger.info("Updating conversation in database...") conversation.bot_reply = bot_reply db.session.commit() app.logger.info("Conversation updated successfully.") return jsonify({"response": bot_reply, "session_id": session_id, "name": user_name}) except Exception as e: app.logger.error(f"Error processing request: {e}") return jsonify({"response": "Sorry, there was an error processing your request."})
测试对话
我:你好,我叫Osama
机器人:你好,Osama!今天我能为你提供哪些医疗相关的帮助?
我:我叫什么名字?
机器人:抱歉,我无法访问你的个人信息比如姓名。今天我能为你提供什么帮助?
我:你好,我叫osamah
机器人:你好,Osamah!今天我能为你提供什么帮助?
我:我叫什么名字?
机器人:抱歉,我无法访问该信息。今天我能为你提供什么帮助?
前端React app.js代码
function App() { const [chatHistory, setChatHistory] = useState([]); const [message, setMessage] = useState(''); const [loading, setLoading] = useState(false); const [sessionId, setSessionId] = useState(''); const [userName, setUserName] = useState(''); // Initialize a new session ID when the component mounts useEffect(() => { const initSession = async () => { try { const response = await axios.post('http://localhost:5000/chat', { message: '' }); setSessionId(response.data.session_id); console.log('Session initialized:', response.data); } catch (error) { console.error('Error initializing session:', error); } }; initSession(); }, []); const handleSendMessage = async () => { if (message.trim() === '' || !sessionId) return; setChatHistory([...chatHistory, { role: 'user', content: message }]); try { setLoading(true); const response = await axios.post('http://localhost:5000/chat', { message: message, session_id: sessionId, name: userName }); console.log('Response from server:', response.data); setChatHistory(prev => [ ...prev, { role: 'assistant', content: response.data.response } ]); } catch (error) { console.error('Error fetching data:', error); setChatHistory(prev => [ ...prev, { role: 'assistant', content: 'Error: Unable to get a response.' } ]); } finally { setLoading(false); setMessage(''); } }; const handleUserNameChange = (event) => { setUserName(event.target.value); };
问题排查与修复方案
核心问题分析
- 姓名变量被错误覆盖:后端存储用户姓名到数据库后,又用
session.get("name", "User")覆盖了user_name变量。这里的session是Flask服务器端会话,和前端传入的会话ID不是同一概念,导致传给OpenAI的始终是默认值"User"。 - 历史记录格式错误:用逗号拼接消息的方式无法让OpenAI模型正确理解对话上下文,且只传递了用户消息,缺少机器人的回复记录。
- 会话记录被覆盖:更新会话时直接替换了
user_message字段,导致数据库中仅保留最后一条用户消息,无法存储完整对话历史。
修复步骤
1. 修正姓名传递逻辑
删除user_name = session.get("name", "User")这一行,直接使用从前端传入并存储到数据库的user_name值。
2. 修复会话历史存储与传递
- 修改数据库操作,每次新增一条会话记录而非覆盖:
# 移除原有的单条记录更新逻辑,改为每次新增 conversation = Conversation(session_id=session_id, user_name=user_name, user_message=user_input, bot_reply="") db.session.add(conversation) db.session.commit()
- 调整历史记录格式,按照OpenAI要求的角色结构传递完整对话:
# 构建符合OpenAI要求的对话历史 conversations = Conversation.query.filter_by(session_id=session_id).all() conversation_history = [] for c in conversations: conversation_history.append({"role": "user", "content": c.user_message}) if c.bot_reply: conversation_history.append({"role": "assistant", "content": c.bot_reply})
- 更新OpenAI请求的消息结构:
response = openai.ChatCompletion.create( model="gpt-3.5-turbo", messages=[ {"role": "system", "content": f"You are a medical assistant. Remember the user's name is {user_name}. Provide accurate medical information and advice. If unsure, advise consulting a healthcare professional."}, *conversation_history, # 展开完整对话历史 {"role": "user", "content": user_input} ], max_tokens=300, temperature=0.7 )
3. 前端补充姓名输入绑定
在JSX中添加姓名输入框,确保用户输入的姓名能正确绑定到userName状态:
<input type="text" value={userName} onChange={handleUserNameChange} placeholder="请输入你的姓名" />
验证效果
修复后,后端会存储完整的对话历史(包括用户消息和机器人回复),并正确传递给OpenAI模型。用户告知姓名后,后续询问姓名时,模型能从历史上下文提取并回复正确姓名。
内容的提问来源于stack exchange,提问作者osamah alini
相关产品推荐
相关产品推荐

