NLWeb とは何か。商品の構造化データから会話検索を作って分かったこと
NLWeb は、サイトの構造化データを取り込み、文章での質問に商品の一覧で答える仕組み。その概要を説明し、架空の EC サイトに組み込んで分かったことをまとめる。LLM が書く説明文には、商品ページに無い内容が入ることがあった。
検証・実装Photo: Eric Prouzet / Unsplash- NLWeb は商品の構造化データから会話検索と MCP サーバを作る仕組み。Microsoft が 2025年5月に発表
- デモで NLWeb が返した商品はカタログ内のものだけだった。その説明文は LLM が書き、商品ページに無い内容も入った
- 1 質問で LLM を 26〜90 回呼び、費用は平均約 4〜14 円。試すなら、説明文の見せ方と費用の上限を先に決める
NLWeb(Natural Language Web)は、サイトが公開している構造化データを取り込み、文章での質問に商品や記事の一覧で答える窓口を作る、オープンソースの仕組みです。Microsoft が 2025年5月19日に発表しました。
NLWeb が作る窓口には、人向けの /ask と、AI 向けの MCP(Model Context Protocol)サーバである /mcp の 2 つの入口があります。本ラボは NLWeb を架空の EC サイト「ACLAB Store」(24 商品)に組み込んで公開しました。
手元で動かした NLWeb に質問 8 問(うち 1 問は英語)を 144 回送り、返ってきた商品とその説明文を、元の商品データと照らし合わせました。商品がカタログに実在するか、説明文が商品ページの記述と合っているかを確かめています。
NLWeb は商品ページの構造化データを会話検索の入力にする
本ラボのデモ EC にある玉露の商品ページには、商品名や価格を機械が読める形で書いた JSON-LD が、次のように入っています。
{
"@context": "https://schema.org",
"@type": "Product",
"@id": "https://nlweb.demo.agentic-commerce-lab.jp/products/tea-gyokuro-50g",
"url": "https://nlweb.demo.agentic-commerce-lab.jp/products/tea-gyokuro-50g",
"name": "玉露 50g",
"description": "静岡県産の玉露です。覆いをかけて育てた茶葉で旨みが強く、渋みは控えめです。60度ほどのぬるめの湯で2〜3分かけて淹れると、甘みがはっきり出ます。",
"image": "https://nlweb.demo.agentic-commerce-lab.jp/products/tea-gyokuro-50g/image.svg",
"sku": "tea-gyokuro-50g",
"category": "日本茶",
"brand": {
"@type": "Brand",
"name": "ACLAB Store"
},
"keywords": "贈り物, ギフト, 高級, 緑茶",
"offers": {
"@type": "Offer",
"url": "https://nlweb.demo.agentic-commerce-lab.jp/products/tea-gyokuro-50g",
"price": 2800,
"priceCurrency": "JPY",
"availability": "https://schema.org/InStock",
"itemCondition": "https://schema.org/NewCondition"
},
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": 4.5,
"reviewCount": 5,
"bestRating": 5,
"worstRating": 1
}
}nlweb-ec-demo/core/jsonld.ts が出力する JSON-LD
このようにページに埋め込んだ機械向けのデータを、構造化データと呼びます。フィールドの名前は、schema.org(構造化データの共通の語彙)の Product に従ったものです。
Google は、検索結果に価格や在庫を出すためのデータとして、この書き方を案内しています。玉露の JSON-LD には名前、説明、価格、在庫、評価、キーワードがそろい、Google の Merchant listing(検索結果での商品表示)が必須とするフィールドも満たしています。
このデータは検索エンジンに向けたもので、ページを開いた買い物客の目には触れません。NLWeb は、この見えないデータを会話検索の入力にします。NLWeb のクローラは商品ページから JSON-LD だけを取り出し、ページの本文は読みません。
同じ形のデータは、多くのサイトにすでにあります。NLWeb の README(GitHub で公開されたコードに添えた説明書き)によると、schema.org や RSS のような形式は 1 億を超えるサイトで使われています。NLWeb は、こうした形式で書かれたデータを使って、文章で質問できる窓口を手軽に作るための仕組みです。
NLWeb を考案した R.V. Guha 氏は、RSS、RDF、Schema.org を作った人物です。2025年5月19日に NLWeb を発表した Microsoft は、その発表文で同氏をそう紹介しました。
NLWeb をサイトに置くと、入口が 2 つできます。人がサイトの検索窓から質問すると、/ask が商品の一覧を JSON で返します。AI が呼ぶのは、MCP サーバの /mcp にある ask、list_sites、who の 3 つのツールです。
/ask と /mcp は同じ索引(検索用に整理した商品データ)を引くので、人への答えも AI への答えも、同じ商品データから作られます。
カート、注文、決済は、NLWeb の範囲に入りません。本ラボのエージェンティックコマース全体マップが示す 5 つの層でいえば、NLWeb は主に発見の層にあたり、MCP サーバとして AI とつながる点では接続の層にもかかります。
本ラボの WebMCP の記事では、AI がサイトを使う経路の 1 つとして、サイトが MCP サーバを立てる方法(remote MCP)を図に入れました。NLWeb の /mcp は、その MCP サーバのうち商品検索の部分を、商品データから用意するものにあたります。
LLM が動く場所も、NLWeb とほかの規格とでは違います。NLWeb を置いたサイトが LLM を呼ぶので、質問が来るたびにかかる LLM の費用は、そのサイトの負担です。WebMCP、UCP、ACP との違いを次の表にまとめました。
| 規格・技術 | 扱う範囲 | サイトが用意するもの | LLM が動く場所 |
|---|---|---|---|
| NLWeb | 商品を見つける | 構造化データと、NLWeb を動かすサーバ | サイト側。質問ごとの費用もサイトが持つ |
| WebMCP(サイトの機能を AI にツールとして渡す Web の仕様案) | 開いているページでの検索、カート、注文の手前まで | ページに登録するツール | ブラウザ側の AI |
| UCP(Universal Commerce Protocol。Google・Shopify が主導する取引の共通規格) | 商品カタログの公開から、カート、チェックアウトまで | 規格に沿ったカタログとチェックアウトの窓口 | AI サービスの側 |
| ACP(Agentic Commerce Protocol。OpenAI・Stripe が主導する購入手続きの規格) | 商品フィードと購入手続き | 商品フィードと決済の窓口 | AI サービスの側 |
NLWeb には、まだ決定版がありません。NLWeb の README は、NLWeb を「オープンなプロトコルと、それに付随するオープンソースのツールの集まり」と呼んでいます。同じリポジトリ(GitHub 上のコードの置き場)のコードについては、概念実証だと断っています。
NLWeb の参照実装(仕様の動作を示す見本のコード)には、リリースやバージョンのタグもなく、依存ライブラリの自動更新を除くと、最後の変更は 2026年4月7日です。README からリンクされた NLWeb の仕様ページ(nlweb.ai/spec)も、2026年10月1日の時点で開けませんでした。
そのためこの記事は、NLWeb のリポジトリにある文書と実装を、仕様の一次情報として参照しています。リポジトリは当初の microsoft/NLWeb から nlweb-ai/NLWeb に移り、古い URL は新しい URL に転送されます。リポジトリの作成からの主な出来事は次のとおりです。
| 時期 | 出来事 | 根拠 |
|---|---|---|
| 2025年4月28日 | リポジトリの作成 | GitHub の記録 |
| 2025年5月19日 | Microsoft が NLWeb を発表 | Microsoft の発表文 |
| 2025年8月28日 | Cloudflare が、NLWeb と同社の AutoRAG を組み合わせる方法を公表 | Cloudflare Blog |
| 2026年4月7日 | 依存ライブラリの更新を除くと、これが最後の変更(2026年10月1日時点) | リポジトリのコミット履歴 |
| 2026年6月10日 | main ブランチの最新コミット(依存ライブラリの自動更新) | リポジトリのコミット履歴 |
| 2026年7月10日 | Cloudflare の文書が更新。AI Search に NLWeb の Worker を用意(public preview) | Cloudflare の文書 |
| 2026年10月1日 | README がリンクする仕様ページ(nlweb.ai/spec)は開けない | 本ラボ実測 |
Microsoft による NLWeb の発表文には、協力先として Shopify、Tripadvisor、Eventbrite、Qdrant、Snowflake など 12 の名前が並んでいます。
その後、Cloudflare は同社の AI Search に NLWeb の Worker(Cloudflare 上で動くプログラム)を用意しました。自分でサーバを動かさずに NLWeb を使う方法です。2026年7月10日に更新された Cloudflare の文書には、public preview(公開の試験提供)とあります。
本ラボが動かした NLWeb の参照実装は Python で書かれたオープンソースで、手元の PC でも起動しました。Cloudflare の NLWeb Worker は試していません。
本ラボの公開デモには、次のボックスから質問を送れます。
リンクを開くと、公開デモの /ask の画面に質問が自動で送られます。公開デモには回数の上限があり、同じ IP アドレスからは 10 分に 10 回まで、全体では 1 日 200 回までです。
Claude Code(Anthropic のコーディング用エージェント)から公開デモの /mcp につなぐコマンドは、次の 1 行です。
claude mcp add --transport http aclab-nlweb https://nlweb.demo.agentic-commerce-lab.jp/mcp質問が来てから答えが返るまで
NLWeb が質問から答えを作る流れを、公開デモに実際に送った「渋みの少ない緑茶はありますか」という 1 問で追います。
質問を受け取った NLWeb は、まず LLM に、質問を検索語へ言い換えさせます。この 1 問は「渋みの少ない緑茶」「緑茶 まろやか」「低タンニン緑茶」など 5 つの検索語になりました。同じ会話に前の質問があるときは、その内容もここで引き継ぎます。
続いて LLM が、質問に合うツールを選びます。ここでいうツールは NLWeb の中で使うもので、/mcp が AI に出す 3 つのツールとは別です。商品のようなデータ向けには検索、詳細、比較、組み合わせの 4 つがあり、この 1 問には検索が選ばれました。
選ばれた検索のツールは、商品の JSON-LD から作った索引で、質問に近い商品を取り出します。取り出す数の上限は 50 件で、本ラボのデモ EC は 24 商品なので、全件が候補になりました。
候補はここから 1 件ずつ LLM に渡り、0〜100 点の点数と短い説明文が付きます。既定では、51 点を超えた商品だけが返ります。この 1 問では、95 点の玉露と 72 点の玄米茶の 2 件が返りました。
従来の検索エンジンなら専用のアルゴリズムで行う処理を、LLM の呼び出しに置き換えた作りだと、NLWeb の文書「Life of a Chat Query」は説明しています。
返ってきた玉露の 1 件を、公開デモの応答から抜き出しました。読みやすいように整形し、一部のフィールドを省いています。
{
"url": "https://nlweb.demo.agentic-commerce-lab.jp/products/tea-gyokuro-50g",
"name": "玉露 50g",
"score": 95,
"description": "玉露 50g - 静岡県産の高級緑茶。覆い栽培により旨みが強く、渋みは控えめに仕上げられています。ぬるめのお湯で淹れることで甘みが引き出される特性があり、渋みの少ない緑茶を求める方に最適です。",
"schema_object": {
"name": "玉露 50g",
"description": "静岡県産の玉露です。覆いをかけて育てた茶葉で旨みが強く、渋みは控えめです。60度ほどのぬるめの湯で2〜3分かけて淹れると、甘みがはっきり出ます。",
"offers": {
"price": 2800,
"priceCurrency": "JPY",
"availability": "https://schema.org/InStock"
}
}
}応答に入った商品 1 件は、url、name、score、description、schema_object などのフィールドでできています。schema_object は索引に入れた JSON-LD そのものです。価格や在庫はここに入っています。
score と description は、LLM がその場で書いたものです。以下では、LLM が書いたこの description を説明文、JSON-LD の description を商品説明と呼びます。玉露の説明文には、商品説明にある「渋みは控えめ」が入っていました。
公開デモの /ask の画面は、価格と在庫を schema_object から出し、その横に説明文を添えています。
この流れで LLM が受け持つのは、言い換え、ツールの選択、採点と説明文です。返る商品そのものは、索引から取り出したものに限られます。返る結果はデータベースから来るので作り話の結果は返らない、ただし最良でない結果はあり得る、と Life of a Chat Query も書いています。
同じ質問を手元の NLWeb に 3 回送ると、LLM の呼び出しは 1 回の質問につき 29 回でした。採点が商品 1 件につき 1 回で 24 回、それ以外が 5 回です。
NLWeb のコードを読むと、この 5 回は検索語への言い換え 1 回と、4 つのツールを 1 つずつ評価する 4 回にあたります。1 回の質問の往復は約 3 秒、費用は Anthropic の料金表の定価で換算して $0.036(1 ドル 150 円換算で約 5 円)でした。
質問の種類が変わると、LLM を呼ぶ回数も変わりました。
LLM の呼び出しは、商品の詳細を聞く質問で 53 回、2 つの商品を比べる質問で 70 回でした。比較の質問は、往復に 10〜16 秒かかっています。Life of a Chat Query の注記にも、1 つの質問の処理で LLM を 50 回以上呼ぶことがあると書かれています。
カタログに無い商品を聞いた質問は、採点の呼び出しが 48 回に増え、合計は 53 回でした。48 回は 24 商品を 2 回ずつ採点した数にあたり、2 回になった理由は確かめていません。
使うモデルでも、1 質問の費用は変わります。Anthropic のモデルのうち、小型で安価な Claude Haiku 4.5 と、上位の Claude Sonnet 5 の組み合わせを変えて試しました。
8 問の平均は、Haiku 4.5 だけの構成で $0.045(約 7 円)、Sonnet 5 だけの構成で $0.090(約 14 円)でした。採点だけを Haiku 4.5 にした構成(以下、混合構成)は $0.056(約 8 円)です。
NLWeb で選ばれるツールも、質問によって変わりました。3 つのモデル構成で 3 回ずつ送ると、「玉露はどう淹れればいいですか」には 9 回中 9 回で詳細のツールが、「玉露と煎茶の違いを教えてください」には 9 回中 8 回で比較のツールが選ばれています。
ここまでは、NLWeb が商品の一覧を返す使い方です。NLWeb には、一覧に要約を添えるモード(summarize)と、回答文を作るモード(generate)もあります。generate は、NLWeb の API の文書によると、従来の RAG(検索した内容をもとに LLM に回答を書かせる方式)に近いモードです。
要約や回答文のような後処理を足すと、カタログに無い内容が答えに混ざるおそれがあるので、足すときはよく試すように、と Life of a Chat Query は注意しています。本ラボが 2 つのモードを試した結果は、あとの章に書きます。
デモ EC への組み込みと、そのままでは動かなかった箇所
商品ページの JSON-LD から索引を作る
組み込み先は、本ラボの WebMCP の記事でも使った架空の EC サイト「ACLAB Store」です。日本茶、和菓子、台所用品、衣料の 24 商品を並べ、サイト本体を Vercel に、NLWeb を Railway に置きました。
NLWeb から呼ぶ LLM には、Anthropic の Claude Haiku 4.5 と Claude Sonnet 5 を使いました。商品の索引は Qdrant です。
商品データを NLWeb の索引に入れるときの埋め込み(文章を、近さを比べられる数値の列に変える処理)には、Google の gemini-embedding-001 を使っています。
NLWeb の参照実装はコミット b423f15 に固定し、動かすための変更は 3 つのパッチと設定ファイルにまとめて、デモのコードと一緒に公開しています。
商品データの取り込みは、20 秒で終わりました。デモ EC の 24 商品のページに JSON-LD を出力しておき、NLWeb のクローラに公開デモのサイトマップ(25 URL)をたどらせた結果です。
Progress: 25/25 (100.0%) | Success: 25 | Failed: 0 | Already crawled: 0 | JSON: 30.1KB | Schemas: 24 | Docs uploaded: 24 | Types: Product:24, Brand:24, Offer:24
[e1] crawl took 20s
[e1] crawl (A) = 24 docs, jsonl (B) = 24 docs
[e1] identical schema_json: 24 / 24[e1] で始まる行は、本ラボの確認用スクリプトの出力です。クロールで作った索引を、同じ商品データをファイルから直接読み込ませた索引と比べ、24 件すべての内容が一致することを確かめました。
ただ、商品ページから取り込める経路は、このクローラだけでした。NLWeb の参照実装にあるデータ読み込み用のコマンド(db_load)は、HTML から JSON-LD を取り出さないためです。この記事で送った質問には、ファイルから読み込ませたほうの索引を使っています。
既定の上限では、日本語の詳細と比較の質問に答えが返らなかった
質問を送り始めると、NLWeb の参照実装は既定の設定のままでは動きませんでした。直した箇所は次の表のとおりです。
| 症状 | 原因 | 対処 |
|---|---|---|
| Anthropic を選んでも、LLM の呼び出しが失敗する | 既定のモデル名が提供の終わったもの。メッセージの先頭が assistant。Sonnet 5 は temperature を受け付けない | Anthropic 用のコードを置き換えるパッチ |
| 日本語の詳細と比較の質問に、答えが返らない | 一部の呼び出しが 8 秒と 512 トークンで打ち切られ、失敗は空の結果として扱われる | 上限を 30 秒と 2,048 トークンに上げるパッチ |
mode=generate を付けても、回答文が出ない | 処理の振り分けは generate_mode という別の引数を読む | 両方の引数に同じ値を送る |
| ストリーミングを切ると、詳細と比較の中身が消える | streaming=false の応答は content 以外のフィールドを落とす | ストリーミングのまま最後まで読む |
/ask と /mcp を誰でも呼べる | 本番用の設定でも /mcp は認証用の文字列を照合せず、空でなければ通す。/ask は常に公開で、回数制限も無い | 決まった文字列を必須にするパッチと、回数制限つきの中継 |
表の 2 行目の上限は、答えが返る回数を大きく変えました。上げる前は 24 回の質問のうち 15 回で答えが返り、上げたあとは 21 回でした。残りの 3 回は、カタログに無い商品を聞いた質問です。
NLWeb を公開するには、認証と回数制限も自分で足す必要がありました。本ラボのデモは、デモ EC の側に NLWeb への呼び出しを取り次ぐ中継を置き、NLWeb には中継からの呼び出しだけを通しています。
返ってきた答えを商品データと照らし合わせる
質問は 8 問用意し、手元で動かした NLWeb にそれぞれ 3 回ずつ送りました。NLWeb が使うモデルの構成は、すべて Haiku 4.5、混合構成、すべて Sonnet 5 の 3 つです。この 3 つに上限を上げる前の構成を加えた 96 回は、商品の一覧を返すモードで送っています。
要約と回答文のモードは、混合構成で 24 回ずつ、計 48 回送りました。質問は次の 8 問です。
| 種類 | 質問 | 確かめること |
|---|---|---|
| 検索 | 渋みの少ない緑茶はありますか | 商品説明に「渋みは控えめ」とある玉露が返るか |
| 詳細 | 玉露はどう淹れればいいですか | 淹れ方(60 度、2〜3 分)が商品説明どおりに返るか |
| 比較 | 玉露と煎茶の違いを教えてください | 湯の温度と渋みの違いが商品説明と合っているか |
| 組み合わせと予算 | 5,000 円以内で、お茶と和菓子を組み合わせた手土産を提案してください | 茶と和菓子を組み合わせ、合計が 5,000 円以内に収まるか |
| 続きの質問 | もっと安いのは(1 問目に続けて送る) | 前の質問(渋みの少ない緑茶)を引き継いで、より安い茶が返るか |
| カタログに無い商品 | コーヒー豆はありますか | 無いと答えるか。細口のケトルを豆として説明しないか |
| 在庫切れの商品 | コーヒー用の細口ケトルが欲しい | 説明文が在庫切れに触れるか |
| 英語の質問 | a gift set of tea and sweets under 3,000 yen | 説明文が何語で返るか。合計が 3,000 円以内に収まるか |
返ってきた商品
144 回の質問で、カタログに無い商品は 1 件も返りませんでした。カタログに無いコーヒー豆を聞いた質問には、一覧のモードの 12 回すべてで 0 件が返っています。
説明文に出てくる価格と在庫の記述は、商品データと機械的に照合しました。食い違いは 0 件でした。
「玉露はどう淹れればいいですか」には、商品説明にある「60度ほどのぬるめの湯で2〜3分かけて淹れると、甘みがはっきり出ます。」という文が、9 回中 9 回、そのまま返りました。
渋みの少ない緑茶を聞いた質問では、商品説明に「渋みは控えめ」とある玉露が、12 回中 10 回、95 点で先頭に返りました。残りの 2 回は、玉露が一覧に入りませんでした。商品説明に「渋みが出やすい」とある粉茶が返った回はありません。
NLWeb がうまく答えられなかった質問もあります。「5,000 円以内で、お茶と和菓子を組み合わせた手土産を提案してください」に組み合わせ用のツールが選ばれたのは 12 回中 1 回で、ほかの 11 回は商品の一覧が返り、合計金額は示されませんでした。
「もっと安いのは」という続きの質問は、1 問目の「渋みの少ない緑茶はありますか」を引き継いで検索されました。ただ、返る商品は回ごとに違い、12 回中 4 回は、1 問目で先頭だった玉露が再び含まれていました。
LLM が書く説明文
NLWeb が返す説明文は、LLM が書きます。先ほど見た公開デモの応答で 72 点だった玄米茶の説明文を、玉露の説明文と並べます。
玄米茶の商品説明は、香ばしさと、茶葉が少なめでも満足感があることを書いていて、渋みには触れていません。それでも LLM は、玄米茶の説明文に「相対的に渋みを抑えた飲み方ができる点で参考になります」と書き足しています。
玄米茶の説明文に渋みの話を足す文は、3 つのモデル構成のすべてで出ました。なぜそうなるのかは、NLWeb の採点用のプロンプトを読んで分かりました。
Assign a score between 0 and 100 to the following item
based on how relevant it is to the user's question. Use your knowledge from other sources, about the item, to make a judgement.
If the score is above 50, provide a short description of the item highlighting the relevance to the user's question, without mentioning the user's question.
Provide an explanation of the relevance of the item to the user's question, without mentioning the user's question or the score or explicitly mentioning the term relevance.
If the score is below 75, in the description, include the reason why it is still relevant.NLWeb の採点用のプロンプトは、ほかの情報源から得た知識も使って判断するよう、LLM に指示しています。50 点を超えたら質問との関連を強調した短い説明を書くこと、75 点未満なら、それでも関連がある理由を説明に含めることも求めています。
玄米茶は 72 点なので、75 点未満のこの条件に当たる商品です。説明文の渋みの話は、それでも関連がある理由として書き足されたものと推定できます。
NLWeb の説明文は、商品ページの要約として書かれているわけではありません。質問との関連を説明する文として書かれ、その材料には LLM が持っている一般の知識も含まれます。Microsoft による NLWeb の発表文も、LLM の外部知識を足して構造化データを補強すると説明しています。
一覧のモードの説明文は、各モデル構成で 1 回目に返った上位 3 件、計 57 件を確認しました。誤りは 1 件で、ドリップケトルの説明文に、商品ページに無い「温度管理」が入っていました。
商品ページには無いものの、一般の知識としては通る補足は 7 件で、すべて玄米茶と渋みの組み合わせです。説明文の確認は、Claude が全件を読んで候補を挙げ、書き手が 1 件ずつ判断する形で行いました。
モデル構成ごとの結果は次の表のとおりです。「適合」は、返った上位 3 件の商品が、質問ごとにあらかじめ決めた「返ってほしい商品」なら 2 点、許容できる商品なら 1 点として平均した値です。
| 構成 | 答えが返った回 | 適合(最大 2) | 説明文の誤り | 説明文の補足 | LLM 呼び出し(中央値) | 費用(1 質問の平均) | 往復(中央値) |
|---|---|---|---|---|---|---|---|
| 上限を上げる前(混合) | 15 / 24 | 1.50 | 1 件(12 件中) | 2 件 | 29.5 回 | $0.054 | 5.3 秒 |
| 混合(採点は Haiku 4.5、ほかは Sonnet 5) | 21 / 24 | 1.19 | 0 件(16 件中) | 2 件 | 30 回 | $0.056 | 5.3 秒 |
| Haiku 4.5 だけ | 21 / 24 | 1.38 | 0 件(16 件中) | 1 件 | 29.5 回 | $0.045 | 5.6 秒 |
| Sonnet 5 だけ | 21 / 24 | 1.85 | 0 件(13 件中) | 2 件 | 30 回 | $0.090 | 5.5 秒 |
要約と回答文のモード
NLWeb の回答文を作るモードでは、在庫切れの商品が、在庫に触れないまま勧められました。質問は「コーヒー用の細口ケトルが欲しい」で、返ったドリップケトルは在庫切れの商品です。
コーヒー用の細口ケトルをお探しでしたら、ドリップケトルをお勧めします。このケトルはコーヒーのドリップに最適な細口設計で、注ぎ口が細く湯量調整が容易です。直火とIH両方に対応しており、非常に使いやすい商品です。価格は5,800円です。この質問への回答文は、3 回中 2 回、在庫に触れずにドリップケトルを勧めました。同じ応答に付いていた商品データでは、在庫のフィールド(availability)は 3 回とも在庫切れを示しています。
同じ質問で在庫切れに触れた回は、要約のモードの要約で 3 回中 3 回、一覧のモードの説明文で 12 回中 9 回でした。
回答文のモードには、日本語で答えが返らない質問もありました。組み合わせの質問には 3 回とも英語のエラー文が返り、続きの質問とカタログに無い商品の質問には、3 回とも英語の定型文が返っています。
要約のモードは、24 回すべてで要約が付きました。ただ、渋みの少ない緑茶の質問で玉露が一覧に入らなかった回の要約は、玄米茶を「渋みが自然に抑えられている」として勧めています。
要約と回答文の 2 つのモードの説明文には、誤りが 2 件ありました。要約のモードは、抹茶用の茶筅を玉露用の道具と説明しました。回答文のモードは、英語の質問に対し、カステラ 1 本を「A gift set combining tea and sweets」(茶と菓子を組み合わせたギフトセット)と説明しています。
回答文のモードでは、質問と回答全体の文脈で商品を説明するよう、NLWeb の説明文用のプロンプトが指示しています。カステラの誤りは、質問の「組み合わせ」に引きずられた可能性があります(推定)。
| モード | 文が返った回 | 商品が 1 件も付かなかった回 | 説明文の誤り | 説明文の補足 | LLM 呼び出し(中央値) | 費用(1 質問の平均) | 往復(中央値) |
|---|---|---|---|---|---|---|---|
| 要約(summarize) | 24 / 24 | 3 回 | 1 件(16 件中) | 4 件 | 26 回 | $0.039 | 6.7 秒 |
| 回答文(generate) | 24 / 24 | 9 回 | 1 件(8 件中) | 1 件 | 28 回 | $0.029 | 9.0 秒 |
Claude から同じ質問を送る
人向けの /ask と同じ索引を、AI からも引いてみました。Claude Code に公開デモの /mcp を登録し、8 問のうち続きの質問を除く 7 問を、3 回ずつ送っています。Claude Code のモデルは Haiku 4.5 です。
1. ask {"query": "渋みの少ない緑茶", "generate_mode": "list", "site": ["ACLAB Store"]}
返った商品は 0 件
2. list_sites {}
{"sites": ["aclab"]}
3. ask {"query": "渋みの少ない緑茶", "generate_mode": "list", "site": ["aclab"]}
玉露 50g(95 点)、煎茶 100g(72 点)、ほうじ茶 100g(72 点)、玄米茶 100g(72 点)このログは、Claude が NLWeb に登録されたサイト名を「ACLAB Store」と推測して、先に ask を呼んだ回です。空の応答を受けたあと、list_sites で正しいサイト名を調べ、もう一度 ask を呼んでいます。こうした回は 21 回中 3 回ありました。
Claude Code から送った 21 回のうち 20 回で、Claude は ask を呼んで答えを返しました。15 回は、最初に list_sites でサイト名を調べています。
質問に答えられるサイトを探す who というツールを、Claude が選んだ回も 3 回ありました。本ラボは Claude Code の設定で ask と list_sites だけを許可していたので、who の呼び出しは断られ、うち 1 回は検索しないまま終わっています。
| 項目 | 結果 |
|---|---|
| 実行した回数 | 21 回 |
ask を呼んで答えた回 | 20 回 |
ask の呼び出し | 30 回(1 問あたり平均 1.4 回) |
最初に list_sites を呼んだ回 | 15 回 |
サイト名を推測して先に ask を呼んだ回 | 3 回 |
許可していない who の呼び出し | 3 回 |
/ask の上位 3 件との重なり | 平均 1.39 件(18 回) |
| 往復(中央値) | 24.4 秒 |
| Claude 側の費用(1 問の平均) | $0.027 |
ask の戻りの読み違い | 0 回 |
| 事実の誤りがあった回答 | 5 回 |
ask ツールの戻りは、NLWeb が返したメッセージをすべて区切りなしでつなげた 1 つのテキストでしたが、Claude はこれを読み違えませんでした。本ラボの中継を通さずに NLWeb のサーバへ直接つないだ条件でも 7 回送っていて、合わせた 28 回で読み違いは 0 件です。
Claude の回答に出た商品は、同じ質問を /ask に送ったときの上位 3 件と、平均 1.39 件重なりました。Claude は 1 問につき ask を平均 1.4 回呼び、質問から回答までの往復の中央値は 24 秒です。
Claude から質問するときの費用は、2 か所で発生します。Claude 側は 1 問あたり $0.027(約 4 円)で、これに、ask が呼ばれるたびにサイト側で発生する NLWeb の費用が加わります。
サイト側の NLWeb の費用は、この実験では記録していません。手元の NLWeb での計測では、検索の質問 1 回が $0.03〜0.05(約 5〜8 円)でした。
Claude を通して利用者に届く文章は、NLWeb の説明文を Claude がさらに書き直したものになります。Claude の回答のうち事実の誤りがあったものは、表の 21 回のうち 5 回、直接つないだ 7 回を含めると 28 回中 6 回でした。
この 6 回のうち 2 回は NLWeb の説明文に由来し、残りの 4 回は Claude が答えを書くときに加えた誤りでした。組み合わせの質問では、この 6 回とは別に、合計金額の計算違いも 2 回ありました。
この章の数字には限りがあります。各条件は 3 回ずつで、説明文を確認したのは 1 回目の上位 3 件だけです。
適合の平均は、採点を Sonnet 5 にした構成で 1.85、Haiku 4.5 が採点した構成で 1.19〜1.50 でした。ただ、同じ Haiku 4.5 の構成どうしでもこれだけの幅があるので、モデルの差は傾向として読んでください。
デモ EC の 24 商品は、NLWeb が候補を取り出す上限の 50 件より少なく、毎回すべての商品が採点されていました。商品数が多いカタログで、索引が候補をどこまで絞り込めるかは確かめられていません。
自社の EC で試すときに決めること
自社の EC で試すなら、最初に商品ページの JSON-LD を開いてみてください。商品説明に、味、使い方、対応する機器のように、質問されそうなことが書いてあるかを見ます。商品ページの URL を Google のリッチリザルト テストに入れると、ページから読み取れる構造化データを確かめられます。
本ラボのデモでは、玉露の淹れ方の質問に、商品説明に書いた文がそのまま返りました。商品説明を書き換えて結果を比べる実験はしていません。
NLWeb を自社の EC で公開するなら、次の点を先に決めておく必要があります。
- 価格と在庫は
schema_objectから画面に出し、LLM が書く説明文は補助として添えるか、出さないかを決めます。回答文のモードは、在庫切れの商品を在庫に触れずに勧めることがありました - 本ラボのデモは、使うモードの既定を商品の一覧を返すモードにしています。要約と回答文のモードは、自社の商品と質問で試してから足すほうが安全です
- 費用の上限も必要です。本ラボが送った 144 回の質問では、NLWeb が 1 つの質問で呼んだ LLM は 26〜90 回、費用は構成とモードごとの平均で約 4〜14 円でした。採点は候補の商品 1 件につき 1 回で、NLWeb の参照実装は 1 回の検索で候補を最大 50 件取り出します。商品数の多いカタログでは、デモの 24 回より採点が増える計算です。AI エージェントからの
askも、サイト側の費用になります - NLWeb の参照実装には回数制限が無く、
/mcpは本番用の設定でも認証用の文字列を照合せず、空でなければ通します。このままでは誰からの質問にもサイトの費用で LLM が動くので、認証と回数制限は自分で用意します - 在庫や価格が変わる商品は、索引をいつ作り直すかを決めておきます。NLWeb の README は、本番の多くは内容を複製せず、稼働中のデータベースに NLWeb をつなぐ形になると書いています
まだ確かめていないこと
Cloudflare の NLWeb Worker、50 商品を超えるカタログ、Anthropic 以外のモデルは試していません。
商品レビューのように利用者が書いた文章を NLWeb に読み込ませたとき、そこに書かれた命令が答えに混ざるかどうかも未検証です。claude.ai のカスタムコネクタからの接続と、在庫や価格を変えたあとの索引の更新も、今回は扱っていません。
検証環境と再現手順
| 項目 | 値 |
|---|---|
| デモ | ACLAB Store(Next.js、Vercel。商品は架空の 24 点)。NLWeb は Railway |
| NLWeb | nlweb-ai/NLWeb のコミット b423f15(2026年6月10日)に、本ラボのパッチ 3 件と設定ファイル |
| LLM | Claude Haiku 4.5(claude-haiku-4-5)と Claude Sonnet 5(claude-sonnet-5) |
| 埋め込みと索引 | Gemini の gemini-embedding-001(3,072 次元)、Qdrant(ローカルモード、qdrant-client 1.19.1) |
| 手元の計測 | 2026年9月28日。macOS、Python 3.12.13、Node 24.18.0。一覧のモード 96 回、要約と回答文 48 回。LLM の呼び出しは記録用のプロキシで記録 |
| 公開デモのクロール | 2026年9月30日 |
| Claude Code からの質問 | 2026年10月1日(公開デモを通さない条件は 9月30日)。Haiku 4.5、21 回と 7 回 |
| 説明文の確認 | 2026年10月1日。Claude が候補を挙げ、書き手が判断 |
| 費用 | Anthropic の料金表の定価で換算。円の表記は 1 ドル 150 円で換算した概算。実験全体で約 $9(約 1,350 円) |
本ラボのデモの NLWeb を手元で動かすのに要るのは、Docker と、Anthropic と Gemini の API キーです。記事末尾のリンク先(公開リポジトリ)の nlweb-ec-demo/server/ で次のコマンドを実行すると、起動時に 24 商品が索引に読み込まれます。
git clone https://github.com/STRACT-Inc/aclab-demos
cd aclab-demos/nlweb-ec-demo/server
docker build -t aclab-nlweb .
docker run --rm -p 8000:8000 \
-e ANTHROPIC_API_KEY=<Anthropic の API キー> \
-e GEMINI_API_KEY=<Gemini の API キー> \
-e NLWEB_SHARED_SECRET=local \
-e NLWEB_DB_PATH=/data/db \
aclab-nlwebServer started at http://0.0.0.0:8000 と表示されたら、別の端末から質問を送ります。
curl -G 'http://localhost:8000/ask' \
-H 'Authorization: Bearer local' \
--data-urlencode 'query=渋みの少ない緑茶はありますか' \
-d 'site=aclab' -d 'streaming=false'本ラボの環境では、玉露(95 点)を先頭に 3 件が約 5 秒で返りました(2026年10月2日)。このサーバは、Authorization を付けない呼び出しを 401 で断る作りです。公開デモに送る場合の curl の例は、デモの /lab にあります。
自社の商品ページに構造化データがあれば、NLWeb で会話検索と MCP サーバを試せます。
この記事で使った質問を公開デモに送るボックスは、次のとおりです。続きの質問(「もっと安いのは」)は、1 問目を送ったあとに同じ画面で入力すると試せます。
英語の質問: a gift set of tea and sweets under 3,000 yen
確かめること: 説明文が何語で返るか。合計が 3,000 円以内に収まるか
これまで紹介してきた、AI エージェントや LLM にツールを使わせて買い物を代行させる方式では、基本的には良い商品検索がツールとして使えることが前提でした。一方で、AI にとって使いやすい検索システムとはどういったものかについては、まだ正解と呼べるものがないのが現状だと筆者はみています。
NLWeb は、すでに広く使われている JSON-LD から、AI にとって使いやすく信頼できる検索ツールを生成できる仕組みとして、価値のあるものです。ただ、仕様をきちんと定める動きがないことや、実運用にはコスト面の課題が大きいことなど、まだまだ過渡期の中で生まれたものという印象もあります。
関連技術も含めて、引き続き注目したいと思います。
全記事に執筆後記を掲載しています(編集方針)
nlweb-ai/NLWeb (NLWeb の参照実装のリポジトリと README。この記事はコミット b423f15、2026年6月10日を使用)github.com
Life of a Chat Query (NLWeb の文書。質問を処理する流れと注記)github.com
NLWeb Rest API (NLWeb の文書。/ask と /mcp の引数と、応答のフィールド)github.com
config/prompts.xml (NLWeb の参照実装のプロンプト。コミット b423f15)github.com
Introducing NLWeb: Bringing conversational interfaces directly to the web (Microsoft の発表文、2025年5月19日)news.microsoft.com
NLWeb (Cloudflare AI Search docs。NLWeb Worker の案内、2026年7月10日更新)developers.cloudflare.com
Make Your Website Conversational for People and Agents with NLWeb and AutoRAG (Cloudflare Blog、2025年8月28日)blog.cloudflare.com
How To Add Merchant Listing Structured Data (Google Search Central。必須の項目、2026年9月8日更新)developers.google.com
Product (schema.org の型の定義)schema.org
リッチリザルト テスト (Google。ページから読み取れる構造化データを確かめるツール)search.google.com
Connect Claude Code to tools via MCP (Claude Code Docs。claude mcp add の書き方)code.claude.com
Pricing (Claude API 料金表、Anthropic。費用の定価換算に使用)platform.claude.com
Embeddings (Gemini API。gemini-embedding-001 の説明)ai.google.dev
ACLAB Store (本ラボのデモ EC。NLWeb を組み込んだ架空のストア)nlweb.demo.agentic-commerce-lab.jp
ACLAB Store /lab (NLWeb の版、当てたパッチ、上限、curl の例を載せたページ)nlweb.demo.agentic-commerce-lab.jp
WebMCP とは何か。EC サイトに実装して分かった、ツール設計の勘所 (本ラボの記事)agentic-commerce-lab.jp
エージェンティックコマース全体マップ 2026 (本ラボの記事)agentic-commerce-lab.jp

チーム随一の技術力で実装・実証系テーマを最も厚く担当。WebMCP・NLWeb などの新 API 検証から認証の実装・解説までを担う。
宇佐美 佑の記事一覧 →