界面已本地化;技能介绍与说明文档按所选语言由 AI 自动翻译,代码、命令、路径和专业术语保留原文,以原作者文档为准。
探索技能
数据与研究 · SKILL.md

geo-keyword-research

geo-keyword-research

【数据与研究】GEO 关键词研究 Skill。为指定品牌生成行业推荐型 + 品牌直指型关键词报告, 支持 DAG 并发搜索模式,产出两份 Markdown 文件。

独立 GitHub 快照 · 自动分类 · 以原作者文档为准

技能说明

GitHub

name: geo-keyword-research description: > GEO 关键词研究 Skill。为指定品牌生成行业推荐型 + 品牌直指型关键词报告, 支持 DAG 并发搜索模式,产出两份 Markdown 文件。

GEO Keyword Research - GEO 关键词研究技能

技能定义

本技能用于生成 GEO 关键词研究报告,帮助任何品牌/产品优化在 AI 回复中的露出率和回复准确性。

适用于所有行业:汽车、轮胎、家电、美妆、数码、餐饮、服务等。


GEO 核心目标

GEO 关键词分为两大类:

🎯 第一类:行业推荐型

特征:[场景/品类/规格/车型/品类+品牌] + 推荐

  • 用户提问不包含目标品牌名
  • AI 在回答时会自然列举多个品牌/产品(包括目标品牌和竞品)
  • 优化目标:通过发布优质内容笔记,让 AI 在回答这类问题时优先推荐/提及目标品牌,提升品牌曝光和露出率

🎯 第二类:品牌直指型

特征:问题中明确包含目标品牌/产品全称

  • 用户直接提问关于目标品牌/产品的问题
  • 优化目标:优化内容,确保 AI 回复准确、完整、客观,避免 AI 出现不准确、不完整、不客观的错误

工作流程(DAG 模式)

本技能在 DAG 模式下运行,分为并发搜索和单一汇总两个阶段。

阶段一:并发搜索(多个 Subtask 并行,每个绑定唯一维度)

每个搜索 Subtask 必须:

  1. 绑定下方维度表中的一个独立维度,不得与其他 Subtask 重叠
  2. 使用 search tool 执行 1 次查询
  3. 将返回结果(URL + 页面标题 + 来源网站 + 搜索日期)写入临时文件: {workspace}/geo-keyword-research/{task_id}/{task_id}_search_{N}.tmp.md(N 为维度序号)

维度划分表(Planning LLM 按品牌特点从中选取 3-5 个维度):

维度示例 query(中文)示例 query(英文)备注
品牌官网 ⭐{品牌}官网{brand} official site products必选,用 fetch-web 直接抓官网产品页,获取官方产品线信息
品牌总体评价{品牌}怎么样{brand} review
竞品对比{品牌} vs 竞品{brand} vs competitor
耐磨/寿命耐磨{品类}品牌推荐most durable {category} brands
噪音/舒适静音{品类}品牌推荐quietest {category} brands
价格/性价比性价比高的{品类}品牌best value {category} brands
细分场景 A(根据品牌核心场景定制)
细分场景 B
特定产品系列{品牌}{旗舰系列}评测{brand} {flagship line} review
使用维护{品牌}使用年限/更换标准{brand} maintenance guide
技术特性{品牌}技术优势{brand} technology
购买指南{品牌}选购指南{brand} buying guide

⭐ 品牌官网维度为必选:该 Subtask 需先用 search tool 查到官网 URL,再用 fetch-web 脚本抓取官网产品页正文, 将内容写入 {workspace}/geo-keyword-research/{task_id}/{task_id}_official_site.txt, 供汇总阶段直接读取作为产品信息来源。

阶段二:汇总 Subtask(单一 Worker,依赖所有搜索 Subtask 完成)

  1. 合并所有临时文件

    • 读取所有 *.tmp.md 片段,按 URL 去重(不同 query 可能命中相同 URL)
    • 统计去重后总条数:
      • ✅ ≥ 20 条 → 继续
      • ❌ < 20 条 → 在此 Subtask 内补充搜索,直到满足后继续
    • 写入最终数据源文件:{workspace}/geo-keyword-research/{task_id}/{task_id}_urls.md
    • 删除所有 *.tmp.md 临时片段
  2. 抓取核心页面正文(为报告分析提供真实内容依据)

    • 从 {task_id}_urls.md 中,按来源多样性选取 8-12 个高价值页面:
      • 优先选:官网、主流汽车媒体(汽车之家、易车、太平洋汽车等)、专业评测、知乎/小红书用户讨论
      • 排除:内容明显为广告/推广页、重复来源
    • 对每个选中 URL,使用 fetch-web 脚本抓取正文(三层降级策略:Jina → urllib → CDP),脚本路径在运行时通过以下命令解析:
      FETCH_SCRIPT=$(python3 -c "from nanobot.agent.skills import BUILTIN_SKILLS_DIR; print(BUILTIN_SKILLS_DIR / 'fetch-web/scripts/fetch.py')")
      python3 "$FETCH_SCRIPT" --url "{url}" --output "{workspace}/geo-keyword-research/{task_id}/page_{n}.txt"
      
    • ⚠️ fetch 失败控制规则(必须严格遵守):
      • 每个 URL 只抓取 1 次,不重试
      • 若抓取返回错误或超时,立即记录 "[FETCH FAILED]" 并跳过,继续处理下一个 URL
      • 连续失败 3 次后,停止继续尝试新的 URL,使用已成功抓取的内容继续下一步
      • fetch 总尝试次数上限为 12 次(无论成功失败),达到上限立即进入下一步
      • 禁止对同一 URL 或任何 URL 进行第二次 fetch 尝试
    • 抓取内容合计约 5000-20000 字即可继续,不要为了凑字数而无限抓取
  3. 第一类关键词验证(自问自答,LLM 内部推理)

    • 基于已抓取的页面内容和搜索标题,确认候选关键词
    • 直接提问自己:[关键词]
    • 检查回复:
      • ✅ 回复中出现行业品牌(包括目标品牌或竞品)→ 保留
      • ❌ 回复中完全无品牌露出 → 删除,换补候补词
  4. 生成报告(基于真实抓取内容分析)

    • 品牌/产品理解、目标人群分析,必须基于已抓取的页面正文内容
    • 按关键词维度约束:每个维度最多贡献 1 个关键词,确保最终 20 个关键词无重复
    • 写入 {workspace}/geo-keyword-research/{task_id}/{task_id}_report.md
  5. 清理临时文件(报告生成成功后执行)

    rm -f {workspace}/geo-keyword-research/{task_id}/page_*.txt
    rm -f {workspace}/geo-keyword-research/{task_id}/{task_id}_product_page.txt
    rm -f {workspace}/geo-keyword-research/{task_id}/*.tmp.md
    

    ⚠️ 不删除 {task_id}_official_site.txt:后续 on_success.py 需读取此文件生成产品画像。


产物规范

产物目录:{workspace}/geo-keyword-research/{task_id}/

文件内容
{task_id}_urls.md所有真实访问 URL、标题、来源网站、搜索日期(≥ 80 条)
{task_id}_report.md品牌分析 + 目标人群 + 20 个关键词 + 总结
{task_id}_result.jsonDAG 完成后自动生成:含 brand_name / sku_name / brand_url / brand_summary / user_image_summary / keywords_data / product_image_task_id / user_image / brand_mentions / coverage_summary 的统一结构化产物

输出格式({task_id}_report.md)

前置:数据源统计

执行了多少次 search tool / 浏览了多少个数据源 / 数据源文件路径

第一段:品牌/产品理解

基于 web 搜索 + 官网内容,输出:

  • 品牌定位
  • 核心产品线
  • 产品信息:基于官网抓取内容,列出主要产品系列、型号、核心规格、价格区间
  • 主要优势特点
  • 市场地位
  • 信息来源:列出本段内容的来源 URL(官网地址及其他参考页面,每行一条)

第二段:目标人群理解

基于 web 搜索,输出:核心人群特征 / 主要痛点 / 搜索行为特点

末尾必须输出以下格式的人群分类列表(供系统自动处理,格式严格):

**人群分类:**
- 人群名称A:人群特征一句话简要描述(20-80字)
- 人群名称B:人群特征一句话简要描述(20-80字)

人群数量通常为 2-4 个,每个名称简洁(2-6字),描述须包含年龄/性别/核心需求等关键维度。

第三段:关键词列表(⚠️ 格式严格,供系统自动解析,不可更改结构)

必须严格按以下模板输出,每个关键词一个编号标题 + 两个子项。不要使用表格、不要合并行、不要更改标签名称。

### 第一类关键词(行业推荐型)- 10个

1. 关键词文本A
- **为什么选择**:选择理由说明
- **GEO策略**:对应的GEO优化策略

2. 关键词文本B
- **为什么选择**:选择理由说明
- **GEO策略**:对应的GEO优化策略

...(共10个)

### 第二类关键词(品牌直指型)- 10个

1. 关键词文本A
- **为什么选择**:选择理由说明
- **GEO策略**:对应的GEO优化策略

...(共10个)

格式规则:

  • 编号使用 1.、2. ... 10.,后接关键词文本(不要加粗,不要加 **)
  • 子项标签必须是 **为什么选择** 和 **GEO策略**,不要用其他名称
  • 每个子项以 - 开头
  • 关键词文本中不要包含编号、冒号、引号

第四段:总结与研究洞察

第一行:数据覆盖描述(保留原格式): 「本次执行 N 次搜索,收集 M 条数据源,满足/未满足 覆盖目标」 不进行精确覆盖百分比计算,只需说明满足/未满足覆盖目标。

末尾必须输出以下「研究洞察」结构化区块(供系统自动解析,格式严格):

**研究洞察:**
- [洞察段落A,2-4句](XX%内容支持)
- [洞察段落B,2-4句](XX%内容支持)

洞察规则:

  • 输出 2-3 条,合并同类观点、保留最具战略价值的洞察,不堆砌
  • 每条洞察写成 2-4 句完整段落,采用叙述分析的方式,而非标签模板。参考写法:
    • 第一句:点明核心发现或品牌战略定位(有明确论断)
    • 第二句:用本次研究中的具体数字、竞品名称、用户行为等实证支撑论点
    • 第三句(可选):说明竞品的差异化优劣,或指出用户痛点与市场机会
    • 最后:自然过渡到 GEO 内容行动方向,或总结该洞察对品牌的战略意义
  • 参考段落质感(以下为示例,内容需根据实际研究替换):

    「目标品牌以"A卖点 + B卖点"为核心战略,在 XX 价位市场建立了清晰的竞争优势。X元起售价将旗舰级配置拉入中端市场,辅以 Y 和 Z 形成差异化护城河。竞品 P、Q、R 虽在单项指标上各有建树,但目标品牌的综合均衡性和生态是难以复制的竞争力。GEO 内容应重点覆盖…场景,强化…心智认知。」

  • 每条洞察末尾必须标注「(XX%内容支持)」,XX 为估算有多少比例的抓取内容/搜索结果支持该结论
  • 内容涵盖:市场竞争格局、用户高频关注点、目标品牌核心优劣势、GEO 策略机会点
  • 禁止使用「可能」「也许」「建议考虑」等模糊措辞,每句话须有实证依据或明确论断

验证标准(第一类关键词)

情况处理方式
目标品牌排名第 1✅ 保留(高价值)
目标品牌排名第 2-3✅ 保留(有露出就有价值)
目标品牌排名第 4+✅ 保留(只要提及就有价值)
目标品牌完全没有提及❌ 删除,换补候补词

注意:只要回复中出现了行业品牌(包括竞品)就算满足,不一定只要求目标品牌出现。


使用触发方式

用户提供:brand_name(例:固特异轮胎)
系统输出:`
  1. {task_id}_urls.md(数据源记录,≥ 80 条)
  2. {task_id}_report.md(10 个第一类 + 10 个第二类关键词报告)
  3. {task_id}_result.json(on_success.py 自动生成,含 brand_name + sku_name 等字段)

核心规则(必须严格遵守)

  1. ✅ 通用适配:不限行业,适用于任何品牌/产品
  2. ✅ 维度唯一:每个并发搜索 Subtask 必须绑定唯一维度,禁止维度重叠
  3. ✅ URL 必须真实可追溯:禁止使用 /xxxx 或任何占位路径,搜索失败须记录"失败原因",不得伪造 URL
  4. ✅ 第一类必须验证:每一个关键词都要自己提问自己,检查是否有品牌露出
  5. ✅ 第二类直接输出:不需要验证,直接输出挖掘到的关键词
  6. ✅ 最终输出 10+10:固定输出 10 个第一类 + 10 个第二类,每个带解释
  7. ✅ 关键词不重复:每个维度最多贡献 1 个关键词到最终 20 个
  8. ✅ 数据完整才生成报告:URL 条数 < 80 必须补充搜索,不完整不出报告
  9. ✅ 不胡编乱造:关键词必须来自 web 搜索和社交平台,不能瞎编
  10. ✅ 有不确定就确认:不确定是否符合要求,必须找用户确认

覆盖目标参考

目标覆盖需要 search 次数需要 URL 数量
70%+5-8 次20-30 个
85%+10-15 次80-100 个
90%+15-20 次120-180+ 个

任务类型:geo_keyword_match(关键词-画像匹配)

当 task_type 为 geo_keyword_match 时,不执行上述关键词研究流程,而是执行以下匹配任务:

功能说明

根据前端传入的关键词列表和用户画像(含具体 profiles),使用 LLM 完成:

  1. 为所有关键词 × 所有画像生成问题:不再从关键词中「选择」,而是对每个画像下所有关键词(industry + brand + custom)分批生成 profile 问题
  2. 给出每个关键词对该画像的置信值(confidence 0-100),作为优先级排序依据
  3. 结合目标地区和语言,为每个画像下的每个 profile 生成一个差异化的自然语言问题
    • 同一关键词下不同 profile 的问题必须使用不同提问模式(疑问/推荐/对比/评价/体验/求助/列举等)
  4. ⚠️ 问题必须与关键词类型保持一致:
    • industry 关键词的问题严禁包含具体品牌名、产品名等专有名词,保持行业通用视角
    • brand 关键词的问题必须包含关键词中的品牌名
    • custom 关键词的问题必须直接体现关键词的核心词
  5. ✅ 全量关键词覆盖(强制):所有传入的关键词(industry + brand + custom)必须全部出现在最终产物中
  6. ✅ 问题数量裁剪(≤ max_questions,默认 150):
    • 生成完所有原始条目后,按 confidence 降序排列
    • 第一步:每个关键词各取 confidence 最高的 1 条(保底覆盖所有关键词)
    • 第二步:剩余预算(150 - 关键词数)按 confidence 降序填满
    • 若总条数不足 150,则全部保留

输入(metadata)

字段类型说明
keywordsobject关键词数据,包含 industry、brand、custom 三个数组
keywords.industryarrayAI 研究生成的行业推荐型关键词,每项 {keyword, reason}
keywords.brandarrayAI 研究生成的品牌直指型关键词,每项 {keyword, reason}
keywords.customarray用户自定义关键词,支持字符串或 {keyword} dict,必须全部覆盖
user_imagesarray用户画像列表,每个含 persona、desc、profiles
locationstring目标地区(如"中国大陆")
langstring目标语言(如"中文")
max_questionsint可选,最终问题数上限,默认 150;不得低于关键词总数
variants_countint可选,每条问题生成的语义变体数,默认 2;0 = 关闭

执行方式

直接调用脚本,不要使用 DAG 模式:

MATCH_SCRIPT=$(python3 -c "from nanobot.agent.skills import BUILTIN_SKILLS_DIR; print(BUILTIN_SKILLS_DIR / 'geo-keyword-research/scripts/keyword_match.py')")
python3 "$MATCH_SCRIPT" \
    --config-file {config} \
    --task-id {task_id} \
    --output-dir {workspace}/geo-keyword-research/ \
    --metadata-file {workspace}/.tasks/sessions/{task_id}/_task.json

产物

文件内容
{task_id}_keyword_match.json每个画像的匹配关键词(按 confidence 排序,总问题数 ≤ max_questions)+ 置信值 + profile 问题 + 语义变体

{task_id}_keyword_match.json 严格格式(⚠️ 如需手动生成,必须完全遵守此结构)

{
  "location": "中国大陆",
  "lang": "中文",
  "matches": [
    {
      "persona": "画像名称",
      "matched_keywords": [
        {
          "keyword": "关键词文本",
          "keyword_type": "industry | brand | custom",
          "confidence": 95,
          "reason": "该画像对此关键词的匹配理由",
          "profile_questions": [
            {
              "profile_id": "profile-id-xxx",
              "question": "该 profile 会问的主问题",
              "variants": [
                "语义变体1",
                "语义变体2"
              ]
            }
          ]
        }
      ]
    }
  ]
}

⚠️ 格式约束:

  • 顶层键为 matches(数组),不是 results
  • 嵌套顺序为:matches[].matched_keywords[].profile_questions[]
  • profile_questions 每项含 profile_id、question、variants 三个字段
  • 不存在 profiles[] 或 question_variant 等字段

result.json 字段说明

on_success.py 自动写入 {task_id}_result.json,字段如下:

字段类型来源说明
brand_namestring报告标题 或 metadata纯品牌名,如 "肯德基" / "BMW"
sku_namestringmetadata.brand_name LLM 拆分产品型号,如 "吮指原味鸡" / "X1";无则空字符串
target_typestringsku_name 是否为空推导"brand" = 纯品牌模式,"sku" = 品牌+SKU 模式
brand_urlstring报告信息来源块品牌官网 URL
brand_summarystring报告第一段品牌定位与产品概述
user_image_summarystring报告第二段目标人群描述
keywords_dataobject报告第三段{industry: {...}, brand: {...}}
product_image_task_idstringon_success 子任务产品画像子任务 ID
user_imagearrayon_success 子任务[{persona, task_id, desc}]

sku_name 提取方式(on_success.py 内部逻辑):

  • 从 metadata.brand_name(用户当初输入的完整品牌名)调用 LLM 解析
  • Prompt 要求 LLM 返回 {brand_name: "...", sku_name: "..."}
  • 若 LLM 无法识别独立产品型号,sku_name 为空字符串,target_type 为 "brand"
  • 若 LLM 拆分出 SKU,target_type 为 "sku"
  • LLM 调用失败时并不阻断流程,sku_name 兑备为 ""

版本信息

  • 技能名称:geo-keyword-research
  • 适用场景:GEO 优化,AI 品牌露出优化,AI 回复准确性优化
  • 适用范围:任何行业,任何品牌/产品
  • 版本:v3.5
  • 更新时间:2026-05-22
  • 更新内容:
    1. 重写为 DAG 并发搜索模式(阶段一:并发搜索 Subtask / 阶段二:汇总 Subtask)
    2. 新增维度唯一性约束,从源头防止关键词重复
    3. 新增 URL 去重规则(URL 级)
    4. 明确产物存储路径:{workspace}/geo-keyword-research/{task_id}/
    5. 禁止伪造 URL,必须写入真实搜索结果
    6. 覆盖率改为区间描述性结论,不要求精确百分比
    7. 删除旧版重复的"第五步输出格式"段落
    8. 【v3.0】第二段新增结构化人群分类列表要求(供 on_success.py 解析)
    9. 【v3.0】清理步骤调整:不再删除 official_site.txt(on_success.py 读取)
    10. 【v3.0】产物规范新增 {task_id}_result.json(由系统 on_success.py 自动生成)
    11. 【v3.1】result.json 新增 sku_name 字段:on_success.py 调用 LLM 从用户输入的 brand_name 中自动解析品牌名和产品型号,无需用户额外填写
    12. 【v3.2】第四段新增「研究洞察」bullet 区块(供 on_success.py 解析 coverage_summary)
    13. 【v3.2】result.json 新增 brand_mentions(品牌+SKU tuple 数组)和 coverage_summary(洞察观点数组)
    14. 【v3.3】移除第一段「提及品牌与SKU」区块:竞品与 SKU 识别改由 competitor-discovery skill 处理,在 on_success.py 中通过 run_competitor_discovery.py 调用 LLM 完成
    15. 【v3.4】result.json 新增 target_type:根据 LLM 是否拆分出 SKU 推导 "brand" 或 "sku",影响下游竞品发现和 QA 分析的粒度
    16. 【v3.5】geo_keyword_match 重大重写:从「每画像选4个关键词」改为「所有关键词×所有画像全量生成问题」;新增 max_questions(默认150)裁剪机制:按 confidence 降序优先保留,每个关键词至少1条保底;支持 custom 关键词类型(必须全部覆盖)
我的收藏