山东大学软件学院创新实训——个人博客(七)拒绝“千人一面”:画风建模系统联调与验证
拒绝“千人一面”:画风建模系统联调与验证
本周的核心任务是完成画风建模系统的联调与验证。这一系统是我们项目的重要创新点:通过分析玩家多局绘画行为数据,调用大模型生成个性化的“画风档案”,并将其注入AI识别环节,让AI能够“认识”每位玩家的绘画风格,从而提升猜词准确率。
端到端测试
画风建模系统的工作流程分为特征聚合、档案生成和AI识别注入三个层次,链路已打通。
特征聚合(aggregate_features)
utils/style_profiler.py中的核心函数将多局原始行为数据聚合成稳定的画风指标。通过对同一玩家多局数据的求平均,平滑单局波动,提取长期习惯。
def aggregate_features(behaviors):
"""把多局原始 behavior 数据聚合成画风指标"""
speed_avg = safe_avg('stroke_speed_avg')
coverage = safe_avg('canvas_coverage')
symmetry = safe_avg('symmetry_score')
undo_rate = round(safe_avg('undo_count') + safe_avg('eraser_count'), 2)
# ... 聚合多个维度的数据
return {
'rounds_analyzed': n,
'avg_stroke_speed': speed_avg,
'avg_canvas_coverage': coverage,
'avg_symmetry': symmetry,
'avg_undo_eraser': undo_rate,
'avg_stroke_count': stroke_count,
# ... 更多指标
}
档案生成(generate_profile_text)
利用聚合后的特征,调用DeepSeek-V3.2生成自然语言描述的档案。温度设为0.4,保证输出的稳定性。
def _call_deepseek(features, nickname):
"""调用 DeepSeek-V3.2 生成自然语言档案"""
prompt = _build_profile_prompt(features, nickname)
resp = client.chat.completions.create(
model='deepseek-chat',
messages=[
{'role': 'system', 'content': '你是一个细致的绘画行为分析师...'},
{'role': 'user', 'content': prompt}
],
temperature=0.4,
max_tokens=400,
)
return resp.choices[0].message.content.strip()
生成的档案包含总体定位、关键识别特征和画法偏好推测。
AI识别注入(ai_recognizer.py)
在AI识别的Prompt中注入玩家的画风档案,指导AI结合玩家习惯进行识别。
def _build_prompt(difficulty, category, word_list=None, style_profile=''):
prompt = "你是一个绘画猜词游戏中的AI选手..."
if style_profile:
prompt += (
f"\n\n【该玩家的画风档案(基于历史绘画行为)】\n{style_profile}\n"
"请结合该玩家的画风习惯进行识别,但最终判断仍以画面内容为准。"
)
return prompt
端到端测试记录
| 测试步骤 | 输入数据 | 预期输出 | 实际结果 |
|---|---|---|---|
| 1. 模拟3局绘画行为 | 3条drawing_behaviors记录 | 特征聚合成功 | ✅ 通过 |
| 2. 调用DeepSeek生成档案 | 聚合后的特征字典 | 100-180字自然语言描述 | ✅ 通过 |
| 3. 档案写入数据库 | profile_text + features_json | player_style_profiles表新增记录 | ✅ 通过 |
| 4. AI识别时注入档案 | 玩家ID + 绘画图片 | prompt中包含档案内容 | ✅ 通过 |
| 5. 无档案时的降级处理 | 错误user_id | 使用模板拼接档案 | ✅ 通过 |
实际生成的档案示例:
张三的画风总体呈现「中速运笔、一气呵成(极少修改)、对称偏好」的特征。平均每局画18笔、用时45秒、画面覆盖率约45%。AI识别时可优先关注其惯用构图与笔触节奏,结合当前画面做联想。
3局触发机制验证
为确保数据充足且控制成本,画风档案设置了至少积累3局数据才首次生成的触发门槛。
触发条件设计
- 数据充足性:少于3局的行为数据波动太大,不足以反映稳定的画风特征。
- API成本控制:避免新用户频繁触发DeepSeek调用。
- 用户体验:确保首次看到档案时,系统已有一定的“了解”。
在config.py中配置了触发阈值:
STYLE_PROFILE_MIN_ROUNDS = 3 # 至少积累几局才首次生成档案
STYLE_PROFILE_BEHAVIOR_LIMIT = 10 # 取最近多少局数据做聚合
触发逻辑实现
每回合结束后,后台异步执行档案刷新任务,并检查局数是否达标。
def _refresh_style_profile_async(user_id, room_id):
behaviors = models.get_user_behaviors(user_id, limit=10)
if len(behavior_dicts) < min_rounds:
print(f'[StyleProfiler] 玩家 {user_id} 仅 {len(behavior_dicts)} 局 '
f'(<{min_rounds}),暂不生成档案')
return
# 生成并保存档案
result = style_profiler.build_and_save_profile(...)
触发时机验证测试
| 测试场景 | 当前局数 | 是否应有档案 | 触发结果 |
|---|---|---|---|
| 新玩家第1局结束 | 1局 | ❌ 不生成 | ✅ 符合预期 |
| 新玩家第2局结束 | 2局 | ❌ 不生成 | ✅ 符合预期 |
| 新玩家第3局结束 | 3局 | ✅ 生成 | ✅ 符合预期 |
| 有档案玩家第4局结束 | 4局 | ✅ 更新 | ✅ 符合预期 |
| 有档案玩家第10局结束 | 10局 | ✅ 更新(取最近10局) | ✅ 符合预期 |
日志输出验证了触发机制的准确性。
有无画风档案时AI准确率对比
为量化评估画风档案的效果,设计了对照实验,使用同一批测试图片,在有/无画风档案的情况下调用AI识别。
实验条件
- 测试集:20张标准绘画样本(涵盖object/action/concept三个分类)。
- 有档案组:使用积累了5局以上数据的玩家ID。
- 无档案组:使用新的测试用户ID(无历史档案)。
- 难度:统一设置为medium模式。
测试数据记录
| 绘画主题 | 真实答案 | 无档案-猜测结果 | 无档案-置信度 | 有档案-猜测结果 | 有档案-置信度 |
|---|---|---|---|---|---|
| 猫 | 猫 | 狗 | 0.72 | 猫 | 0.85 |
| 太阳 | 太阳 | 太阳 | 0.88 | 太阳 | 0.91 |
| 房子 | 房子 | 建筑 | 0.65 | 房子 | 0.82 |
| 苹果 | 苹果 | 樱桃 | 0.58 | 苹果 | 0.78 |
| 飞机 | 飞机 | 鸟 | 0.52 | 飞机 | 0.71 |
统计结果
| 指标 | 无画风档案 | 有画风档案 | 提升幅度 |
|---|---|---|---|
| 正确识别数 | 12/20 | 15/20 | +3张 |
| 准确率 | 60.0% | 75.0% | +15% |
| 平均置信度 | 0.68 | 0.79 | +16.2% |
| 模糊答案数 | 5 | 2 | -3次 |
结果分析
实验结果显示,画风档案对AI识别有明显的正向效果。
- 准确率提升15%:画风档案帮助AI更好地理解特定玩家的绘画风格,减少误判。
- 置信度提升16.2%:AI结合画风档案做判断时,对结果的确定性更高。
- 模糊答案减少:有档案后,AI给出的答案更具体精准。
DeepSeek-V3.2调用稳定性测试
画风建模使用DeepSeek的文本模型(deepseek-chat),调用方式与OpenAI兼容。
稳定性测试方案
对DeepSeek-V3.2进行了连续调用和高并发场景测试。
连续调用50次
| 调用批次 | 成功次数 | 失败次数 | 成功率 | 平均响应时间 |
|---|---|---|---|---|
| 50次连续调用 | 49 | 1 | 98.0% | 1.2秒 |
高并发场景(模拟4人房间)
| 并发数 | 总请求 | 成功 | 失败 | 成功率 | P95响应时间 |
|---|---|---|---|---|---|
| 4 | 20次 | 20 | 0 | 100% | 2.1秒 |
错误处理降级
当DeepSeek不可用时,系统会自动降级到模板拼接模式,确保功能可用。
def generate_profile_text(features, nickname='该玩家'):
try:
if provider == 'deepseek' and DEEPSEEK_API_KEY:
return _call_deepseek(features, nickname)
else:
print(f'[StyleProfiler] DeepSeek 未配置,使用模板降级')
return _template_fallback(features, nickname)
except Exception as e:
print(f'[StyleProfiler] LLM 调用失败: {e}')
return _template_fallback(features, nickname)
API成本估算
| 指标 | 数值 |
|---|---|
| 每条档案Prompt长度 | 约500字符 |
| 每条档案生成长度 | 约150字符 |
| 单次Token消耗 | 约650 tokens |
| DeepSeek价格 | 约¥0.001/千tokens |
| 单次调用成本 | 约¥0.00065 |
| 1000个活跃用户/月 | 约¥6.5 |
遇到的问题与解决
问题1:画风档案更新过于频繁
- 现象:每回合结束都会触发更新,API调用量较大。
- 解决方案:增加了
STYLE_PROFILE_BEHAVIOR_LIMIT = 10配置,只取最近10局数据做聚合。后续可考虑加入“每N局更新一次”的节流机制。
问题2:跨房间数据隔离
- 现象:玩家在多个房间的画风数据是否应该合并。
- 解决方案:保持当前设计,画风是玩家的个人特征,跨房间合并是合理的。
问题3:首个档案生成延迟
- 现象:第3局结束后生成档案,可能导致第3局AI识别无档案可用。
- 解决方案:使用
start_background_task异步执行,不阻塞主流程。档案是“给下一局用的”,时序合理。
下周计划
- 画风档案可视化:设计前端展示页面,让用户能直观看到自己的画风特征。
- 档案版本历史:利用数据库中保存的历史版本,展示玩家画风的演变趋势。
- AI识别模块的最终优化:结合画风档案的测试结果,调整prompt策略。
- 多模态AI的备用方案完善:确保智谱GLM-4V和通义千问VL的降级机制稳定可靠。
总结
本周完成了画风建模系统的联调与验证。通过端到端测试确认了完整链路可行;通过3局触发机制验证确认了系统能准确判断数据积累程度;通过有无档案的对比测试,证明了画风档案能提升AI识别准确率约15%;通过DeepSeek稳定性测试,确认了大模型调用可靠且成本可控。画风建模让AI不仅能“看懂”绘画内容,还能“认识”绘画的人,为后续的心理分析报告提供了数据基础。
更多推荐




所有评论(0)