> ## Documentation Index
> Fetch the complete documentation index at: https://novita.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Web にグラウンディングされた回答

モデル単体では、トレーニングのカットオフ後の出来事に関する質問に答えたり、出典を引用したりすることはできません。解決策は *グラウンディング* です。リクエスト時に関連する Web コンテンツを取得し、それをコンテキストとしてモデルに渡します。このガイドでは、Novita [AI Search](/docs/ja/guides/ai-search-quickstart) を検索に使用し、[LLM API](/docs/ja/guides/llm-api) を合成に使用 — すべて 1 つの API キーの背後で。

## RAG とは？

Retrieval-augmented generation (RAG) は、ここでのすべての根拠に基づく回答の背後にあるパターンです。モデルが学習中に記憶した内容に頼るのではなく、リクエスト時に関連ドキュメントを*取得*し、それらでプロンプトを*拡張*することで、モデルがその新しく検証可能なコンテキストから回答を*生成*します。

その取得ステップこそが、AI Search が提供するものです。Web があなたのナレッジベースになり、始めるためにベクトルデータベースを構築・保守する必要はありません — 検索呼び出しが該当箇所を返し、LLM が残りを行います。後で*自分の*プライベートドキュメントに対して取得を行いたくなった場合も、同じ 3 ステップの形が適用できます。Web 検索をベクトルストアに置き換えるだけです。

RAG は、素のモデルでは提供できない 3 つのものをもたらします。

* **鮮度** — 回答は、モデルの学習カットオフ後に公開されたコンテンツを反映します。
* **出典表示** — すべての主張は、ユーザーが確認できるソース URL に紐づけられます。
* **ハルシネーションの低減** — 取得したテキストにモデルをグラウンディングすることで、事実をでっち上げるのを防ぎます。

## グラウンディングの仕組み

1 回の RAG ターンは 3 つのステップに従います。

1. 質問に関連するページを Web で**検索**（取得）します。
2. 必要なコンテンツ — スニペットまたはページ全文 — をプロンプトに**抽出**（拡張）します。
3. そのコンテンツを LLM に渡し、出典を引用するよう依頼して、回答を**合成**（生成）します。

これは 2 回の呼び出し（検索 + LLM）で行うことも、1 回で行うことさえできます。Exa と Tavily はどちらも、あなたの代わりに回答を合成できるためです。最終的な文言と引用をどれだけ制御したいかに基づいて選択してください。

## プロバイダーに回答を書かせる

最速の方法です。Tavily の Search は、次を設定すると LLM 生成の回答を返します。 `include_answer`, Exa は専用の [Answer](/docs/ja/api-reference/model-apis-exa-answer) エンドポイント。1 回の呼び出しで、オーケストレーションは不要です。

<CodeGroup>
  ```bash Tavily theme={"system"}
  curl -X POST 'https://api.novita.ai/v3/tavily/search' \
    -H "Authorization: Bearer ${NOVITA_API_KEY}" \
    -H 'Content-Type: application/json' \
    -d '{
      "query": "What changed in the latest Python release?",
      "include_answer": "advanced",
      "max_results": 5
    }'
  ```

  ```bash Exa theme={"system"}
  curl -X POST 'https://api.novita.ai/v3/exa/answer' \
    -H "Authorization: Bearer ${NOVITA_API_KEY}" \
    -H 'Content-Type: application/json' \
    -d '{
      "query": "What changed in the latest Python release?",
      "text": true
    }'
  ```
</CodeGroup>

最小限のコードで良い回答が欲しい場合に使用します。モデル、トーン、出力形式、または引用の表示方法を制御する必要がある場合は、以下の retrieve-then-synthesize アプローチを選んでください。

## 取得してから、LLM で統合する

これにより完全に制御できます。ソースを検索し、その結果を [LLM API](/docs/ja/guides/llm-api) に、そのコンテキストのみを使用して回答し、各主張に引用を付けるよう指示します。

```python theme={"system"}
import os
import requests
from openai import OpenAI

NOVITA_KEY = os.environ["NOVITA_API_KEY"]
QUESTION = "What changed in the latest Python release?"

# 1. Retrieve relevant web content.
search = requests.post(
    "https://api.novita.ai/v3/tavily/search",
    headers={"Authorization": f"Bearer {NOVITA_KEY}"},
    json={
        "query": QUESTION,
        "max_results": 5,
        "include_raw_content": "text",
    },
).json()

# 2. Build a compact, numbered context block the model can cite.
sources = []
for i, r in enumerate(search["results"], start=1):
    body = (r.get("raw_content") or r.get("content") or "")[:1500]
    sources.append(f"[{i}] {r['title']} ({r['url']})\n{body}")
context = "\n\n".join(sources)

# 3. Synthesize a grounded, cited answer.
client = OpenAI(base_url="https://api.novita.ai/openai", api_key=NOVITA_KEY)
completion = client.chat.completions.create(
    model="deepseek/deepseek-v4-flash",
    messages=[
        {
            "role": "system",
            "content": (
                "Answer using ONLY the provided sources. "
                "Cite claims with [n] referring to the source number. "
                "If the sources don't contain the answer, say so."
            ),
        },
        {"role": "user", "content": f"Question: {QUESTION}\n\nSources:\n{context}"},
    ],
)
print(completion.choices[0].message.content)
```

同じフローは Exa Search でも機能します — ルートを次のように差し替えます `/v3/exa/search` および読み取り `text` 各結果からではなく `raw_content`.

## 検索品質のチューニング

根拠に基づいた回答の品質は、モデルよりも *何を検索するか* に大きく左右されます。効果の大きい調整項目をいくつか挙げます。

* **鮮度。** 時間依存の質問では、日付で制約します。Tavily は `time_range` および `start_date`/`end_date`; Exa は公開しています `startPublishedDate`/`endPublishedDate`. これにより、古くなったページがコンテキストから除外されます。
* **ソースの信頼性。** 使用してください `include_domains`/`excludeDomains` 取得を信頼できるソース（公式ドキュメント、信頼性の高い出版社）に制限し、低品質なサイトを排除するために。
* **トピックのヒント。** Tavily の `topic` (`news`, `finance`, `general`) と Exa の `category` エンジンを適切な種類の結果へ導きます。
* **コンテキストの適正化。** 抽出テキストを制限します（Tavily `chunks_per_source`, Exa `maxCharacters`) モデルのコンテキストウィンドウやトークン予算を使い切らずに、十分なシグナルを渡せるようにします。

## Search vs. extract vs. crawl

ニーズに合った取得プリミティブを選択してください。

* **Search** — 質問があり、関連ページを*発見*する必要がある場合。デフォルトの出発点です。
* **Extract / Contents** — URL がすでにわかっていて、それらからクリーンなテキストを取得したい場合。固定されたドキュメントセットに基づくグラウンディングに適しています。詳しくは [Tavily Extract](/docs/ja/api-reference/model-apis-tavily-extract) および [Exa Contents](/docs/ja/api-reference/model-apis-exa-contents).
* **Crawl / Map** — サイト全体またはセクションを、リンクをたどりながら取り込みたい場合。オフラインでナレッジベースを構築するのに適しています。詳しくは [Tavily Crawl](/docs/ja/api-reference/model-apis-tavily-crawl) および [Tavily Map](/docs/ja/api-reference/model-apis-tavily-map).

<Tip>
  反復的に検索し、多くのソースに基づいて推論する、より本格的なエージェントについては、[DeepSearcher 統合](/docs/ja/guides/deepsearcher).
</Tip>

## 本番環境に持ち込む

* **空の結果を処理する。** 検索で関連するものが何も返らない場合は、でっち上げるのではなく、答えられないとモデルに言わせます。上記のシステムプロンプトはこれを行います。
* **可能な場合はキャッシュする。** 同一のクエリは似た結果を返します。取得をキャッシュするとコストとレイテンシが削減されます。
* **レート制限に注意する。** 取得と LLM 呼び出しは別々に制限されます — 検索リクエストが LLM クォータを消費することはありません。次の場合はバックオフする `429` どちらの場合も同様です。詳しくは [LLM のレート制限](/docs/ja/guides/llm-rate-limits) LLM 側用。
* **キーはサーバー側に保持する。** ここでは Novita key がすべての呼び出しを認証します — クライアント側コードに含めて配布しないでください。
