ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

【openclaw实用Skill】local-places 技能:用 Google Places API 打造本地地点搜索能力

2026/9/26 16:01:24 拓冰建站 浏览量
【openclaw实用Skill】local-places 技能:用 Google Places API 打造本地地点搜索能力 1. 为什么要在 openclaw 里接一个本地地点搜索 Skillopenclaw 的 Skill 体系里local-places 是一个很典型的「本地代理型」技能它本身不直接对外发起请求而是在你本机起一个 FastAPI 服务把 Google Places API 的能力包装成两个清晰的接口——先解析位置再搜索地点。这样做的好处是AI 工具在调用时不用关心 Google 的鉴权细节只需要对着127.0.0.1:8000发 JSON 就行。它适合谁如果你正在用 openclaw 做 Agent、做本地生活类问答、或者想让模型回答「附近有没有营业中的咖啡馆」这类问题local-places 就是那个把「模糊地名」变成「精确经纬度」再变成「结构化地点列表」的中间层。核心检索词就三个openclaw、local-places、Google Places API。我实测下来这个 Skill 的价值在于两步流程的设计。很多地点搜索工具一上来就让你给坐标但用户嘴里说的是「伦敦 Soho」「我家附近」local-places 先用/locations/resolve把文本转成坐标再用/places/search在半径内搜逻辑上更贴近真实对话。下面从环境准备讲到验证请求每一步都给可复制的骨架。2. TaoToken 前置统一 Key 与 API 通道怎么接local-places 默认读的是GOOGLE_PLACES_API_KEY但如果你不想在多个 Skill 里散落不同的 Key可以用 TaoToken 做统一入口。TaoToken 的定位是给 AI 工具提供统一的 Key 管理和 API 通道官网在 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_end API 基址是 https://taotoken.net/api 。这里要分清两件事Google Places API Key 是 local-places 真正去查地点用的TaoToken 的 Key 是你用来管理模型调用、coding plan、以及统一接入通道的。两者不冲突可以并存。我的做法是.env里保留GOOGLE_PLACES_API_KEY给 local-places 用同时在 openclaw 的全局配置里填 TaoToken 的 Key让模型对话和 Skill 调度走同一条通道。你需要先去 TaoToken 控制台拿 Key地址是 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite 然后在 API Keys 页面生成一个页面在 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 。拿到之后openclaw 的config.toml里填 TaoToken 的 base_url 和 keylocal-places 的.env里填 Google 的 key各司其职。注意不要把 Google Places API Key 和 TaoToken Key 混在同一个变量里排障时会很难定位是哪个通道出的问题。如果你后面要做长期编码或 Agent 任务可以看 Coding Planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 。只是想验证模型对话是否通用模型对话页就行https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodelsutm_campaignrewrite 。3. 可复制配置config.toml 与 settings.json 骨架先把 openclaw 的 Skill 目录拉下来local-places 在skills/local-places下。进入目录后核心是两份配置一份给 openclaw 主程序看的config.toml一份给 local-places 服务看的settings.json或者.env两者选一我习惯用.env管密钥、settings.json管默认参数。config.toml的骨架如下重点是base_url指向 TaoToken 的 API 地址api_key填你在控制台生成的那串[llm] provider openai-compatible base_url https://taotoken.net/api api_key sk-你的TaoTokenKey model gpt-4o-mini [skills.local-places] enabled true endpoint http://127.0.0.1:8000 timeout_seconds 15settings.json管的是 local-places 自己的默认行为比如默认搜索半径、默认返回条数、以及 Google Key 的读取方式。如果你用.env就写成GOOGLE_PLACES_API_KEY...如果坚持用settings.json可以这样{ google_places_api_key: AIza...你的GoogleKey, default_radius_m: 1000, default_limit: 10, default_language: zh-CN, server: { host: 127.0.0.1, port: 8000 } }环境准备命令按官方给的来先建虚拟环境再装依赖cd skills/local-places echo GOOGLE_PLACES_API_KEYAIza...你的GoogleKey .env uv venv uv pip install -e .[dev] uv run --env-file .env uvicorn local_places.main:app --host 127.0.0.1 --port 8000启动后你会看到 uvicorn 打印Uvicorn running on http://127.0.0.1:8000这就说明本地代理起来了。此时 openclaw 通过config.toml里的endpoint找到它模型侧通过 TaoToken 的base_url走统一通道两条链路互不干扰。4. 验证请求一次地点查询的完整动作与预期返回配置填完必须验证否则你永远不知道是 Key 错了还是服务没起。验证分两步正好对应 local-places 的两步流程。第一步解析位置。把「Soho, London」这种模糊文本转成坐标curl -X POST http://127.0.0.1:8000/locations/resolve \ -H Content-Type: application/json \ -d {location_text: Soho, London, limit: 5}预期返回里会有lat和lng比如51.5137和-0.1366以及一个formatted_address。如果这一步返回空数组多半是 Google Places API Key 没生效或者.env没被--env-file读到。第二步用解析出的坐标搜咖啡馆带上营业中和评分过滤curl -X POST http://127.0.0.1:8000/places/search \ -H Content-Type: application/json \ -d { query: coffee shop, location_bias: {lat: 51.5137, lng: -0.1366, radius_m: 1000}, filters: {open_now: true, min_rating: 4.0}, limit: 10 }预期返回结构是这样的results数组里每个元素包含place_id、name、address、location、rating、price_level、types、open_now末尾可能带next_page_token{ results: [ { place_id: ChIJ..., name: Coffee Shop, address: 123 Main St, location: {lat: 51.5, lng: -0.1}, rating: 4.6, price_level: 2, types: [cafe, food], open_now: true } ], next_page_token: ... }拿到place_id后想看详情就再发一个 GETcurl http://127.0.0.1:8000/places/ChIJ...这一步会返回完整地址、营业时间、联系方式。如果next_page_token存在把它作为参数再请求一次就能翻页。整个验证链路跑通说明 openclaw、local-places、Google Places API、TaoToken 通道四者都正常。5. 本篇常见错排查从 401 到空结果排障时按「服务层 → 鉴权层 → 参数层」的顺序查能省很多时间。服务起不来端口被占。报Address already in use说明 8000 端口有别的进程。换端口uvicorn local_places.main:app --host 127.0.0.1 --port 8001同时把config.toml里的endpoint改成http://127.0.0.1:8001。401 或 PERMISSION_DENIED。这是 Google Places API Key 的问题。检查.env里变量名是不是GOOGLE_PLACES_API_KEY值有没有多余空格以及 Google Cloud 控制台里 Places API 是否已启用、Key 是否限制了 IP。如果你同时用了 TaoToken确认 401 是来自 Google 还是来自 TaoToken看响应体里的error.message能区分。resolve 返回空数组。位置文本太模糊比如只写「附近」。local-places 需要可解析的地名换成「Soho, London」或具体地址再试。另外limit解析时范围是 1–10超了会被拒。search 返回 400。常见是filters.types填了多个类型。约束是只能指定一个类型比如restaurant或cafe不能写成数组塞两个。filters.min_rating必须是 0–5 且以 0.5 为增量写 4.3 会报错。location_bias.radius_m必须大于 0。结果里 open_now 全是 false。检查filters.open_now是不是布尔值true而不是字符串true。JSON 里字符串和布尔值行为不同。翻页拿不到更多结果。next_page_token有时效性拿到后要尽快用隔太久会失效。另外limit搜索时是 1–20超过 20 不会报错但会被截断。提示排障时先单独 curl local-places 的接口确认它自己能通再去 openclaw 里测 Skill 调用。分层定位比一上来就查 openclaw 日志快得多。6. 接入与后续把 local-places 用顺的几个动作local-places 跑通之后真正影响体验的是参数习惯。我自己的做法是在 openclaw 的 Skill 描述里写清楚「先 resolve 再 search」让模型别跳步default_radius_m设 1000 到 1500 之间太小搜不到、太大结果杂min_rating默认给 4.0能过滤掉一批低质结果。如果你要把这套能力接到更长的编码或 Agent 流程里TaoToken 的 Coding Plan 可以统一管 Key 和额度https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 。接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 里面有 base_url 和鉴权头的完整说明。ClaudeCode 相关的接入看 https://taotoken.net/claudecode-anthropic?utm_sourcetaotoken_aicg_blog_endutm_contentclaudecode-anthropicutm_campaignrewrite 。最后留一个实用技巧把 resolve 的结果缓存到本地同一个地名短时间内重复问就不用反复调 Google既省额度又快。local-places 本身不提供缓存但你在 openclaw 的 Skill 包装层加一层字典就行键用location_text值存坐标过期时间设 10 分钟。这个改动很小但对话体验会顺很多。