Felo API PlatformFelo API Platform

研究

把市场问题变成一份 go-to-market 简报

向市场提出一个精确的问题,读答案背后的品类和定价页面,收集买家在 X 上怎么描述问题,再保存一份有来源主张和开放问题的 GTM 简报。

构建时间30 分钟难度进阶更新于2026-10-30
适合谁创始人与运营者产品市场销售负责人

复制 prompt

把方括号里的字段替换掉,然后粘贴到 Claude Code、Codex 或任何能访问终端的 AI。它会安装 Felo skill、在花额度前询问,并执行这套 workflow。

为[产品]进入[地区]的[细分市场或 ICP]制作一份 go-to-market 研究简报,语言为[语言]。

模式:[自助 / 销售主导 / 渠道]。它支持的决策:[发布 / 定价 / 重新定位]。时间范围:[过去 90 天 / 过去 12 个月]。

输出一份 Markdown 简报,包含:
1. 细分市场定义:他们是谁、今天用什么、来源对规模怎么说——引用来源,或写“暂无数据”。
2. 买家语言:他们如何描述问题,附链接和日期。
3. 替代方案:他们从什么切换过来,包括电子表格和“什么都不做”。
4. 异议,以及买家要求的证明。
5. 公开来源无法回答的开放问题。
6. 完整来源列表。

规则:
- 每个市场主张都需要链接和日期。不要凭感觉估算市场规模、增长或预算。
- 区分独立来源、厂商页面和你自己的推断。
- X 只用于语言和异议,不作为市场规模的证据。
- 把时间范围和地区落实为明确值。
- 消耗额度前,先展示计划执行的 API 调用并等待我批准。
- 不要发布、发送、排期,或写入任何 CRM。
- 将结果写入 ./gtm-brief.md,并在对话中总结。

复制的内容也包含安装步骤和安全规则。

你会得到什么

一次运行的示例输出,不是实时生成。

GTM 简报示例(节选)

GTM 简报 — [地区] 的 [细分]

细分定义

用电子表格排期的小型运营团队。规模:所查阅的公开来源暂无数据——没有来源就不要在简报里写数字。

买家语言

  • “我们还在用电子表格做这件事” — X 帖子,2026-10-18
  • “最难的是配置” — X 帖子,2026-10-02

标注为语言,不作为普遍性证据。

买家提到的替代方案

电子表格、现有套件,以及什么都不做。来源:https://example.com/thread(2026-10-18)。

异议和所需证明

安全审查和迁移路径。买家要求可具名的参考客户;我们目前没有公开的,所以这仍是开放问题。

开放问题

  • 这个细分里有多少已有专门预算项?
  • 异议会随公司规模变化吗?

来源

  • https://example.com/category-page
  • https://example.com/pricing-page
  • https://example.com/thread

实际调用

给开发者:同一套 workflow 的可复制代码,按执行顺序排列。

展开实际 API 调用
  1. 框定市场问题

    Chat 会返回答案和用过的页面,所以从一个窄到能回答的问题开始:谁在买、他们今天用什么、会遇到什么异议。把资源保留为线索链接;答案是线索,链接才是证据,它们最后会组成来源列表。下面的 helper 只发送一次 Key,非 2xx 响应会抛错。

    gtm.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 product = "scheduling tool"; // replace with your product
    const segment = "operations teams at 50-200 person companies";
    const region = "DACH";
    
    const market = await felo<ChatData>("/v2/chat", {
      query: `Who buys ${product} for ${segment} in ${region}, what do they use today, and what objections come up?`,
    });
    
    const seedSources = market.data.resources.slice(0, 5);

    示例输出

    {
      "answer": "Buyers in this segment usually start from spreadsheets and …",
      "sources": [
        { "link": "https://example.com/category-page", "title": "…", "snippet": "…" }
      ]
    }
  2. 读品类页面本身

    抓取框定市场的页面:品类概览、对比页和定价页。用 readability 抽成 Markdown,并给每页盖上抓取日期,因为市场阅读的质量取决于背后的页面。

    gtm.ts
    type ExtractData = { data: { content: string } };
    
    const marketPages = [
      { url: "https://example.com/category", title: "Category overview" },
      { url: "https://example.com/comparison", title: "Comparison page" },
      { url: "https://example.com/pricing", title: "Pricing page" },
    ];
    
    const pages = await Promise.all(
      marketPages.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/category",
      "checkedAt": "2026-10-30",
      "content": "# Category overview\n\nExtracted page text…"
    }
  3. 收集买家怎么描述问题

    在 X 搜索买家遇到问题时使用的词,而不是你的产品名。保留账号和日期;简报用这些帖子获取语言和异议,绝不把它们当作市场规模或异议普遍程度的度量。

    gtm.ts
    type XData = {
      data: {
        tweets: {
          content: string;
          author: { username: string };
          created_at: string;
          metrics: { retweet_count: number; favorite_count: number };
        }[];
      };
    };
    
    const since = Math.floor((Date.now() - 90 * 24 * 60 * 60 * 1000) / 1000);
    
    const language = await felo<XData>("/v2/x/tweet/search", {
      query: `(spreadsheet OR "scheduling tool") (alternative OR "looking for")`,
      limit: 25,
      since_time: since,
    });
    
    const quotes = language.data.tweets.slice(0, 5);

    示例输出

    { "data": { "tweets": [
      {
        "content": "we are still doing this in a spreadsheet",
        "author": { "username": "example_ops" },
        "created_at": "2026-10-18T11:05:00Z",
        "metrics": { "retweet_count": 1, "favorite_count": 18 }
      }
    ] } }
  4. 围绕决策写简报

    把细分定义、买家语言、替代方案、异议和开放问题拼成一段 Markdown。每条主张保留来源和日期,市场规模只有来源提供时才写,公开来源回答不了的内容放进开放问题,而不是推断。

    gtm.ts
    const today = new Date().toISOString().slice(0, 10);
    
    const sourceLine = (title: string, url: string, date: string) =>
      `- ${title}: ${url} (checked ${date})`;
    
    const brief = [
      `# GTM brief — ${segment} in ${region}`,
      "",
      "## Segment definition",
      "See the category page for how the segment is described. Market size: Not available from public sources reviewed.",
      "",
      "## Buyer language",
      ...quotes.map((post) => `- @${post.author.username}, ${post.created_at.slice(0, 10)}: ${post.content}`),
      "",
      "## Alternatives buyers mention",
      "Spreadsheets, an incumbent suite, and doing nothing. Treated as language until a source ranks them.",
      "",
      "## Objections and proof required",
      "Migration path and a named reference. Marked open: whether the objection changes by company size.",
      "",
      "## Open questions",
      "- How much of the segment already has a dedicated budget line?",
      "- Which objection blocks a pilot most often?",
      "",
      "## Sources",
      ...pages.map((page) => sourceLine(page.title, page.url, page.checkedAt)),
      ...seedSources.map((source) => `- ${source.title}: ${source.link}`),
    ].join("\n");
    
    console.log(brief);

    示例输出

    # GTM brief — operations teams at 50-200 person companies in DACH
  5. 把证据留给下一个市场

    每个细分和地区建一个 LiveDoc,把抓到的页面作为 URL 资源加进去,再把简报本身作为文档资源加进去。下一个市场从同一批来源开始,不用重新抓品类页,重复 URL 会自动去重。

    gtm.ts
    type LiveDocData = { data: { short_id: string } };
    
    const briefDoc = await felo<LiveDocData>("/v2/livedocs", {
      name: `GTM: ${segment} — ${region}`,
      description: `Market evidence checked ${today}`,
    });
    
    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: `GTM brief ${today}`,
      content: brief,
    });
    
    console.log(briefDoc.data.short_id); // reuse for the next region

    示例输出

    { "short_id": "PvyKouzJirXjFdst4uKRK3" }

包含什么

  • 来自 Chat API 的有来源市场阅读,以及背后的页面
  • 品类、对比和定价页面的 Markdown 提取
  • X 上带账号和日期的买家语言与异议
  • 围绕发布决策而不是话题组织的简报
  • 让下一个地区或发布复用证据的 LiveDoc

不做什么

  • 只覆盖公开来源;没有付费市场报告、panel 或客户访谈
  • 绝不估算市场规模或增长——缺失数据写“暂无数据”
  • X 帖子提供语言和信号,不代表买家的有代表性样本
  • 它不会替你选择细分或定价
  • 它不会发布简报,也不会写进 CRM

常见问题

需要买付费市场研究报告吗?

不需要。workflow 读公开来源并标出空白。如果你已经有报告,把它作为文档资源加进 LiveDoc,像其他来源一样引用。

可以研究其他语言的市场吗?

可以。设置地区和语言占位符。引语保留原文,并在旁边附翻译,方便本地 reviewer 检查措辞。

它会给我市场规模吗?

只有当某个来源明确给出时才会,并附链接和日期。否则简报写“暂无数据”,不会编数字,也不会从一条帖子外推。

它能和客户对话吗?

不能。它只读公开来源。把访谈笔记作为文档资源加进去并标为内部;简报不会把私人笔记当成公开证据。

它和研究简报 workflow 有什么区别?

研究简报回答一个问题。这套 workflow 把证据组织成 go-to-market 决策——细分、买家语言、替代方案、异议和买家要求的证明——输出可以直接喂给发布计划。

一份简报要花多少?

每次 chat、抽取和 X 搜索都会消耗按量计费的额度;当前费率在价格页面。prompt 会在花额度之前请求确认。

相关 workflow

改成你的版本

同一套配方,按你实际的交付方式调整。

按地区各跑一次

保持章节结构不变,只改地区和语言占位符。每个地区一个 LiveDoc、同样的问题,这样几份简报可以对比,而不是变成三份互不相关的文档。

加入你自己的访谈笔记

把客户通话笔记粘贴成文档资源并标为内部。简报可以把它们放在公开证据旁边引用,但绝不会把私人笔记当成公开来源。

喂给发布 deck

把异议和证明部分交给 deck workflow,并保留来源列表。简报是证据层,deck 是它的展示,不是第二个真相来源。

这套配方背后的参考页面,以及下一步可以看什么。