OpenSEO 关键词研究技能实战:用 MCP 数据把种子主题打磨成优先级关键词机会清单
【免费下载链接】open-seoOpen source alternative to Semrush and Ahrefs项目地址: https://gitcode.com/GitHub_Trending/op/open-seo
导读
OpenSEO 的开源插件中内置了九大 SEO 技能,其中keyword-research负责把零散的种子主题(seed topics)转化为一份经过排序、可执行的关键词机会清单:哪些值得立刻投入内容、哪些应该保存到项目、哪些还需要继续深挖。本文以 keyword-research 技能定义 为骨架,结合仓库中对应 MCP 工具的源码实现(research-keywords.ts、dataforseo-research-tools.ts 等),逐层拆解它的输入约束、项目上下文机制、十个工具的职责边界、完整工作流与输出规范。读完你可以直接把这套方法复用到自己的 Agent 工作流里:先读项目记忆,再拉 Search Console 的真实需求,用批量工具补全量价指标,最后按业务契合度而非单纯搜索量排序并保存关键词。
技能目标与定位
在 SKILL.md 的开头,技能的 Goal 被定义得非常明确:
Turn seed topics into a prioritized keyword opportunity set using OpenSEO MCP data.
即:用 OpenSEO 的 MCP 实时数据,把种子主题转成一份"按优先级排序的关键词机会集"。产出的核心不是一份大而全的词表,而是三个决策答案:
- 要打什么(what to target)——最高信号的机会主题与头部关键词;
- 要保存什么(what to save)——值得写入项目 saved-keywords 清单的词;
- 下一步研究什么(what to research next)——是去做关键词聚类、写内容简报,还是保存后继续扩张。
技能本身不代替人做判断,它约束的是"如何有依据地做判断":每个结论都要能回溯到 MCP 工具返回的真实指标,而不是 Agent 的凭空猜测。
从插件整体看,OpenSEO 的定位是"给 Agent 真实的 SEO 数据和引导式工作流",plugins/openseo/README.md 明确列出了它能做的事:发现与评估关键词、研究竞争对手与内容缺口、审计站点、分析外链、跟踪自然排名与 Google Maps 排名、对接 Search Console 与 Analytics 数据。keyword-research正是其中"发现与评估关键词"这一环的完整方法论。
必需输入与前置约束
技能对输入有明确要求,这决定了它能否被正确触发:
| 输入 | 是否必需 | 说明 |
|---|---|---|
projectId | 必需 | 缺失时先调用list_projects找到目标项目 |
| 种子主题 | 必需 | 一个或多个:产品、页面、竞品、受众痛点、已有词 |
| 市场 / 位置 / 语言 | 可选 | 会实质影响指标时必须向用户确认,否则用 MCP 工具默认值 |
种子主题的"规格"是刻意宽泛的——它可以来自任何方向:用户正在做的产品、某个着陆页、一个已知竞品域名,或者一个还没被满足的受众问题。技能的默认策略是:能不问就不问。只有当目标市场/位置/语言不明确、且会实质性影响搜索量与难度这类指标时,才向用户提问;否则直接采用项目级默认市场。
这一策略在源码层面有对应实现:research_keywords与get_keyword_metrics都通过resolveMarket解析市场,显式传入的locationCode/languageCode优先,缺省时继承项目的默认市场(见 research-keywords.ts 与 dataforseo-research-tools.ts 中的resolveMarketSelector)。也就是说,"用工具默认值"在实现上等于"用项目市场",而项目市场是用户在 OpenSEO 中配置好的,Agent 无需重复询问。
项目上下文:先读记忆,再花钱
keyword-research技能最独特的一点,是它把"研究前先读项目上下文"设成了硬性前置步骤。项目上下文工具是免费的,且与应用内其他 Agent(包括 SAM)共享同一份记忆。
第一步永远是 get_project_context
调用get_project_context,把研究"锚定"在项目已有信息上:业务是什么、目标是什么、覆盖哪些市场、已经保存了哪些竞品和关键页面。从源码看(project-context.ts),该工具返回的完整结构包括:
sections——业务概览(business_overview)、当前目标(current_goal)、定位、写作偏好等自由文本段落;missingSections——当前为空、值得用update_project_context补齐的段落;competitors/keyPages——已保存的竞品与关键词目标落地页短名单;researchLog——最近的研究日志(谁在什么时间买了什么数据)。
工具描述里写得很直白:Uses no credits. Call this before SEO work to ground it in what the user already told OpenSEO, and check the research log before re-buying research.
business_overview 与 current_goal 的最小内联补齐
技能要求这两个段落非空。如果任一为空,不要前端加载完整的访谈问卷,而是做"最小内联设置":
- 问用户,或从站点内容推断并确认;
- 恰好填满这两个字段即可;
- 用
update_project_context写回; - 继续研究。
完整的项目画像访谈被推迟到研究结束,技能会在结尾建议用户运行seo-project-setup技能(仓库中该技能位于 plugins/openseo/skills/seo-project-setup)去补齐剩余部分。
研究日志:30 天内不重复购买
在消耗任何积分(credits)之前,检查researchLog:如果同样的研究在过去 30 天内已经跑过,直接复用结果并明确告知用户,而不是再买一次。这正是update_project_context中appendResearchLog操作存在的意义——写入一条形如{ appendResearchLog: { summary: "Keyword research: <seeds/market>. Verdict: <conclusion>" } }的日志,让所有 Agent(包括未来的自己)都能看到"这笔数据已经买过、结论是什么"。project-context.ts 中buildUpdateProjectContextTool的注释还特别指出:SAM 也通过同一个工具写上下文,仅 author 参数不同,避免了两条写入路径漂移。
研究结束后写回持久信息
收尾时,把值得沉淀的内容写回共享记忆:
- 精炼后的
business_overview或current_goal; - 在 SERP 中反复出现的竞品——通过
addCompetitors追加; - 关键词应该落地的页面——通过
addKeyPages追加; - 一条
appendResearchLog日志记录本次研究。
这样下一次任何 Agent 做相关研究时,get_project_context就能直接读到这些沉淀。
OpenSEO MCP 工具全景
SKILL.md 一共引用了十个 MCP 工具,它们的职责边界非常清晰。下面按"发现、补全、验证、本地、保存"五类整理,并给出源码确认的参数细节。
发现类
research_keywords——主发现工具
每次调用携带 1-5 个种子词,除非用户要求穷尽式研究,否则默认取每种子 150 条结果。源码(research-keywords.ts)确认了完整参数:
| 参数 | 类型 | 默认 | 说明 |
|---|---|---|---|
seeds | 数组(1-5) | 必填 | 每个种子独立研究,返回相关词及量/难度/CPC |
resultLimit | 150 / 300 / 500 | 150 | 每种子返回的最大词数 |
includeClickstreamData | boolean | false | 用点击流数据拆分 Google Ads 的分组近似变体(复数/拼写错误);每个种子的积分成本翻倍;对由 Google Ads 数据服务的国家无效果 |
实现上每个种子是独立异步执行的(Promise.all逐 seed 处理),单个坏种子不会让整个批次失败——输出中每个 seed 都有独立的ok/rowCount/source/usedFallback状态。工具的 description 还给出了计费量级:每个种子约 30-100 积分,具体取决于数据源;由 Google Ads 数据服务的国家约 96 积分(这类国家 KD 与 intent 不可用)。
get_ranked_keywords——拉取某个域/页的真实排名词
当研究简报涉及一个目标域名或页面时使用。源码(dataforseo-research-tools.ts)确认的完整能力:
target:域名(不带协议与 www)或绝对页面 URL,支持scope在domain/subdomains/exact_url之间切换;resultTypes:organic / paid / featured_snippet / local_pack / ai_overview_reference,默认 organic + paid;- 过滤:
minSearchVolume、maxRank(1-100)、excludeBrandTerms(最多 10 个品牌词,按not_ilike排除); - 排序:
rank/search_volume/traffic_estimate/cpc,默认按搜索量降序; - 分页:
limit1-100(默认 50)、offset。
它返回每个关键词的排名、URL、搜索量、CPC 等行级数据,适合用来找"已在排名但接近临界"的缺口、或者竞品占据的词。
补全类
get_keyword_metrics——批量水合已知词
一次调用最多为700 个已知关键词补充搜索量、关键词难度(KD)、搜索意图、CPC 和月度趋势。技能明确建议用它给候选词打分,包括第 1 步从 Search Console 挖出的"striking distance"查询词。源码(dataforseo-research-tools.ts)确认:
includeMonthlyTrends:默认 true,返回逐月搜索量趋势行;includeClickstreamData:默认 false,开启后积分成本翻倍;sortBy:search_volume/keyword_difficulty/cpc/competition,默认搜索量降序。
返回的每行包含search_volume、keyword_difficulty、main_intent、cpc、competition、competition_level以及monthly_searches数组(年/月/量)。
get_search_console_performance——第一方真实需求
当项目连接了 Search Console 时,研究不一定要从冷启动的宽泛发现开始,而是从项目自己的第一方需求出发:已经获得展示、接近排名("striking distance")的查询词。源码(search-console-tools.ts)确认了两个关键实现细节:
rowLimit默认 1000、上限 1000;- GSC 按点击量排序且无法按位置过滤,所以"striking distance"(平均位置 5-20)必须在客户端过滤,并用
startRow配合hasMore分页。
技能的建议是:请求高rowLimit,在客户端筛出平均位置 5-20 的词,再用get_keyword_metrics给这些查询附加难度与意图。这样得到的是一份"已经验证有真实需求、且接近排名"的名单——这是最快的机会集,优先于宽泛发现去处理。
验证类
get_serp_results——检查 SERP 形态
对高潜力或意图模糊的词,用实时 SERP 检查"这条查询的首页长什么样",尤其当 SERP 形态会改变推荐结论时。源码(get-serp-results.ts)确认:
queries:1-10 个查询,批量友好;depth:10-100、10 的倍数,默认 20;- 计费:默认深度下每关键词约 5 积分,每加深 10 增加约 2.5 积分(Google 没有 offset,更深抓取会重复抓取头部结果),只有需要前 20 名之后的排名时才加深;
- 单查询失败不会拖垮整个批次。
返回每行精简为 type / rank / title / url / domain / description,足够判断意图与可竞争性。
本地 SEO 类
当业务/位置半径相关时,用本地工具替代纯国家级的词量与 SERP 数据:
search_local_businesses:在坐标附近搜索商家名录,支持按评分(minRating)、评论数(minReviews)、认领状态(isClaimed,false能挖出未认领的外联机会)过滤,默认返回 20 条;get_local_serp_results:抓取某坐标附近的 Google Maps 或 Local Finder SERP,默认 mobile 设备、20 条结果;get_google_business_questions:抓取某个商家的 Google Business Profile 问答,depth默认 20。
这三个工具的完整输入 schema 均在 dataforseo-research-tools.ts,仓库中还有更深入的本地排名网格工具get_local_rank_grid(按网格点逐一搜索 Maps,输出商家在各点的排名热区,见 local-seo-tools.ts),可用来度量本地可见性的辐射范围。
保存类
list_saved_keywords——避免重复劳动
列出项目已保存的关键词(含缓存的量/难度/CPC 与标签)。免费,直接读 OpenSEO 数据库,不调用 DataForSEO。支持search文本过滤与tags标签过滤(多标签按 ANY 匹配),limit可选 50/100/250,默认 100(见 list-saved-keywords.ts)。用它避免保存重复词,或把已有标签当作上下文线索。
save_keywords——仅确认后保存
把选定的关键词写入项目的 saved-keywords 清单。免费、幂等(重复保存已是存在的词是 no-op)。关键约束(save-keywords.ts):
- 每次 1-100 个词;
metrics可选:从research_keywords的行里复制 keyword / searchVolume / keywordDifficulty / cpc / competition / intent,按 keyword 字段匹配;tags:最多 20 个,可为所有被保存的词附加;tagMode:append(默认,追加)或replace(先移除这些词上的现有标签再应用新标签,适合重组成页面/主题簇);replace模式下必须提供替换标签,否则报错。
标准工作流:从种子到清单的 10 步
SKILL.md 给出的工作流是完整闭环,结合源码可以把每一步的意图讲透:
- 归一化研究角度:把种子收敛成一小撮差异化研究角度。若项目连接了 Search Console,先拉
get_search_console_performance(高rowLimit、默认回溯窗口),客户端过滤 striking distance(约 5-20 位),再用get_keyword_metrics水合 KD 与意图——这份排序后的水合名单是最快的机会集,先做它再做大范围发现。 - 本地 SEO 分流:若请求是本地 SEO,先确认商家、位置/坐标或服务半径、本地类目。对最重要的位置/关键词组合用
search_local_businesses与get_local_serp_results,而不是只依赖国家级关键词/SERP 数据。 - 探索性发现:对探索性种子调用
research_keywords,尽可能用批量调用(一次 1-5 种子)。 - 水合固定词表:用
get_keyword_metrics给固定关键词列表(或第 1 步的 striking-distance 查询)补上量、KD、意图,再做优先级排序。 - 排名词扩展:当用户给出域名/页面并想基于当前排名、临界词或竞品占据词找机会时,用
get_ranked_keywords。 - 清洗:移除无关、重复、纯品牌词与意图不匹配的词。
- 按实际机会而非单纯量排序,六个判据:
- 与用户产品/页面/主题强匹配;
- 搜索意图清晰;
- 难度合理;
- 有可用的量/CPC 信号;
- SERP 形态下用户有可竞争空间;
- 本地 SEO 场景下,考虑本地包/Maps 可见性与距离契合度。
- SERP 验证:对高潜力或意图模糊的关键词用
get_serp_results(保持默认小深度)。 - 输出:一份短名单 + 一份更长的机会表。
- 确认后保存:保存前必须询问用户;保存时建议使用简洁标签,如
topic:<topic>、intent:<intent>、page:<slug>。
输出格式:先给最高信号结论,再给表,最后给下一步
技能规定的输出结构是"结论优先",而不是把原始表格直接抛给用户:
最高信号推荐(放在最前面):
- 最佳机会主题(Best opportunity theme);
- 现在就该打的关键词(Top keywords to target now);
- 建议保存的关键词(Keywords to save);
- 风险或 SERP 注意事项(Risks or SERP caveats)。
紧凑表格(每词一行,指标列靠右对齐):
| Keyword | Intent | Volume | KD | CPC | Priority | Notes |
|---|
这张表与 MCP 工具返回的文本表形态一致——research_keywords和get_keyword_metrics在 text 内容块里就用formatMcpTable渲染出 keyword / volume / KD / CPC / competition / intent 六列(见 research-keywords.ts)," — "表示该指标不可用。Agent 应把 Priority 与 Notes 两列作为自己判断的承载:Priority 依据第 7 步的六个判据综合得出,Notes 记录 SERP 观察、意图判断或落地页建议。
下一步动作(收尾):明确是否运行关键词聚类、创建内容简报、或保存所选关键词。仓库中对应的承接技能包括 keyword-clustering(聚类)与 seo-coach 等,可在 plugins/openseo/skills 目录下找到全部九个技能。
三条护栏:不编造、不越权、不追量
SKILL.md 以三条 guardrails 收尾,它们是整个方法论的安全边界,也与工具实现互相印证:
- 不编造指标:OpenSEO 没返回的值就写
unknown。这与工具行为一致——Google Ads 数据服务的国家 KD/intent 为 null、GSC 在 discover/googleNews 类型下不报告 position(见 search-console-tools.ts 的说明),这些"不可用"都是真实状态而非失败,Agent 必须如实呈现。 - 未经明确确认不得调用
save_keywords:保存是写操作(工具的destructiveHint: true,且支持tagMode: replace会移除既有标签),所以技能强制"先问后存"。 - 业务契合与意图契合优先于最大量词:这是整个技能的价值取向——机会清单服务于用户的实际业务目标,而不是一份单纯按搜索量排序的词表。第 7 步的六条判据把"匹配度、意图、难度、量信号、可竞争性"放在同等重要的位置,正是这一护栏的展开。
小结:这套方法论能复用的部分
keyword-research技能的价值不仅在于"调哪些工具",更在于一套可迁移的研究纪律:
- 先读共享记忆再消费数据(
get_project_context+ 30 天研究日志去重); - 先处理已验证的真实需求(Search Console striking distance),再宽泛发现;
- 用批量工具把量/难度/意图水合到已知词表上,再排序;
- 按业务机会而非单纯量做决策,并用
get_serp_results验证意图; - 结论优先的输出结构,配合紧凑表格与明确的下一步;
- 写操作前置确认、数据缺失如实标注。
如果你希望把同样的流程接入自己的 Agent,可以直接参考 SKILL.md 的完整文本与上述源码路径;要了解插件整体的连接方式(OAuth 登录、托管 MCP 服务器与九个技能清单),见 plugins/openseo/README.md。
【免费下载链接】open-seoOpen source alternative to Semrush and Ahrefs项目地址: https://gitcode.com/GitHub_Trending/op/open-seo
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考