Mistral Agents API活用術：技術的詳細解説


## はじめに：アクション指向AIの夜明け

Mistral AIは最近、AIを単なる受動的なテキスト生成ツールから、積極的な問題解決パートナーへと進化させるための大きな一歩となる、新しいAgents APIを発表しました。従来のLLM（大規模言語モデル）は、人間のようなテキストを生成する上で目覚ましい能力を発揮してきましたが、アクションの実行、外部システムとの直接的な連携、長期間の対話における永続的なコンテキストの維持といった点では限界がありました。Mistral Agents APIは、Mistralの強力な言語モデルと、エージェント機能のための堅牢なフレームワークを組み合わせることで、これらの課題に直接的に対処します。

この新しいAPIは、以下の3つの主要な柱を基盤として設計されています。

1.  **組み込みコネクタとMCPツール連携：** コード実行、ウェブ検索、画像生成、ドキュメントライブラリへのアクセス、そしてModel Context Protocol（MCP）を介した広範な外部ツールの活用といった、エージェントがすぐに利用できる機能を提供します。
2.  **会話をまたいだ永続的メモリ：** エージェントがコンテキストと履歴を維持できるようにし、より一貫性のある有意義な長期的インタラクションを可能にします。
3.  **エージェントオーケストレーション機能：** 複雑なマルチステップタスクに共同で取り組むために、複数の特化型エージェントの協調を可能にします。

Agents APIは、既存のChat Completion APIを単に拡張するものではなく、それを強力に補完するものです。エージェントを活用した高度なユースケースを実装するための専用の、合理化されたフレームワークを提供し、エンタープライズグレードのエージェントプラットフォームの基盤技術としての地位を確立します。AIエージェントが複雑なタスクを確実に処理し、重要なコンテキストを維持し、複数のアクションを調整できるようにすることで、Agents APIは企業がAIをより実用的で影響力のある方法で展開するための新たな境地を切り開きます。

本記事では、Mistral Agent APIの技術的な側面を包括的に探求し、そのコアコンセプト、機能、高度な特徴、そしてデプロイ戦略について深く掘り下げます。開発者やアーキテクトが、現実世界の課題に取り組むことができる強力なAIエージェントを構築するために必要な知識を提供することを目指します。

## コアコンセプト：構成要素の理解

Mistral Agent APIを最大限に活用するためには、その基本的な構成要素とそれらがどのように相互作用するかを理解することが不可欠です。

### AIエージェントとは？

Mistral APIの文脈におけるAIエージェントとは、LLMを搭載した自律的なシステムです。高レベルの指示を与えられると、これらのエージェントは以下のことが可能です。

*   **計画：** 複雑な目標を管理可能なステップに分解します。
*   **ツールの使用：** 様々な組み込みコネクタや外部ツール（MCPまたは関数呼び出し経由）と対話し、情報を収集したりアクションを実行したりします。
*   **処理ステップの実行：** 情報を分析し、意思決定を行い、新しい入力に基づいて戦略を調整します。
*   **アクションの実行：** 指定された目標を達成するためにタスクを実行します。

これらのエージェントは、高度な自然言語処理能力を活用して、複雑なタスクを効率的に理解し実行します。さらに、他のエージェントと協力し、専門的なスキルを持つ他のエージェントにタスクを引き渡すことで、単一のエージェントだけでは達成できない、より高度な成果を生み出す能力も備えています。

Agents APIは、以下のような機能を備えた、そのようなエージェントを構築するためのインフラストラクチャを開発者に提供します。
*   複数のマルチモーダルモデル（テキストおよびビジョン）へのアクセス。
*   会話をまたいだ永続的な状態。
*   ベースモデル、単一エージェント、または複数のエージェントとの会話機能。
*   組み込みコネクタツールのスイート。
*   複雑なワークフロー作成のためのハンドオフ機能。
*   構造化出力、ドキュメント理解、ツール使用、引用など、チャット補完エンドポイントの機能のサポート。

### 組み込みコネクタ：エージェントへの必須ツールの提供

コネクタは、Mistralによってデプロイおよび管理される事前構築済みのツールであり、エージェントは特定のタスクを実行するためにオンデマンドで呼び出すことができます。これらは、エージェントの能力をテキスト生成以外にも大幅に拡張します。

#### 1. コード実行（Code Interpreter）

Code Interpreterコネクタは、エージェントが安全なサンドボックス環境内でPythonコードを実行できるようにします。これは、計算、データ操作、または視覚化を必要とするタスクにとって非常に価値があります。

*   **機能：**
    *   数学的計算と分析。
    *   データの視覚化とプロット（例：データからのグラフ生成）。
    *   科学計算とシミュレーション。
    *   ユーザー提供スニペットのコード検証と実行。

*   **Code Interpreterエージェントの作成：**
    エージェントのツールセットに`"code_interpreter"`を含めることで、コード実行機能を備えたエージェントをインスタンス化できます。

    *Pythonの例：*
    ```python
    from mistralai import Mistral

    client = Mistral(api_key="YOUR_API_KEY")

    code_agent = client.beta.agents.create(
        model="mistral-medium-latest", # または mistral-large-latest
        name="Coding Agent",
        description="Agent used to execute code using the interpreter tool.",
        instructions="Use the code interpreter tool when you have to run code.",
        tools=[{"type": "code_interpreter"}],
        completion_args={
            "temperature": 0.3,
            "top_p": 0.95,
        }
    )
    # agent_id は code_agent.id に格納されます
    ```
    *cURLの例：*
    ```bash
    curl --location "https://api.mistral.ai/v1/agents" \
         --header 'Content-Type: application/json' \
         --header 'Accept: application/json' \
         --header "Authorization: Bearer $MISTRAL_API_KEY" \
         --data '{
         "model": "mistral-medium-latest",
         "name": "Coding Agent",
         "description": "Agent used to execute code using the interpreter tool.",
         "instructions": "Use the code interpreter tool when you have to run code.",
         "tools": [{"type": "code_interpreter"}],
         "completion_args": {
             "temperature": 0.3,
             "top_p": 0.95
         }
     }'
    ```

*   **会話と出力：**
    エージェントがCode Interpreterを使用すると、APIレスポンスには実行の詳細が含まれます。

    *リクエスト例 (Python)：*
    ```python
    response = client.beta.conversations.start(
        agent_id=code_agent.id,
        inputs="Run a fibonacci function for the first 20 values."
    )
    # response.outputs を処理
    ```

    *簡略化されたJSON出力構造：*
    ```json
    {
      "conversation_id": "conv_...",
      "outputs": [
        {
          "type": "message.output", // 初期エージェント応答
          "content": "Sure, I can help with that...",
          // ... その他のメタデータ
        },
        {
          "type": "tool.execution",
          "name": "code_interpreter",
          "id": "tool_exec_...",
          "info": {
            "code": "def fibonacci(n):\n    # ... (フィボナッチ数列のコード)\nfibonacci_20 = fibonacci(20)\nfibonacci_20",
            "code_output": "[0, 1, 1, ... , 4181]\n"
          }
          // ... その他のメタデータ
        },
        {
          "type": "message.output", // 結果を含む最終エージェント応答
          "content": "The first 20 values of the Fibonacci sequence are:\n\n[0, 1, ... , 4181]",
          // ... その他のメタデータ
        }
      ],
      "usage": { /* ... トークン使用量の詳細 ... */ }
    }
    ```
    `tool.execution`エントリはツールの`name`を示し、その`info`ブロックには実行された`code`と対応する`code_output`が含まれます。

#### 2. 画像生成

Black Forest Lab FLUX1.1 [pro] Ultraを搭載した画像生成コネクタにより、エージェントはテキストプロンプトに基づいて多様な画像を生成できます。

*   **ユースケース：**
    *   教育コンテンツ用の視覚資料の生成。
    *   マーケティング資料用のカスタムグラフィックの作成。
    *   芸術的な画像やイラストの制作。

*   **画像生成エージェントの作成：**
    エージェントのツール設定に`"image_generation"`を含めます。

    *Pythonの例：*
    ```python
    image_agent = client.beta.agents.create(
        model="mistral-medium-latest",
        name="Image Generation Agent",
        description="Agent used to generate images.",
        instructions="Use the image generation tool when you have to create images.",
        tools=[{"type": "image_generation"}],
        completion_args={ /* ... */ }
    )
    ```

*   **会話と出力：**
    画像が生成されると、レスポンスには画像ファイルへの参照が含まれます。

    *リクエスト例 (Python)：*
    ```python
    response = client.beta.conversations.start(
        agent_id=image_agent.id,
        inputs="Generate an orange cat in an office."
    )
    ```

    *簡略化されたJSON出力構造：*
    ```json
    {
      "conversation_id": "conv_...",
      "outputs": [
        {
          "type": "tool.execution",
          "name": "image_generation",
          // ... メタデータ
        },
        {
          "type": "message.output",
          "content": [
            {
              "type": "text",
              "text": "Here is your image: an orange cat in an office.\n\n"
            },
            {
              "type": "tool_file",
              "tool": "image_generation",
              "file_id": "933c5b5a-1c47-4cdd-84f6-f32526bd161b", // 重要なID
              "file_name": "image_generated_0",
              "file_type": "png"
            }
          ],
          // ... その他のメタデータ
        }
      ],
      "usage": { /* ... */ }
    }
    ```
    `message.output`には`content`配列が含まれます。`type: "tool_file"`のチャンクは、生成された画像の`file_id`、`file_name`、`file_type`を提供します。

*   **画像のダウンロード：**
    `tool_file`チャンクから取得した`file_id`を使用して、filesエンドポイント経由で画像をダウンロードします。

    *Pythonの例：*
    ```python
    from mistralai.models import ToolFileChunk # このクラスまたは類似のクラスが存在すると仮定

    # 'response' はAPIレスポンスオブジェクトであり、
    # 関連する出力は最後のものと仮定
    image_chunk = None
    for chunk in response.outputs[-1].content:
        if hasattr(chunk, 'type') and chunk.type == 'tool_file': # ToolFileChunkまたは類似のものか確認
             image_chunk = chunk
             break

    if image_chunk:
        file_bytes = client.files.download(file_id=image_chunk.file_id).read()
        with open(f"{image_chunk.file_name}.{image_chunk.file_type}", "wb") as file:
            file.write(file_bytes)
    ```

#### 3. ドキュメントライブラリ（ベータ版）

このコネクタは、組み込みのRAG（Retrieval-Augmented Generation）機能を提供し、エージェントがMistral Cloudにアップロードされたドキュメントから情報にアクセスして活用できるようにします。

*   **主な特徴：**
    *   ユーザー提供のカスタムデータでエージェントの知識を強化します。
    *   エージェントは、指定されたライブラリから関連情報をクエリして取得できます。

*   **セットアップと使用法：**
    1.  **ライブラリの作成：** 現在、ドキュメントライブラリはLe Chat（Mistralのチャットインターフェース）経由で作成する必要があります。
    2.  **権限：** エージェントがライブラリにアクセスできるようにするには、組織の管理者が組織と共有する必要があります。
    3.  **ライブラリID：** `library_id`は、Le Chat上のライブラリのURLにあります（例：`https://chat.mistral.ai/libraries/<library_id>`）。

*   **ドキュメントライブラリエージェントの作成：**
    `document_library`ツールタイプを指定し、アクセス可能な`library_ids`を提供します。

    *Pythonの例：*
    ```python
    library_agent = client.beta.agents.create(
        model="mistral-medium-latest",
        name="Document Library Agent",
        description="Agent used to access documents from the document library.",
        instructions="Use the library tool to access external documents.",
        tools=[{
            "type": "document_library",
            "library_ids": ["<your_library_id_1>", "<your_library_id_2>"]
        }],
        completion_args={ /* ... */ }
    )
    ```

*   **会話と出力：**
    エージェントがドキュメントライブラリをクエリすると、出力構造は他のツール実行と同様になり、その後、取得したドキュメントに基づいてエージェントが統合した回答が続きます。

    *リクエスト例 (Python)：*
    ```python
    response = client.beta.conversations.start(
        agent_id=library_agent.id, # 原文の例では image_agent.id だったのを修正
        inputs="How does the vision encoder for Pixtral 12B work?"
    )
    ```
    *簡略化されたJSON出力構造：*
    ```json
    {
      "conversation_id": "conv_...",
      "outputs": [
        {
          "type": "tool.execution",
          "name": "document_library",
          // ... メタデータ
        },
        {
          "type": "message.output",
          "content": [
            {
              "type": "text",
              "text": "The vision encoder for Pixtral 12B, known as PixtralViT, is designed to process images..." // 詳細な回答
            }
            // 引用が有効で関連性がある場合、tool_referenceチャンクの可能性あり
          ],
          // ... その他のメタデータ
        }
      ],
      "usage": { /* ... */ }
    }
    ```
    `message.output`内のエージェントの応答には、ドキュメントライブラリから取得および処理された情報が含まれます。このツールは、ウェブ検索と同様に、該当する場合は引用のために`tool_reference`チャンクも使用できます。

#### 4. ウェブ検索

このコネクタにより、エージェントはインターネットから最新情報にアクセスでき、LLMの知識カットオフの制限を克服できます。

*   **利点：**
    *   多様なトピックに関する最新情報を提供します。
    *   エージェントが特定のウェブサイトやニュースソースにアクセスできるようにします。
    *   知識集約型タスクのパフォーマンスを大幅に向上させます（例：Mistral LargeおよびMistral MediumのSimpleQAベンチマークスコアは、ウェブ検索により劇的に向上しました）。

*   **バージョン：**
    *   `web_search`：一般的な検索エンジンにアクセスする標準的なウェブ検索ツール。
    *   `web_search_premium`：検索エンジンに加えて、AFP（フランス通信社）やAP（AP通信）などの通信社にもアクセスできる、より高度なバージョン。

*   **ウェブ検索エージェントの作成：**
    エージェントのツールに`"web_search"`または`"web_search_premium"`を含めます。

    *Pythonの例：*
    ```python
    websearch_agent = client.beta.agents.create(
        model="mistral-medium-latest",
        description="Agent able to search information over the web...",
        name="Websearch Agent",
        instructions="You have the ability to perform web searches with `web_search` to find up-to-date information.",
        tools=[{"type": "web_search"}], // または web_search_premium
        completion_args={ /* ... */ }
    )
    ```

*   **会話と出力：**
    APIレスポンスには、検索実行の詳細とエージェントの回答が含まれ、多くの場合、出典の引用が付随します。

    *リクエスト例 (Python)：*
    ```python
    response = client.beta.conversations.start(
        agent_id=websearch_agent.id,
        inputs="Who won the last European Football cup?"
    )
    ```

    *簡略化されたJSON出力構造：*
    ```json
    {
      "conversation_id": "conv_...",
      "outputs": [
        {
          "type": "tool.execution",
          "name": "web_search",
          // ... メタデータ
        },
        {
          "type": "message.output",
          "content": [
            {
              "type": "text",
              "text": "The last winner of the European Football Cup was Spain..."
            },
            {
              "type": "tool_reference", // 引用
              "tool": "web_search",
              "title": "UEFA Euro Winners List...",
              "url": "https://www.marca.com/en/football/uefa-euro/winners.html",
              "source": "brave" // 検索プロバイダーの例
            },
            // ... さらに tool_reference チャンクと text チャンク
          ],
          // ... その他のメタデータ
        }
      ],
      "usage": { /* ... connector_tokens を含むトークン使用量 ... */ }
    }
    ```
    `message.output`の`content`配列は、`text`チャンク（エージェントの回答）と`tool_reference`チャンクを交互に配置します。各`tool_reference`は、回答のその部分に使用されたソースに関するメタデータ（タイトル、URL、ソースプロバイダー）を提供し、透明性を高め、事実確認を可能にします。

### MCP (Model Context Protocol) ツール：エージェントと外部システムの橋渡し

組み込みコネクタに加えて、Agents API SDKはModel Context Protocol (MCP) 上に構築されたツールをサポートします。MCPは、AIエージェントと多種多様な外部システムとの間のシームレスで安全な統合を促進するために設計された、オープンで標準化されたプロトコルです。

*   **MCPの目的：**
    *   エージェントがAPI、データベース、ユーザー固有のデータ、ドキュメント、その他の動的リソースを含む実世界のコンテキストにアクセスできるようにします。
    *   断片化されたカスタム統合を統一されたプロトコルに置き換えます。
    *   AIモデルがライブデータや実世界のシステムに接続することで、より関連性の高い正確な応答を生成するのに役立ちます。

*   **MistralエージェントでのMCPの使用：**
    Mistral Python SDKは、エージェントをMCPクライアントと統合するためのユーティリティを提供し、エージェントがMCPサーバーによって公開される関数やサービスを呼び出せるようにします。

*   **例：天気情報のためのローカルMCPサーバー**
    これには、MCPサーバーとして機能するローカルPythonスクリプトと、それにクエリを実行するエージェントのセットアップが含まれます。

    1.  **MistralクライアントとMCPコンポーネントの初期化：**
        ```python
        # stdio_mcp_weather_example.py
        import asyncio
        import os
        from mistralai import Mistral
        from mistralai.extra.run.context import RunContext
        from mcp import StdioServerParameters # 'mcp' パッケージから
        from mistralai.extra.mcp.stdio import MCPClientSTDIO
        from pathlib import Path
        from mistralai.types import BaseModel # 構造化出力用

        # 現在の作業ディレクトリと使用するモデルを設定
        cwd = Path(__file__).parent
        MODEL = "mistral-medium-latest" # または mistral-large-latest

        async def main() -> None:
            api_key = os.environ.get("MISTRAL_API_KEY")
            if not api_key:
                raise ValueError("MISTRAL_API_KEY environment variable not set.")
            client = Mistral(api_key=api_key)

            # ローカルMCPサーバーのパラメータを定義
            # このスクリプトに対して相対的に 'mcp_servers/stdio_server.py' が存在し、
            # MCPロジック（例：天気サービス）を実装していると仮定
            server_params = StdioServerParameters(
                command="python", # またはサーバー実行可能ファイル
                args=[str((cwd / "mcp_servers/stdio_server.py").resolve())],
                env=None, # またはサーバー用の特定の環境変数
            )

            # エージェントを作成
            weather_agent = client.beta.agents.create(
                model=MODEL,
                name="Weather Teller Agent (MCP)",
                instructions="You can tell the weather using available tools.",
                description="An agent that uses an MCP server to fetch weather.",
            )

            # 期待される構造化出力形式を定義
            class WeatherResult(BaseModel):
                user: str
                location: str
                temperature: float

            # エージェントの実行コンテキストを作成
            async with RunContext(
                agent_id=weather_agent.id,
                output_format=WeatherResult, # 構造化出力用
                continue_on_fn_error=True,
            ) as run_ctx:
                # MCPクライアントを作成し、実行コンテキストに登録
                # このクライアントは stdio_server.py と通信します
                mcp_client = MCPClientSTDIO(stdio_params=server_params)
                await run_ctx.register_mcp_client(mcp_client=mcp_client)

                # (オプション) ローカルPython関数もツールとして登録
                import random
                @run_ctx.register_func
                def get_location(name: str) -> str:
                    """ユーザーの模擬的な場所を取得する関数。"""
                    return random.choice(["New York", "London", "Paris"])

                # クエリでエージェントを実行
                # エージェントは get_location または MCP ツールのどちらを使用するかを決定します
                run_result = await client.beta.conversations.run_async(
                    run_ctx=run_ctx,
                    inputs="Tell me the weather in John's location currently.",
                )

                print("All run entries:")
                for entry in run_result.output_entries:
                    print(f"{entry}")
                    print()
                
                if run_result.output_as_model:
                    print(f"Final model output (structured): {run_result.output_as_model}")
                else:
                    print(f"Final model output (raw): {run_result.output_entries[-1] if run_result.output_entries else 'N/A'}")


        if __name__ == "__main__":
            # mcp_servers/stdio_server.py が存在し、実行可能であることを確認してください
            # mcp_servers/stdio_server.py のスタブ例：
            # #!/usr/bin/env python
            # import sys, json
            # def get_weather(location: str): return {"temperature": 25.5, "condition": "Sunny"}
            # if __name__ == "__main__":
            #     for line in sys.stdin:
            #         req = json.loads(line)
            #         # 簡略化されたMCPインタラクション： 'get_weather_for_location' を持つ 'tool_call' を想定
            #         if req.get("tool_calls") and req["tool_calls"][0].get("function", {}).get("name") == "get_weather_for_location":
            #             loc = json.loads(req["tool_calls"][0]["function"]["arguments"]).get("location")
            #             res = {"tool_results": [{"id": req["tool_calls"][0]["id"], "result": get_weather(loc)}]}
            #             sys.stdout.write(json.dumps(res) + "\n")
            #             sys.stdout.flush()
            #         else: # ツール呼び出しでない場合はエコーバック、基本的なMCPハンドシェイク用
            #             sys.stdout.write(json.dumps({"message": "MCP Server Ready"}) + "\n")
            #             sys.stdout.flush()
            asyncio.run(main())
        ```
        *注：この例の`stdio_server.py`は非常に簡略化されています。実際のMCPサーバーは、ツール登録、呼び出し、応答に関する完全なMCP仕様に準拠します。*

    2.  **MCPとのストリーミング会話：**
        非ストリーミングと同様ですが、結果は到着時に非同期的に処理されます。
        ```python
        # RunContext ブロック内
        events = await client.beta.conversations.run_stream_async(
            run_ctx=run_ctx,
            inputs="Tell me the weather in John's location currently.",
        )

        run_result_stream = None
        async for event in events:
            if isinstance(event, client.beta.conversations.RunResult): # SDK に応じてクラス名を調整
                run_result_stream = event
            else:
                print(f"Stream event: {event}") # 中間イベント/チャンクを印刷

        if not run_result_stream:
            raise RuntimeError("No run result found from stream")
        # run_result と同様に run_result_stream を処理
        ```

### メモリとコンテキスト：ステートフルな会話の実現

Agents APIの主要な差別化要因の1つは、本質的にステートフルな堅牢な会話管理システムです。

*   **永続的コンテキスト：** 各会話はその履歴を保持し、時間の経過とともに一貫性のある文脈を意識した対話を可能にします。開発者は会話履歴を手動で追跡する必要がありません。
*   **会話の開始：**
    *   **エージェントと共に：** 特定の`agent_id`を使用して会話を開始し、その事前定義されたツール、指示、モデルを活用します。
        ```python
        response = client.beta.conversations.start(
            agent_id="ag_xxxxxxxx",
            inputs="Initial user query."
        )
        conversation_id = response.conversation_id
        ```
    *   **直接アクセス：** `model`と`completion_args`を直接指定して会話を開始し、エージェントを事前に定義することなく組み込みコネクタに迅速にアクセスします。
*   **会話履歴：** 対話は構造化された`conversation entries`として保存され、コンテキストが確実に保持されます。
*   **ステートフルな対話と分岐：**
    *   開発者は過去の会話エントリを表示できます。
    *   どの会話も最後のポイントから継続できます。
    *   既存の会話の任意の過去のポイントから新しい会話パス（分岐）を開始できます。
*   **ストリーミング出力：** APIは、新しい会話の開始と既存の会話の継続の両方でストリーミングをサポートし、リアルタイムの更新とインタラクティブなエクスペリエンスを可能にします。

## エージェントオーケストレーション：協調的な問題解決

Agents APIの真の力は、複雑で多面的な問題を解決するために複数のエージェントをオーケストレーションする能力に現れます。

### 動的オーケストレーション

エージェントは、必要に応じて会話に動的に追加したり削除したりできます。各エージェントは、より大きな問題のさまざまな部分に取り組むために、独自の機能（特化されたツール、異なるモデル、または特定の指示）を提供します。

### ハンドオフによるエージェントワークフローの作成

1.  **必要なエージェントの作成：**
    まず、ワークフローに参加するすべての個々のエージェントを作成します。各エージェントは、特定のツール、モデル、指示で調整できます。たとえば、次のようなものを作成できます。
    *   `finance-agent`（複雑な推論のために`mistral-large-latest`を使用するなど）。
    *   `web-search-agent`（`web_search`ツールを装備）。
    *   `calculator-agent`（`code_interpreter`またはカスタム関数呼び出しツールを備えている可能性あり）。
    *   `ecb-interest-rate-agent`（特定のAPIの関数呼び出しを使用）。
    *   `graph-plotting-agent`（視覚化のために`code_interpreter`を使用）。

    *cURLの例（Finance Agentの作成）：*
    ```bash
    curl --location "https://api.mistral.ai/v1/agents" \
         --header 'Content-Type: application/json' \
         --header 'Accept: application/json' \
         --header "Authorization: Bearer $MISTRAL_API_KEY" \
         --data '{
         "model": "mistral-large-latest",
         "name": "finance-agent",
         "description": "Agent used to answer financial related requests"
      }'
    # 返された agent_id を <finance_agent_id> として保存
    ```
    `web_search_agent`（ツール：`web_search`）、`graph_agent_id`（ツール：`code_interpreter`）、`calculator_agent_id`（ツール：`code_interpreter`）などの他のエージェントについても繰り返します。

2.  **ハンドオフ責任の定義：**
    エージェントが作成されたら、それらを更新して、タスクを引き渡すことができる他のエージェントを指定します。これは、`agent_id`のリストを取る`handoffs`パラメータを介して行われます。

    *cURLの例（Web Search Agentのハンドオフ設定更新）：*
    ```bash
    curl --location "https://api.mistral.ai/v1/agents/<web_search_agent_id>" \
         --header 'Content-Type: application/json' \
         --header 'Accept: application/json' \
         --header "Authorization: Bearer $MISTRAL_API_KEY" \
         --data '{
         "handoffs": ["<graph_agent_id>", "<calculator_agent_id>"]
      }'
    ```
    この設定により、`web-search-agent`は、会話が`graph-plotting-agent`または`calculator-agent`の特定の機能を必要とする場合に、これらのエージェントにタスクを委任できます。

### ハンドオフの仕組み

最初のエージェント（例：`finance-agent`）への単一のユーザーリクエストが、複数のエージェントにまたがる一連のアクションを引き起こす可能性があります。各エージェントは、その専門分野に関連するリクエストの部分を処理します。

*   **`handoff_execution` パラメータ：** 会話API呼び出しのこのパラメータは、ハンドオフの管理方法を制御します。
    *   `server`（デフォルト）：ハンドオフはMistralのクラウドサーバー上で内部的に実行されます。最終的な応答またはさらなる入力が必要になるまで、プロセスはエンドユーザーにとってシームレスです。
    *   `client`：ハンドオフがトリガーされると、APIは保留中のハンドオフを示す応答をクライアントに返します。これにより、クライアントアプリケーションはハンドオフのロジックを管理したり、さらにはオーバーライドしたりでき、より詳細な制御が可能になります。

*   **ワークフロー例 A：米国金利と複利計算**
    *ユーザーのクエリ：* 「現在の米国銀行金利を取得し、今後10年間投資した場合の複利効果を計算してください。」
    *期待されるフロー（サーバーサイドハンドオフ）：*
    1.  リクエストは`finance-agent`に送られます。
    2.  `finance-agent`は現在の金利と計算が必要であると判断します。
    3.  「現在の米国銀行金利」を見つけるために`web-search-agent`にハンドオフする可能性があります。
    4.  `web-search-agent`が検索を実行し、金利を返します。
    5.  その後、コンテキスト（金利を含む）が`calculator-agent`にハンドオフされる（または`finance-agent`に戻り、そこからハンドオフされる）可能性があります。
    6.  `calculator-agent`は、その`code_interpreter`または関数を使用して、10年間の複利を計算します。
    7.  最終結果が統合され、ユーザーに返されます。

*   **ワークフロー例 B：ECB金利とグラフプロット**
    *ユーザーのクエリ：* 「2025年1月時点の欧州中央銀行の金利を基に、今後10年間の複利金利のグラフをプロットしてください。」
    *期待されるフロー（ローカルの場合、関数呼び出しの実現のためにクライアントサイドのハンドオフが関与する可能性あり）：*
    1.  `finance-agent`へのリクエスト。
    2.  `finance-agent`はECB金利とグラフの必要性を特定します。
    3.  （「2025年1月」の金利を取得するために、特定のおそらくクライアント管理のAPIの関数呼び出しを使用する）`ecb-interest-rate-agent`へのハンドオフ。
        *   `handoff_execution: client`が使用され、関数がクライアントサイドである場合、APIはクライアントに関数を実行して結果を返すように通知します。
    4.  金利が取得されると、コンテキストは`graph-plotting-agent`にハンドオフされます。
    5.  `graph-plotting-agent`は`code_interpreter`を使用してプロットデータと、場合によってはグラフの画像を生成します。
    6.  グラフ（またはその`file_id`）と分析が返されます。画像はその`file_id`を使用してダウンロードできます（例：`curl ... /files/<file_id>/content`）。

## 高度な機能と使用法

### 関数呼び出し

組み込みコネクタとMCPを補完するものとして、エージェントはカスタム関数のJSONスキーマを定義することで、標準的な関数呼び出しを使用できます。これにより、エージェントは任意の外部APIまたは独自のシステムと対話できます。

*   **関数の定義：**
    エージェントを作成または更新する際に、`name`、`description`、および`parameters`（JSONスキーマとして）を詳細に記述した`function`オブジェクトを持つ`type: "function"`のツールを提供します。

    *cURLの例（関数を持つエージェントの作成）：*
    ```bash
    curl --location "https://api.mistral.ai/v1/agents" \
         --header 'Content-Type: application/json' \
         --header 'Accept: application/json' \
         --header "Authorization: Bearer $MISTRAL_API_KEY" \
         --data '{
         "model": "mistral-medium-latest",
         "name": "ecb-interest-rate-agent",
         "description": "Can find the current interest rate of the European central bank",
         "instructions": "You can provide interest rate and information regarding the European central bank.",
         "tools": [
             {
                 "type": "function",
                 "function": {
                     "name": "get_european_central_bank_interest_rate",
                     "description": "Retrieve the real interest rate of European central bank.",
                     "parameters": {
                         "type": "object",
                         "properties": {
                             "date": {
                                 "type": "string",
                                 "description": "The date for which to fetch the rate, e.g., YYYY-MM-DD"
                             }
                         },
                         "required": ["date"]
                     }
                 }
             }
         ]
     }'
    # agent_id を保存
    ```

*   **関数呼び出しを持つエージェントの使用：**
    1.  **会話の開始：** ユーザーのクエリを送信します。エージェントが関数を使用すると判断した場合、`tool_calls`エントリを含む応答を返すことがあります。
        *cURL（会話の開始）：*
        ```bash
        curl --location "https://api.mistral.ai/v1/conversations" \
             --header 'Content-Type: application/json' \
             --header 'Accept: application/json' \
             --header "Authorization: Bearer $MISTRAL_API_KEY" \
             --data '{
             "inputs": [
                 {
                     "role": "user",
                     "content": "Whats the current 2025 real interest rate for ECB?",
                     "object": "entry",
                     "type": "message.input"
                 }
             ],
             "stream": false,
             "agent_id": "<agent_id_with_function>"
         }'
        ```
        *期待される部分的な応答（関数が呼び出された場合）：* 応答の`outputs`には、`type`が`tool.calls`（またはエージェント関数呼び出しの正確なAPI仕様に基づく類似のもの）であるエントリが含まれ、`tool_call_id`と関数名および引数が含まれます。

    2.  **関数結果の提供：** クライアントが関数を実行した後、`tool_call_id`を参照して結果を返送し、会話を続行します。
        *cURL（関数結果で会話を続行）：*
        ```bash
        CONV_ID="<conversation_id_from_previous_step>"
        TOOL_CALL_ID="<tool_call_id_from_previous_step>" # 例： "6TI17yZkV"

        curl --location "https://api.mistral.ai/v1/conversations/$CONV_ID" \
             --header 'Content-Type: application/json' \
             --header 'Accept: application/json' \
             --header "Authorization: Bearer $MISTRAL_API_KEY" \
             --data-raw '{
             "inputs": [
                 {
                     "tool_call_id": "'"$TOOL_CALL_ID"'",
                     "result": "{\"date\": \"2025-01-15\", \"interest_rate\": \"2.75%\"}",
                     "object": "entry",
                     "type": "function.result"
                 }
             ],
             "stream": false,
             "store": true,
             "handoff_execution": "server"
         }'
        ```
        その後、エージェントはこの結果を使用して最終的な回答を作成します。
    *   MCPオーケストレーションは、MCPの例で`run_ctx.register_func`を使用して示されているように、ローカル関数呼び出しにも使用できます。

### サポートされているモデル

当初、Agents APIは`mistral-medium-latest`と`mistral-large-latest`をサポートしています。Mistral AIは将来、より多くのモデルを有効にする予定です。

### 継承された機能：構造化出力、ドキュメント理解、引用

Agents APIは、Chat Completions APIで利用可能な機能も利用できます。
*   **構造化出力：** エージェントは、特定のJSONスキーマで出力を生成するように誘導でき、プログラムによる消費に役立ちます（MCPの例で`output_format=WeatherResult`で実証済み）。
*   **ドキュメント理解：** モデルは、提供されたドキュメントのコンテンツを処理および理解できます（Document Libraryコネクタに関連）。
*   **引用：** RAG関連のツール使用（Web SearchやDocument Libraryなど）の場合、エージェントは応答で使用された情報のソースを示す引用（`tool_reference`チャンク）を提供できます。これは透明性と事実確認にとって不可欠です。

## デプロイおよび統合戦略

エージェントを強化するモデルを含むMistralモデルは、さまざまな環境にデプロイできます。

### vLLMによる自己デプロイ

vLLMはオープンソースのLLM推論およびサービングエンジンであり、Mistralモデルのオンプレミスデプロイに適しています。

*   **前提条件：**
    *   vLLM要件を満たすハードウェア。
    *   Hugging Faceからウェイトを調達する場合、Hugging Face認証（READ権限を持つHF_TOKEN）。モデルカードの規約に同意していることを確認してください。
    *   または、ローカルモデルアーティファクトを使用する場合は、vLLMにそのパスをポイントします。

*   **インストールとセットアップ：**
    ```bash
    pip install vllm # 互換性のためにバージョン >=0.6.1.post1 を確認
    huggingface-cli login --token $HF_TOKEN
    ```

*   **オフラインモード推論（バッチ処理）：**
    *例（Mistral NeMo / Mistral Small - テキスト入力）：*
    ```python
    from vllm import LLM, SamplingParams

    # Mistral NeMo / Small の場合：
    model_name = "mistralai/Mistral-Nemo-Instruct-2407" # または mistralai/Mistral-Small-latest
    # Pixtral-12B (マルチモーダル) の場合：
    # model_name = "mistralai/Pixtral-12B-Instruct-v0.1"

    sampling_params = SamplingParams(max_tokens=1024, temperature=0.7) # 必要に応じて調整

    llm = LLM(
        model=model_name,
        tokenizer_mode="mistral", # Mistralモデルにとって重要
        # 新しいモデルの場合、これらは自動検出されるか 'auto' を使用する可能性があります
        # load_format="mistral",
        # config_format="mistral",
        # Pixtralの場合、追加のマルチモーダル設定が必要になる場合があります
        # enable_lora=True, # LoRAアダプターを使用する場合
    )

    messages = [{"role": "user", "content": "Who is the best French painter? Explain briefly."}]

    # Pixtralの場合、messagesは 'role' と 'content' を持つ辞書のリストになり、
    # contentはテキストと画像のアイテムのリストになります：
    # messages_pixtral = [{
    #     "role": "user",
    #     "content": [
    #         {"type": "text", "text": "Describe this image."},
    #         {"type": "image_url", "image_url": {"url": "data:image/jpeg;base64,..."}} # Base64エンコードされた画像
    #     ]
    # }]

    # テキストモデルの場合：
    outputs = llm.generate(prompt_token_ids=[llm.get_tokenizer().encode(messages[0]["content"])], sampling_params=sampling_params) # またはチャット形式のプロンプトには llm.chat() を使用
    # チャットモデルの場合（新しいvLLMバージョンは llm.chat を直接サポート）
    # outputs = llm.chat(messages=messages, sampling_params=sampling_params)

    # print(outputs[0].outputs[0].text) # 生成されたテキストへのアクセス

    # Pixtralの場合（マルチモーダルのgenerateを使用した例、最新のAPIについてはvLLMドキュメントを確認）
    # from vllm.multimodal.utils import process_image_pil
    # from PIL import Image
    # image = Image.open("path_to_your_image.jpg")
    # processed_image_input = {"image": image} # このAPIは変更される可能性があります
    # outputs = llm.generate(
    #     prompts=["Describe this image <image>"], # 画像のプレースホルダー
    #     multi_modal_data=processed_image_input,
    #     sampling_params=sampling_params
    # )
    # print(outputs[0].outputs[0].text)
    ```
    *注：PixtralのvLLMでの使用には特定のマルチモーダル設定が必要です。最新の方法についてはvLLMのドキュメントを参照してください。*


*   **サーバーモード推論（OpenAI互換API）：**
    *サーバーの起動（例：Mistral NeMo）：*
    ```bash
    vllm serve mistralai/Mistral-Nemo-Instruct-2407 \
      --tokenizer_mode mistral \
      --load_format mistral \
      --config_format mistral \
      # --port 8000 (デフォルト)
      # --host 0.0.0.0
      # --tensor-parallel-size N (マルチGPU用)
    ```
    *サーバーへのクエリ（cURL）：*
    ```bash
    curl http://localhost:8000/v1/chat/completions \
        -H "Content-Type: application/json" \
        -H "Authorization: Bearer sk-xxxxxxxx" \ # ローカルvLLMの場合、トークンは任意であることが多い
        -d '{
            "model": "mistralai/Mistral-Nemo-Instruct-2407",
            "messages": [
              {"role": "user", "content": "Who is the best French painter? One short sentence."}
            ],
            "max_tokens": 50
          }'
    ```

*   **Dockerによるデプロイ：**
    vLLMの公式Dockerイメージを使用します。
    ```bash
    export HF_TOKEN=your-hugging-face-access-token
    docker run --runtime nvidia --gpus all \
        -v ~/.cache/huggingface:/root/.cache/huggingface \
        --env "HUGGING_FACE_HUB_TOKEN=${HF_TOKEN}" \
        -p 8000:8000 \
        --ipc=host \
        vllm/vllm-openai:latest \
        --model mistralai/Mistral-Nemo-Instruct-2407 \
        --tokenizer_mode mistral \
        --load_format mistral \
        --config_format mistral
        # 必要に応じて他のvLLM CLI引数を追加
    ```

### Cloudflare Workers AIによるデプロイ

Cloudflare Workers AIを使用すると、Cloudflareのグローバルネットワーク上のサーバーレスGPUでLLMを実行できます。

*   **セットアップ：**
    1.  Cloudflareアカウントを作成します。
    2.  アカウントIDを取得します。
    3.  Workers AI権限を持つAPIトークンを生成します。

*   **補完リクエストの送信（Mistral-7BのcURL例）：**
    ```bash
    ACCOUNT_ID="your_account_id"
    API_TOKEN="your_api_token"

    curl "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/ai/run/@cf/mistral/mistral-7b-instruct-v0.1" \
      -X POST \
      -H "Authorization: Bearer $API_TOKEN" \
      -d '{ "messages": [{ "role": "user", "content": "
 What is 2 + 2 ? 
" }]}'
    ```
    *期待される出力：*
    ```json
    {"result":{"response":" 2 + 2 = 4."},"success":true,"errors":[],"messages":[]}
    ```
    PythonおよびTypeScriptのSDK/例も通常、Cloudflareから入手できます。

## はじめに と リソース

Mistral Agent APIの旅を始めるのは簡単です。
1.  **公式ドキュメントの参照：** 詳細なAPIリファレンス、ガイド、更新情報の主要な情報源です。
2.  **最初のエージェントの作成：** Web SearchやCode Interpreterなどの組み込みコネクタを持つ簡単なエージェントを定義して実験します。
3.  **クックブックの探求：** Mistralは、さまざまなアプリケーションのためのエージェントワークフローを紹介する実用的な例とチュートリアル（クックブック）を提供しています。
    *   GitHub Agent：ソフトウェア開発タスクの自動化。
    *   Linear Tickets Assistant：プロジェクト成果物の管理。
    *   Financial Analyst：財務指標の調達と洞察の編集。
    *   Travel Assistant：旅行の計画と宿泊施設の予約。
    *   Food Diet Companion：栄養の追跡と食事計画。

### よくある質問（FAQ）
*   **どのモデルがサポートされていますか？**
    現在、`mistral-medium-latest`と`mistral-large-latest`がサポートされており、まもなくより多くのモデルが有効になる予定です。

## まとめ：未来はエージェントと共に

Mistral Agent APIは、より高性能で自律的なAIシステムへの重要な一歩を表しています。組み込みツール、MCPおよび関数呼び出しを介した外部システム連携、永続的メモリ、そして高度なエージェントオーケストレーションのための堅牢なフレームワークを提供することで、Mistral AIは開発者が複雑な問題やデジタル環境に積極的に関与できるAIエージェントを構築できるようにします。

それぞれが独自のスキルを提供する特化されたエージェントを連鎖させる能力は、複雑なワークフローの自動化、深い調査の実行、そして高度にインタラクティブでインテリジェントなアプリケーションの作成の可能性を解き放ちます。リポジトリを管理するコーディングアシスタントから市場データを統合する金融アナリストまで、潜在的なアプリケーションは広大で変革的です。

企業がAIをコア業務にますます統合しようとする中、Mistral Agent APIは強力で柔軟かつスケーラブルなソリューションを提供します。エージェントAIへの旅は始まったばかりであり、Mistral Agent APIのようなツールがあれば、開発者は次世代のインテリジェントシステムを設計するための十分な準備ができています。高度な言語モデルと実行可能な機能の組み合わせは、AIが受動的な情報提供者から積極的な協力者および問題解決者へと移行する新しい時代の到来を告げています。