Prechádzať zdrojové kódy

feat: 实现数据目录独立和版本化输出管理

主要改动:
1. 数据目录迁移到上级目录,支持多项目共享
2. 自动使用项目目录名作为输出版本(how_1124_v1)
3. 输出路径版本化隔离,便于对比不同版本结果
4. 支持灵活的数据根目录配置(环境变量 > 配置文件 > 默认值)

配置更新:
- config/accounts.json: 添加 data_root 配置,输出路径支持 {version} 变量
- script/data_processing/path_config.py: 实现版本自动识别和路径变量替换

文档完善:
- README.md: 项目快速参考指南
- docs/数据目录配置说明.md: 详细配置说明和使用场景
- docs/其他项目迁移指南.md: 迁移其他项目的步骤
- docs/迁移完成总结.md: 完整总结和最佳实践

数据目录结构:
../data/账号/{账号名}/how解构_outputs/{版本}/
├── intermediate/
├── results/
└── visualization/

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
yangxiaohui 1 týždeň pred
rodič
commit
b927055b88

+ 197 - 0
README.md

@@ -0,0 +1,197 @@
+# How 解构项目 v1124
+
+## 🚀 快速开始
+
+```bash
+# 运行完整流程
+./script/data_processing/run_all_with_config.sh 阿里多多酱1
+
+# 验证配置
+python script/data_processing/path_config.py
+```
+
+## 📂 项目结构
+
+```
+how_1124_v1/                    # 项目代码
+├── config/
+│   └── accounts.json          # 配置文件(data_root: "../data")
+├── script/
+│   └── data_processing/       # 数据处理脚本
+├── lib/                       # 核心库
+└── docs/                      # 文档
+
+../data/                        # 共享数据目录
+└── 账号/阿里多多酱1/
+    ├── what单独解构/          # 输入:当前帖子
+    ├── 用于pattern聚类/       # 输入:历史帖子
+    ├── pattern相关文件/       # 输入:pattern聚合
+    └── how解构_outputs/        # 输出(版本化)
+        └── how_1124_v1/       # 本项目输出
+            ├── intermediate/
+            ├── results/
+            └── visualization/
+```
+
+## 🎯 核心特性
+
+### 1. 自动版本识别
+- ✅ 输出自动使用项目目录名作为版本(`how_1124_v1`)
+- ✅ 不同版本输出自动隔离,互不干扰
+
+### 2. 共享数据目录
+- ✅ 所有项目共享 `../data/` 输入数据
+- ✅ 支持环境变量 `DATA_ROOT` 覆盖
+
+### 3. 版本化输出
+- ✅ 输出路径:`../data/账号/{账号名}/how解构_outputs/{版本}/`
+- ✅ 便于对比不同版本的结果
+
+## 📊 数据处理流程
+
+```
+输入:
+├─ pattern聚合结果.json
+├─ 历史帖子what解构/*.json
+└─ 当前帖子what解构/*.json
+
+↓ 步骤1: 提取特征分类映射
+├─ 特征名称_分类映射.json
+└─ 分类层级映射.json
+
+↓ 步骤2: 提取特征帖子来源
+└─ 特征名称_帖子来源.json
+
+↓ 步骤3: 提取当前帖子解构任务列表
+└─ 当前帖子_解构任务列表.json
+
+↓ 步骤4: 匹配灵感特征(核心)
+└─ {帖子ID}_how.json × N
+
+↓ 步骤5: 可视化结果
+└─ how解构结果_可视化.html
+
+输出位置:
+../data/账号/阿里多多酱1/how解构_outputs/how_1124_v1/
+```
+
+## 🔧 配置说明
+
+### 数据根目录(优先级从高到低)
+1. 环境变量:`DATA_ROOT=~/Documents/数据`
+2. 配置文件:`config/accounts.json` 中的 `data_root`
+3. 默认值:`../data`(当前配置)
+
+### 输出版本(优先级从高到低)
+1. 环境变量:`OUTPUT_VERSION=test_version`
+2. 配置文件:`config/accounts.json` 中的 `output_version`
+3. 默认值:项目目录名(`how_1124_v1`)✅ 推荐
+
+### 账号名称(优先级从高到低)
+1. 命令行参数:`./run_all_with_config.sh 账号名`
+2. 环境变量:`ACCOUNT_NAME=账号名`
+3. 配置文件:`default_account`
+
+## 📝 常用命令
+
+```bash
+# 处理单个账号
+./script/data_processing/run_all_with_config.sh 阿里多多酱1
+
+# 处理所有启用的账号
+./script/data_processing/run_all_with_config.sh --all
+
+# 使用环境变量
+ACCOUNT_NAME=阿里多多酱1 ./script/data_processing/run_all_with_config.sh
+
+# 自定义输出版本
+OUTPUT_VERSION=experiment ./script/data_processing/run_all_with_config.sh 阿里多多酱1
+
+# 查看所有版本输出
+ls ../data/账号/阿里多多酱1/how解构_outputs/
+
+# 打开可视化
+open ../data/账号/阿里多多酱1/how解构_outputs/how_1124_v1/visualization/how解构结果_可视化.html
+```
+
+## 📖 文档
+
+- [数据目录配置说明](docs/数据目录配置说明.md) - 详细的配置说明和使用场景
+- [其他项目迁移指南](docs/其他项目迁移指南.md) - 迁移其他 how_* 项目的步骤
+- [迁移完成总结](docs/迁移完成总结.md) - 本次迁移的总结和下一步建议
+
+## 🎨 功能亮点
+
+### 1. 笛卡尔积批量计算
+使用混合模型一次性计算 M×N 的特征相似度矩阵,大幅提升性能。
+
+```python
+# lib/hybrid_similarity.py
+similarity_results = await compare_phrases_cartesian(
+    feature_names,      # M个特征
+    persona_names,      # N个人设
+    max_concurrent=100  # LLM最大并发数
+)
+```
+
+### 2. 进度实时显示
+```
+进度: [████████████████████░░░░░░░░] 1234/2000 (61.7%), 预计剩余: 45秒
+```
+
+### 3. 多账号批量处理
+```bash
+# 一次性处理所有启用的账号
+./script/data_processing/run_all_with_config.sh --all
+```
+
+## ⚙️ 依赖
+
+- Python 3.8+
+- 依赖库:详见 `requirements.txt`(如果有)
+
+## 🐛 故障排除
+
+### 问题:路径不存在
+
+**症状**:
+```
+⚠️  警告: 部分输入路径不存在!
+```
+
+**解决**:
+```bash
+# 检查数据目录是否存在
+ls -la ../data/账号/阿里多多酱1/
+
+# 验证配置
+python script/data_processing/path_config.py
+```
+
+### 问题:版本不正确
+
+**症状**:输出到了错误的版本目录
+
+**解决**:
+```bash
+# 检查是否设置了环境变量
+echo $OUTPUT_VERSION
+
+# 清除环境变量
+unset OUTPUT_VERSION
+
+# 重新运行
+python script/data_processing/path_config.py
+```
+
+## 📄 许可
+
+内部项目
+
+## 👤 作者
+
+Semsevens
+
+---
+
+**最后更新**: 2024-11-24

+ 6 - 5
config/accounts.json

@@ -1,4 +1,5 @@
 {
+  "data_root": "../data",
   "accounts": [
     {
       "name": "阿里多多酱",
@@ -17,7 +18,7 @@
     }
   ],
   "default_account": "阿里多多酱1",
-  "comment": "原始数据目录不动,所有输出结果统一放到 how解构/ 目录下",
+  "comment": "数据根目录可通过 data_root 配置(支持绝对路径、~、环境变量),也可通过 DATA_ROOT 环境变量覆盖",
   "filter_mode": "exclude_current_posts",
   "filter_modes": {
     "exclude_current_posts": {
@@ -34,16 +35,16 @@
     }
   },
   "paths": {
-    "account_base": "data/账号",
+    "account_base": "账号",
     "input": {
       "current_posts": "what单独解构",
       "historical_posts": "用于pattern聚类",
       "pattern_cluster": "pattern相关文件/optimization/optimized_clustered_data_gemini-3-pro-preview.json"
     },
     "output": {
-      "intermediate": "how解构/intermediate",
-      "how_results": "how解构/results",
-      "visualization": "how解构/visualization"
+      "intermediate": "how解构_outputs/{version}/intermediate",
+      "how_results": "how解构_outputs/{version}/results",
+      "visualization": "how解构_outputs/{version}/visualization"
     }
   }
 }

+ 269 - 0
docs/其他项目迁移指南.md

@@ -0,0 +1,269 @@
+# 其他项目迁移指南
+
+## 目标结构
+
+```
+/Users/semsevens/Desktop/workspace/daily/1113/
+├── data/                    ← 共享数据目录(已迁移)
+│   └── 账号/
+│       └── 阿里多多酱1/
+│           ├── what单独解构/
+│           ├── 用于pattern聚类/
+│           ├── pattern相关文件/
+│           └── how解构_outputs/
+│               ├── how_1124_v1/     ← 当前项目输出
+│               ├── how_1121_v2/     ← 未来其他项目输出
+│               └── ...
+│
+├── how_1124_v1/            ← 已完成迁移 ✓
+├── how_1121_v2/            ← 待迁移
+├── how_1120_v3/            ← 待迁移
+└── ...其他项目/            ← 待迁移
+```
+
+## 快速迁移步骤
+
+### 方式1: 手动迁移单个项目(推荐)
+
+为每个需要使用共享数据的项目执行以下步骤:
+
+```bash
+# 1. 进入项目目录
+cd /Users/semsevens/Desktop/workspace/daily/1113/how_1121_v2
+
+# 2. 删除项目内的data目录(如果存在且不需要保留)
+# 注意:如果这个项目有独特数据,先备份!
+rm -rf data
+
+# 3. 复制最新的配置文件
+cp ../how_1124_v1/config/accounts.json config/accounts.json
+
+# 4. 复制最新的 path_config.py
+cp ../how_1124_v1/script/data_processing/path_config.py script/data_processing/path_config.py
+
+# 5. 验证配置
+python script/data_processing/path_config.py
+```
+
+### 方式2: 批量迁移脚本
+
+创建一个脚本来批量处理:
+
+```bash
+#!/bin/bash
+# migrate_all_projects.sh
+
+BASE_DIR="/Users/semsevens/Desktop/workspace/daily/1113"
+REFERENCE_PROJECT="how_1124_v1"
+
+# 要迁移的项目列表
+PROJECTS=(
+    "how_1121_v2"
+    "how_1121_v1"
+    "how_1120_v3"
+    "how_1120_v2"
+    "how_1120_v1"
+    # 添加更多项目...
+)
+
+for project in "${PROJECTS[@]}"; do
+    echo "========================================"
+    echo "处理项目: $project"
+    echo "========================================"
+
+    cd "$BASE_DIR/$project" || continue
+
+    # 备份旧配置(如果需要)
+    if [ -f "config/accounts.json" ]; then
+        cp config/accounts.json config/accounts.json.backup
+    fi
+
+    # 复制新配置
+    cp "$BASE_DIR/$REFERENCE_PROJECT/config/accounts.json" config/accounts.json
+    cp "$BASE_DIR/$REFERENCE_PROJECT/script/data_processing/path_config.py" script/data_processing/path_config.py
+
+    # 验证
+    echo "验证配置..."
+    python script/data_processing/path_config.py
+
+    echo ""
+done
+
+echo "所有项目迁移完成!"
+```
+
+使用:
+```bash
+chmod +x migrate_all_projects.sh
+./migrate_all_projects.sh
+```
+
+### 方式3: 软链接方式(最简单,但不推荐)
+
+如果某个旧项目不想修改代码,可以创建软链接:
+
+```bash
+cd /Users/semsevens/Desktop/workspace/daily/1113/how_1120_v1
+
+# 删除旧的 data 目录
+rm -rf data
+
+# 创建指向共享 data 的软链接
+ln -s ../data data
+
+# 验证
+ls -la data
+```
+
+**注意**: 软链接方式不支持版本化输出,所有使用软链接的项目会共享同一个输出目录。
+
+## 迁移后的优势
+
+### 1. 数据共享
+所有项目共享同一份输入数据,节省磁盘空间。
+
+### 2. 版本隔离
+每个项目的输出自动保存到独立的版本目录:
+
+```
+data/账号/阿里多多酱1/how解构_outputs/
+├── how_1120_v1/
+├── how_1120_v2/
+├── how_1120_v3/
+├── how_1121_v1/
+├── how_1121_v2/
+└── how_1124_v1/
+```
+
+### 3. 便于对比
+可以轻松对比不同版本的输出结果:
+
+```bash
+# 查看所有版本
+ls data/账号/阿里多多酱1/how解构_outputs/
+
+# 对比两个版本的结果
+diff -r data/账号/阿里多多酱1/how解构_outputs/how_1120_v1/results \
+         data/账号/阿里多多酱1/how解构_outputs/how_1124_v1/results
+
+# 打开不同版本的可视化
+open data/账号/阿里多多酱1/how解构_outputs/how_1120_v1/visualization/how解构结果_可视化.html
+open data/账号/阿里多多酱1/how解构_outputs/how_1124_v1/visualization/how解构结果_可视化.html
+```
+
+## 验证清单
+
+迁移完成后,确保以下内容正确:
+
+- [ ] `config/accounts.json` 中 `data_root` 设置为 `"../data"`
+- [ ] `script/data_processing/path_config.py` 已更新
+- [ ] 运行 `python script/data_processing/path_config.py` 无错误
+- [ ] 输入路径验证全部通过 ✓
+- [ ] 输出版本自动识别为项目目录名
+
+## 常见问题
+
+### Q: 某个旧项目有独特的数据怎么办?
+
+如果某个项目的 `data/` 目录包含独特数据(不在共享 data 中),有两个选择:
+
+1. **迁移独特数据到共享目录**
+```bash
+# 复制独特数据到共享目录
+cp -r old_project/data/账号/特殊账号/* ../data/账号/特殊账号/
+
+# 然后按正常流程迁移项目
+```
+
+2. **保持项目独立**
+```bash
+# 修改该项目的配置,使用项目内 data
+# config/accounts.json:
+{
+  "data_root": "data",  // 保持使用项目内的data
+  ...
+}
+```
+
+### Q: 如何清理旧的输出数据?
+
+```bash
+# 进入共享数据目录
+cd /Users/semsevens/Desktop/workspace/daily/1113/data/账号/阿里多多酱1
+
+# 查看所有版本(按时间排序)
+ls -lt how解构_outputs/
+
+# 删除旧版本(谨慎操作!)
+rm -rf how解构_outputs/how_1113_v1
+rm -rf how解构_outputs/how_1113_v2
+
+# 或者只保留最新3个版本
+cd how解构_outputs
+ls -t | tail -n +4 | xargs rm -rf
+```
+
+### Q: 能否使用绝对路径?
+
+可以,但不推荐。使用相对路径 `"../data"` 可以保持项目的可移植性。
+
+如果确实需要绝对路径:
+```json
+{
+  "data_root": "/Users/semsevens/Desktop/workspace/daily/1113/data",
+  ...
+}
+```
+
+### Q: 如何恢复到迁移前的状态?
+
+```bash
+# 1. 复制共享数据回项目内
+cp -r ../data ./data
+
+# 2. 修改配置
+# config/accounts.json:
+{
+  "data_root": "data",
+  ...
+}
+
+# 3. 验证
+python script/data_processing/path_config.py
+```
+
+## 推荐的项目清理流程
+
+迁移完成后,可以清理不再需要的旧项目:
+
+```bash
+# 1. 确认所有需要的输出已保存到共享data
+ls -la /Users/semsevens/Desktop/workspace/daily/1113/data/账号/阿里多多酱1/how解构_outputs/
+
+# 2. 删除不再需要的旧项目
+cd /Users/semsevens/Desktop/workspace/daily/1113
+rm -rf how_1113_v1
+rm -rf how_1113_v2
+# ...
+
+# 3. 只保留最近的几个版本作为代码参考
+# 建议保留: how_1124_v1, how_1121_v2, how_1120_v3
+```
+
+## 下次创建新项目
+
+当你创建新项目时(比如 `how_1125_v1`),只需:
+
+```bash
+# 1. 复制最新项目
+cp -r how_1124_v1 how_1125_v1
+
+# 2. 清理不需要的文件
+cd how_1125_v1
+rm -rf data  # 删除data目录(如果复制时带过来了)
+
+# 3. 配置已经是 "../data",无需修改
+
+# 4. 开始开发
+# 输出会自动保存到:../data/账号/阿里多多酱1/how解构_outputs/how_1125_v1/
+```

+ 277 - 0
docs/数据目录配置说明.md

@@ -0,0 +1,277 @@
+# 数据目录配置说明
+
+## 概述
+
+本项目支持将数据目录独立于代码目录,并自动使用项目文件夹名称作为输出版本标识,实现不同代码版本的输出隔离。
+
+## 核心特性
+
+### 1. 数据根目录配置
+
+支持三种方式配置数据根目录(优先级从高到低):
+
+#### 方式1: 环境变量(临时使用,推荐)
+
+```bash
+# 临时设置
+DATA_ROOT=~/Documents/账号数据 ./script/data_processing/run_all_with_config.sh 阿里多多酱1
+
+# 永久设置(添加到 ~/.zshrc 或 ~/.bashrc)
+export DATA_ROOT=~/Documents/账号数据
+```
+
+#### 方式2: 配置文件(项目级配置)
+
+编辑 `config/accounts.json`:
+
+```json
+{
+  "data_root": "~/Documents/账号数据",  // 支持 ~、绝对路径、相对路径
+  ...
+}
+```
+
+#### 方式3: 默认值(向后兼容)
+
+如果不配置,默认使用项目内的 `data/` 目录。
+
+### 2. 输出版本自动识别
+
+**默认行为:自动使用项目根目录名称作为输出版本**
+
+例如:
+- 项目目录:`how_1124_v1` → 输出版本:`how_1124_v1`
+- 项目目录:`how_1121_v2` → 输出版本:`how_1121_v2`
+
+**覆盖方式**(优先级从高到低):
+
+1. 通过环境变量:
+```bash
+OUTPUT_VERSION=experiment_weighted ./script/data_processing/run_all_with_config.sh 阿里多多酱1
+```
+
+2. 通过配置文件:
+```json
+{
+  "output_version": "custom_version_name",
+  ...
+}
+```
+
+3. 通过代码参数:
+```python
+config = PathConfig(account_name="阿里多多酱1", output_version="v1_baseline")
+```
+
+## 目录结构
+
+### 典型配置(数据独立)
+
+```
+# 代码目录
+~/Desktop/workspace/daily/1113/
+├── how_1120_v1/          # 项目版本1
+├── how_1121_v2/          # 项目版本2
+└── how_1124_v1/          # 项目版本3(当前)
+
+# 数据目录(独立存储)
+~/Documents/账号数据/
+└── 账号/
+    └── 阿里多多酱1/
+        ├── what单独解构/              # 输入:当前帖子
+        ├── 用于pattern聚类/           # 输入:历史帖子
+        ├── pattern相关文件/           # 输入:pattern聚合
+        │
+        └── how解构_outputs/           # 输出(按版本隔离)
+            ├── how_1120_v1/          # 版本1的输出
+            │   ├── intermediate/
+            │   ├── results/
+            │   └── visualization/
+            │
+            ├── how_1121_v2/          # 版本2的输出
+            │   └── ...
+            │
+            ├── how_1124_v1/          # 版本3的输出
+            │   └── ...
+            │
+            └── latest -> how_1124_v1/  # 软链接(可选)
+```
+
+## 使用场景
+
+### 场景1: 默认使用(项目内数据)
+
+```bash
+cd ~/Desktop/workspace/daily/1113/how_1124_v1
+./script/data_processing/run_all_with_config.sh 阿里多多酱1
+
+# 数据路径:
+# 输入:./data/账号/阿里多多酱1/what单独解构/
+# 输出:./data/账号/阿里多多酱1/how解构_outputs/how_1124_v1/
+```
+
+### 场景2: 独立数据目录(推荐)
+
+```bash
+# 一次性设置
+export DATA_ROOT=~/Documents/账号数据
+
+cd ~/Desktop/workspace/daily/1113/how_1124_v1
+./script/data_processing/run_all_with_config.sh 阿里多多酱1
+
+# 数据路径:
+# 输入:~/Documents/账号数据/账号/阿里多多酱1/what单独解构/
+# 输出:~/Documents/账号数据/账号/阿里多多酱1/how解构_outputs/how_1124_v1/
+```
+
+### 场景3: 多个项目版本并行实验
+
+```bash
+# 终端1:运行旧版本
+cd ~/Desktop/workspace/daily/1113/how_1120_v1
+DATA_ROOT=~/Documents/账号数据 ./script/data_processing/run_all_with_config.sh 阿里多多酱1
+# 输出到:~/Documents/账号数据/账号/阿里多多酱1/how解构_outputs/how_1120_v1/
+
+# 终端2:同时运行新版本
+cd ~/Desktop/workspace/daily/1113/how_1124_v1
+DATA_ROOT=~/Documents/账号数据 ./script/data_processing/run_all_with_config.sh 阿里多多酱1
+# 输出到:~/Documents/账号数据/账号/阿里多多酱1/how解构_outputs/how_1124_v1/
+
+# 两个版本互不干扰!
+```
+
+### 场景4: 自定义版本名称
+
+```bash
+# 强制使用自定义版本名
+OUTPUT_VERSION=experiment_20241124 ./script/data_processing/run_all_with_config.sh 阿里多多酱1
+
+# 输出到:.../how解构_outputs/experiment_20241124/
+```
+
+### 场景5: 查看和对比不同版本
+
+```bash
+# 查看所有版本
+ls ~/Documents/账号数据/账号/阿里多多酱1/how解构_outputs/
+# 输出:
+# how_1120_v1/
+# how_1121_v2/
+# how_1124_v1/
+
+# 打开旧版本的可视化
+open ~/Documents/账号数据/账号/阿里多多酱1/how解构_outputs/how_1120_v1/visualization/how解构结果_可视化.html
+
+# 打开最新版本的可视化
+open ~/Documents/账号数据/账号/阿里多多酱1/how解构_outputs/how_1124_v1/visualization/how解构结果_可视化.html
+```
+
+## 验证配置
+
+运行以下命令查看当前配置:
+
+```bash
+python script/data_processing/path_config.py
+```
+
+输出示例:
+
+```
+============================================================
+项目根目录: /Users/semsevens/Desktop/workspace/daily/1113/how_1124_v1
+项目名称: how_1124_v1
+数据根目录: /Users/semsevens/Desktop/workspace/daily/1113/how_1124_v1/data
+输出版本: how_1124_v1
+账号: 阿里多多酱1
+过滤模式: exclude_current_posts
+账号根目录: .../data/账号/阿里多多酱1
+
+输入路径:
+  当前帖子目录: .../what单独解构
+  过去帖子目录: .../用于pattern聚类
+  pattern聚合文件: .../pattern相关文件/optimization/...
+
+输出路径:
+  中间结果目录: .../how解构_outputs/how_1124_v1/intermediate
+  how解构结果目录: .../how解构_outputs/how_1124_v1/results
+  可视化结果目录: .../how解构_outputs/how_1124_v1/visualization
+============================================================
+```
+
+## 配置文件参考
+
+完整的 `config/accounts.json` 配置示例:
+
+```json
+{
+  "data_root": "data",
+  "accounts": [
+    {
+      "name": "阿里多多酱1",
+      "enabled": true,
+      "description": "主账号"
+    }
+  ],
+  "default_account": "阿里多多酱1",
+  "filter_mode": "exclude_current_posts",
+  "paths": {
+    "account_base": "账号",
+    "input": {
+      "current_posts": "what单独解构",
+      "historical_posts": "用于pattern聚类",
+      "pattern_cluster": "pattern相关文件/optimization/optimized_clustered_data_gemini-3-pro-preview.json"
+    },
+    "output": {
+      "intermediate": "how解构_outputs/{version}/intermediate",
+      "how_results": "how解构_outputs/{version}/results",
+      "visualization": "how解构_outputs/{version}/visualization"
+    }
+  }
+}
+```
+
+## 最佳实践
+
+1. **开发阶段**:使用项目内 `data/` 目录(默认)
+2. **生产阶段**:设置 `DATA_ROOT` 环境变量,指向独立数据目录
+3. **多版本对比**:保持不同项目目录并行,共享同一个数据根目录
+4. **版本命名**:项目目录命名规范化,如 `how_MMDD_v{N}`
+
+## 常见问题
+
+### Q: 如何迁移现有数据?
+
+```bash
+# 1. 创建新的数据目录
+mkdir -p ~/Documents/账号数据/账号
+
+# 2. 移动数据
+mv data/账号/* ~/Documents/账号数据/账号/
+
+# 3. 设置环境变量
+export DATA_ROOT=~/Documents/账号数据
+
+# 4. 验证
+python script/data_processing/path_config.py
+```
+
+### Q: 如何删除旧版本的输出?
+
+```bash
+# 删除特定版本
+rm -rf ~/Documents/账号数据/账号/阿里多多酱1/how解构_outputs/how_1120_v1/
+
+# 只保留最新3个版本(示例)
+cd ~/Documents/账号数据/账号/阿里多多酱1/how解构_outputs/
+ls -t | tail -n +4 | xargs rm -rf
+```
+
+### Q: 如何在配置文件中使用环境变量?
+
+```json
+{
+  "data_root": "${HOME}/Documents/账号数据"
+}
+```
+
+注意:需要使用 `${VAR}` 格式,不是 `$VAR`。

+ 242 - 0
docs/迁移完成总结.md

@@ -0,0 +1,242 @@
+# 数据目录迁移完成总结
+
+## ✅ 已完成的工作
+
+### 1. 数据目录迁移
+- ✅ 将 `how_1124_v1/data` 移动到 `/Users/semsevens/Desktop/workspace/daily/1113/data`
+- ✅ 更新配置文件 `config/accounts.json`,设置 `data_root: "../data"`
+- ✅ 验证配置正确,所有输入路径验证通过
+
+### 2. 代码功能增强
+- ✅ 支持数据根目录配置(环境变量 > 配置文件 > 默认值)
+- ✅ 自动使用项目目录名作为输出版本(`how_1124_v1`)
+- ✅ 输出路径支持版本变量 `{version}`
+- ✅ 增强调试信息(显示项目名称、数据根目录、输出版本)
+
+### 3. 文档完善
+- ✅ 创建《数据目录配置说明.md》
+- ✅ 创建《其他项目迁移指南.md》
+- ✅ 创建《迁移完成总结.md》
+
+## 📊 当前目录结构
+
+```
+/Users/semsevens/Desktop/workspace/daily/1113/
+├── data/                               ← 共享数据目录(新)
+│   ├── .DS_Store
+│   ├── 1、匹配人设标签.md
+│   ├── data_1117/
+│   ├── data_1118/
+│   ├── data_1121/
+│   ├── 阿里多多酱/
+│   └── 账号/
+│       └── 阿里多多酱1/
+│           ├── what单独解构/                      ← 输入:当前帖子
+│           ├── 用于pattern聚类/                   ← 输入:历史帖子
+│           ├── pattern相关文件/                   ← 输入:pattern聚合
+│           └── how解构_outputs/                   ← 输出(版本化)
+│               └── how_1124_v1/                  ← 当前项目输出
+│                   ├── intermediate/
+│                   ├── results/
+│                   └── visualization/
+│
+├── how_1124_v1/                       ← 当前项目(已完成迁移)
+│   ├── config/
+│   │   └── accounts.json             ← data_root: "../data"
+│   ├── script/
+│   │   └── data_processing/
+│   │       └── path_config.py        ← 支持版本化输出
+│   └── docs/
+│       ├── 数据目录配置说明.md
+│       ├── 其他项目迁移指南.md
+│       └── 迁移完成总结.md
+│
+├── how_1121_v2/                       ← 待迁移
+├── how_1121_v1/                       ← 待迁移
+├── how_1120_v3/                       ← 待迁移
+└── ...其他项目/                        ← 待迁移
+```
+
+## 🎯 核心优势
+
+### 1. 数据共享
+- 所有 `how_*` 项目共享同一份输入数据
+- 节省磁盘空间
+- 数据更新一次,所有项目受益
+
+### 2. 版本隔离
+- 每个项目的输出自动保存到独立的版本目录
+- 项目名称即版本名称(`how_1124_v1`)
+- 不同版本互不干扰
+
+### 3. 便于对比
+- 可以轻松查看和对比不同版本的输出
+- 所有历史版本的输出都保留在同一位置
+
+### 4. 灵活配置
+- 支持环境变量覆盖
+- 支持相对路径和绝对路径
+- 向后兼容(默认使用项目内 data)
+
+## 🚀 快速使用
+
+### 当前项目
+```bash
+cd /Users/semsevens/Desktop/workspace/daily/1113/how_1124_v1
+
+# 运行数据处理(自动使用共享数据)
+./script/data_processing/run_all_with_config.sh 阿里多多酱1
+
+# 输出位置
+# ../data/账号/阿里多多酱1/how解构_outputs/how_1124_v1/
+```
+
+### 查看输出
+```bash
+# 查看所有版本
+ls ../data/账号/阿里多多酱1/how解构_outputs/
+
+# 打开可视化
+open ../data/账号/阿里多多酱1/how解构_outputs/how_1124_v1/visualization/how解构结果_可视化.html
+```
+
+### 验证配置
+```bash
+python script/data_processing/path_config.py
+```
+
+## 📋 下一步建议
+
+### 1. 迁移其他活跃项目(可选)
+
+如果其他项目(如 `how_1121_v2`)仍在使用,可以按照《其他项目迁移指南.md》迁移它们。
+
+```bash
+# 快速迁移单个项目
+cd ../how_1121_v2
+rm -rf data  # 如果有
+cp ../how_1124_v1/config/accounts.json config/accounts.json
+cp ../how_1124_v1/script/data_processing/path_config.py script/data_processing/path_config.py
+python script/data_processing/path_config.py  # 验证
+```
+
+### 2. 清理旧项目(建议)
+
+对于不再使用的旧项目,可以考虑删除:
+
+```bash
+cd /Users/semsevens/Desktop/workspace/daily/1113
+
+# 检查是否有需要保留的数据
+ls -la how_1113_v1/data  # 如果有独特数据,先备份
+
+# 删除旧项目
+rm -rf how_1113_v1
+rm -rf how_1113_v2
+rm -rf how_1117_v1
+# ...
+```
+
+**建议保留**:
+- `how_1124_v1`(当前最新)
+- `how_1121_v2`(次新版本,作为参考)
+- `how_1120_v3`(稳定版本,作为备份)
+
+### 3. 创建新项目的最佳实践
+
+下次创建新项目时:
+
+```bash
+# 1. 复制最新项目
+cp -r how_1124_v1 how_1125_v1
+
+# 2. 清理(git会自动忽略data)
+cd how_1125_v1
+git init  # 如果需要
+# 配置已经正确(data_root: "../data"),无需修改
+
+# 3. 开始开发
+# 输出会自动保存到 ../data/账号/阿里多多酱1/how解构_outputs/how_1125_v1/
+```
+
+### 4. 设置全局环境变量(可选)
+
+如果希望将数据移到更安全的位置(如 ~/Documents),可以:
+
+```bash
+# 1. 移动数据
+mv /Users/semsevens/Desktop/workspace/daily/1113/data ~/Documents/账号数据
+
+# 2. 设置环境变量(永久)
+echo 'export DATA_ROOT=~/Documents/账号数据' >> ~/.zshrc
+source ~/.zshrc
+
+# 3. 所有项目自动使用新位置
+cd /Users/semsevens/Desktop/workspace/daily/1113/how_1124_v1
+python script/data_processing/path_config.py  # 验证
+```
+
+## 🔍 配置优先级说明
+
+系统会按以下优先级确定配置:
+
+### 数据根目录
+1. 环境变量 `DATA_ROOT`(最高优先级)
+2. 配置文件 `config/accounts.json` 中的 `data_root`
+3. 默认值 `项目根/data`(最低优先级)
+
+### 输出版本
+1. 函数参数 `PathConfig(output_version="xxx")`(最高优先级)
+2. 环境变量 `OUTPUT_VERSION`
+3. 配置文件 `config/accounts.json` 中的 `output_version`
+4. 项目根目录名称(默认,推荐)
+
+### 账号名称
+1. 函数参数 `PathConfig(account_name="xxx")`(最高优先级)
+2. 环境变量 `ACCOUNT_NAME`
+3. 配置文件 `config/accounts.json` 中的 `default_account`
+4. 无默认值(必须指定)
+
+## 📝 配置文件示例
+
+### 当前配置(how_1124_v1/config/accounts.json)
+
+```json
+{
+  "data_root": "../data",
+  "accounts": [
+    {
+      "name": "阿里多多酱1",
+      "enabled": true,
+      "description": "新目录结构"
+    }
+  ],
+  "default_account": "阿里多多酱1",
+  "filter_mode": "exclude_current_posts",
+  "paths": {
+    "account_base": "账号",
+    "input": {
+      "current_posts": "what单独解构",
+      "historical_posts": "用于pattern聚类",
+      "pattern_cluster": "pattern相关文件/optimization/optimized_clustered_data_gemini-3-pro-preview.json"
+    },
+    "output": {
+      "intermediate": "how解构_outputs/{version}/intermediate",
+      "how_results": "how解构_outputs/{version}/results",
+      "visualization": "how解构_outputs/{version}/visualization"
+    }
+  }
+}
+```
+
+## ✨ 总结
+
+通过这次迁移,实现了:
+
+1. **代码与数据分离** - 代码在各自的项目目录,数据统一管理
+2. **版本自动识别** - 无需手动配置版本名,自动使用项目目录名
+3. **输出自动隔离** - 不同版本的输出互不干扰,便于对比
+4. **配置灵活** - 支持多种配置方式,适应不同场景
+5. **向后兼容** - 不破坏现有项目的工作方式
+
+**现在可以放心地并行开发多个版本,所有输出都会自动管理!** 🎉

+ 76 - 2
script/data_processing/path_config.py

@@ -15,12 +15,13 @@ import os
 class PathConfig:
     """路径配置管理类"""
 
-    def __init__(self, account_name: Optional[str] = None):
+    def __init__(self, account_name: Optional[str] = None, output_version: Optional[str] = None):
         """
         初始化路径配置
 
         Args:
             account_name: 账号名称,如果不指定则使用默认账号或环境变量
+            output_version: 输出版本,如果不指定则使用项目根目录名称
         """
         # 获取项目根目录
         self.project_root = Path(__file__).parent.parent.parent
@@ -29,12 +30,18 @@ class PathConfig:
         # 加载配置
         self._load_config()
 
+        # 获取数据根目录
+        self.data_root = self._get_data_root()
+
         # 确定账号名称
         self.account_name = self._determine_account_name(account_name)
 
+        # 确定输出版本(默认使用项目根目录名)
+        self.output_version = self._determine_output_version(output_version)
+
         # 构建路径
         account_base = self.config["paths"]["account_base"]
-        self.account_dir = self.project_root / account_base / self.account_name
+        self.account_dir = self.data_root / account_base / self.account_name
 
     def _load_config(self):
         """加载配置文件"""
@@ -44,6 +51,34 @@ class PathConfig:
         with open(self.config_file, "r", encoding="utf-8") as f:
             self.config = json.load(f)
 
+    def _get_data_root(self) -> Path:
+        """
+        获取数据根目录
+
+        优先级:
+        1. 环境变量 DATA_ROOT
+        2. 配置文件 data_root
+        3. 默认值 project_root/data(向后兼容)
+        """
+        # 1. 环境变量
+        data_root = os.environ.get("DATA_ROOT")
+        if data_root:
+            return Path(os.path.expanduser(data_root))
+
+        # 2. 配置文件
+        data_root_config = self.config.get("data_root")
+        if data_root_config:
+            # 支持 ~ 和环境变量
+            expanded = os.path.expandvars(os.path.expanduser(data_root_config))
+            path = Path(expanded)
+            if path.is_absolute():
+                return path
+            else:
+                return self.project_root / path
+
+        # 3. 默认值(向后兼容)
+        return self.project_root / "data"
+
     def _determine_account_name(self, account_name: Optional[str]) -> str:
         """
         确定要使用的账号名称
@@ -81,6 +116,38 @@ class PathConfig:
             "3. 配置文件: 在 config/accounts.json 中设置 default_account"
         )
 
+    def _determine_output_version(self, output_version: Optional[str]) -> str:
+        """
+        确定输出版本
+
+        优先级:
+        1. 函数参数
+        2. 环境变量 OUTPUT_VERSION
+        3. 配置文件中的 output_version
+        4. 项目根目录名称(默认)
+        """
+        # 1. 参数指定
+        if output_version:
+            return output_version
+
+        # 2. 环境变量
+        env_version = os.environ.get("OUTPUT_VERSION")
+        if env_version:
+            return env_version
+
+        # 3. 配置文件指定
+        config_version = self.config.get("output_version")
+        if config_version:
+            return config_version
+
+        # 4. 使用项目根目录名称(默认)
+        project_dir_name = self.project_root.name
+        return project_dir_name
+
+    def _replace_version_var(self, path_template: str) -> str:
+        """替换路径模板中的 {version} 变量"""
+        return path_template.replace("{version}", self.output_version)
+
     def get_enabled_accounts(self) -> List[str]:
         """获取所有启用的账号列表"""
         accounts = self.config.get("accounts", [])
@@ -130,6 +197,7 @@ class PathConfig:
     def intermediate_dir(self) -> Path:
         """中间结果目录"""
         rel_path = self.config["paths"]["output"]["intermediate"]
+        rel_path = self._replace_version_var(rel_path)
         return self.account_dir / rel_path
 
     @property
@@ -156,12 +224,14 @@ class PathConfig:
     def how_results_dir(self) -> Path:
         """how解构结果目录"""
         rel_path = self.config["paths"]["output"]["how_results"]
+        rel_path = self._replace_version_var(rel_path)
         return self.account_dir / rel_path
 
     @property
     def visualization_dir(self) -> Path:
         """可视化结果目录"""
         rel_path = self.config["paths"]["output"]["visualization"]
+        rel_path = self._replace_version_var(rel_path)
         return self.account_dir / rel_path
 
     @property
@@ -194,6 +264,10 @@ class PathConfig:
     def print_paths(self):
         """打印所有路径信息(用于调试)"""
         print("="*60)
+        print(f"项目根目录: {self.project_root}")
+        print(f"项目名称: {self.project_root.name}")
+        print(f"数据根目录: {self.data_root}")
+        print(f"输出版本: {self.output_version}")
         print(f"账号: {self.account_name}")
         print(f"过滤模式: {self.filter_mode}")
         print(f"账号根目录: {self.account_dir}")