前情提要
事情是这样的:我想用AI 规划一条云南7天行程(昆明→ 大理→ 丽江),并希望能把行程同步到手机高德App,扫码直接导航。
在这个过程中踩了几个坑,最后成功跑通了一套完整的AI → 高德地图工作流。
两个高德地图Skill,傻傻分不清
一开始装错了skill,导致白跑半天。高德官方在Clawhub 上发布了两套工具,定位完全不同:
Skill 名称 | 功能定位 | 输出形式 |
amap-cli-skill | 地图可视化+ 路径规划CLI | 在amap-gui 容器里渲染地图 |
personal-map | 生成个人专属地图小程序二维码 | 扫码在高德App 打开 |
我想实现的是「扫码让手机高德App 获取路线」,所以personal-map才是正确答案。
安装命令:
clawhubinstall personal-map
踩坑一:AMAP_KEY 和AMAP_API_KEY 是两套Key
配置Key 的时候遇到了一个经典问题:高德开放平台有两套独立的Key 体系:
Key 变量 | Key 类型 | 用途 |
AMAP_KEY+ AMAP_SECURITY_KEY | Web JS API Key | 地图可视化(amap-gui 用) |
AMAP_API_KEY | Web 服务API Key | REST API 调用(personal-map 用) |
之前配的是AMAP_KEY(Web JS API),但personal-map需要单独申请Web 服务API Key。
申请步骤:
1.打开https://console.amap.com/dev/key/app
2.登录→ 点击「创建Key」
3.勾选Web 服务API
4.复制新的Key
写入~/.openclaw/openclaw.json:
"personal-map":{
"env":{
"AMAP_API_KEY":"你的新Key"
}
}
踩坑二:pointInfoList 里的name 字段不能漏
一开始调用maps_schema_personal_map报错:poiId不能为空
改为传入poiId 后又报错:name不能为空
调试后发现,personal-map的POI 数据结构要求name、lon、lat、poiId 四个字段缺一不可,而SKILL.md 示例里漏了name字段。
正确格式:
line_list=[
{
"title": "Day3-4 大理",
"pointInfoList": [
{"name": "大理古城", "lon": 100.164, "lat": 25.694836, "poiId": "B0FFFZH0RQ"},
{"name": "洱海", "lon": 100.247321, "lat": 25.603053, "poiId": "B0368006Y0"},
]
},
]
踩坑三:POI ID 要用搜索API 获取
直接用地理坐标是不行的,必须先通过maps_text_search获取POI ID(高德地图内部POI 唯一标识)。
获取POI ID 示例:
client=AMapPersonalMapClient()
result =client.maps_text_search("大理古城", "大理", offset=1)
poi_id =result[0]['id'] # B0FFFZH0RQ
poi_lon =result[0]['location']['longitude'] # 100.164
poi_lat =result[0]['location']['latitude'] # 25.694836
注意:高德搜索API 返回的字段是id(不是poiId),坐标在location.longitude/latitude,不是顶层的lon/lat。
踩坑四:飞书不认file:// 路径的图片
生成二维码后的PNG 图片保存在~/Downloads/目录,直接在飞书消息里用格式是不显示的。
解决方案:上传到临时存储,生成公开URL 再发送。
importurllib.request
qr_url =result['qr_code_url'].replace('size=300x300', 'size=1000x1000')
out_path ='/Users/devinchan/Downloads/云南行程_个人地图二维码.png'
urllib.request.urlretrieve(qr_url, out_path)
# 上传到tmpfiles.org 获取公开URL
完整使用流程
1. 安装skill
clawhubinstall personal-map
2. 申请Web 服务API Key
去高德控制台申请,写入配置文件。
3. 用Python 调用
importsys, urllib.request
sys.path.insert(0, '~/.openclaw/workspace/skills/personal-map/scripts')
fromamap_personal_map_client importAMapPersonalMapClient
client =AMapPersonalMapClient() # 自动读取AMAP_API_KEY 环境变量
# 搜索POI 获取ID
pois =client.maps_text_search("大理古城", "大理", offset=1)
poi =pois[0]
# 构造行程数据
line_list =[
{
"title": "大理两日游",
"pointInfoList": [
{
"name": poi['name'],
"lon": poi['location']['longitude'],
"lat": poi['location']['latitude'],
"poiId": poi['id']
}
]
}
]
# 生成二维码
result =client.maps_schema_personal_map("我的行程", line_list, sceneType=1)
qr_url =result['qr_code_url']
4. 下载并展示
out_path='/Users/devinchan/Downloads/行程二维码.png'
urllib.request.urlretrieve(qr_url.replace('300x300', '1000x1000'), out_path)
# 上传到tmpfiles.org 获取公开URL
最终成果
云南7天行程(昆明→ 石林→ 大理→ 丽江)已生成个人专属地图二维码:
用高德地图App 扫码就能在手机上看到完整的行程路线,点每个景点直接导航。
附:两个Skill 对比总结
amap-cli-skill | personal-map | |
核心功能 | 地图可视化+ 路径规划 | 生成小程序二维码 |
输出 | amap-gui 容器地图 | QR code 图片 |
Key | AMAP_KEY + AMAP_SECURITY_KEY | AMAP_API_KEY |
适用场景 | 在AI 对话里看地图 | 扫码在手机高德App 查看 |
安装命令 | clawhub install amap-cli-skill | clawhub install personal-map |

夜雨聆风