我把刘备一生做成了可播放的高德地图,还把整套方法封装成了 Skill
人生很短,不过三万天。 当时间被放到地图上,一个人的一生,会不会变成一条可以被看见、被播放、被重新理解的路?
我们了解一个历史人物时,通常会看到这样的文字:
- 161 年,刘备出生于涿郡;
- 194 年,接掌徐州;
- 201 年,屯兵新野;
- 214 年,进入成都;
- 221 年,称帝;
- 223 年,病逝于白帝城。
这些信息单独看都没有问题,但读完之后,我脑子里仍然缺少一个直观印象:
刘备这一生,到底走了多远?
他为什么不断改变落脚点?
从华北到中原,从荆州到益州,一次次迁徙背后意味着什么?
如果把这些事件放回真实地图,并沿时间顺序逐段播放,也许我们就能从空间视角重新理解这个人物。
于是,我做了 LifeTrace · 人生经纬。
它是一个基于高德开放平台的人物一生足迹地图 Skill,可以把人物资料整理成"时间---地点---事件---来源---可信度"数据,在真实高德地图上播放人物轨迹,同时展示人物形象、历史事件、资料来源和现代位置。
项目既能用于刘备这样的历史人物,也支持导入普通人的 JSON 或 CSV 数据,生成属于自己的数字人生地图。


但我并不想只做一个"刘备人生地图"。
如果项目最终只能展示刘备,那么它仍然只是一个完成度较高的案例。
真正让我决定把它包装成 Skill 的原因是:
我希望任何人都能把自己、家人、偶像或者某位历史人物,变成这样一张可以播放、可以浏览、可以分享的人生地图。
用户不需要掌握高德地图 API,也不需要手动修改大量前端代码。
他只需要提供时间、地点和故事,Agent 就可以按照 Skill 中定义的流程,完成资料整理、地点处理、坐标查询、页面构建和本地预览。
这也是 LifeTrace 从一个前端项目走向 Skill 的核心原因:
网页交付的是一个结果,Skill 交付的是持续生成结果的能力。
一、为什么要把人物传记放到地图上?
传统人物传记通常围绕时间展开。
例如:
javascript
161 年:出生于涿郡
184 年:参与镇压黄巾军
194 年:接掌徐州
201 年:屯兵新野
214 年:领益州牧
221 年:成都称帝
223 年:白帝城托孤
这种表达足够清晰,但缺少空间关系。
"从涿郡到徐州"意味着什么?
"从中原辗转到新野"有多远?
"进入益州"为什么会成为刘备人生真正的转折点?
"夷陵战败后退到白帝城",在空间上又是怎样的一次回撤?
这些内容,仅靠一条纵向时间轴很难建立直觉。
地图则天然能够把一个人的经历组织成三个维度:
javascript
什么时候发生
+
在哪里发生
+
发生了什么
当时间轴和地图叠加之后,人物经历不再是一组相互独立的事件,而会变成一条连续的人生路径。
所以,我希望这个项目不只是显示若干地点,而是能够像播放视频一样:
- 从人物的出生地开始;
- 按照年份依次点亮地点;
- 绘制前后事件之间的轨迹;
- 同步切换人物故事;
- 高亮当前人生阶段;
- 最后停留在人物生命的终点。
这就是 LifeTrace 最初的产品构想。

二、最终做出来的,不是一张静态地图
在当前刘备案例中,用户可以:
- 播放完整人生轨迹;
- 暂停并继续播放;
- 调整播放速度;
- 点击地图节点查看事件;
- 点击时间轴跳转到对应年份;
- 按人生阶段筛选事件;
- 浏览人物像与核心故事插图;
- 查看事件来源与可信度;
- 打开地点对应的高德地图位置;
- 重置并重新播放整段人生。
项目 README 将这些功能概括为:高德地理编码、真实 JS API 地图、地点标记、路线播放、阶段筛选、地图与时间线联动、人物与故事画廊,以及史料来源与可信度标记。
整个页面主要分成四个区域:

javascript
左侧:人物标题、阶段统计、事件信息
中间:高德地图与动态轨迹
右侧:人物画廊与人生纪事
底部:完整人生时间轴与播放控制
地图不是装饰背景,而是整个叙事的中心。
人物每前进到一个事件,地图、路线、信息卡片、人物画廊和时间轴都会同步变化。
三、为什么选择高德?不是先选 JS API,而是先通过 Skill 和 CLI 找到实现路径
在开始这个项目之前,我对地图开发并不熟悉。
我知道自己想要实现什么:把刘备一生中的时间、地点和事件放到地图上,让路线可以播放,让地图节点能够与时间轴和人物故事联动。
但真正开始开发时,一系列问题很快出现了:
- 人物地点应该用什么方式显示?
- 地点之间的路线应该怎样绘制?
- 地址怎样转换成经纬度?
- 地图如何跟随事件自动移动?
- 点击节点后怎样展示人物故事?
- 应该选择 Web 服务、JS API,还是其他地图开发方案?
- 高德 Key、安全密钥和坐标参数应该如何配置?
对熟悉地图开发的人来说,这些可能只是基础问题。但对我而言,如果直接从大量 API 文档开始查找,很容易出现"知道自己想做什么,却不知道该从哪个接口开始"的情况。
所以,我最开始并不是直接决定使用高德 JS API 2.0,而是先借助了高德提供的 Skill 和 CLI 工具。

高德已经针对不同开发场景提供了多类 Skill,例如:
- 位置服务 Skill:提供 POI 搜索、路径规划、地理编码等位置服务能力;
- 地图开发 Skill:面向 Web 地图开发,提供地图加载、覆盖物绘制和 LBS 服务集成能力;
- Android Agent Skill:帮助 Android 应用接入地图导航与 AI 助手能力;
- iOS Agent Skill:面向 iOS 应用提供自然语言驱动的地图能力;
- RTOS 地图 Skill:面向智能手表等轻量级设备;
- 时空洞察 Skill:用于分析业务数据中的时空规律。
这些 Skill 并不是简单地列出一批 API,而是按照具体使用场景,告诉开发者和 Agent:
javascript
要完成什么任务
↓
应该选择哪类地图能力
↓
需要使用哪些接口
↓
如何配置和调用
↓
常见问题怎样处理
这对于我这样的地图开发初学者非常重要。
我不需要先完整学习整个地图技术体系,再从几十种能力中自行组合,而是可以先把需求描述清楚:
javascript
我要制作一个 Web 人物轨迹页面。
页面中需要展示多个地点节点,
按照时间顺序连接路线,
支持点击节点查看事件,
并让地图与时间轴同步播放。
地图开发 Skill 会围绕这个目标,帮助我理解需要使用的核心能力,包括:
- 创建 Web 地图;
- 添加人物地点 Marker;
- 使用 Polyline 绘制轨迹;
- 监听地图和覆盖物点击事件;
- 调整地图中心点与缩放级别;
- 使用地理编码将地点转换为坐标;
- 配置 Web 端 Key 与安全密钥。
在这个过程中,我才逐渐明确:
LifeTrace 最终需要的不是一张静态地图,也不是单纯的位置查询服务,而是一套能够在浏览器中承载节点、轨迹和交互状态的地图开发能力。
因此,项目最终选择了 高德地图 JS API 2.0。
换句话说,我的技术选择过程并不是:
javascript
先决定使用 JS API 2.0
↓
再研究它能做什么
而是:
javascript
先明确人物轨迹展示需求
↓
借助高德 Skill 理解地图能力
↓
通过 CLI 和示例验证调用方式
↓
确认项目需要 Web 交互地图
↓
最终选择高德 JS API 2.0
Skill 帮我理解"应该用什么"
高德 Skill 更像一份面向 Agent 和开发者的地图开发指南。
它帮助我把模糊的产品需求转换成具体的技术能力:
td {white-space:nowrap;border:0.5pt solid #dee0e3;font-size:10pt;font-style:normal;font-weight:normal;vertical-align:middle;word-break:normal;word-wrap:normal;}
| LifeTrace 的产品需求 | 对应地图能力 |
|---|---|
| 在地图上显示人生地点 | Marker 点标记 |
| 连接前后人生事件 | Polyline 折线 |
| 点击地点查看故事 | 覆盖物点击事件 |
| 播放时移动地图视野 | 地图中心与缩放控制 |
| 将城市名称转换成坐标 | 地理编码 |
| 在浏览器中展示完整页面 | JS API 2.0 |
| 后续查询地点和位置 | 位置服务能力 |
对于熟悉高德地图的开发者,这些对应关系可能非常自然;但对初次接触地图开发的人来说,Skill 相当于先帮助我完成了技术路线梳理。
CLI 帮我验证"应该怎样调用"
在理解需要哪些能力之后,CLI 又进一步降低了尝试成本。
过去验证一个位置服务,可能需要先创建工程、安装依赖、编写请求代码,然后才能看到结果。
通过 CLI,一些地图或位置能力可以直接在终端中调用和验证。
它让开发流程从:
javascript
查文档
↓
创建测试页面
↓
写临时代码
↓
启动项目
↓
查看结果
缩短为:
javascript
描述或输入参数
↓
执行命令
↓
查看地图或位置结果
对 LifeTrace 来说,这种方式特别适合前期验证:
- 一个现代地址能否正确解析;
- 某个地点名称是否存在歧义;
- 坐标是否落在合理区域;
- Key 和安全密钥是否配置成功;
- 当前需求更适合 Web 服务还是 JS API;
- 地图能力是否能够进入后续自动化流程。
Skill 负责告诉我"应该选择什么能力",CLI 负责帮助我快速验证"这种能力怎样使用",而 JS API 2.0 最终负责在正式页面中完成地图渲染和交互。
三者之间的关系可以概括为:
javascript
高德 Skill
帮助理解和选择地图能力
↓
高德 CLI
帮助快速调用和验证能力
↓
高德 JS API 2.0
负责正式页面的地图展示与交互
为什么最终是 JS API 2.0?
经过 Skill 的引导和 CLI 的验证,我确认 LifeTrace 需要满足几个关键条件:
- 运行在浏览器中
- 项目最终生成的是一个可浏览、可分享的人物人生页面,因此需要 Web 地图能力。
- 支持多种地图覆盖物
- 人物事件需要显示为地点节点,前后经历需要绘制为折线,还要展示事件信息和当前状态。
- 支持丰富的交互事件
- 用户需要点击节点、拖动地图、切换时间轴,并在播放过程中自动调整地图视野。
- 能够与页面状态联动
- 地图不是独立模块,而要与事件卡片、故事画廊、播放进度和时间轴同步变化。
- 方便继续接入位置服务
- 项目后续还需要地理编码、地点查询以及现代位置链接等能力。
高德 JS API 2.0 刚好能够承载这些需求,因此它不是项目一开始凭经验选定的技术,而是在高德 Skill 和 CLI 的辅助下,逐步确认出的实现方案。
这也是我在开发 LifeTrace 时,对高德工具体系感受最深的一点:
对一个不熟悉地图开发的人来说,真正困难的往往不是写出某一行 API 代码,而是先知道自己应该使用什么能力。
高德 Skill 把文档和开发经验整理成可理解、可复用的工作方法,CLI 又进一步降低了能力验证和调用的门槛。它们让我不必先成为地图专家,也能够逐步完成一个包含地图节点、动态轨迹、时间轴联动和人物故事展示的完整项目。
四、高德 JS API 如何承载人物轨迹?
在 LifeTrace 中,每一段人生经历最终都会变成一个地图事件。
一个简化后的事件数据可以写成:
javascript
{
year: 201,
title: "屯兵新野",
stage: "荆州时期",
position: [112.36, 32.52]
}
页面根据事件数据创建 Marker:
javascript
const marker = new AMap.Marker({
position: event.position,
title: event.title
});
map.add(marker);
再将前后事件连接成 Polyline:
javascript
const polyline = new AMap.Polyline({
path: [
previousEvent.position,
currentEvent.position
],
strokeWeight: 6,
strokeOpacity: 0.9
});
map.add(polyline);
高德官方提供的 amap-jsapi-skill 覆盖了地图生命周期、Marker、InfoWindow、Polyline、Polygon、图层、交互事件、地理编码、路线规划和 POI 搜索等完整能力。
这套能力与 LifeTrace 的需求几乎天然对应:
td {white-space:nowrap;border:0.5pt solid #dee0e3;font-size:10pt;font-style:normal;font-weight:normal;vertical-align:middle;word-break:normal;word-wrap:normal;}
| LifeTrace 需求 | 高德能力 |
|---|---|
| 显示人物地点 | AMap.Marker |
| 连接人生节点 | AMap.Polyline |
| 点击查看事件 | 地图与覆盖物事件 |
| 聚焦当前地点 | setCenter、setZoom |
| 展示地点信息 | AMap.InfoWindow |
| 地址转换坐标 | AMap.Geocoder |
| 搜索现代地点 | AMap.PlaceSearch |
| 展示大量节点 | LabelsLayer、MassMarks |
对于一个以中国人物和中国地点为核心的项目而言,高德让"时间---地点---事件"这套数据能够非常自然地落到真实地图上。
五、高德最方便的地方,不只是 API
传统地图开发的流程往往是:
javascript
阅读文档
↓
确定接口
↓
复制示例
↓
配置 Key
↓
修改代码
↓
排查地图白屏
↓
处理交互细节
这种方式当然仍然有效。
但进入 Agent 时代之后,一个新的问题出现了:
能不能把地图开发知识直接交给 Agent,让 Agent 知道应该调用什么、如何配置以及怎样避开常见错误?
高德给出的答案是:Skill 与 CLI。
高德 JSAPI Skills 将 JS API 2.0 的官方文档、最佳实践和代码模板整理为结构化技能文件,面向 Cursor、Claude、Cline 等 AI 编程工具使用。它的目标不仅是生成代码,也包括提醒安全配置、避免常见错误并提供经过验证的示例。
这意味着,地图能力不再只是"人去读文档,再写代码",也可以变成:
javascript
开发者描述需求
↓
Agent 读取高德 Skill
↓
选择正确的 API
↓
生成符合规范的地图代码
↓
开发者检查与迭代
对于 LifeTrace 来说,这一点非常关键。
因为项目本身也是一个 Skill,而它的底层地图能力又能够由高德 Skill 提供支持。
六、高德 Skill 到底解决了什么问题?
高德官方目前提供的基础能力 Skill 中,比较适合本项目的主要有两个。
1. amap-jsapi-skill
它更适合开发带地图的网页应用。
覆盖内容包括:
- 地图加载与销毁;
- 安全密钥配置;
- Marker、LabelMarker、InfoWindow;
- Polyline、Polygon、Circle 等矢量图形;
- 地图点击、拖拽和缩放事件;
- 地理编码和逆地理编码;
- POI 搜索;
- 路径规划;
- 自定义图层和数据可视化。
高德官方也明确建议:开发带地图的网页、交互式搜索或自定义地理数据可视化页面时,优先使用 amap-jsapi-skill。

2. amap-lbs-skill
它更适合在 Agent 对话或脚本中快速使用位置服务。
主要能力包括:
- POI 关键词搜索;
- 周边地点搜索;
- 地理编码;
- 步行、驾车、骑行和公交规划;
- 旅游路线规划;
- 地图链接生成;
- 热力图生成。
高德官方将它定位为开箱即用的 LBS 综合服务 Skill。

对于 LifeTrace 而言,两者可以分别承担:
javascript
amap-jsapi-skill
负责生成和维护前端地图页面
amap-lbs-skill
负责地点搜索、地址解析和位置服务
在 LifeTrace 的开发阶段,我主要借助了地图开发 Skill 和高德 CLI,理解 Web 地图加载、覆盖物绘制以及交互状态控制。
amap-lbs-skill 属于可选能力。只有在需要让 Agent 动态完成 POI 搜索、地址解析、地理编码或路径规划时,才需要安装它并申请 Web 服务 Key。当前刘备 Demo 的地点坐标已经整理完成,因此打开页面并不依赖位置服务 Skill。
七、如何获取高德地图 API Key?
运行 LifeTrace 的真实地图前,需要先准备高德 Web 端Key。
第一步:注册并登录高德开放平台
进入高德开放平台控制台。
如果还没有开发者账号,需要先完成开发者注册:console.amap.com/dev/key/app...
第二步:创建应用
进入"应用管理",创建一个新应用。

例如:
javascript
应用名称:LifeTrace
应用类型:工具或其他
第三步:添加 Web 端 Key
进入应用详情,选择"添加 Key"。

建议填写:
javascript
Key 名称:life-trace-web
服务平台:Web服务
创建成功后,记录:
javascript
Key
八、LifeTrace 如何配置高德 Key?
项目没有将高德 Key 直接写进人物数据,也没有把 Key 构建进最终 HTML。
运行项目时,通过环境变量传入。
PowerShell:
javascript
$env:AMAP_KEY="你的高德 Web JS API Key"
$env:AMAP_SECURITY_KEY="对应的安全密钥"
macOS 或 Linux:
javascript
export AMAP_KEY="你的高德 Web JS API Key"
export AMAP_SECURITY_KEY="对应的安全密钥"
然后启动本地预览:
javascript
node life-trace.mjs serve demo.html
项目 README 明确说明,高德 Key 只从环境变量读取,不写入 Skill、人物数据或最终 HTML。
这样设计有两个好处:
- 公开 GitHub 仓库时,不会直接泄漏 Key;
- 同一个 Demo 可以在不同开发者环境中使用不同 Key。
九、如何安装高德官方 Skill?
高德官方 Skill 可以通过 ClawHub 安装,也可以下载压缩包后放到工作区的 Skills 目录。
第一步:安装 ClawHub CLI
javascript
npm install -g clawhub
验证安装:
javascript
clawhub --version

第二步:安装高德 JS API Skill
javascript
clawhub install amap-jsapi-skill
安装完成后,Skill 文件会出现在 workspace 的 skills/ 目录下。
第三步:按需安装 LBS Skill
javascript
clawhub install amap-lbs-skill
如果项目既涉及地图网页,也涉及地理编码和地点搜索,可以同时安装两个 Skill。
第四步:验证安装
javascript
clawhub list

安装成功后,可以直接对 Agent 说:
javascript
请使用高德地图 JS API,
创建一个带多个人生节点的交互式地图。
节点之间按照年份连接,
点击节点时展示对应人物事件。
Agent 会根据高德 Skill 中的 SKILL.md 和代码规范,选择相应的 API 来完成开发。高德官方文档给出的示例也是通过自然语言要求 Agent 创建带标记点的地图。
十、高德 CLI 又解决了什么问题?
Skill 解决的是:
Agent 应该怎样理解和使用高德地图。
CLI 解决的是:
地图能力能否像普通开发命令一样进入终端、脚本和自动化工作流。
高德开放平台提供了地图用户界面 CLI。
安装命令:
javascript
npm install -g @amap-lbs/amap-gui

配置环境变量:
javascript
export AMAP_KEY=your_amap_web_js_key
export AMAP_SECURITY_KEY=your_amap_security_key
启动地图容器:
javascript
amap-gui start
随后可以通过命令行调用地图功能。例如:
javascript
amap-gui route --json '{
"from": {
"position": "北京站"
},
"to": {
"position": "中关村"
},
"type": "transit",
"city": "北京"
}'
同时,高德也提供了 amap-cli-skill:
javascript
clawhub install amap-cli-skill
安装后,Agent 可以通过高德 CLI 对地图进行智能操控。
对 LifeTrace 来说,CLI 的意义不一定是直接绘制历史人物路线,而是让整个工作流进一步自动化。
例如未来可以形成:
javascript
读取人物资料
↓
提取地点名称
↓
批量查询地点
↓
检查异常坐标
↓
生成标准事件数据
↓
构建人生地图
API 提供底层能力,CLI 让能力可以被脚本化调用,Skill 则让 Agent 知道这些能力应该怎样使用。
十一、既然已经有高德 Skill,为什么还要做 LifeTrace Skill?
这是项目最重要的设计决定。
高德 Skill 解决的是:
如何正确使用高德地图和位置服务。
LifeTrace Skill 解决的是:
如何把一个人的一生,整理成一张可信、完整、可以播放的人生地图。
两者的关系可以概括为:
javascript
高德 Skill 是地图开发专家
LifeTrace Skill 是人物人生地图策展人
高德 Skill 更接近底层能力:
javascript
创建地图
添加标记
绘制折线
搜索地点
执行地理编码
调用路线服务
LifeTrace Skill 则定义了具体场景中的完整流程:
javascript
判断人物类型
↓
读取人物资料
↓
提取时间、地点和事件
↓
区分史料与文学故事
↓
映射古代地点与现代位置
↓
标记来源和可信度
↓
生成结构化数据
↓
调用高德地图能力
↓
构建可播放页面
地图开发能力并不会自动回答这些问题:
- 一生中哪些事件值得保留?
- 历史事件和文学典故如何区分?
- 古代地名应怎样映射现代位置?
- 地点不确定时该如何表达?
- 普通人的隐私信息怎样处理?
- 人物图片和故事图片如何组织?
- 页面应该具备怎样的播放逻辑?
- 最终结果如何校验和交付?
这些正是 LifeTrace Skill 需要补充的内容。
十二、为什么一定要包装成 Skill?
如果只做一个刘备网页,用户想换成自己,通常需要:
- Fork 仓库;
- 找到刘备数据文件;
- 手动替换年份和地点;
- 查询经纬度;
- 修改人物名称;
- 更换人物图片;
- 重新处理事件画廊;
- 构建 HTML;
- 配置高德 Key;
- 检查地图交互。
对于前端开发者来说,这并不算太困难。
但对于普通用户来说,依然存在明显门槛。
我真正希望实现的交互是:
javascript
用户:
这是我的人生经历,
请帮我做成一张可播放的人生地图。
然后 Agent 自动完成:
javascript
读取用户资料
↓
整理时间和地点
↓
发现缺失信息
↓
向用户确认
↓
生成标准数据
↓
查询或补充位置
↓
构建页面
↓
启动预览
所以,LifeTrace 不能只是一份代码。
它必须同时包含:
- 数据格式;
- 工作流程;
- 处理原则;
- 隐私约束;
- 构建脚本;
- 示例数据;
- 图片规范;
- 测试方法。
项目当前将这些内容组织在 life-trace/ 目录中,包括 SKILL.md、life-trace.mjs、刘备示例数据、完整 Demo、人物与故事图片提示词,以及测试文件。
把项目包装成 Skill,本质上是把一次性的开发结果,转化成任何人都能重复调用的能力。
十三、网页和 Skill 的本质区别
只交付网页时:
javascript
这是刘备的人生地图。
你可以浏览,但很难换成自己。
交付 Skill 时:
javascript
这是生成任何人人生地图的方法。
刘备只是其中一个示例。
一个普通用户只需要准备:
javascript
year,place,title,description
2004,呼和浩特,出生,我的人生起点
2010,包头,开始上学,第一次进入校园
2022,北京,进入大学,开启新的成长阶段
2026,上海,第一份工作,开始职业生涯
然后告诉 Agent:
javascript
请使用 LifeTrace Skill,
把这份经历做成我的人生轨迹地图。
缺少信息时先向我确认,
不要主动搜索我的个人信息。
Agent 就可以按照 Skill 流程:
- 检查字段;
- 整理事件;
- 询问缺失地点;
- 在用户同意后获取坐标;
- 生成标准数据;
- 构建 HTML;
- 启动地图预览。
这让项目不再局限于历史人物,也能用于:
- 自己的人生地图;
- 父母和长辈的人生回忆;
- 家庭迁徙路线;
- 偶像成长经历;
- 作家游历地图;
- 校友发展地图;
- 旅行足迹;
- 纪念地图;
- 数字人文教学;
- 人物主题展览。
十四、LifeTrace 的数据模型:地图之前,先解决可信度问题
这个项目最难的地方,其实不是地图 API。
真正困难的是:
怎样把一个人的一生,变成一套既能播放,又能追溯的数据?
地图会给用户带来非常强的确定感。
一个点只要出现在地图上,人们就容易认为:
javascript
这件事一定发生在这个精确位置。
但历史资料并不总是如此。
例如:
- 古代行政区与现代行政区不完全对应;
- 一场战争可能发生在较大区域;
- 部分事件只能确定到某个城市附近;
- 正史和文学作品可能存在差异;
- 古代城址和现代城市中心并非同一地点。
因此,LifeTrace 不只保存年份和坐标。
每个事件还应该包含:
javascript
时间
历史地名
现代位置
事件标题
事件说明
人生阶段
资料来源
可信度
事件类型
一个简化的数据结构可以是:
javascript
{
"person": {
"name": "刘备",
"years": "161---223",
"title": "昭烈帝足迹"
},
"coordinateSystem": "GCJ-02",
"events": [
{
"id": "xinye-201",
"year": "201",
"place": "新野",
"modernPlace": "河南省南阳市新野县",
"title": "屯兵新野",
"phase": "荆州时期",
"coordinates": [112.3601, 32.521282],
"confidence": "confirmed",
"sources": [
{
"label": "《三国志·蜀书二·先主传》",
"url": "..."
}
]
}
]
}
(完整的刘备 15 条事件数据已经放在仓库的 liu-bei.json 中)
可信度可以划分为:
javascript
confirmed
资料和地点相对明确
inferred
现代位置或事件范围为推定
disputed
资料之间存在争议
literary
来自文学作品或后世故事
例如"桃园结义"具有极高的文化知名度,但它不能与明确的正史事件完全采用相同标记。
地图不仅应该告诉用户"发生了什么",还应该告诉用户:
- 这条信息来自哪里;
- 属于正史还是文学;
- 地点是否为现代推定;
- 当前结论是否存在争议。
项目 README 也将"来源与可信度标记"列为核心功能之一。
十五、古代地名如何放到现代高德地图上?
历史人物地图不能简单地把"涿郡""许都""邺城""葭萌"等名称丢给地图,然后完全采用第一个搜索结果。
LifeTrace 的处理流程是:
javascript
确认古代地名
↓
查阅人物与地点资料
↓
判断现代行政区或历史地标
↓
通过高德获取坐标
↓
人工检查位置
↓
保存古名、现代名和可信度
例如:
javascript
历史地名:涿郡涿县
现代位置:河北省保定市涿州市
状态:现代位置映射
再如:
javascript
历史地名:白帝城·永安宫
现代位置:重庆市奉节县白帝城区域
状态:现代历史地标映射
如果已有结构化地址,可以使用高德地理编码能力,将地址转换成经纬度。
高德 JS API 的 AMap.Geocoder 支持地址与坐标之间的转换;高德 Web 服务同样可以用于批量或脚本化地理编码。
但自动编码之后仍需人工复核。
因为地理编码只能回答"这个名称在现代地图中通常对应哪里",它无法自动判断某个历史事件应当采用古城遗址、现代城区还是行政区域中心。
十六、为什么历史路线不能直接使用现代导航?
这是历史地图中非常容易出现的错误。
假设刘备先后出现在成都和白帝城,如果直接调用现代驾车路线,地图会沿今天的高速、公路和桥梁生成一条路线。
视觉效果可能很好,但历史表达是错误的。
因为历史人物:
- 不会沿现代高速行军;
- 不会按照今天的道路网络移动;
- 很多具体行军路线没有足够资料;
- 地图中保存的通常只是关键事件地点。
所以 LifeTrace 的历史人物模式只绘制"事件关系线"。
javascript
const path = events.map(event => [
event.place.longitude,
event.place.latitude
]);
它表达的是:
javascript
人物在地点 A 发生一个事件后,
下一个重要事件出现在地点 B。
它不代表:
- 精确历史行军路线;
- 古代道路复原;
- 真实航迹;
- 现代导航方案。
如果制作现代人物地图,并且用户明确需要展示真实驾车、步行或骑行路线,则可以使用高德路径规划能力,但需要在页面中明确区分:
javascript
人生事件连接线
与
现代导航路线
高德 Skill 本身提供驾车、步行、公交和骑行等路线规划能力,但在 LifeTrace 中是否使用这些能力,应取决于人物类型和数据语义。
十七、让一条静态路线真正"活起来"

如果页面一打开,就显示完整人生线路,用户看到的只是最终结果。
但人生不是一张一次性展开的图。
所以我为页面加入了逐段播放机制。
点击"播放足迹"后,系统会依次执行:
javascript
点亮当前节点
↓
移动地图视野
↓
绘制下一段线路
↓
更新时间轴
↓
切换事件说明
↓
切换故事画面
页面内部需要维护几个核心状态:
javascript
let currentIndex = 0;
let playing = false;
let playbackRate = 1;
let playTimer = null;
每一次激活事件:
javascript
function activateEvent(index) {
currentIndex = index;
highlightMarker(index);
drawRouteUntil(index);
focusMap(index);
updateTimeline(index);
updateStoryPanel(index);
updateProgress(index);
}
地图、时间轴和人物故事区需要双向联动:
- 点击地图节点,跳转到对应年份;
- 点击时间轴,地图聚焦对应地点;
- 自动播放时,信息卡片同步更新;
- 切换人生阶段时,高亮对应路线;
- 点击重置后,回到第一站。
这也是项目为什么不仅使用地图 API,还需要自己维护一层叙事状态。
高德负责"地图如何显示",LifeTrace 负责"人生应该如何播放"。
十八、为什么地图右侧还需要一个数字人物馆?

如果页面只有地图、节点和线路,它仍然更像一个 GIS 工具。
但一个人不是由经纬度组成的。
人物还包括:
- 形象;
- 性格;
- 关系;
- 代表故事;
- 文学记忆;
- 历史评价。
因此,LifeTrace 在地图右侧加入了人物与故事画廊。
第一张展示人物主视觉,后续展示核心人生故事,例如:
- 桃园结义;
- 青梅煮酒;
- 三顾茅庐;
- 长坂败退;
- 入蜀益州;
- 白帝托孤。

并不是每一个事件都必须配图。
如果所有事件都生成插图,会带来:
- 页面体积快速增加;
- 图片风格难以统一;
- 视觉信息过载;
- 地图失去主体地位。
所以项目只为关键事件准备核心故事图,并使用 portrait-prompt.md 和 story-prompt.md 约束人物像与故事图的生成方式。
项目当前会将人物像和故事插图统一放入 4:3 循环画廊,并支持在构建后的 Demo 中自包含图片。
十九、为什么最终生成单文件 HTML?
常规地图应用可能采用:
javascript
前端框架
+
后端服务
+
数据库
+
对象存储
LifeTrace 没有选择复杂架构。
因为它的核心目标不是运营一个大型平台,而是:
- 方便 Agent 生成;
- 方便开发者修改;
- 方便用户预览;
- 方便静态托管;
- 方便 Skill 分发;
- 方便换一份数据生成新人物。
所以项目采用:
javascript
JSON / CSV 数据
↓
构建脚本
↓
单文件 HTML
执行:
javascript
node life-trace.mjs build liu-bei.json demo.html
构建脚本负责:
- 读取人物数据;
- 校验必填字段;
- 检查事件顺序;
- 处理人生阶段;
- 注入人物信息;
- 处理人物像与故事图;
- 生成完整 HTML。
这种方式不要求用户长期维护服务器,也方便部署到静态托管环境。
项目仓库当前主要由 HTML 和 JavaScript 构成,核心工具集中在 life-trace.mjs 中。
二十、普通人物模式:越真实,越要重视隐私
公开人物和普通人不能走完全相同的数据处理流程。
对公开人物
可以:
- 查询公开资料;
- 核对多个来源;
- 整理重要人生节点;
- 查询历史地点的现代位置;
- 使用公开人物资料或生成式人物图。
对普通人物
默认应该:
- 只处理用户主动提供的内容;
- 不主动搜索私人经历;
- 不从零散材料推断家庭住址;
- 不推断实时位置;
- 未经许可不处理私人照片;
- 地理编码前征得用户同意;
- 公开时降低地点精度。
例如,普通人的公开事件适合写成:
javascript
北京市
而不是:
javascript
北京市某区某街道某小区某栋
公开前还应移除:
- 精确住址;
- 联系方式;
- 身份证件;
- 未成年人信息;
- 未授权照片;
- 可以推断实时位置的内容。
LifeTrace README 明确规定:普通人物默认只处理用户主动提供的资料,公开前应移除精确住址、联系方式、未成年人信息和未获授权的照片。
一个完善的 Skill,不仅要告诉 Agent 如何完成任务,也必须说明哪些事情不能做。
二十一、项目结构
项目核心目录如下:
javascript
life-trace-amap/
├─ README.md
├─ LICENSE
└─ life-trace/
├─ SKILL.md
├─ life-trace.mjs
├─ liu-bei.json
├─ demo.html
├─ test.mjs
├─ portrait-prompt.md
└─ story-prompt.md
各文件职责:
javascript
SKILL.md
定义 Skill 工作流、输入规范和处理原则
life-trace.mjs
负责数据校验、HTML 构建、预览和地理编码
liu-bei.json
刘备完整案例数据
demo.html
构建后的人生地图 Demo
portrait-prompt.md
人物主视觉生成规范
story-prompt.md
核心故事插图生成规范
test.mjs
项目自动化测试
这些文件共同组成的不是一份单独网页,而是一套完整的可复用能力。
二十二、快速运行 LifeTrace
项目需要:
javascript
Node.js 18+
高德 Web JS API Key
高德安全密钥
进入项目目录:
javascript
cd .\life-trace
- 校验刘备数据
javascript
node life-trace.mjs validate liu-bei.json
- 构建 Demo
javascript
node life-trace.mjs build liu-bei.json demo.html
- 设置高德 Key
PowerShell:
javascript
$env:AMAP_KEY="你的高德 Web JS API Key"
$env:AMAP_SECURITY_KEY="对应的安全密钥"
- 启动预览
javascript
node life-trace.mjs serve demo.html
- 运行测试
javascript
node --test test.mjs
这些命令与环境要求均来自项目 README。
二十三、如何安装 LifeTrace Skill?
LifeTrace 已经提供了 GitHub 发布入口。项目 README 中同时列出了 GitHub、ClawHub 和在线预览地址。
安装时可以在 GitHub 中找到:
javascript
life-trace
安装完成后,可以直接对 Agent 说:
javascript
请安装:https://github.com/LucianaiB2004/life-trace-amap。
我想制作一张自己的人生地图。
下面是我的人生经历。
缺少年份或地点时先向我确认,
不要主动搜索我的个人信息。
制作公开人物地图时,可以这样描述:
javascript
请使用 LifeTrace Skill,
制作一张苏轼的人生轨迹地图。
整理重要时间、地点与事件,
区分史料和文学故事,
为关键节点保留来源与可信度。
此时,Agent 不只是生成一张地图,还需要按照 LifeTrace Skill 的规则完成:
- 人物类型判断;
- 资料读取;
- 事件筛选;
- 地点处理;
- 来源记录;
- 可信度标记;
- 数据校验;
- 页面构建;
- 地图预览。
二十四、从高德 API 到高德 Skill,再到 LifeTrace Skill
完成这个项目后,我越来越明显地感受到,开发方式正在发生变化。
过去我们关心的是:
javascript
这个 API 能提供什么?
现在我们还要关心:
javascript
这个能力如何被 Agent 理解?
如何被自动化调用?
如何被普通用户重复使用?
高德 API 负责底层地图和位置能力。
高德 CLI 负责将这些能力带入终端、脚本和自动化流程。
高德 Skill 负责把高德官方文档、最佳实践和代码模板整理成 Agent 能够使用的知识。
LifeTrace Skill 则在这些基础能力之上,提供面向人物人生地图的完整场景工作流。
整个关系可以写成:
javascript
高德地图 API
解决"地图能做什么"
↓
高德 CLI
解决"地图如何被命令行和 Agent 调用"
↓
高德官方 Skill
解决"Agent 如何正确使用高德能力"
↓
LifeTrace Skill
解决"如何把任何人的一生制作成地图"
这也是我为什么选择把项目封装成 Skill。
我不希望最终交付的只是一个刘备案例。
我希望交付的是一种能力:
任何人,只要提供自己的时间、地点和故事,就可以生成一张属于自己的人生地图。
二十五、开发过程中最容易踩的几个坑
- 经纬度顺序写反
高德地图坐标通常采用:
javascript
[longitude, latitude]
也就是:
javascript
[经度, 纬度]
如果写反,节点可能出现在完全错误的位置。
- 把古代地点当成现代精确坐标
正确表达应当是:
javascript
历史地点:夷陵一带
现代位置:湖北省宜昌市夷陵区
状态:现代位置推定
而不是让用户误认为事件发生在某个现代行政中心的精确坐标上。
- 用现代导航冒充历史路线
历史人物应使用事件关系线。
现代路径规划只有在处理现代人物、旅行或真实出行轨迹时才适用。
- 把 Key 提交到 GitHub
不要在公开代码中写:
javascript
const key = "真实高德Key";
应通过环境变量、白名单或服务端代理管理凭据。
- 搜索摘要直接作为史料来源
搜索摘要只能帮助发现资料,不能直接替代原始来源。
需要打开原始页面,确认它支持哪一条事件,以及属于史料、地方资料、论文还是文学作品。
- Skill 写得过于抽象
如果 Skill 只写:
javascript
请生成人生轨迹地图
Agent 每一次执行的结果都会不稳定。
一个可用的 Skill 必须明确:
- 输入格式;
- 事件字段;
- 地点规则;
- 可信度规则;
- 隐私限制;
- 构建命令;
- 验证方法;
- 最终交付物。
二十六、写在最后:一生,如何成为一条路?
当刘备的全部人生事件被放到同一张地图上时,我第一次直观地感受到,他的一生并不是历史课本中几个著名故事的集合。
他从涿郡出发,在中原反复辗转。
失去过徐州,依附过曹操和袁绍,在新野长期停留,又从荆州进入益州。
直到成都,他才真正拥有一个稳定的政治中心。
但称帝之后,他的人生路线再次向东延伸,最终在夷陵遭遇失败,并停在白帝城。
在普通时间轴中,这些内容是:
javascript
起兵、依附、入蜀、称帝、托孤。
在地图上,它们却变成:
javascript
一次次离开,
一次次迁徙,
一次次失败,
以及一次次重新寻找方向。
这正是地图的意义。
它不一定能够解释一个人的全部人生,却可以让那些原本抽象的年份、地点和故事,第一次拥有真实的距离。
而 Skill 的意义,是让这种表达不再只属于某一个开发者、某一个历史人物或某一个项目。
今天它可以展示刘备。
明天,它可以展示苏轼、杜甫、徐霞客,可以展示一位偶像、一位长辈,也可以展示每一个普通人的成长、求学、工作、旅行和迁徙。
我们没有办法回到小时候。
也没有办法重新走一遍已经走过的人生。
但借助高德地图、CLI、Skill 和 Agent,我们可以把那些散落在时间中的城市与故事重新连接起来。
看看过去的自己,究竟走过了一条怎样的路。
人生很短,不过三万天。 人生经纬,高德陪你看看过去的人生。