← 返回 Skill 列表
extension
分类: 效率与办公API Key 暂未确认

周边去哪儿

基于高德 MCP 的周边地点推荐 Skill。根据用户给出的起点坐标、地点类型和步行时间上限,调用高德地点搜索与步行路线规划,筛出最多 3 个真实可达的地点,并用工具返回的步行距离、步行耗时和类型匹配度给出推荐理由,不凭记忆或直线距离补全信息。

person作者: tjqsaahubModelScope

周边去哪儿

根据用户的位置和一句话需求,通过高德 MCP 查询真实地点与步行路线,筛选后给出最多 3 个推荐。回答中的地点名称、地址、步行距离和步行时间必须来自工具返回结果。

核心原则

  1. 先查后答:没有查到地点,就不给具体地点;没有查到步行路线,就不把该地点列为符合条件的推荐。
  2. 数据原样:名称、地址、距离、耗时都取自工具结果,不凭记忆、常识或地图直线距离补全。
  3. 硬条件优先:步行时间上限、推荐数量、地点类型是硬条件,不因“看起来更合适”而放宽。
  4. 无依据不写:排队、安静程度、营业状态、环境氛围等没有数据支撑的信息标注“未核实”,不编造。
  5. 失败要说清:查不到或查询失败时如实说明,并给出可执行的放宽建议,不用相近地点凑数。

一、解析需求

从用户输入中提取以下要素;缺省时按右列处理,不要为了追问而停下。

| 要素 | 说明 | 缺失时 | | --- | --- | --- | | 起点 | 用户给出的经纬度,格式为“经度,纬度” | 只有地址时用 maps_geo 转坐标;两者都没有则请用户补充起点 | | 城市 | 用于关键词搜索和结果核对 | 有坐标时可用 maps_regeocode 反查,或直接沿用用户提到的城市 | | 地点类型 | 咖啡、餐厅、公园、景点、药店等 | 开放式提问按“景点 / 公园 / 咖啡”等常见去处选一类查询 | | 步行上限 | 分钟数,例如“步行不超过 15 分钟” | 默认按 15 分钟筛选,并在回答开头说明这是默认值;用户明确说不限时间时才不设上限 | | 推荐数量 | 最多几家 | 默认 3 个;用户要求更少时按用户数量,最多不超过 3 个 | | 排序偏好 | “优先近一点”“评分高一点”等 | 默认按步行时间从短到长 | | 排除项 | 不要连锁、不要某类、不要某品牌等 | 不额外排除 |

注意:

  • 坐标顺序固定为 经度,纬度,不要颠倒。
  • “15 分钟内”是硬条件;“优先近一点”是排序偏好,两者要同时满足。
  • 用户一句话里可能同时包含类型、时间、数量和偏好,先全部列清楚再调工具。
  • 起点是地铁站、商场等名称且已给坐标时,直接使用给定坐标,不要再做地址解析。
  • 用户只给坐标、没有可读的起点名时,可调用 maps_regeocode 取行政区或地址用于开头复述,不要编造具体站名或门牌。
  • 信息基本齐全时直接执行,不要为了确认而反问;只有连起点都无法确定时才请用户补充。

二、搜索候选地点

2.1 首选周边搜索

调用 maps_around_search:

  • location:起点坐标,经度在前。
  • keywords:地点类型关键词,用用户原词加一个同义词或上位词(咖啡 / 咖啡厅、餐厅 / 美食、公园 / 绿地)。
  • radius:搜索半径,单位为米。按步行上限估算,仅用于圈定查询范围,绝不能用来回答步行时间:
    • radius = min(3000, max(500, 上限分钟 × 80 × 1.25)),取整到 100 米。
    • 15 分钟约 1500 米;10 分钟约 1000 米;5 分钟约 500 米。
    • 未给时间上限时按默认 15 分钟计算,用 1500 米;用户明确不限时间时用 2000 米。
    • 按工具 schema 传值(有的实现要求字符串,如 "1500")。

2.2 结果不足时的补充

  • 先用最贴近的关键词查一次;结果明显偏少或类型不符时,换一个同义词再查一次。
  • 周边搜索不可用,或周边结果不足时,改用 maps_text_search:keywords 为类别词,city 为用户城市;工具支持 citylimit 时设为 true,不支持时仅用 city 限定。关键词搜索结果同样可能没有坐标,后续仍需查详情补 location。
  • 仍不足且当前半径小于 3000 米时,可把半径扩大到 3000 米再查一次。
  • 地点搜索总共不超过 3 次,不要反复换关键词刷结果。
  • 用户指定品牌时,把品牌名并入关键词;查不到该品牌就如实说明,不要用其他品牌替代。

2.3 读取字段

从返回的 POI 列表中读取:id、name、address、location、type 或 typecode、distance、rating。字段名以实际返回为准,不要假设每个字段都存在。

不同高德 MCP 实现的返回字段可能不同:

  • 周边搜索通常返回 id、name、address、typecode,部分实现还会返回 location、distance、rating。
  • 部分实现(例如官方 Node 版 MCP)的周边 / 关键词搜索结果不含 location,只给 POI ID;这时必须先用 maps_search_detail(id) 取回坐标,才能查步行路线。
  • 评分 rating 可能直接返回,也可能在 biz_ext 里,还可能要调详情才有;没有就当作没有,不编造。
  • address 为空字符串、空数组或缺失,都视为“高德未返回地址”;location 为空则视为坐标缺失。

三、筛选候选

按以下顺序处理:

  1. 类型匹配:名称或类型明显不符合需求的排除。例如找咖啡馆时排除咖啡豆 / 咖啡器具商店、便利店内的自助咖啡机;找公园时排除小区绿地类的非公共空间。
  2. 去重:同一 id,或“名称 + 地址”完全相同的,只保留一个。同品牌的不同门店是不同地点,可以分别保留。
  3. 初步排序:有 distance 时按直线距离从近到远;没有时按返回顺序(高德周边搜索通常已按距离或综合相关度排序,不要自行重排)。这个距离只用于决定先查哪几条路线,不能写进最终回答当作步行距离。
  4. 控制候选池:取前 6~8 个进入路线查询。用户要 3 个时不要只查 3 个,要留出超时或路线失败后的备选。
  5. 明显超范围的不查:有 distance 且已超过“上限分钟 × 80 × 1.5”的,可以不查路线,但不要把它列为推荐。
  6. 补全坐标与地址:进入路线查询前,每个候选必须有 location。缺少时调用 maps_search_detail(id),取其 location;地址为空也用它补全。取不到坐标的候选直接排除,不能拿地址或猜的坐标去查路线。最多补 8 个。

四、查询步行路线

对每个候选单独调用步行路线工具:

  • 首选 maps_direction_walking,参数 origin = 起点坐标,destination = 该 POI 的 location(搜索结果没有时用 maps_search_detail 返回的 location)。
  • 如果当前环境只提供 maps_direction_walking_by_coordinates,用同样的 origin / destination 坐标调用。
  • 不要用地址版路线:地址解析可能落到另一个门或另一栋楼,导致距离和耗时与 POI 对不上。
  • 不要用 maps_distance 的直线距离或自行估算代替步行路线。

从结果中读取步行方案的 distance(米)和 duration(秒),常见位置是 paths[0].distance 和 paths[0].duration,字段名以实际返回为准。这两个值可能是字符串,比较和计算前先转成数字。若返回多条方案,默认取第一条(通常是 paths[0]),不要为了显得更近而挑更短的一条;只有第一条缺失时才用其他方案。

判定规则:

  • 合格:duration ≤ 步行上限分钟 × 60。未给上限时按默认 15 分钟过滤;用户明确不限时间时才不做时间过滤,但仍要按 duration 排序并如实给出时间。
  • 展示:步行时间 = duration / 60 四舍五入到整分钟;步行距离直接使用返回的 distance 米数(可写“约 X 米”),不要自行换算或取整。
  • duration 缺失、为 0 或路线查询报错时,视为该地点路线不可用,不纳入合格推荐,也不要估算一个时间填进去。
  • 若合格数量不足且还有未查询的合理候选,可再补查最多 2 条路线;仍不足则按实际数量回答。

五、排序与挑选

  • 用户说“优先近一点”“越近越好”:按 duration 从短到长排序;耗时相同再按 distance 从短到长。
  • 用户更看重评分或环境:可在合格集合内参考 rating(可能直接返回,也可能在 biz_ext 中,或需调 maps_search_detail)排序,但必须保证时间数据真实;没有评分数据的候选排在后面,所有候选都没有评分时退回按步行时间排序,不要编造评分。
  • 用户没有明确偏好:按步行时间从短到长,兼顾类型匹配度。
  • 最多返回 3 个;用户要求的数量更少时按用户数量。用户要求超过 3 个时,仍只给 3 个并说明这是推荐上限。
  • 每个地点都是同一起点出发的独立备选,不要把它们串成一条多站行程。

六、组织回答

先用一句话说明起点、要找的类型和筛选条件,再用表格给出结果:

| # | 地点 | 地址 | 步行距离 | 步行时间 | 推荐理由 | | --- | --- | --- | --- | --- | --- | | 1 | 地点名称 | 高德返回的地址 | 约 320 米 | 约 5 分钟 | 候选中步行时间最短;名称与类型符合咖啡需求 | | 2 | 地点名称 | 高德返回的地址 | 约 540 米 | 约 8 分钟 | 步行时间在候选中排第二,仍在上限内;类型匹配 |

表格之后补一行简短说明:

距离和时间为高德步行路线规划结果;营业状态、排队情况和安静程度未核实。

写作要求:

  • 地点名称、地址原样使用工具返回值;地址为空时写“高德未返回地址”,不要补造。
  • 推荐理由只写有数据支撑的内容:步行耗时 / 距离在候选中较近、类型匹配、评分(若返回)、所在商圈或道路(若返回)。每条理由至少引用一个路线数据(耗时或距离)。
  • 不要写“环境安静”“不用排队”“正在营业”“人气很高”等没有依据的描述;用户若关心,统一标注“未核实”。
  • 不展示原始 JSON、工具名、坐标或调用过程,回答保持简洁。
  • 使用与用户相同的语言回答。

七、结果不足、无结果与失败

| 情况 | 处理方式 | | --- | --- | | 合格地点少于要求数量 | 按实际数量推荐,说明“符合条件的只有 N 家”;可说明还有候选因步行超过上限被排除,建议放宽时间或更换类型 | | 搜索没有结果 | 如实说明“以起点为中心约 X 米范围内未找到符合需求的地点”,建议扩大范围或换关键词,不用相近但不相关的地点凑数 | | 所有候选都超时 | 说明最近候选也超过步行上限,建议放宽时间;不把超时地点列为符合条件的推荐 | | 地点搜索失败或超时 | 说明“高德地点搜索暂时不可用”,可重试一次;仍失败则如实告知,不编造地点 | | 步行路线查询失败 | 该地点不纳入推荐;若全部失败,说明路线服务异常,可给出已核实的地点名称,但明确“步行时间未能查询” | | 搜索结果缺坐标且无法补全 | 不推荐该地点;若全部如此,说明无法核实步行路线,建议换一批地点或稍后重试,不用地址或猜测坐标代替 | | 当前环境没有高德工具 | 直接说明无法查询高德地点与路线,不用记忆或常识推荐具体地点 | | 地址等部分信息缺失 | 能补则用 maps_search_detail 按 id 补全;补不到就写“未返回”,不猜 | | 用户没有给起点 | 请用户补充起点名称或坐标;不要默认城市中心或热门商圈 |

失败说明保持一两句话,不输出技术堆栈、内部错误码或大段日志。

区分“空结果”和“接口异常”:返回空列表或 0 条 POI 时按“没有找到”处理;只有工具明确报错、超时或返回异常文本时,才说服务异常。

八、工具速查

| 能力 | 工具名 | 关键参数 | | --- | --- | --- | | 周边搜索 | maps_around_search | location、keywords、radius | | 关键词搜索 | maps_text_search | keywords、city;部分实现还支持 citylimit / types | | 地点详情 | maps_search_detail | id | | 步行路线 | maps_direction_walking | origin、destination | | 地址转坐标 | maps_geo | address、city | | 坐标转地址 | maps_regeocode | location |

使用提醒:

  • 所有坐标均为“经度,纬度”字符串,例如 120.1536,30.2875;radius、citylimit 等参数按当前工具 schema 传对应类型(如 radius 常为字符串,citylimit 为布尔)。
  • 工具名可能带 _by_coordinates 等后缀,按“地点搜索 / 步行路线”的能力选择可用工具,不要因为名字不同就跳过路线查询。
  • 若周边 / 关键词搜索的结果没有 location,先对候选调用 maps_search_detail(id) 取坐标,再查步行路线;这是官方 Node 版 MCP 的常见情况。
  • 路线查询的终点必须用 POI 的 location,不要用名称或地址重新解析。
  • 只调用地点搜索、地点详情和步行路线;不要调用驾车、公交、天气、IP 定位等与本题无关的工具。
  • 不要向用户索取或输出高德 API Key。

调用预算

  • 地点搜索(周边 + 关键词 + 扩半径)合计 ≤ 3 次。
  • 地点详情 ≤ 8 次,只补给将要查路线的候选。
  • 步行路线 ≤ 8 次;查完候选池即停,不遍历所有搜索结果。
  • 任何一步返回异常,按第七节处理一次即可,不要无限重试。

九、完整流程示例

用户输入:“我在杭州西湖文化广场地铁站附近(坐标 120.1637,30.2875),想找一家咖啡馆,步行不超过 15 分钟,推荐最多 3 家,优先近一点的。”

执行顺序:

  1. 解析:起点 120.1637,30.2875;类型咖啡;上限 15 分钟;数量 3;偏好近。
  2. 计算半径:15 × 80 × 1.25 = 1500 米。
  3. 调用 maps_around_search(location="120.1637,30.2875", keywords="咖啡", radius="1500")。
  4. 过滤掉类型不符的店铺,去重后按返回顺序(有 distance 则按距离)取前 6 个。
  5. 若搜索结果没有 location,对候选调用 maps_search_detail(id) 取坐标;仍取不到坐标的排除。
  6. 对每个候选调用 maps_direction_walking(origin="120.1637,30.2875", destination="该店 location")。
  7. 只保留 duration ≤ 900 秒的地点,按 duration 升序取前 3 个。
  8. 按第六节表格输出,并在说明中标注“营业状态、排队情况未核实”。

如果第 3 步没有结果,改为 maps_text_search(keywords="咖啡", city="杭州"),再对结果查详情和步行路线;仍然没有合格地点时,按第七节如实说明并建议放宽条件。

十、输出前自检

逐项确认后再发送回答:

  • [ ] 每个推荐地点都在本次工具返回的 POI 列表里,名称和地址没有改写或合并。
  • [ ] 每个步行距离和步行时间都来自对应的步行路线查询,没有用直线距离或经验估算。
  • [ ] 每条路线耗时都不超过用户给的步行上限(未给时按默认 15 分钟);数量不超过 3 个,且不超过用户要求的数量。
  • [ ] 排序与用户偏好一致(“优先近一点”时按耗时从短到长)。
  • [ ] 推荐理由中的每个事实都能在工具结果中找到依据。
  • [ ] 结果不足、无结果或查询失败时,已经如实说明并给出放宽建议。
  • [ ] 营业状态、排队、安静程度等未核实信息已标注,没有编造。
  • [ ] 回答使用表格或列表,简洁易读,没有暴露原始 JSON、工具名或坐标。
<!-- OB-S:xhpg_tYc5ObUqYu_-sSmxA -->