deeppersona-experience / BUGFIX_SUMMARY.md
Yufan_Zhou
Update footer text to show correct model name (GPT-4.1-mini)
de4ba6a

A newer version of the Gradio SDK is available: 6.13.0

Upgrade

Bug Fix Summary - Profile Generation Not Using Preset Inputs

⚠️ 重要更新 (2025-11-10)

问题已通过重构解决! 参考 experience_temp/generation_user_profile 的工作版本,我们完全重写了参数传递逻辑。

关键改变:

  • ❌ 移除了文件系统依赖(不再保存/读取 user_profile.json
  • ✅ 在内存中直接构建和传递 profile
  • ✅ 匹配参考版本的简单流程:build → select → summarize
  • ✅ 用户输入现在被正确使用

详见 REFACTOR_NOTES.md


Bug Fix Summary - Profile Generation Not Using Preset Inputs

问题描述

当用户通过Web界面输入部分预设内容(如年龄、性别、职业等)时,生成的profile仍然是完全随机的,没有使用用户的预设输入。

用户需求

核心原则:用户输入了什么就用什么,没输入的才基于已输入内容生成

  • 用户输入的字段:直接使用,不调用GPT重新生成
  • 用户未输入的字段:基于已输入的字段,调用 based_data.py 中的函数生成
  • 有多少用多少,灵活处理部分输入的情况

根本原因

generate_profile.pygenerate_single_profile() 函数中,代码会调用 select_attributes.py 中的 generate_user_profile() 函数来重新生成用户配置文件。这个函数会完全随机生成所有基础信息(年龄、性别、职业、地点等),从而覆盖了用户在 web_api_bridge.py 中预设的输入。

问题代码流程:

  1. 用户在Web界面输入预设值
  2. web_api_bridge.py 将预设值保存到 user_profile.json
  3. generate_single_profile() 被调用
  4. 问题点: generate_single_profile() 调用 generate_user_profile() 重新随机生成配置
  5. 新生成的随机配置覆盖了用户的预设输入

修复方案

1. 修改 generate_profile.py (主要修改)

文件: /Users/yufan_zhou/Documents/deeppersona/deeppersona-experience/generate_user_profile_final/code/generate_profile.py

修改内容:

  • 在调用属性选择之前,检查是否已存在 user_profile.json(由 web_api_bridge.py 保存)
  • 如果存在,读取并使用该文件(包含用户预设输入)
  • 将 web 格式的配置转换为 AttributeSelector 期望的格式
  • 在属性选择完成后,恢复原始的 user_profile.json,避免被覆盖

关键代码:

# 检查是否已经存在user_profile.json(由web_api_bridge.py保存)
if os.path.exists(user_profile_path):
    # 读取已存在的用户配置文件(包含预设输入)
    print(f"Found existing user_profile.json, using preset inputs...")
    with open(user_profile_path, 'r', encoding='utf-8') as f:
        base_profile = json.load(f)
    
    # 保存原始配置,稍后恢复
    original_base_profile = base_profile.copy()
    using_preset = True
    
    # 转换为AttributeSelector期望的格式
    user_profile = convert_web_profile_to_selector_format(base_profile)
else:
    # 如果不存在,生成新的配置文件
    user_profile = gen_profile()

2. 添加格式转换函数到 select_attributes.py

文件: /Users/yufan_zhou/Documents/deeppersona/deeppersona-experience/generate_user_profile_final/code/select_attributes.py

新增函数: convert_web_profile_to_selector_format()

功能: 将 web_api_bridge.py 保存的配置格式转换为 AttributeSelector 期望的格式

核心逻辑(严格遵循"有多少用多少"原则):

# 对每个字段进行检查:
# 1. 如果用户提供了该字段 → 直接使用,打印 "✓ Using user-provided ..."
# 2. 如果用户没提供 → 基于已有信息生成,打印 "✗ ... not provided, generated ..."

# 示例:年龄处理
age = web_profile.get("age")
if age:
    age_info = {"age": age, "age_group": calculate_age_group(age)}
    print(f"✓ Using user-provided age: {age}")
else:
    age_info = generate_age_info()  # 只有没提供时才生成
    print(f"✗ Age not provided, generated: {age_info['age']}")

格式对比:

  • Web格式: {"age": int, "gender": str, "Occupations": [str], ...}
  • Selector格式: {"age_info": {"age": int, "age_group": str}, "gender": str, "career_info": {"status": str}, ...}

处理的字段:

  • ✅ age → age_info (如果提供了就用,否则生成)
  • ✅ gender (如果提供了就用,否则生成)
  • ✅ location (如果提供了就用,否则生成)
  • ✅ Occupations → career_info (如果提供了就用,否则生成)
  • ✅ personal_values (如果提供了就用,否则基于已有信息生成)
  • ✅ life_attitude (如果提供了就用,否则基于已有信息生成)
  • ✅ personal_story (如果提供了就用,否则基于已有信息生成)
  • ✅ interests (如果提供了就用,否则基于故事生成)

3. 修复 web_api_bridge.py 中的数据类型问题

文件: /Users/yufan_zhou/Documents/deeppersona/deeppersona-experience/generate_user_profile_final/code/web_api_bridge.py

修复内容:

  1. 修复 values_orientation 类型问题:

    • generate_personal_values() 返回字典,需要提取 values_orientation 字段
  2. 修复 personal_story 嵌套问题:

    • 避免重复嵌套 {"personal_story": {"personal_story": ...}}

修改文件列表

  1. /Users/yufan_zhou/Documents/deeppersona/deeppersona-experience/generate_user_profile_final/code/generate_profile.py
  2. /Users/yufan_zhou/Documents/deeppersona/deeppersona-experience/generate_user_profile_final/code/select_attributes.py
  3. /Users/yufan_zhou/Documents/deeppersona/deeppersona-experience/generate_user_profile_final/code/web_api_bridge.py

测试建议

测试场景 1:部分输入(只输入基本信息)

输入:

  • Age: 25
  • Gender: Male
  • Occupation: Software Engineer
  • City: Tokyo
  • Country: Japan

预期输出:

✓ Using user-provided age: 25
✓ Using user-provided gender: Male
✓ Using user-provided location: Tokyo, Japan
✓ Using user-provided occupation: Software Engineer
✗ Personal values not provided, generated based on user inputs
✗ Life attitude not provided, generated based on user inputs
✗ Life story not provided, generated based on user inputs
✗ Interests not provided, generated based on life story

测试场景 2:完整输入(输入所有字段)

输入:

  • Age: 30
  • Gender: Female
  • Occupation: Teacher
  • Location: Paris, France
  • Personal Values: "Values education and creativity"
  • Life Attitude: "Optimistic and passionate about learning"
  • Life Story: "Born in Lyon, moved to Paris for university..."
  • Interests: "Reading, painting, traveling"

预期输出:

✓ Using user-provided age: 30
✓ Using user-provided gender: Female
✓ Using user-provided location: Paris, France
✓ Using user-provided occupation: Teacher
✓ Using user-provided personal values: Values education and creativity
✓ Using user-provided life attitude: Optimistic and passionate about learning
✓ Using user-provided life story: Born in Lyon, moved to Paris for university...
✓ Using user-provided interests: Reading, painting, traveling

测试场景 3:空输入(完全随机生成)

输入: 全部留空

预期输出:

✗ Age not provided, generated: 42
✗ Gender not provided, generated: female
✗ Location not provided, generated: Mumbai, India
✗ Occupation not provided, generated: Marketing Manager
✗ Personal values not provided, generated based on user inputs
✗ Life attitude not provided, generated based on user inputs
✗ Life story not provided, generated based on user inputs
✗ Interests not provided, generated based on life story

预期结果

  • ✅ 用户输入的预设值会被直接使用,不会被重新生成
  • ✅ 未输入的字段会基于已输入的信息智能生成
  • ✅ 生成的profile与用户输入保持完全一致性
  • ✅ 控制台会清晰显示哪些字段使用了用户输入(✓),哪些是生成的(✗)