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

# Exa

[Exa](https://exa.ai) は、AI アプリケーション向けに構築された Web 検索 API です。各検索結果とともに、そのまま利用できるクリーンなページコンテンツを返すため、SambaNova モデルの応答を最新の Web 情報に基づかせる (グラウンディングする) ことが容易になります。

## 前提条件

作業を始める前に、以下の環境を準備してください。

* [SambaCloud](https://cloud.sambanova.ai?utm_source=exa\&utm_medium=external\&utm_campaign=cloud_signup) アカウントと [API キー](https://cloud.sambanova.ai/apis?utm_source=exa\&utm_medium=external\&utm_campaign=cloud_signup)
* [Exa](https://dashboard.exa.ai/api-keys) アカウントと API キー
* Python 3.9 以降、または Node.js 18 以降

## セットアップ

以下の手順に従って、必要な依存パッケージをインストールし、環境を設定します。

<Steps>
  <Step title="依存パッケージのインストール">
    使用する言語に応じて、必要な SDK をインストールします。

    <Tabs>
      <Tab title="Python">
        ```bash theme={}
        pip install "exa-py>=2.0" openai python-dotenv
        ```
      </Tab>

      <Tab title="Node.js">
        ```bash theme={}
        npm install exa-js openai dotenv
        ```
      </Tab>
    </Tabs>

    <Note>
      Node.js の例では ES モジュールとトップレベル `await` を使用しています。ファイルは `.mjs` 拡張子で保存してください (または `package.json` に `"type": "module"` を設定してください)。
    </Note>
  </Step>

  <Step title="API キーの設定">
    プロジェクトディレクトリに `.env` ファイルを作成します。

    ```bash theme={}
    SAMBANOVA_API_KEY=your-sambanova-api-key
    EXA_API_KEY=your-exa-api-key
    ```
  </Step>

  <Step title="Exa による Web 検索">
    Exa を使って、クエリに関連する Web コンテンツとハイライトを取得します。

    <Tabs>
      <Tab title="Python">
        ```python theme={}
        from dotenv import load_dotenv
        from exa_py import Exa
        import os

        load_dotenv()

        exa = Exa(api_key=os.environ["EXA_API_KEY"])

        results = exa.search(
            "latest developments in AI agents",
            type="auto",
            num_results=10,
            contents={"highlights": True},
        )
        ```
      </Tab>

      <Tab title="Node.js">
        ```javascript theme={}
        import 'dotenv/config';
        import Exa from 'exa-js';

        const exa = new Exa(process.env.EXA_API_KEY);

        const results = await exa.search(
          'latest developments in AI agents',
          {
            type: 'auto',
            numResults: 10,
            contents: { highlights: true },
          }
        );
        ```
      </Tab>
    </Tabs>
  </Step>

  <Step title="検索結果による SambaNova モデルのグラウンディング">
    前のステップで取得した `results` を使い、Exa の検索結果をコンテキストとして整形して、SambaNova でホストされているモデルに渡します。

    <Tabs>
      <Tab title="Python">
        ```python theme={}
        from dotenv import load_dotenv
        from openai import OpenAI
        import os

        load_dotenv()

        client = OpenAI(
            api_key=os.environ["SAMBANOVA_API_KEY"],
            base_url="https://api.sambanova.ai/v1",
        )

        context = "\n\n".join(
            f"Source: {result.url}\n{' '.join(result.highlights or [])}"
            for result in results.results
        )

        response = client.chat.completions.create(
            model="MiniMax-M2.7",
            messages=[
                {
                    "role": "system",
                    "content": "Using only the provided search results, write a short summary.",
                },
                {
                    "role": "user",
                    "content": f"Search results:\n\n{context}",
                },
            ],
        )

        print(response.choices[0].message.content)
        ```
      </Tab>

      <Tab title="Node.js">
        ```javascript theme={}
        import 'dotenv/config';
        import OpenAI from 'openai';

        const client = new OpenAI({
          apiKey: process.env.SAMBANOVA_API_KEY,
          baseURL: 'https://api.sambanova.ai/v1',
        });

        const context = results.results
          .map(
            (result) =>
              `Source: ${result.url}\n${(result.highlights || []).join(' ')}`
          )
          .join('\n\n');

        const response = await client.chat.completions.create({
          model: 'MiniMax-M2.7',
          messages: [
            {
              role: 'system',
              content:
                'Using only the provided search results, write a short summary.',
            },
            {
              role: 'user',
              content: `Search results:\n\n${context}`,
            },
          ],
        });

        console.log(response.choices[0].message.content);
        ```
      </Tab>
    </Tabs>
  </Step>

  <Step title="(任意) Exa によるツール呼び出しの有効化">
    エージェント型ワークフローでは、Exa 検索を Function tool として公開することで、モデル自身が Web 検索を行うタイミングを判断できるようになります。

    <Tabs>
      <Tab title="Python">
        ```python theme={}
        from dotenv import load_dotenv
        from exa_py import Exa
        from openai import OpenAI
        import os
        import json

        load_dotenv()

        exa = Exa(api_key=os.environ["EXA_API_KEY"])
        client = OpenAI(
            api_key=os.environ["SAMBANOVA_API_KEY"],
            base_url="https://api.sambanova.ai/v1",
        )

        tools = [
            {
                "type": "function",
                "function": {
                    "name": "exa_search",
                    "description": "Search the web using Exa and return grounded results.",
                    "parameters": {
                        "type": "object",
                        "properties": {
                            "query": {
                                "type": "string",
                                "description": "The search query.",
                            }
                        },
                        "required": ["query"],
                    },
                },
            }
        ]

        messages = [
            {"role": "user", "content": "What are the latest developments in AI agents?"}
        ]

        response = client.chat.completions.create(
            model="MiniMax-M2.7",
            messages=messages,
            tools=tools,
        )

        if response.choices[0].finish_reason == "tool_calls":
            tool_call = response.choices[0].message.tool_calls[0]
            args = json.loads(tool_call.function.arguments)

            search_results = exa.search(
                args["query"],
                type="auto",
                num_results=5,
                contents={"highlights": True},
            )

            context = "\n\n".join(
                f"Source: {r.url}\n{' '.join(r.highlights or [])}"
                for r in search_results.results
            )

            messages.append(response.choices[0].message)
            messages.append({
                "role": "tool",
                "tool_call_id": tool_call.id,
                "content": context,
            })

            final_response = client.chat.completions.create(
                model="MiniMax-M2.7",
                messages=messages,
                tools=tools,
            )

            print(final_response.choices[0].message.content)
        ```
      </Tab>

      <Tab title="Node.js">
        ```javascript theme={}
        import 'dotenv/config';
        import Exa from 'exa-js';
        import OpenAI from 'openai';

        const exa = new Exa(process.env.EXA_API_KEY);
        const client = new OpenAI({
          apiKey: process.env.SAMBANOVA_API_KEY,
          baseURL: 'https://api.sambanova.ai/v1',
        });

        const tools = [
          {
            type: 'function',
            function: {
              name: 'exa_search',
              description: 'Search the web using Exa and return grounded results.',
              parameters: {
                type: 'object',
                properties: {
                  query: { type: 'string', description: 'The search query.' },
                },
                required: ['query'],
              },
            },
          },
        ];

        const messages = [
          { role: 'user', content: 'What are the latest developments in AI agents?' },
        ];

        const response = await client.chat.completions.create({
          model: 'MiniMax-M2.7',
          messages,
          tools,
        });

        if (response.choices[0].finish_reason === 'tool_calls') {
          const toolCall = response.choices[0].message.tool_calls[0];
          const args = JSON.parse(toolCall.function.arguments);

          const searchResults = await exa.search(args.query, {
            type: 'auto',
            numResults: 5,
            contents: { highlights: true },
          });

          const context = searchResults.results
            .map((r) => `Source: ${r.url}\n${(r.highlights || []).join(' ')}`)
            .join('\n\n');

          messages.push(response.choices[0].message);
          messages.push({
            role: 'tool',
            tool_call_id: toolCall.id,
            content: context,
          });

          const finalResponse = await client.chat.completions.create({
            model: 'MiniMax-M2.7',
            messages,
            tools,
          });

          console.log(finalResponse.choices[0].message.content);
        }
        ```
      </Tab>
    </Tabs>
  </Step>
</Steps>

## 検索モードと鮮度の制御

Exa は複数の検索戦略に対応しています。

| 検索タイプ | 適した用途 |
| - | - |
| `auto` | 推奨。品質と速度のバランスが最も優れています。 |
| `fast` | 最も低レイテンシな検索体験を提供します。 |
| `deep` | 最も網羅的な検索カバレッジを提供します。 |

返されるコンテンツの新しさは、`max_age_hours` (Python) または `maxAgeHours` (Node.js) で制御できます。`0` に設定すると Exa はライブコンテンツのみを取得し、`24` に設定すると 1 日前までの結果が許容されます。

## ユースケースの例

この連携により、以下のような一般的なユースケースを実現できます。

* チャットボットの応答を最新の Web 情報でグラウンディングする
* 出典の引用付きリサーチアシスタントを構築する
* 最近のニュースや動向を取得する
* AI エージェントに Web 検索機能を追加する
* 独自の検索インフラを維持することなく、検索拡張生成 (RAG) ワークフローを構築する

## 参考情報

* [Exa ドキュメント](https://exa.ai/docs): Exa の Python / Node.js SDK の完全なリファレンス
* [Exa Search API リファレンス](https://exa.ai/docs/reference/search): API パラメータとレスポンススキーマの詳細
* [SambaNova ドキュメント](/docs/ja/get-started/overview): モデルの選択肢、API エンドポイント、利用ガイド
