导语:一名叫 Oldcircle 的开发者10月18日在 GitHub 上线了一个叫 geo-sleuth 的 Agent Skill,核心能力是”扔一张照片给 AI 智能体,它告诉你拍摄地点”。这套工具不靠文字、地标或车牌,只用 OpenStreetMap 几何、海拔天际线、卫星瓦片和街景图像交叉定位,仓库自带 3 个真实案例,最远精度做到 ±2 米。它采用标准 Agent Skill 协议(SKILL.md + 脚本),所以一份副本能同时跑在 Claude Code、Codex、Cursor、Gemini CLI、OpenCode 与 GitHub Copilot 6 款主流 agent 上。
一、它做什么
一句话工作流是:给 AI 智能体一张照片,说一句”find where this photo was taken”,它会回你相机经纬度、镜头朝向、误差半径和一张卫星证据图。
与常规反向图片搜索不同,geo-sleuth 不靠图片指纹或文本标签。它的判断完全来自”几何”——桥墩间距当尺子、阴影当方位、远山轮廓当指纹,再叠加海拔、卫星和街景数据,把候选点逐级收窄。
仓库地址:https://github.com/Oldcircle/geo-sleuth,MIT 协议,截至 2026-10-18 已有 3,357 颗星、453 个 fork。首次提交 9 月 18 日,一个月内涨到该数字。

二、它怎么工作
geo-sleuth 的核心设计是”脚本做决定,脚本做感知,模型只在 top few 里判断”。20 多个独立小脚本各管一摊,模型只在候选名单里挑答案。
flowchart LR
A["photo"] --> B["intake.py
EXIF · OCR · reverse image search"]
B --> C["board.py
candidate board: clues, likelihood ratios, ranking"]
C --> D{"which branch?"}
D --> E["sun.py · terrain.py · osm.py · pose.py
shadows, skylines, OSM corridors, camera pose"]
D --> F["sat_scan.py · match.py · gsv.py · baidu_pano.py
CLIP satellite tiles, DINOv2+SIFT street view"]
E --> G["board.py check · report"]
F --> G
G --> H["evidence.py
coordinates ± radius · evidence image · graded confidence"]
三层分工:
- 决策层(
board.py):维护候选名单、累积线索权重、决定下一步往哪里扫。 - 感知层(
intake.py/ocr.py/clues.py/sat_scan.py/match.py/terrain.py等):读取 EXIF、做 OCR、跑反向图片搜索、计算天际线、把街景和照片做 DINOv2 + SIFT 匹配。 - 判断层(
SKILL.md+ 模型):从候选 top few 里挑出最终位置。
仓库强调”每个结论都需指向运行过的命令和产生的文件”。人口和知名度不能当证据,所有线索都来自脚本实测。
三、三个真实案例
仓库 README 给出的三个公开案例各自代表一种方法论。
案例一:稻田和高架桥(±2 米,广东清远)
EXIF 被剥离的一张手机照片:白灶台、远处高架桥、右侧陡山,画面里没有任何字符。geo-sleuth 把广州-清远城际 27,335 个 OSM 铁路桥段全部拉下来,每 400 米采一个点算出 360° 天际线,筛掉地面没有平地、附近几公里没有山、视野没有清晰山脊的,得到 171 个候选点。再用天际线拟合 14,372 个相机位置,top 20 在 0.1° 内,叠加”桥近-远”的约束后只剩 22 个点。把 17 根桥墩当成 17 条方向线打过去,它们在铁路上投影必须等距——只有 1 个点满足,到确认相机位置 ±2 米。
案例二:沙漠天际线(87 米,青海大柴旦)
前景沙丘、远山、电塔,画面里没有文字、公路或建筑,反向图片搜索只能给通用沙漠图。脚本在新疆、甘肃、宁夏、青海 4 省拉出 1,537 个候选点,按天际线打分。青海的前 25 个点在 9.6 到 11.7 像素之间挤在一起——真人拍照手机通常有 1° 左右倾斜,这一误差就会在 2048 像素画幅的边缘产生 18 像素的偏移,差不多就是候选点之间的差距。terrain.py fit 加入滚转角(roll)联合求解后,青海的真实点从 11.1 像素掉到 6.2 像素,第二名 9.4 像素,差距拉开。沿着视线方向 1 公里内有三个月牙形沙丘和一处营地,相机就站在营地西侧的沙丘顶上,朝向 205°。

案例三:温哥华樱花街(3 米,W 60th Ave)
照片是一棵樱花树、BC 省白蓝车牌、深绿色路灯、温哥华风格住宅。温哥华市政府公开了 184,517 棵街道树的坐标、树种与树干直径,候选从这份数据里来:树径 ≥ 40 厘米的樱花、每个 block 至少 3 棵,1,095 棵树,97 个 block。再用阴影方向和横坡去掉 72 个 block 里不匹配的,剩几条街。100 号 W 60th Ave 北侧排满大樱花,南侧 30–60 米处是 7.6 厘米的幼苗,下一棵大树要 75 米开外——和照片里”近端没树、远端有粉色花冠”完全对应。叠加 2009、2024 街景里的石阶、挡土墙、灯柱、屋顶露台,相机在北侧人行道上朝东,3 米误差。

这三个案例都跑过盲测复跑:给新 agent 一张照片(沙漠那张只给”在中国”一个提示),按现行技能从头跑到尾,结果分别为 87 米(32 分钟)和 3 米(53 分钟)。仓库把这些作为回归基线,约束核心脚本的修改不得影响已有案例。
四、数据源、安装与平台
数据源来自 4 个公开服务,仓库不内置任何数据库:
- OpenStreetMap(ODbL)——铁路、街道、输电线、行政区划。脚本实时跑 Overpass API 查询,不打包 OSM 数据。
- AWS Terrain Tiles(Terrarium)——海拔数据,用于天际线与地势判断。
- Baidu 街景 / Google Street View——地面级图像匹配。
- CLIP / DINOv2 / Apple Vision / RapidOCR——卫星瓦片 zero-shot 评分、街景相似度、文字识别。
安装方式两种。最简单是 npx:
npx skills add Oldcircle/geo-sleuth
按提示勾选要启用的 agent 即可。手动安装则把所有 6 款 agent 一次性装到 ~/.agents/skills/,再软链到 ~/.claude/skills/:
git clone https://github.com/Oldcircle/geo-sleuth
cp -r geo-sleuth/skills/geo-sleuth ~/.agents/skills/
ln -s ~/.agents/skills/geo-sleuth ~/.claude/skills/geo-sleuth
平台支持列表:Claude Code、Codex、Cursor、Gemini CLI、OpenCode、GitHub Copilot,以及”任何读 SKILL.md 并能跑 shell 的 agent”。agent 间共享同一份副本,互不重复占空间。
首次使用前要在智能体里跑一次 doctor.py 检查 Python 3.10+、uv、curl、浏览器(Chrome 或 Playwright Chromium)等依赖。match.py / sat_scan.py 跑 ML 模型,CUDA 优先、MPS 次之、CPU 兜底;Windows 默认装的是 CPU 版 torch,要用 NVIDIA GPU 需追加 CUDA 构建(首跑约下载 2.4 GB 模型权重)。
五、使用须知与限制
- 仓库采用 MIT 协议,但 OSM 数据遵循 ODbL,发布查询结果时需标注 © OpenStreetMap contributors。
revimg.py依赖 Google Chrome 或 Playwright Chromium,没有装的话反向图片搜索会失败;本地图像处理仍可用。- 所有结论必须能追溯到具体命令与文件——”人口多”或”网红打卡”不能当证据。
- 不同 agent 或模型在同张照片上可能给出不同结果,README 的”Reproduction conditions and checkpoints”明确列出了每步的检查点(候选数、阈值、过滤条件),方便复现者定位”是哪一步开始跑偏的”。
- 在国内环境下,Baidu 街景可用,Google Street View 不可用;卫星瓦片服务依区域会有访问限制。
geo-sleuth 不只是个 demo——它把 OSINT 圈 14 个创作者的视频、22 道公开谜题和多次真实跑批的方法论拆成 20 多个脚本,让”凭经验猜”变成”按规则跑”。这恰好是 Agent Skill 范式最擅长的事:把”过程”交给代码,把”判断”留给模型,结果可复现、可审计、可扩展。














暂无评论内容