研究
把一个搜索词变成 SEO 内容简报
看当前哪些页面在回答这个搜索词,把它们读成 Markdown,梳理它们回答和遗漏的问题,再写一份编辑可以直接拿去列大纲的简报。
复制 prompt
把方括号里的字段替换掉,然后粘贴到 Claude Code、Codex 或任何能访问终端的 AI。它会安装 Felo skill、在花额度前询问,并执行这套 workflow。
为[产品或站点]写一份针对查询[目标查询]的 SEO 内容简报。 读者:[读者]。市场与语言:[地区]、[语言]。角度:[指南 / 对比 / 产品页]。它支持的决策:[新文章 / 更新 / 补缺口]。 先读当前有哪些页面在回答这个查询,再列大纲。输出一份 Markdown 简报,包含: 1. 目标查询和你推断的搜索意图,并给出这一判断的依据。 2. 当前页面覆盖了什么:标题、URL、开篇章节。 3. 当前页面回答了哪些问题,漏掉了哪些问题。 4. 建议大纲,每个章节用一句话说明它必须证明什么。 5. 来自来源的证据和例子,附链接。 6. 完整来源列表。 规则: - 不要声称搜索量、关键词难度、排名位置或流量。这个工作流不测量这些;用“此处未测量”代替数字。 - 不要编造统计、引文或关于竞品内容的说法。 - 把意图描述为对页面的解读,而不是测量出的事实。 - 引文要短、注明出处并附链接。 - 把地区和语言落实为明确值。 - 消耗额度前,先展示计划执行的 API 调用并等待我批准。 - 不要发布、排期或发送任何内容。 - 将结果写入 ./seo-brief.md,并在对话中总结。
复制的内容也包含安装步骤和安全规则。
你会得到什么
一次运行的示例输出,不是实时生成。
SEO 简报 — “如何自动化支持分诊”
目标查询和意图
查询:“如何自动化支持分诊”。返回的页面以实施步骤开头,而不是产品页,所以意图读作 how-to。这是对页面的解读,不是测量出的意图标签。
当前页面覆盖什么
| 页面 | URL | 开头内容 |
|---|---|---|
| 自动化支持分诊:实用指南 | https://example.com/guide | 路由规则,然后是标签 |
| 分诊自动化清单 | https://example.com/checklist | 清单本身 |
页面回答的问题
- 分诊自动化改变了什么
- 从哪些路由规则开始
页面漏掉的问题
- 如何衡量分诊是否真的改善
- 分类器判断错误时怎么办
建议大纲
- 分诊自动化改变了什么——证明它关乎队列,而不是人头。
- 值得自动化的前三条路由规则——每条用实例证明。
- 第一个月如何衡量——用运营负责人能取到的指标证明。
- 自动化出错时——证明人工兜底路径。
证据
- 路由规则示例,引自 https://example.com/guide(2026-10-30 核对)
此处未测量
搜索量、关键词难度和排名位置。这个工作流读取公开页面,不查询搜索索引或排名工具。
来源
- https://example.com/guide
- https://example.com/checklist
实际调用
给开发者:同一套 workflow 的可复制代码,按执行顺序排列。
展开实际 API 调用
先看当前谁在回答
用 Chat 问这个搜索词,拿到答案和它引用的页面;这些页面就是当前的竞争内容。
seo-brief.ts const BASE = "https://openapi.felo.ai"; const headers = { Authorization: `Bearer ${process.env.FELO_API_KEY}`, "Content-Type": "application/json", }; async function felo<T>(path: string, body?: unknown): Promise<T> { const res = await fetch(`${BASE}${path}`, { method: body ? "POST" : "GET", headers, body: body ? JSON.stringify(body) : undefined, }); if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`); return res.json() as Promise<T>; } type ChatData = { data: { answer: string; resources: { link: string; title: string; snippet: string }[]; }; }; const query = "how to automate support triage"; const ourSite = "example.com"; const coverage = await felo<ChatData>("/v2/chat", { query: `What pages currently answer the search query "${query}"? List the pages and what each one covers.`, }); const candidates = coverage.data.resources .filter((resource) => !resource.link.includes(ourSite)) .slice(0, 5) .map((resource) => ({ url: resource.link, title: resource.title }));示例输出
{ "answer": "Readers searching this usually want a step-by-step …", "sources": [ { "link": "https://example.com/guide", "title": "…", "snippet": "…" } ] }把页面读成 Markdown
用 Web Fetch 把最强的三到五个页面抓成 Markdown,保留标题和问题。
seo-brief.ts type ExtractData = { data: { content: string } }; const pages = await Promise.all( candidates.map(async (page) => { const res = await felo<ExtractData>("/v2/web/extract", { url: page.url, output_format: "markdown", with_readability: true, with_cache: true, }); const checkedAt = new Date().toISOString().slice(0, 10); return { ...page, checkedAt, content: res.data.content }; }), );示例输出
{ "url": "https://example.com/guide", "checkedAt": "2026-10-30", "content": "# Automating support triage\n\n## Routing rules\n…" }梳理覆盖和遗漏
把每页的 H2/H3 和 FAQ 问题抽出来,做一张覆盖表:哪些问题被回答,哪些没有。
seo-brief.ts type Heading = { page: string; heading: string }; const headings: Heading[] = pages.flatMap((page) => page.content .split("\n") .filter((line) => line.startsWith("## ")) .map((line) => ({ page: page.title, heading: line.replace(/^##\s+/, ""), })), ); const questions = headings.filter((item) => item.heading.includes("?")); const byTopic = new Map<string, string[]>(); for (const item of headings) { byTopic.set(item.heading, [...(byTopic.get(item.heading) ?? []), item.page]); }示例输出
// questions [ { "page": "…", "heading": "What routes should you automate first?" } ]写简报
写目标词、意图、覆盖对比、遗漏问题、建议大纲和来源列表。
seo-brief.ts const today = new Date().toISOString().slice(0, 10); const brief = [ `# SEO brief — "${query}"`, `Checked ${today}. Site: ${ourSite}.`, "", "## Intent read", "The pages returned for this query lead with: " + headings.slice(0, 6).map((item) => item.heading).join("; ") + ". This is a reading of their structure, not a measured intent label.", "", "## What the pages cover", "| Page | URL | Checked |", "| --- | --- | --- |", ...pages.map((page) => `| ${page.title} | ${page.url} | ${page.checkedAt} |`), "", "## Questions the pages answer", ...questions.map((item) => `- ${item.heading} (${item.page})`), "", "## Topics more than one page covers", ...[byTopic.entries()] .filter(([, pageTitles]) => pageTitles.length > 1) .map(([heading, pageTitles]) => `- ${heading} (${pageTitles.length} pages)`), "", "## Proposed outline", ...questions.slice(0, 5).map((item, index) => `${index + 1}. ${item.heading}`), "", "## Questions they miss", "<!-- Only questions none of the fetched pages answer. Delete this comment when filled. -->", "", "## Not measured here", "Search volume, keyword difficulty, and ranking position. This workflow reads public pages; it does not query a search index or a rank tracker.", "", "## Sources", ...pages.map((page) => `- ${page.title}: ${page.url}`), ].join("\n"); console.log(brief);示例输出
# SEO brief — "how to automate support triage"
存进 LiveDoc
把简报和页面链接存进 LiveDoc,下次更新只抓变化的部分。
seo-brief.ts type LiveDocData = { data: { short_id: string } }; const briefDoc = await felo<LiveDocData>("/v2/livedocs", { name: `SEO briefs: ${ourSite}`, description: "One document resource per target query", }); await felo(`/v2/livedocs/${briefDoc.data.short_id}/resources/urls`, { urls: pages.map((page) => ({ url: page.url, title: page.title })), }); await felo(`/v2/livedocs/${briefDoc.data.short_id}/resources/doc`, { title: `SEO brief — ${query}`, content: brief, }); console.log(briefDoc.data.short_id); // the next query adds to this archive示例输出
{ "short_id": "PvyKouzJirXjFdst4uKRK3" }
包含什么
- 来自 Chat 的有来源页面列表,以及答案背后的链接
- 当前排名靠前的页面,转成 Markdown
- 这些页面覆盖的标题和问题
- 一份可直接列大纲的简报
- 保存来源的 LiveDoc,下次更新可以接着用
不做什么
- 不测排名、搜索量、关键词难度或流量
- 只读公开页面;登录墙和付费墙可能失败
- 不会替你发布或改写整篇文章
- 一个搜索词对应一次运行;批量词需要你自己循环
- 不保证内容一定排名
常见问题
它测量搜索量或排名吗?
不测。它只读公开页面,判断当前哪些内容在回答这个搜索词;排名和搜索量请用你现有的 SEO 工具。
数据从哪里来?
Chat 返回有来源的页面,Web Fetch 把页面转成 Markdown。简报里的每个判断都指向具体页面和日期。
能处理多个搜索词吗?
可以,但每次只跑一个词。批量处理时,为每个词重复同样的步骤,并各自保存一份简报。
适合什么类型的搜索词?
适合信息型、比较型和“怎么做”类查询,因为公开页面能提供足够信号。交易型词还需要你自己的产品与转化数据。
会直接写文章吗?
不会。它产出的是简报和大纲,真正写作仍由编辑或你的写作 agent 完成。
一次要花多少?
Chat 和页面抽取都会消耗按量计费的额度;当前费率在价格页面。prompt 会在花额度前请求确认。
相关 workflow
改成你的版本
同一套配方,按你实际的交付方式调整。
只做对比型搜索词
把范围限定在“X vs Y”“最佳 X”这类词,覆盖表会更容易看出差异化角度。
加入你自己的产品页
把产品页作为额外来源加进去,让大纲能落到你的功能和定价上。
按季度刷新
同一个 LiveDoc 重跑,观察竞争页面和大纲建议怎么变化。
继续深入
这套配方背后的参考页面,以及下一步可以看什么。