Qwen2.5-1.5B实战教程:添加对话评分反馈机制与用户满意度数据收集
Qwen2.5-1.5B实战教程添加对话评分反馈机制与用户满意度数据收集1. 引言为什么需要对话评分想象一下你正在使用一个本地部署的AI助手它回答了你关于Python编程的问题。你觉得这个回答怎么样是准确、有用还是有点跑题作为开发者我们通常只能看到用户问了什么AI答了什么但很难知道用户对每次对话的真实感受。这就是我们今天要解决的问题。一个只会回答问题的AI助手就像一个只会讲课但从不看学生反应的老师。它不知道自己的回答是否让人满意也不知道哪里需要改进。为了让我们的Qwen2.5-1.5B本地对话助手变得更“聪明”、更“贴心”我们需要给它加上“耳朵”和“大脑”——也就是对话评分反馈机制和用户满意度数据收集功能。通过本教程你将学会如何在现有的Streamlit聊天界面中为每一条AI回复添加一个简单的评分按钮。将用户的评分比如“有用”或“没用”以及对应的对话内容安全地保存到本地的文件中。初步了解如何利用这些收集到的数据来观察和评估模型的对话表现。整个过程完全在本地运行不涉及任何云端数据上传继续守护你的隐私安全。让我们开始吧给你的AI助手装上“反馈收集器”。2. 项目回顾与改造思路在开始动手之前我们先快速回顾一下现有项目的核心结构并理清我们要做什么。2.1 现有项目核心逻辑我们的项目基于Streamlit构建核心流程非常简单初始化启动时从本地路径加载Qwen2.5-1.5B-Instruct模型和分词器并缓存起来。对话处理用户在前端输入问题Streamlit将问题添加到对话历史列表。模型推理使用模型的apply_chat_template方法格式化历史对话然后让模型生成回复。展示结果将AI的回复展示在聊天界面上并更新对话历史。所有的状态主要是对话历史列表都保存在Streamlit的会话状态st.session_state中。侧边栏的“清空对话”按钮其作用就是重置这个列表并清理显存。2.2 新增功能设计思路我们要新增两个核心功能评分和数据收集。评分按钮集成我们需要在每一条AI回复的旁边增加一个让用户操作的入口。Streamlit的st.button组件很适合这个场景。我们可以为每条消息创建一个独特的按钮。反馈数据存储当用户点击评分按钮时我们需要捕获这个事件。捕获的信息至少应包括被评分的对话内容用户问题和AI回答以及评分结果正/负。这些数据需要被持久化保存最简单的办法就是追加写入到一个本地文本文件如.jsonl格式或CSV文件中。状态管理要避免用户对同一条消息重复评分。我们可以通过记录每条消息是否已被评分过来实现。听起来有点复杂别担心我们会一步步拆解用最直观的代码来实现它。3. 分步实战为聊天界面添加评分功能现在我们开始动手修改代码。请打开你原有的app.py或类似的主程序文件。3.1 第一步导入必要库和初始化数据结构首先确保导入了处理数据可能需要的库并在会话状态中初始化存储评分信息的数据结构。import streamlit as st from transformers import AutoModelForCausalLM, AutoTokenizer import torch import json # 新增用于保存数据 from datetime import datetime # 新增用于记录时间 import os # 新增用于检查文件路径 # ... 原有的模型加载代码保持不变 ... # MODEL_PATH /root/qwen1.5b # model, tokenizer load_model() ... # 初始化会话状态 if messages not in st.session_state: st.session_state.messages [] # 存储对话历史 # 新增初始化一个字典来记录每条AI消息的评分状态 # 键为消息的索引或唯一ID值为评分结果如“positive”, “negative”, None if feedback not in st.session_state: st.session_state.feedback {} # 新增定义反馈数据保存的路径 FEEDBACK_FILE ./chat_feedback.jsonl3.2 第二步修改消息显示逻辑添加评分按钮这是核心改动部分。我们需要在渲染每一条消息特别是AI的消息时在其内容后面添加评分按钮。找到你代码中遍历st.session_state.messages并显示消息的部分通常在一个for循环中。我们将其改造如下# 显示历史聊天消息 for idx, message in enumerate(st.session_state.messages): with st.chat_message(message[role]): st.markdown(message[content]) # 新增只为AI的回复添加评分按钮 if message[role] assistant: # 创建左右排列的列来放置按钮 col1, col2 st.columns([0.85, 0.15]) with col1: # 这里可以留空或者放一些占位内容确保消息内容在左 pass with col2: # 生成该条消息的唯一键这里使用消息索引 msg_key fmsg_{idx} # 检查这条消息是否已经被评分过 current_feedback st.session_state.feedback.get(msg_key) if current_feedback is None: # 如果未评分显示“有用”和“无用”按钮 col_yes, col_no st.columns(2) with col_yes: # 点击“有用”按钮的回调函数 if st.button(, keyfyes_{idx}): # 执行评分操作 handle_feedback(idx, positive, message[content]) with col_no: if st.button(, keyfno_{idx}): handle_feedback(idx, negative, message[content]) else: # 如果已评分显示评分结果 feedback_text ✅ 已评有用 if current_feedback positive else ❌ 已评无用 st.markdown(f{feedback_text})3.3 第三步实现评分处理与数据保存函数上面代码中调用了handle_feedback函数。现在我们来实现它这个函数负责更新状态和保存数据。def save_feedback_to_file(feedback_data): 将单条反馈数据追加保存到文件 try: # 确保目录存在 os.makedirs(os.path.dirname(os.path.abspath(FEEDBACK_FILE)), exist_okTrue) with open(FEEDBACK_FILE, a, encodingutf-8) as f: json_line json.dumps(feedback_data, ensure_asciiFalse) f.write(json_line \n) # 可选在界面上给出一个短暂的成功提示使用st.toast需要Streamlit1.28 # st.toast(感谢您的反馈, icon✅) except Exception as e: st.error(f保存反馈数据时出错: {e}) def handle_feedback(message_index, feedback_type, assistant_content): 处理用户评分。 message_index: AI消息在session_state.messages中的索引。 feedback_type: ‘positive‘ 或 ‘negative‘。 assistant_content: AI的回复内容。 # 1. 更新会话状态中的评分记录 msg_key fmsg_{message_index} st.session_state.feedback[msg_key] feedback_type # 2. 获取对应的用户问题上一条消息 user_query if message_index 0: # 假设AI回复的前一条消息总是用户提问 user_query st.session_state.messages[message_index - 1].get(content, ) # 3. 准备要保存的数据 feedback_record { timestamp: datetime.now().isoformat(), # 记录时间戳 user_query: user_query, assistant_response: assistant_content, feedback: feedback_type, model: Qwen2.5-1.5B-Instruct # 记录模型信息 } # 4. 保存到文件 save_feedback_to_file(feedback_record) # 5. 重要由于Streamlit的交互特性需要立即重新运行脚本以更新按钮状态 st.rerun()3.4 第四步整合与测试将上述所有代码片段整合到你的原有项目中。确保模型加载、对话生成的主逻辑保持不变我们只是在消息显示环节进行了增强。现在运行你的Streamlit应用streamlit run app.py打开浏览器与AI进行几次对话。你应该能在每条AI回复的右下角看到“”和“”按钮。尝试点击它们点击后按钮应该会消失并显示“✅ 已评有用”或“❌ 已评无用”。同时在你的项目根目录下会生成一个名为chat_feedback.jsonl的文件。用文本编辑器打开它你会看到类似以下的记录{timestamp: 2024-01-01T12:00:00.123456, user_query: Python中列表和元组有什么区别, assistant_response: 列表和元组都是Python中的序列类型..., feedback: positive, model: Qwen2.5-1.5B-Instruct}恭喜你的AI助手现在已经具备了收集用户反馈的能力。4. 从数据收集到简单分析收集数据只是第一步让数据产生价值才是目的。虽然深入的模型微调需要更复杂的流程但我们可以先做一些简单的分析来直观感受模型的优缺点。4.1 查看收集到的数据你可以定期打开chat_feedback.jsonl文件查看。.jsonl格式意味着每一行都是一个独立的JSON对象非常适合追加写入和逐行读取。4.2 编写一个简单的数据分析脚本创建一个新的Python脚本比如analyze_feedback.py来快速统计反馈情况。import json from collections import Counter import pandas as pd FEEDBACK_FILE ./chat_feedback.jsonl def load_feedback_data(): 加载反馈数据文件 records [] try: with open(FEEDBACK_FILE, ‘r‘, encoding‘utf-8‘) as f: for line in f: if line.strip(): records.append(json.loads(line.strip())) except FileNotFoundError: print(f反馈文件 {FEEDBACK_FILE} 不存在。) return records def basic_analysis(records): 执行基础分析 if not records: print(暂无反馈数据。) return df pd.DataFrame(records) print(f总反馈数量: {len(df)}) print(\n--- 反馈分布 ---) feedback_counts df[‘feedback‘].value_counts() print(feedback_counts) # 计算好评率 if ‘positive‘ in feedback_counts: positive_rate feedback_counts[‘positive‘] / len(df) * 100 print(f\n用户好评率: {positive_rate:.2f}%) print(\n--- 最近5条反馈 ---) # 按时间戳排序假设时间戳字段是‘timestamp‘ if ‘timestamp‘ in df.columns: df[‘timestamp‘] pd.to_datetime(df[‘timestamp‘]) df_sorted df.sort_values(by‘timestamp‘, ascendingFalse) print(df_sorted[[‘timestamp‘, ‘feedback‘, ‘user_query‘]].head().to_string()) else: print(df[[‘feedback‘, ‘user_query‘]].head().to_string()) if __name__ __main__: data load_feedback_data() basic_analysis(data)运行这个脚本你就能看到类似这样的输出总反馈数量: 23 --- 反馈分布 --- positive 18 negative 5 Name: feedback, dtype: int64 用户好评率: 78.26% --- 最近5条反馈 --- ...4.3 从数据中获取洞察通过简单的分析你可以开始回答一些有用的问题模型整体表现如何好评率是一个宏观指标。哪些问题容易得到差评手动查看feedback为negative的记录分析用户的问题和AI的回答。是事实错误、答非所问还是语言组织有问题高频问题领域是什么可以对user_query进行简单的关键词提取这需要更复杂的NLP处理但人工浏览也能发现端倪。这些洞察非常宝贵。例如如果你发现模型在回答“代码调试”类问题上差评较多而在“文案创作”上好评如潮那么你就能更清楚地了解这个1.5B模型的优势场景和局限性。5. 总结与进阶思考5.1 本教程回顾在本教程中我们成功地为本地部署的Qwen2.5-1.5B对话助手增加了用户反馈系统前端集成在Streamlit聊天界面中为每条AI回复添加了“有用/无用”评分按钮。状态管理利用st.session_state防止用户对同一消息重复评分。数据持久化将评分数据包含对话上下文和时间戳以JSON Lines格式安全地保存到本地文件。初步分析提供了一个简单的Python脚本示例用于统计和查看反馈数据。整个流程完全在本地完成没有数据泄露风险并且对原有轻量、易用的项目架构改动最小。5.2 可能的进阶优化方向当前的实现是一个起点你可以根据需求进一步扩展更细致的评分将二元的“有用/无用”改为五星评分或者增加“准确性”、“相关性”、“流畅度”等多个维度的评分。反馈归因让用户不仅能评分还能通过文本框简要说明原因例如“答案不准确”或“解释得很清楚”。数据可视化在Streamlit应用内增加一个“反馈仪表盘”页面用图表实时展示好评率趋势、常见问题类型等。模型迭代的燃料收集到的“差评”数据尤其是用户指出了具体错误的对话对query-response是极其珍贵的。未来如果你需要对模型进行指令微调Instruction Tuning或基于人类反馈的强化学习RLHF这些高质量的反面教材就是训练数据的重要来源。为AI对话添加反馈机制就像是打开了与用户沟通的另一扇窗。它让你从“猜测”模型表现变为“看见”模型表现。希望这个教程能帮助你更好地理解和优化你的本地AI助手让它越用越聪明。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。