途迹-唤醒我的旅途记忆 (Travel Memory Maker) v2
一条数据驱动的 pipeline,把"散乱照片文件夹"变成沉浸式图文游记 + 多风格分享海报,并自动点亮你的中国旅行地图:所有旅程记忆跨次累积、统一空间保管不丢失,且越用越懂你的风格。
照片文件夹 ─①a─▶ 筛选(去重/剔瑕) ─①─▶ photo_inventory.json ─②─▶ trip-structure.json
│
travelogue.html ◀─③── trip-data.json ──④──▶ 单程海报 PNG
│
└─▶ memory.json(自动写入)
│
轨迹海报/点亮地图 ◀──⑤──┘(随时跑,毫秒级)
何时触发
- "整理旅行照片"、"做成图文游记"、"生成旅行海报"
- "我的半年/一年/三年足迹"、"点亮去过的城市"、"旅行轨迹海报"
- 用户提供了照片文件夹(尤其微信传输、EXIF/GPS 丢失的)
- 用户提到"途迹"、"旅途记忆"、"旅行手账"
核心原则
- 照片识别靠 AI 视觉,脚本负责结构化 — 脚本不"看"图,视觉识别由 agent 完成,脚本融合成 JSON
- JSON 契约驱动 — 阶段间用 JSON 松耦合(schema 见 references/schemas.md)
- 脚本零三方依赖(生成阶段) — 仅标准库;海报是纯 HTML+SVG,离线可渲染。例外:阶段①a 照片筛选需 Pillow 做像素级检测(dhash/清晰度/曝光)
- 记忆层是地基 — 每次单程生成自动写入统一空间
~/Documents/旅途记忆空间/memory.json(首次运行自动从~/.workbuddy/travel-memory/迁移),轨迹海报与点亮地图只读它,零读图、毫秒级
5 阶段工作流
阶段 ①a 照片智能筛选 → _rejected/ + screen_report.json(推荐前置)
python scripts/screen_photos.py <照片文件夹> [--output DIR] [--no-move]
- 目的:采集前清理脏数据,保证游记/海报只用"最佳照片"
- 去重:MD5 完全重复;dhash 感知哈希近似重复(连拍/微信多存/轻微编辑),从一组里选最佳(清晰度+分辨率+文件大小综合评分)
- 瑕疵剔除:模糊(拉普拉斯方差)、过曝、欠曝、低分辨率(缩略图)、损坏文件
- 安全:不删原文件,被剔的移入
<照片文件夹>/_rejected/<原因>_原名可恢复;--no-move仅预览 - 依赖:Pillow(像素级检测必需);详见 references/screening.md
阶段 ① 照片采集分析 → photo_inventory.json
python scripts/build_inventory.py <照片文件夹> <ai_recognition.json> <输出目录> [user_dates.json]
- agent 读取照片(大图先缩到 1280px)→ 视觉识别 → 写
ai_recognition.json(键为文件名) - 支持
user_dates.json:{"城市名":"YYYY-MM-DD"},用户补的真实日期,优先级最高(dateSource=user) - 每张照片产出
takenAt/timeSource(exif|filename|user|filesystem) /timeAccuracy(exact|date-only|approx) /chatOrder字段
城市自动识别(无 GPS / 无 EXIF 时):若 ai_recognition.json 未给城市,build_inventory 会用 references/china-cities.json(95 城,含九华山、黄山、峨眉山等小众景区)按照片所在目录名 + 文件名做匹配兜底,命中即自动填城市/经纬度/省份;未命中才需用户显式提供(命名文件夹含城市名最稳,如 九华山旅游照片,或用 orchestrate.py --city)。
阶段 ② 行程结构汇总 → trip-structure.json
python scripts/generate_trip_structure.py <photo_inventory.json>
- 按
takenAt排序分天、推断 tripType - 新增
timeBasis字段(user-provided / exif / filename-inferred / unknown-inferred)+timeNote诚实说明时间来源
阶段 ③ 游记创作 → trip-data.json + travelogue.html
- 先问文风(治愈走心 / 文艺清新 / 攻略实用 / 诗意古风)
- 基于 trip-structure 按天分章写正文 + 每张照片配文 + 三平台文案 →
trip-data.json - 图文并茂:
python scripts/generate_travelogue.py <trip-data.json> [--photos-dir DIR]→travelogue.html(封面+分章内联照片图廊+配文+三平台文案)
阶段 ④ 单程海报 → HTML + PNG
python scripts/generate_posters.py <trip-data.json> [输出目录]
python scripts/render_png.py <HTML目录> <PNG目录> # 单浏览器批量渲染 + Chrome 兜底
- 4 风格(dark-gold / light-ink / night-glow / fresh)× 2 尺寸(3x4 / 1x1)
render_png.py提速:单浏览器实例批量渲染,Playwright 不可用时自动回退系统 Chrome/Edge
阶段 ⑤ 记忆沉淀 + 轨迹海报 + 点亮城市
写入记忆(每次单程生成后自动执行):
python scripts/memory_store.py append <trip_record.json>
trip_record.json 示例:
{
"tripId": "2026-jiuhua-nanjing",
"title": "金陵夜,九华禅",
"dateStart": "2026-06-10", "dateEnd": "2026-06-11", "dateBasis": "user-provided",
"cities": [{"name":"九华山","province":"安徽","lat":30.48,"lng":117.8},
{"name":"南京","province":"江苏","lat":32.06,"lng":118.8}],
"tripType": "heritage-explore", "photoCount": 10,
"highlights": ["地藏王菩萨","秦淮河夜景"], "coverPhotoPath": "/abs/cover.jpg"
}
轨迹海报(随时跑,读记忆、零读图):
python scripts/generate_trajectory.py <memory.json> <参考日期 YYYY-MM-DD> <窗口 6m|1y|3y|all|auto> [输出目录] [style]
→ trajectory-3x4.html + trajectory-1x1.html(暗金风格:数据卡 + 旅程时间轴 + 点亮城市地图)
点亮城市地图(也可独立生成,离线自包含):
python scripts/city_map.py <visited.json|memory.json> <输出.html> [style] [--from-memory]
- 输出是「真实中国地图 + 时间线侧栏」可交互整页:地图用
references/china-geo.json(35 省界+国界)作底图,已访城市发光点用与底图同一投影落在真实方位;右侧时间线按日期排序,悬停/点击城市点弹卡显示城市·省份·到访日期·行程标题,点击时间线行联动高亮地图上的点。 build_map_svg()仍是纯地图 SVG(含真实轮廓),被轨迹海报内嵌复用——改地图样式时两者同步生效。visited.json:{"title":...,"stats":{...},"cities":[{"name":"九华山","date":"2026-06-10","prov":"安徽","trip":"九华禅意"},...]}(prov/trip可选,用于 tooltip 副信息)- 全局连贯地图:传入累积的
memory.json并加--from-memory,所有整理过的游记按到访日期在真实中国地图上连贯点亮(同城多趟显示多个时间点),是"所有游记在一张地图按时间看"的推荐用法。
多地址 / 多日整理思路
当一趟旅行跨多城市、跨多天时,按下述框架组织(框架已原生支持,无需改核心代码):
- 时间聚类(自动):按
takenAt/ 文件名时间戳自动切分自然日 → 多days - 城市归属(三选一,无 GPS 时):
- 子文件夹分城市(推荐):每城一个子目录,城市名从目录名/识别结果取,最稳
- 用户清单优先:给user_dates.json+ 照片→城市归属(或城市日期区间不重叠时自动推断),时间落哪城区间即属哪城
- 视觉自动归属:接入视觉识别后按地标自动判城市(需视觉能力) - 结构(自动):
generate_trip_structure按「城市 × 日」二维分组 → 多locations,每城一章 - 产出(自动):游记多章(城1-Day1/2,城2-Day1…);点亮地图自动多城连线(
visited为城市列表,原生支持)
> 注意:当前模型不读图、照片 EXIF 常丢,城市无法自动识别。多地址务必由用户给城市归属(子文件夹法最稳),否则地图点亮需事后补。
快速编排(半自动)
orchestrate.py 把 agent 手动拼装的环节固化:自动串 ①a 筛选 → ① 采集 → ② 结构,并产出 ③ 游记骨架 与 ⑤ 记忆/地图骨架,你只需在骨架里补「文案」再跑渲染。
python scripts/orchestrate.py <照片目录> [输出目录] [--city 城市名] [--style 文风] [--trip-type 类型] [--no-screen]
- 自动建空间:不传
<输出目录>时,自动在~/Documents/旅途记忆空间/trips/<年份>-<城市>/建成果目录并生成全局map.html;记忆/偏好沉淀到空间memory.json/prefs.json(客户一触发 skill 就有家,成果归拢不丢) - 复制照片到
<输出>/source_photos(不动原目录),在副本上跑筛选,安全 - 城市:给
--city最高优先;否则查「纠正记忆 folderCity」或按原文件夹名自动识别(命中 95 城库) - 产出
ai_recognition.json/photo_inventory.json/trip-structure.json/trip-data.json(骨架) /trip_record.json(骨架) /visited.json(骨架) /prefs.json(学习偏好) - 自动学习:
--style/--trip-type沉淀到 prefs(下次默认带出);检测到你把_rejected/被剔照片移回source_photos会自动放宽该维度筛选阈值;文件夹名→城市、城市→类型映射被记住 - 之后 agent 填
trip-data.json的chapters.body与platforms,再跑 ③④⑤ 渲染(脚本打印下一步命令)
统一空间与自动学习(v2.0.3)
客户一触发 skill,就在 ~/Documents/旅途记忆空间/ 自动建好"家"——所有成果归拢、长久不丢、跨项目通用、不随工作区删除而丢失。
空间结构
~/Documents/旅途记忆空间/
├── memory.json # 记忆层(全局唯一,所有游记连贯累积)
├── prefs.json # 学习偏好(文风/配色/筛选阈值/纠正记忆)
├── trips/<年份>-<城市>/ # 每趟成果分类目录(source_photos/ 副本 + 各 JSON + posters/ + travelogue.html)
└── map.html # 全局城市地图(吃 memory.json,所有游记按时间连贯点亮)
自动学习进化(越用越聪明)
- 偏好学习:每次
--style/--trip-type沉淀到prefs.json,下次运行默认带出,不用重复选。 - 筛选阈值自适应:检测到你把
_rejected/里被剔照片移回source_photos(即你认为筛选过严),自动放宽该维度阈值(blur/过曝/欠曝/低分辨率/dhash),下次更宽容——闭环靠"你恢复照片"这一动作触发。 - 城市/类型纠正记忆:文件夹名→城市(folderCity)、城市→行程类型(cityType)的映射被记住,下次同场景直接复用,减少确认。
全局连贯地图:city_map.py 直接吃累积 memory.json(加 --from-memory),所有整理过的游记按到访日期在真实中国地图上连贯点亮;同城多趟显示多个时间点和时间线条目,正好满足"看什么时间去这个城市"。
地址无误:所有写入记忆/成果的路径统一 os.path.normpath 规范化,杜绝正/反斜杠混用;写文件前 makedirs 校验父目录。
> 首次运行会自动把旧 ~/.workbuddy/travel-memory/memory.json 迁移进空间(只读复制,不删原文件)。
大图处理
照片 >3MB 或 >3000px 先缩到 1280px 宽存 source_photos_small/,只读取缩小版做识别;filePath 仍指向原图用于渲染。
文件结构
travel-memory-maker/
├── SKILL.md
├── scripts/
│ ├── screen_photos.py # ①a 照片筛选(去重+剔瑕,依赖 Pillow)
│ ├── build_inventory.py # ① EXIF+识别 → photo_inventory(含 user_dates 支持)
│ ├── generate_trip_structure.py# ② 按时间排序 + timeBasis
│ ├── generate_travelogue.py # ③ 图文并茂 travelogue.html
│ ├── generate_posters.py # ④ 单程海报 4风格×2尺寸
│ ├── generate_trajectory.py # ⑤ 轨迹海报(4时间窗,嵌入点亮地图)
│ ├── city_map.py # ⑤ 点亮城市地图
│ ├── memory_store.py # ⑤ 记忆层读写(幂等:tripId / 城市+日期 双重判同程)
│ ├── orchestrate.py # 半自动编排①a→①→②,产出③④⑤骨架
│ └── render_png.py # ④ 单浏览器批量渲染 + Chrome 兜底
├── references/
│ ├── schemas.md # 全部 JSON schema(含 memory/trajectory/map)
│ ├── poster-styles.md # 4风格配色 + 尺寸
│ ├── china-cities.json # 城市经纬度库(95 城,含景区)
│ ├── china-geo.json # 中国省界+国界 GeoJSON(真实地图底图,~570KB)
│ └── workflow.md # 决策树 + 异常处理
└── assets/examples/
依赖
- Python 3.8+;Pillow(阶段①a 照片筛选必需 — dhash/拉普拉斯方差/亮度直方图);Playwright(PNG 渲染,可选,无则 Chrome 兜底)
- 生成阶段(②③④⑤ 脚本主体)零三方依赖
快速开始
# 单程
python scripts/screen_photos.py ./photos # ①a 先筛选(推荐)
python scripts/build_inventory.py ./photos ./ai_recognition.json ./out [./user_dates.json]
python scripts/generate_trip_structure.py ./out/photo_inventory.json
# 写游记 → ./out/trip-data.json
python scripts/generate_travelogue.py ./out/trip-data.json --photos-dir ./photos
python scripts/generate_posters.py ./out/trip-data.json ./out/posters
python scripts/render_png.py ./out/posters ./out/png
# 沉淀记忆
python scripts/memory_store.py append ./trip_record.json
# 轨迹 / 点亮(记忆足够后随时跑)
# 窗口: 6m(半年) | 1y(一年) | 3y(三年) | all(全部) | auto(自动选最小够用窗口)
python scripts/generate_trajectory.py ~/.workbuddy/travel-memory/memory.json 2026-07-20 auto ./out/traj dark-gold
python scripts/render_png.py ./out/traj ./out/traj_png