拒绝“千人一面”:画风建模系统联调与验证

本周的核心任务是完成画风建模系统的联调与验证。这一系统是我们项目的重要创新点:通过分析玩家多局绘画行为数据,调用大模型生成个性化的“画风档案”,并将其注入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_jsonplayer_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/2015/20+3张
准确率60.0%75.0%+15%
平均置信度0.680.79+16.2%
模糊答案数52-3次

结果分析

实验结果显示,画风档案对AI识别有明显的正向效果。

  1. 准确率提升15%:画风档案帮助AI更好地理解特定玩家的绘画风格,减少误判。
  2. 置信度提升16.2%:AI结合画风档案做判断时,对结果的确定性更高。
  3. 模糊答案减少:有档案后,AI给出的答案更具体精准。
DeepSeek-V3.2调用稳定性测试

画风建模使用DeepSeek的文本模型(deepseek-chat),调用方式与OpenAI兼容。

稳定性测试方案

对DeepSeek-V3.2进行了连续调用和高并发场景测试。

连续调用50次

调用批次成功次数失败次数成功率平均响应时间
50次连续调用49198.0%1.2秒

高并发场景(模拟4人房间)

并发数总请求成功失败成功率P95响应时间
420次200100%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异步执行,不阻塞主流程。档案是“给下一局用的”,时序合理。
下周计划
  1. 画风档案可视化:设计前端展示页面,让用户能直观看到自己的画风特征。
  2. 档案版本历史:利用数据库中保存的历史版本,展示玩家画风的演变趋势。
  3. AI识别模块的最终优化:结合画风档案的测试结果,调整prompt策略。
  4. 多模态AI的备用方案完善:确保智谱GLM-4V和通义千问VL的降级机制稳定可靠。
总结

本周完成了画风建模系统的联调与验证。通过端到端测试确认了完整链路可行;通过3局触发机制验证确认了系统能准确判断数据积累程度;通过有无档案的对比测试,证明了画风档案能提升AI识别准确率约15%;通过DeepSeek稳定性测试,确认了大模型调用可靠且成本可控。画风建模让AI不仅能“看懂”绘画内容,还能“认识”绘画的人,为后续的心理分析报告提供了数据基础。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐