多数导航应用只回答一个问题:去那里最快的路线是什么? WanderLust 问的是另一个问题:多出来的那几分钟,也许正是礼物。 你告诉它要去哪里,以及想要什么样的时刻,“一个慢悠悠的周日早晨式散步”“书店和安静的街道”“热闹的咖啡馆巡游”。它会把你从 A 带到 B,路过你真正会喜欢的地方,再用你自己的话解释每一站为什么在这条路线上。目的地没变,但这趟散步会被记住。
WanderLust 是 Build Small Hackathon 的参赛作品(Backyard AI 赛道),支持四大洲的九座城市:巴黎、伦敦、巴塞罗那、柏林、纽约、旧金山、东京、孟买、上海。路线规划完全离线,请求时不调用任何云端 API。
为什么做它
这个项目出自作者自己的需求。两人喜欢骑行,在陌生城市骑车时总会碰上同一个问题:地图只知 道两点之间最快的那条线,可探索身边“后院”的乐趣,往往就藏在那家书店、那个安静的广场、那个直线路线上永远看不到的观景点里。他们想要一个能按当天心情规划 A 到 B 有趣路线的工具。WanderLust 就是这个个人化、本地优先的探索伙伴。
为什么 AI 不可或缺
没有模型,WanderLust 跑不起来。 真正的难点不在路线规划,而在人们描述需求和路由器能优化的目标之间那道鸿沟。用户输入的是模糊、开放的氛围(“感觉像慢悠悠的周日早晨的地方”),MiniCPM5-1B 把它转成具体的、带分数的路由权重,覆盖 17 种地点类别,以及安静、绿意、热闹这些修饰项。查表、关键词列表、规则引擎都没法把没有边界的心情映射到路线上,模型就是那座桥。之后它还会写行程说明,解释每个被选中的站点为什么符合你的要求,并且有约束保证它只能提到路线上真实存在的地点。
(没分到 GPU 时,应用会退回嵌入 + 关键词解释器和确定性模板,不会崩,但正是模型让体验像是读懂了你的心思。)
技术一览
- 模型
openbmb/MiniCPM5-1B:一个 1B 参数的模型干两份活:氛围 → 路由权重(JSON),路线 → 第一人称行程叙述。 - ZeroGPU:模型通过
@spaces.GPU在 HF ZeroGPU 上于 Space 内部运行,权重从 Hub 拉取,没有外部推理 API,数据不出 Space。 - OpenStreetMap + OSMnx:九座城市的步行 / 骑行路网和 POI 预先构建,从公开的 Hub 数据集拉取,启动时预热,每座城市都能即时响应,请求时零云端 API 调用。
- 路线规划(经典、精确):用
networkx+ SciPy 的多源 Dijkstra 算通行时间矩阵,再由自定义的定向越野(orienteering,带奖励收集的 TSP)启发式求解,带子模多样性约束。结果是一座公园、一个观景点、一家书店,而不是五家咖啡馆。 - 前端 Gradio
gr.Server:在 Gradio 的 FastAPI 后端上手写 HTML/CSS/JS 应用外壳,浏览器通过@gradio/client调用,不使用任何默认 Gradio UI。
功能
- 普通路线与探索路线画在同一张地图上,并显示绕路多花的确切时间。
- 氛围 → 路线:自由文本描述的心情会改变路线要找的地方。
- 步行或骑行,覆盖九座城市,带城市选择器(城市核心区数据按需拉取)。
- 绕路预算:滑块用额外时间换探索,路线时间不会超过直达时间的
(1 + budget) ×。预算为 0 就是普通的最快路线。 - 冒险程度:低 → 知名度高的地方;高 → 加入小众宝藏地点。
- 有据可依的叙述:行程说明只会提到真实途经点,背后有严格的零幻觉检查。
- 备选路线:最多三条真正不同的路线。
- 持久化口味档案:长期偏好和收藏地点按设备保存,与每次出行的心情融合。不需要账号。
架构
离线阶段(每座城市构建一次并缓存):OSM 数据提取 → 步行 / 骑行路由图 → 带特征先验和置信度的 POI。巴黎包含全城数据;其余八座城市(伦敦、巴塞罗那、柏林、纽约、旧金山、东京、孟买、上海)用 python -m discoverroute.data.build_city 烘焙成可步行的核心区,托管在公开的 Hub 数据集上,启动时拉取并预热。
运行时(每次请求):选城市 → 解释氛围 → 给走廊内的 POI 打分 → 求解绕路(定向越野)→ 描出真实折线 → 生成叙述并叠加到地图上。
模型只在解释和叙述环节起关键作用,路线规划完全是经典算法。地理编码本地优先:地名在缓存的 POI 索引里解析,不需要网络调用。部署配置 DISCOVERROUTE_OFFLINE=1 下,请求时零云端 API 调用,路线规划限于预先烘焙的城市。地图数据 © OpenStreetMap contributors(ODbL)。
开放数据
项目在 Hub 上公开了两个可复用的产物:城市核心区数据集 build-small-hackathon/discoverroute-cities,以及推理 trace 数据集 build-small-hackathon/discoverroute-traces。完整的构建过程,包括决策、走过的弯路和修复,都记在 FIELD_NOTES.md 里,并发布为 HF 博客文章。
本地运行
uv venv --python 3.11
uv pip install -e ".[ml,dev]" # routing + vibe interpretation/narration + tests
# one-time offline data prep for Paris (downloads OSM, builds the graph + POIs)
python -m discoverroute.data.build_graph
python -m discoverroute.data.build_pois
python app.py # serves the gr.Server app-shell on :7860
其余八座城市会按需从 Hub 数据集拉取(启动时预热)。测试用 pytest 跑,配置在 pyproject.toml,测试文件在 tests/。
相关链接
- Hugging Face Space:build-small-hackathon/WanderLust
- 源代码(GitHub):tristanleduc/wanderlust
- 演示视频:YouTube
- 社交帖子:LinkedIn · X/Twitter
- 构建笔记(HF 博客):WanderLust
项目团队:
- Ishrat Jahan Ananya:Hugging Face · GitHub · 个人网站
- Tristan Leduc:Hugging Face · GitHub · LinkedIn
