リサーチ
在庫を持つ前に商品ニッチを調べる
カテゴリの文脈を集め、明示した日付で競合ページを取得し、X で買い手の不満を読み、証拠とメモを1つの LiveDoc に残して発注前に見返せるようにします。
プロンプトをコピー
角括弧の項目を置き換えて、Claude Code、Codex、ターミナルにアクセスできる AI に貼り付けてください。Felo スキルをインストールし、クレジットを使う前に確認し、ワークフローを実行します。
在庫を持つ、またはローンチする前に、この製品ニッチを調査してください: [製品またはカテゴリ]。 市場: [国または地域]。チャネル: [マーケットプレイス / DTC / 小売]。購入者投稿の期間: 過去 [30] 日。 比較製品または競合 URL: [URLs]。予算と粗利の制約: [制約]。読者: [チーム]。 Markdown のメモに以下を含めてください。 1. 1段落の判定: さらに調査する価値があるか、何が変われば判断が変わるか。 2. 需要シグナル: 関心、季節性、代替品について出典が何と言っているか。 3. 競合製品: 各製品の主張、ページで確認した価格、購入者が不満を述べている点。 4. 価格ポジショニング: ページで実際に見つかった価格帯と、それぞれの確認日。 5. 購入者の不満と満たされていないニーズ(引用、アカウント、日付を添えて)。 6. 在庫購入前に解消すべきリスクと未解決の問い。 7. 出典: 使用したすべてのページと投稿の URL と日付。 ルール: - API が返したものだけを使ってください。市場規模、売上予測、レビュー数、競合価格を捏造しないでください。 - 価格は取得したまま、ページ URL と取得日を添えて報告してください。平均化や正規化はしないでください。 - X の投稿は市場データではなく事例として扱い、サンプルが薄い場合はその旨を書いてください。 - ベンダーの主張と購入者の報告を分けてください。 - クレジットを消費する前に、実行予定の抽出と検索を示して私の承認を待ってください。 - サプライヤーへの連絡、発注、X でのメッセージ送信はしないでください。 - 結果を ./product-research.md に書き、チャットで要約してください。
コピー内容にはインストール手順と安全ルールも含まれます。
完成するもの
実行時の出力例です。リアルタイム生成ではありません。
製品調査 — 例のカテゴリ
判定
もう少し調べる価値はあるが、公開証拠だけでは在庫判断に足りない。下の未解決の問いが次のステップ。
カテゴリの文脈
買い手は圧力よりカウンタースペースと手入れのしやすさで比較する。市場規模の推定を支える公開ソースはない。
競合ページ
- Example A — 製品ページ(2026-10-30 取得)
- Example B — 製品ページ(2026-10-30 取得)
買い手の報告
- @example_buyer:「1年に3回目の交換。シールが壊れる」 — 2026-10-19
- @example_home:「掃除に数分かかる。誰も言わない」 — 2026-10-24
価格ポジショニング
価格は 2026-10-30 にリンク先ページから取得。2つの価格帯に分かれており、各ページを直接引用し、平均は取っていない。
リスクと未解決の問い
- シールの耐久性が最も繰り返される不満。
- 返品率を扱うソースはない。
- 発注前にサプライヤーのリードタイムと着地コストを確認する。
出典
- https://example.com/product-a — 2026-10-30
- https://x.com/example_buyer/status/... — 2026-10-19
実際の呼び出し
開発者向け:同じワークフローを実行順に並べたコピー可能なコード。
実際の API 呼び出しを表示
Chat にカテゴリ全体像を聞く
白紙からではなく出典付きの回答から始めます。Chat は公開 Web を検索し、ページを順位付けし、使ったリソースを返します。需要の文脈、代替品、よくある不満を1つの問いで聞き、上位リソースを証拠リストとして残します。
product-research.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 niche = "portable espresso maker"; // replace with the category you are judging const context = await felo<ChatData>("/v2/chat", { query: `Demand, price bands, and buyer complaints for ${niche} in the US`, }); const sources = context.data.resources.slice(0, 5);出力例
{ "answer": "Buyers compare on counter space and cleanup …", "sources": [ { "link": "https://example.com/category-guide", "title": "…", "snippet": "…" } ] }競合ページを取得する
readability を有効にして競合商品ページを2〜3件 Markdown で抽出します。目的は今日のページの主張と価格であり、言い換えた仕様表ではありません。URL と内容を並べ、取得日をメモに記録します。日付のない価格は噂です。
product-research.ts const PRODUCT_PAGES = [ { url: "https://example.com/product-a", title: "Example A — product page" }, { url: "https://example.com/product-b", title: "Example B — product page" }, ]; type ExtractData = { data: { content: string } }; const listings = await Promise.all( PRODUCT_PAGES.map((page) => felo<ExtractData>("/v2/web/extract", { url: page.url, output_format: "markdown", with_readability: true, }).then((extracted) => ({ ...page, content: extracted.data.content })), ), );出力例
[ { "url": "https://example.com/product-a", "title": "Example A — product page", "content": "# Example A\n\nSpecs and price as displayed…" } ]X で買い手の報告を読む
ベンダーページは機能を並べ、買い手は失敗を語ります。ニッチと、物流・品質・返金などの摩擦語を組み合わせて直近30日を検索し、ハンドル、日付、投稿リンクを残します。これらは逸話であり需要データではないとメモに明記します。
product-research.ts type XData = { data: { tweets: { content: string; author: { username: string }; created_at: string; metrics: { retweet_count: number; favorite_count: number; reply_count: number }; url: string; }[]; }; }; const since = Math.floor((Date.now() - 30 * 24 * 60 * 60 * 1000) / 1000); const search = await felo<XData>("/v2/x/tweet/search", { query: `"${niche}" (shipping OR quality OR refund)`, limit: 50, since_time: since, }); const complaints = search.data.tweets;出力例
{ "data": { "tweets": [ { "content": "Third replacement in a year; the seal fails.", "author": { "username": "example_buyer" }, "created_at": "2026-10-19T15:02:00Z", "metrics": { "retweet_count": 1, "favorite_count": 12, "reply_count": 3 }, "url": "https://x.com/example_buyer/status/..." } ] } }メモを組み立てる
このステップは普通のコードです。カテゴリ回答、取得日、買い手の引用、出典リストを1つの Markdown にまとめます。未解決の問いを正直に残します。ページが証明できることと、サプライヤーに確認すべきことを分けるからこそメモは役立ちます。
product-research.ts const capturedOn = new Date().toISOString().slice(0, 10); const memo = [ `# Product research — ${niche}`, "", "## Category context", context.data.answer, "", "## Competitor pages", ...listings.map( (page) => `- [${page.title}](${page.url}) — captured ${capturedOn}`, ), "", "## What buyers report", ...complaints.slice(0, 10).map( (post) => `- @${post.author.username} (${post.created_at.slice(0, 10)}): ${post.content}`, ), "", "## Sources", ...sources.map((source) => `- [${source.title}](${source.link})`), ].join("\n"); console.log(memo);証拠を LiveDoc に保存する
ニッチごとに1回実行します。LiveDoc を作成し、
short_idを設定に保存します。競合ページと Chat の出典を URL リソースとして追加し、アーカイブで重複排除し、メモをドキュメントリソースとして追加します。発注前に取得結果を検索し、メモ執筆後に動いた価格を確認できます。product-research.ts type LiveDocData = { data: { short_id: string } }; const research = await felo<LiveDocData>("/v2/livedocs", { name: `Product research: ${niche}`, description: "Competitor pages, buyer posts, and the memo", }); await felo(`/v2/livedocs/${research.data.short_id}/resources/urls`, { urls: [ ...listings.map((page) => ({ url: page.url, title: page.title })), ...sources.map((source) => ({ url: source.link, title: source.title })), ].slice(0, 10), }); await felo(`/v2/livedocs/${research.data.short_id}/resources/doc`, { title: `Product memo — ${capturedOn}`, content: memo, });出力例
{ "short_id": "PvyKouzJirXjFdst4uKRK3" }
含まれるもの
- Chat の出典付きカテゴリ全体像と根拠ページ
- 明示した日付で取得した競合商品ページの Markdown
- ハンドル、日付、リンク付きの X 買い手の不満
- これらの入力から組み立てた Markdown メモ
- 証拠とメモをまとめて保存する LiveDoc
やらないこと
- 公開ソースのみ。有料市場レポート、サプライヤー見積もり、社内販売データは対象外
- 市場規模、販売量、粗利は推定しない
- 価格は取得したまま記録し、正規化や平均化はしない
- X 投稿は逸話であり、需要データではない
- サプライヤーへの連絡、発注、リスティング変更はしない
よくある質問
市場の文脈はどこから来ますか?
Chat API は出典付きの回答と使用した公開ページを返します。競合ページは指定 URL から Web Fetch で抽出し、買い手投稿は X Search から取得します。非公開の販売データは使いません。
商品が売れるか分かりますか?
いいえ。公開証拠(カテゴリ文脈、取得価格、買い手の不満)を整理し、不明点を書きます。需要検証には広告、予約販売、サプライヤーとの会話など、自分たちのデータが必要です。
マーケットプレイスが抽出をブロックしたら?
Web Fetch は URL ごとに公開ページを取得し、サイトによってはブロックされます。アクセスできる商品ページやサプライヤーページを使い、メモには取得できなかったことを書きます。価格を推測しません。
競合価格の古さを防ぐには?
メモの各価格はページ URL と取得日に結び付けます。発注判断の直前に再取得してください。アーカイブには過去の取得も残り、価格が動いたことを確認できます。
サプライヤーや販売者に連絡しますか?
いいえ。読み取り専用のワークフローです。ページを取得し、公開投稿を検索し、ローカルにメモを書くだけで、メッセージ送信、発注、リスティング編集はしません。
1回のリサーチ費用は?
Chat、ページ抽出、X 検索は従量制クレジットを使います。現在の料金は料金ページにあります。プロンプトは実行前に承認を求めます。
関連ワークフロー
1つの問いを、出典付きリサーチブリーフに変える
Web に問いを投げ、回答の根拠ページを Markdown で取得し、X の実務者の声を加え、最後に証拠をあとから検索できる LiveDoc に残します。
ワークフローを開くコンテンツSNSの会話を週次のリスニングブリーフに変える
直近1週間の自社ブランドと競合に関する X 投稿を検索し、出典付きの Web 文脈を加え、その背景ページを読み、毎号をアーカイブして翌週は既知の内容から始めます。
ワークフローを開くオフィスリサーチページをスライド資料に変える
ページを抽出し、LiveDoc の文脈として保存し、PPT Task API に deck を作らせ、完成したリンクが出るまでポーリングします。
ワークフローを開く自分の形に変える
同じレシピを、実際の進め方に合わせて調整します。
レビュー動画の文字起こしを加える
カテゴリにレビュー動画がある場合、YouTube Subtitling で文字起こしを取得し、買い手セクションにタイムスタンプ付き引用を2〜3件加えます。動画レビューも1人の体験なので、X 投稿と同じ逸話ラベルを付けます。
2つの候補を並べる
候補ごとに同じ手順を実行し、メモを並べます。主張された機能、取得価格、繰り返し出る不満、未解決の問いです。自分の販売データや返品データができるまでは定性比較のままにします。
発注前に更新する
発注の前日にページ抽出を再実行します。同じ LiveDoc を使い、新しいメモを追加して、デスクリサーチと購入の間に何が変わったか(予算を超えた価格を含む)を残します。
さらに進む
このレシピの背景にあるリファレンスと、次に見るべきページ。