チュートリアル: Azure AI 検索を使用してエンド ツー エンドのエージェント検索ソリューションを構築する

メモ

Azure AI 検索は、Azure ポータル、REST API、およびAzure SDKから使用できます。 また、Foundry IQ は、エンタープライズ コンテンツを、Microsoft Foundry ポータルのエージェントの再利用可能なアクセス許可に対応したナレッジ ベースに変換するマネージド ナレッジ レイヤーです。

重要

機能、またはマークされたプロパティ (プレビュー) は、サービス レベル アグリーメントの対象ではなく、運用環境のワークロードには推奨されず、一般公開される前に変更または制約される可能性があります。 Azure AI 検索 プレビューの用語は、スタンドアロンでも一般公開されている機能の一部でも、すべてのプレビュー機能に適用されます。

Azure AI 検索 と Foundry Agent Service を統合し、エージェント取得を実現する、MCP 対応のインテリジェントなソリューションの構築方法について説明します。 このアーキテクチャは、カスタマー サポートや技術的なトラブルシューティングなど、大規模なナレッジ ドメインに対する複雑な推論を必要とする会話型アプリケーションに使用できます。

このチュートリアルでは、プレビュー REST API サーフェスを 2 か所で使用します。 ナレッジ ベースでは、 output_mode と retrieval_reasoning_effort (プレビュー) を使用して抽出出力と最小限の推論を明示的に指定しますが、同等の動作は一般公開されています。 プロジェクト接続では、RemoteTool (プレビュー) とプロジェクトマネージド ID を使用して、Azure AI 検索に対する認証が行われます。

このチュートリアルでは、次の操作を行います。

  • Azure AI 検索と Microsoft Foundry のロールベースのアクセスを構成する
  • Azure AI 検索で検索インデックス、ナレッジ ソース、ナレッジ ベースを作成する
  • Azure AI 検索 と Microsoft Foundry の間の MCP 通信用のプロジェクト接続を作成する
  • MCP ツールを使用して取得するエージェントを Microsoft Foundry に作成する
  • エージェントとチャットしてソリューションをテストする
  • ソリューションを最適化するためのヒントを確認する

MCP を介した Foundry Agent Service との Azure AI 検索 統合を示すエンドツーエンドのエージェント検索パイプラインのダイアグラム。

ヒント

前提 条件

重要

検索サービスのパブリック ネットワーク アクセスを無効にし、ネットワーク分離された Microsoft Foundry リソースでエージェント ツールとして使用する場合は、Microsoft Foundry (新しい) ポータル、SDK、または CLI を使用してエージェントを構築する必要があります。 Microsoft Foundry (クラシック) ポータルでは、このシナリオはサポートされていません。 詳細については、「 ネットワーク分離を使用したエージェント ツール」を参照してください。

ソリューションを理解する

このソリューションでは、Azure AI 検索と foundry Microsoftを組み合わせて、エンドツーエンドの取得パイプラインを作成します。

  • Azure AI 検索 は、クエリの計画、クエリの実行、結果の合成を処理するナレッジ ベースをホストします。 コンテンツを格納する検索インデックス、インデックスを参照するナレッジ ソース、ナレッジ ソースからのハイブリッド取得を実行するナレッジ ベースを作成します。

  • Microsoft Foundry は、Azure OpenAI モデルのデプロイ、プロジェクト接続、およびエージェントをホストします。 ナレッジ ベースの MCP エンドポイントを指すプロジェクト接続を作成し、MCP ツールを使用してナレッジ ベースにアクセスするエージェントを作成します。

ユーザーは、エージェントを呼び出すチャットボットなどのクライアント アプリと対話してクエリ処理を開始します。 エージェントは、MCP ツールを使用してナレッジ ベースへの要求を調整し、応答を合成します。 チャットボットがエージェントを呼び出すと、MCP ツールはAzure AI 検索でナレッジ ベースを呼び出し、エージェントとチャットボットに応答を送信します。

アクセスの構成

開始する前に、コンテンツと操作にアクセスするためのアクセス許可があることを確認してください。 認証用にMicrosoft Entra IDし、承認用にロールベースのアクセスを行うことをお勧めします。 ロールを割り当てるには、 所有者 または ユーザー アクセス管理者 である必要があります。 ロールが実現できない場合は、代わりに キーベースの認証 を使用します。

このソリューションのアクセスを構成するには:

  1. Azure ポータルにサインインします。

  2. 検索サービスとプロジェクトの両方に対して、システム割り当てマネージド ID を有効にします。 これは、各リソースの [ID] ページで行うことができます。

  3. 検索サービスで、 ロールベースのアクセスを有効に して 、次のロールを割り当てます。

    役割 担当者 目的
    Search Service 寄稿者 ユーザー アカウント オブジェクトを作成する
    検索インデックス データ共同作成者 ユーザー アカウント データの読み込み
    検索インデックス データ閲覧者 ユーザー アカウントとプロジェクトのマネージド ID インデックス付きコンテンツの読み取り
  4. プロジェクトの親リソースで、次のロールを割り当てます。

    役割 担当者 目的
    Foundry ユーザー ユーザー アカウント モデルのデプロイにアクセスし、エージェントを作成する
    ファウンドリー プロジェクト マネージャー ユーザー アカウント プロジェクト接続を作成し、エージェントで MCP ツールを使用する
    Cognitive Services ユーザー 検索サービスの管理対象ID ナレッジ ベースにアクセスする

重要

Foundry RBAC ロールの名前が最近変更されました。 Foundry User, Foundry Owner, Foundry Account Owner、および Foundry Project Manager は、以前は、AZURE AI ユーザー、Azure AI 所有者、Azure AI アカウント所有者、および AZURE AI Project Manager という名前でした。 名前の変更がロールアウトされている間、以前の名前が表示される場合があります。ロール ID とコア アクセス許可は、名前の変更によって変更されません。

環境を設定する

  1. ローカル システムに tutorial-agentic-retrieval という名前のフォルダーを作成します。

  2. Visual Studio Codeでフォルダーを開きます。

  3. View>Command Palette を選択し、 Python: Create Environment を選択します。 プロンプトに従って仮想環境を作成します。

  4. [ターミナル]>[新しいターミナル] を選択します。

  5. 必要なパッケージをインストールします。

    pip install azure-ai-projects==2.0.0b1 azure-mgmt-cognitiveservices azure-identity ipykernel python-dotenv azure-search-documents==11.7.0b2 requests openai
    
  6. .env フォルダーに tutorial-agentic-retrieval という名前のファイルを作成します。

  7. プレースホルダーの値を独自の値に置き換えて、次の変数を .env ファイルに追加します。

    AZURE_SEARCH_ENDPOINT = https://{your-service-name}.search.windows.net
    PROJECT_ENDPOINT = https://{your-resource-name}.services.ai.azure.com/api/projects/{your-project-name}
    PROJECT_RESOURCE_ID = /subscriptions/{subscription-id}/resourceGroups/{resource-group-name}/providers/Microsoft.CognitiveServices/accounts/{account-name}/projects/{project-name}
    AZURE_OPENAI_ENDPOINT = https://{your-resource-name}.openai.azure.com
    AZURE_OPENAI_EMBEDDING_DEPLOYMENT = text-embedding-3-large
     AGENT_MODEL = gpt-5-mini
    

    エンドポイントとリソース ID は、Azure ポータルで確認できます。

    • AZURE_SEARCH_ENDPOINT は、検索サービスの [概要 ] ページにあります。

    • PROJECT_ENDPOINT は、プロジェクトの [エンドポイント] ページにあります。

    • PROJECT_RESOURCE_ID は、プロジェクトの [プロパティ] ページにあります。

    • AZURE_OPENAI_ENDPOINT は、プロジェクトの親リソースの [エンドポイント] ページにあります。

  8. Microsoft Entra IDによるキーレス認証の場合は、Azure アカウントにサインインします。 複数のサブスクリプションがある場合は、Azure AI 検索とMicrosoft Foundryのリソースを含むサブスクリプションを選択します。

    az login
    
  9. tutorial.ipynb フォルダーに tutorial-agentic-retrieval という名前のファイルを作成します。 次のセクションでは、このファイルにコード セルを追加します。

ソリューションをビルドする

このセクションでは、エージェント検索ソリューションのコンポーネントを作成します。 tutorial.ipynb ノートブックの個別のコード セルに各コード スニペットを追加し、セルを順番に実行します。

このセクションの手順は次のとおりです。

  1. 接続の読み込み
  2. 検索インデックスを作成する
  3. ドキュメントをインデックスにアップロードする
  4. ナレッジ ソースを作成する
  5. ナレッジ ベースを作成する
  6. プロジェクト クライアントを設定する
  7. プロジェクト接続を作成する
  8. MCP ツールを使用してエージェントを作成する
  9. エージェントとのチャット
  10. リソースのクリーンアップ

接続を読み込む

次のコードは、.env ファイルから環境変数を読み込み、Azure AI 検索とMicrosoft Foundryへの接続を確立します。

import os

from azure.identity import DefaultAzureCredential
from azure.mgmt.core.tools import parse_resource_id
from dotenv import load_dotenv

load_dotenv(override=True) # Take environment variables from .env

project_endpoint = os.environ["PROJECT_ENDPOINT"]
project_resource_id = os.environ["PROJECT_RESOURCE_ID"]
project_connection_name = os.getenv("PROJECT_CONNECTION_NAME", "earthknowledgeconnection")
agent_model = os.getenv("AGENT_MODEL", "gpt-5-mini")
agent_name = os.getenv("AGENT_NAME", "earth-knowledge-agent")
endpoint = os.environ["AZURE_SEARCH_ENDPOINT"]
credential = DefaultAzureCredential()
knowledge_source_name = os.getenv("AZURE_SEARCH_KNOWLEDGE_SOURCE_NAME", "earth-knowledge-source")
index_name = os.getenv("AZURE_SEARCH_INDEX", "earth-at-night")
azure_openai_endpoint = os.environ["AZURE_OPENAI_ENDPOINT"]
azure_openai_embedding_deployment = os.getenv("AZURE_OPENAI_EMBEDDING_DEPLOYMENT", "text-embedding-3-large")
azure_openai_embedding_model = os.getenv("AZURE_OPENAI_EMBEDDING_MODEL", "text-embedding-3-large")
base_name = os.getenv("AZURE_SEARCH_AGENT_NAME", "earth-knowledge-base")

# Parse the resource ID to extract subscription and other components
parsed_resource_id = parse_resource_id(project_resource_id)
subscription_id = parsed_resource_id['subscription']
resource_group = parsed_resource_id['resource_group']
account_name = parsed_resource_id['name']
project_name = parsed_resource_id['child_name_1']

検索インデックスを作成する

Azure AI 検索では、インデックスはデータの構造化コレクションです。 次のコードでは、ナレッジ ベースの検索可能なコンテンツを格納するインデックスを作成します。

インデックス スキーマには、ドキュメントの識別とページの内容、埋め込み、および数値のフィールドが含まれています。 スキーマには、セマンティック ランク付けとベクター検索の構成も含まれています。この構成では、 text-embedding-3-large デプロイを使用してテキストをベクター化し、セマンティックの類似性に基づいてドキュメントを照合します。

この手順の詳細については、「Azure AI 検索を参照してください。

from azure.search.documents.indexes import SearchIndexClient
from azure.search.documents.indexes.models import (
    AzureOpenAIVectorizer, AzureOpenAIVectorizerParameters,
    HnswAlgorithmConfiguration, SearchField, SearchIndex,
    SemanticConfiguration, SemanticField, SemanticPrioritizedFields,
    SemanticSearch, VectorSearch, VectorSearchProfile
)

index = SearchIndex(
    name=index_name,
    fields=[
        SearchField(name="id", type="Edm.String", key=True, filterable=True, sortable=True, facetable=True),
        SearchField(name="page_chunk", type="Edm.String", filterable=False, sortable=False, facetable=False),
        SearchField(name="page_embedding_text_3_large", type="Collection(Edm.Single)", stored=False, vector_search_dimensions=3072, vector_search_profile_name="hnsw_text_3_large"),
        SearchField(name="page_number", type="Edm.Int32", filterable=True, sortable=True, facetable=True)
    ],
    vector_search=VectorSearch(
        profiles=[VectorSearchProfile(name="hnsw_text_3_large", algorithm_configuration_name="alg", vectorizer_name="azure_openai_text_3_large")],
        algorithms=[HnswAlgorithmConfiguration(name="alg")],
        vectorizers=[
            AzureOpenAIVectorizer(
                vectorizer_name="azure_openai_text_3_large",
                parameters=AzureOpenAIVectorizerParameters(
                    resource_url=azure_openai_endpoint,
                    deployment_name=azure_openai_embedding_deployment,
                    model_name=azure_openai_embedding_model
                )
            )
        ]
    ),
    semantic_search=SemanticSearch(
        default_configuration_name="semantic_config",
        configurations=[
            SemanticConfiguration(
                name="semantic_config",
                prioritized_fields=SemanticPrioritizedFields(
                    content_fields=[
                        SemanticField(field_name="page_chunk")
                    ]
                )
            )
        ]
    )
)

index_client = SearchIndexClient(endpoint=endpoint, credential=credential)
index_client.create_or_update_index(index)
print(f"Index '{index_name}' created or updated successfully")

ドキュメントをインデックスにアップロードする

現在、インデックスは空です。 次のコードは、NASA の Earth at Night 電子書籍の JSON ドキュメントをインデックスに設定します。 Azure AI 検索で必要に応じて、各ドキュメントはインデックス スキーマで定義されているフィールドとデータ型に準拠します。

この手順の詳細については、「 データをインデックスにプッシュする」を参照してください。

import requests
from azure.search.documents import SearchIndexingBufferedSender

url = "https://raw.githubusercontent.com/Azure-Samples/azure-search-sample-data/refs/heads/main/nasa-e-book/earth-at-night-json/documents.json"
documents = requests.get(url).json()

with SearchIndexingBufferedSender(endpoint=endpoint, index_name=index_name, credential=credential) as client:
    client.upload_documents(documents=documents)

print(f"Documents uploaded to index '{index_name}'")

ナレッジ ソースを作成する

ナレッジ ソースは、ソース データへの再利用可能な参照です。 次のコードは、前に作成したインデックスを対象とするナレッジ ソースを作成します。

source_data_fields は、引用文献に含まれるインデックス フィールドを指定します。 この例には、応答に長く解釈できない埋め込みを回避するために、人間が判読できるフィールドのみが含まれています。

この手順の詳細については、「 検索インデックスナレッジ ソースの作成」を参照してください。

from azure.search.documents.indexes import SearchIndexClient
from azure.search.documents.indexes.models import (
    SearchIndexFieldReference, SearchIndexKnowledgeSource,
    SearchIndexKnowledgeSourceParameters
)

ks = SearchIndexKnowledgeSource(
    name=knowledge_source_name,
    description="Knowledge source for Earth at night data",
    search_index_parameters=SearchIndexKnowledgeSourceParameters(
        search_index_name=index_name,
        semantic_configuration_name="semantic_config",
        source_data_fields=[
            SearchIndexFieldReference(name="id"),
            SearchIndexFieldReference(name="page_chunk"),
            SearchIndexFieldReference(name="page_number")
        ]
    ),
)

index_client = SearchIndexClient(endpoint=endpoint, credential=credential)
index_client.create_or_update_knowledge_source(knowledge_source=ks)
print(f"Knowledge source '{knowledge_source_name}' created or updated successfully.")

ナレッジ ベースを作成する

次のコードは、知識ベースを作成し、知識ソースからのエージェントによる情報検索を体系的に調整します。 このコードには、ナレッジ ベースの MCP エンドポイントも格納されます。このエンドポイントは、エージェントがナレッジ ベースへのアクセスに使用します。

Foundry Agent Service と統合するために、ナレッジ ベースは次のパラメーターで構成されます。

  • output_mode(プレビュー)は抽出的データに設定されており、エージェントが根拠付けと推論を行えるよう、そのままの未加工の内容を提供します。 代替モードである応答合成は、ソース コンテンツに対するエージェントの推論能力を制限する事前生成された回答を返します。

  • retrieval_reasoning_effort (プレビュー) は最小限の作業量に設定され、LLM ベースのクエリ計画をバイパスしてコストと待機時間を削減します。 その他の理由から、ナレッジ ベースは LLM を使用して、取得前にユーザー クエリを再調整します。

この手順の詳細については、「Azure AI 検索を参照してください。

from azure.search.documents.indexes import SearchIndexClient
from azure.search.documents.indexes.models import KnowledgeBase, KnowledgeSourceReference
from azure.search.documents.knowledgebases.models import KnowledgeRetrievalMinimalReasoningEffort

knowledge_base = KnowledgeBase(
    name=base_name,
    knowledge_sources=[
        KnowledgeSourceReference(
            name=knowledge_source_name
        )
    ],
    output_mode="extractiveData",
    retrieval_reasoning_effort=KnowledgeRetrievalMinimalReasoningEffort()
)


index_client = SearchIndexClient(endpoint=endpoint, credential=credential)
index_client.create_or_update_knowledge_base(knowledge_base=knowledge_base)
print(f"Knowledge base '{base_name}' created or updated successfully")

mcp_endpoint = f"{endpoint.rstrip('/')}/knowledgebases/{base_name}/mcp?api-version=2026-08-01-preview"

プロジェクト クライアントを設定する

AIProjectClient を使用して、Microsoft Foundry プロジェクトへのクライアント接続を作成します。 プロジェクトにエージェントがまだ含まれていない可能性がありますが、このチュートリアルを既に完了している場合は、エージェントがここに一覧表示されます。

from azure.ai.projects import AIProjectClient

project_client = AIProjectClient(endpoint=project_endpoint, credential=credential)

list(project_client.agents.list())

プロジェクト接続を作成する

次のコードでは、ナレッジ ベースの MCP エンドポイントを指すMicrosoft Foundry にRemoteTool プロジェクト接続 (プレビュー) を作成します。 この接続では、プロジェクトのマネージド ID を使用して、Azure AI 検索に対する認証を行います。

import requests
from azure.identity import get_bearer_token_provider

bearer_token_provider = get_bearer_token_provider(credential, "https://management.azure.com/.default")
headers = {
    "Authorization": f"Bearer {bearer_token_provider()}",
}

response = requests.put(
    f"https://management.azure.com{project_resource_id}/connections/{project_connection_name}?api-version=2025-10-01-preview",
    headers=headers,
    json={
        "name": project_connection_name,
        "type": "Microsoft.MachineLearningServices/workspaces/connections",
        "properties": {
            "authType": "ProjectManagedIdentity",
            "category": "RemoteTool",
            "target": mcp_endpoint,
            "isSharedToAll": True,
            "audience": "https://search.azure.com/",
            "metadata": { "ApiType": "Azure" }
        }
    }
)

response.raise_for_status()
print(f"Connection '{project_connection_name}' created or updated successfully.")

MCP ツールを使用してエージェントを作成する

Warning

MCP の実装は、攻撃、連鎖的な障害、人間の監視の損失などのリスクの影響を受けやすくなります。 これらのリスクを軽減するには、Microsoftの推奨プラクティスとindustry のベスト プラクティスに従って、MCP サーバーのセキュリティと信頼性を確保し、承認メカニズムを実装し、カスケード動作を監視します。

次のコードでは、MCP ツールで構成されたエージェントを作成します。 エージェントは、ユーザー クエリを受け取ると、MCP ツールを使用してナレッジ ベースを呼び出して、応答の基礎となる関連コンテンツを取得できます。

エージェント定義には、その動作と、前に作成したプロジェクト接続を指定する手順が含まれています。 これらの手順は、実験に基づいて、ナレッジ ベースの呼び出しの精度を最大化し、適切な引用形式を確保するのに効果的です。

この手順の詳細については、「 クイック スタート: 新しいエージェントを作成する」を参照してください。

from azure.ai.projects.models import PromptAgentDefinition, MCPTool

instructions = """
You are a helpful assistant that must use the knowledge base to answer all the questions from user. You must never answer from your own knowledge under any circumstances.
Every answer must always provide annotations for using the MCP knowledge base tool and render them as: `【message_idx:search_idx†source_name】`
If you cannot find the answer in the provided knowledge base you must respond with "I don't know".
"""

mcp_kb_tool = MCPTool(
    server_label="knowledge-base",
    server_url=mcp_endpoint,
    require_approval="never",
    allowed_tools=["knowledge_base_retrieve"],
    project_connection_id=project_connection_name
)

agent = project_client.agents.create_version(
    agent_name=agent_name,
    definition=PromptAgentDefinition(
        model=agent_model,
        instructions=instructions,
        tools=[mcp_kb_tool]
    )
)

print(f"AI agent '{agent_name}' created or updated successfully")

(省略可能)要求ごとのヘッダーを使用してアクセス許可を適用する

いずれかのナレッジ ソースにアクセス許可で保護されたコンテンツが含まれている場合、取得エンジンは結果をフィルター処理して、各ユーザーがアクセスを許可されているドキュメントのみを表示できるようにします。 このフィルター処理を有効にするには、サインインしているユーザーの ID トークンを MCP ツール接続の x-ms-query-source-authorization ヘッダーに転送します。 トークンがない場合、アクセス許可が有効なソースはフィルター処理されていない結果を返します。 詳細については、「 クエリ時にアクセス許可を適用する (プレビュー)」を参照してください。

呼び出しごとに異なるユーザーのトークンを渡すなど、要求ごとに MCP ヘッダーを変更するには、エージェント定義で構造化された入力を宣言し、ツールのheadersで{{placeholder}}として参照します。 呼び出し元は、各呼び出しで値を指定します。 この方法は、プロジェクト接続にバインドされた MCP ツールに対して機能します。

MCP サーバーに対するユーザーごとの承認では、 OAuth ID パススルーを使用することもできます。

次のコードは、MCP ツールが構造化された入力から承認ヘッダーを読み取るように、前の手順からエージェントを更新します。

from azure.ai.projects.models import StructuredInputDefinition

# Reference the token as a placeholder in the header
mcp_kb_tool = MCPTool(
    server_label="knowledge-base",
    server_url=mcp_endpoint,
    require_approval="never",
    allowed_tools=["knowledge_base_retrieve"],
    project_connection_id=project_connection_name,
    headers={
        "x-ms-query-source-authorization": "{{search_auth_token}}"
    }
)

# Declare the structured input so the caller can supply the token per request
agent = project_client.agents.create_version(
    agent_name=agent_name,
    definition=PromptAgentDefinition(
        model=agent_model,
        instructions=instructions,
        tools=[mcp_kb_tool],
        structured_inputs={
            "search_auth_token": StructuredInputDefinition(
                description="Per-user Azure AI Search bearer token",
                required=True,
                schema={"type": "string"},
            )
        }
    )
)

print(f"AI agent '{agent_name}' created or updated successfully")

エージェントを呼び出すときは、structured_inputsでAzure AI 検索 トークンを指定します。 この例では、現在の credentialからトークンを解決します。 マルチユーザー アプリの場合は、代わりにサインインしている各ユーザーのトークンを渡します。 たとえば、代理フローを通じて取得されたトークンを使用して、取得エンジンがそのユーザーの結果をフィルター処理できるようにします。

# Resolve an Azure AI Search token from the current credential (use a per-user token in production)
from azure.identity import get_bearer_token_provider

search_token = get_bearer_token_provider(credential, "https://search.azure.com/.default")()

openai_client = project_client.get_openai_client()
conversation = openai_client.conversations.create()

response = openai_client.responses.create(
    conversation=conversation.id,
    tool_choice="required",
    input="{user_query}",
    extra_body={
        "agent_reference": {"name": agent.name, "type": "agent_reference"},
        "structured_inputs": {"search_auth_token": search_token},
    },
)

print(f"Response: {response.output_text}")

エージェントとのチャット

クライアント アプリは、Conversations と Responses API Azure OpenAI を使用してエージェントと対話します。

次のコードでは、会話を作成し、一般的なチャット エクスペリエンスに似たユーザー メッセージをエージェントに渡します。 エージェントは、MCP ツールを使用してナレッジ ベースを呼び出すタイミングを決定し、参照を含む自然言語の回答を返します。 tool_choice="required"設定すると、エージェントがクエリの処理時に常にナレッジ ベース ツールを使用できるようになります。

# Get the OpenAI client for responses and conversations
openai_client = project_client.get_openai_client()

conversation = openai_client.conversations.create()

# Send initial request that will trigger the MCP tool
response = openai_client.responses.create(
    conversation=conversation.id,
    tool_choice="required",
    input="""
        Why do suburban belts display larger December brightening than urban cores even though absolute light levels are higher downtown?
        Why is the Phoenix nighttime street grid is so sharply visible from space, whereas large stretches of the interstate between midwestern cities remain comparatively dim?
    """,
    extra_body={"agent_reference": {"name": agent.name, "type": "agent_reference"}},
)

print(f"Response: {response.output_text}")

応答は、次の例のようになります。

Response: Here are evidence-based explanations to your questions:

---

**1. Why do suburban belts display larger December brightening than urban cores, even though absolute light levels are higher downtown?**

- Suburban belts show a *larger percentage increase* in night brightness during December compared to urban cores, largely because suburban residential areas feature more single-family homes and larger yards, which are typically decorated with holiday lights. These areas start from a lower baseline (less bright overall at night compared to dense urban centers), so the relative change (brightening) is much more noticeable.

- In contrast, the downtown core is already very bright at night due to dense commercial lighting and streetlights. While it also sees a December increase (often 20–30% brighter), the *absolute* change is less striking because it begins at a much higher base of illumination.

- This pattern is observed across U.S. cities, with the phenomenon driven by widespread cultural practices and the suburban landscape’s suitability for holiday lighting displays. The effect is visible in satellite data and was quantified at 20–50% brighter in December, especially in suburbs and city outskirts.

---

**2. Why is the Phoenix nighttime street grid so sharply visible from space, whereas large stretches of the interstate between midwestern cities remain comparatively dim?**

- Phoenix’s sharply visible nighttime street grid from space is a result of its urban layout: the city (like many western U.S. cities) was developed using a regular grid system, with extensive and uniform street lighting and strong urban sprawl. The grid pattern, and the dense network of intersecting surface streets, is brightly illuminated, particularly at intersections, commercial areas, and major thoroughfares.

- The interstate highways between midwestern cities, though significant in length and crucial to national infrastructure, traverse sparsely populated rural areas. These stretches typically have very little artificial lighting (due to low traffic volumes at night and cost considerations), making them much less visible in nighttime satellite imagery. Only nodes (cities and towns) along the route show as bright "pearls" in the darkness, while the "strings" (highways) connecting them remain faint or invisible.

- In summary:
  - Urban areas like Phoenix stand out with strong, connected patterns of light due to dense development and extensive lighting.
  - Rural interstates are sparsely lit, and only their endpoints—cities and large towns—generate notable light visible from space.

---

**References**:
- [Holiday Lights increase most dramatically in suburbs, not downtowns: earth_at_night_508_page_176_verbalized, page 160](4:5)
- [Lighting paths and urban grids are visible from space, while rural highways remain dim: earth_at_night_508_page_124_verbalized, page 108](4:3)
- [Phoenix’s grid and surrounding urban structure: earth_at_night_508_page_104_verbalized, page 88](4:1)

応答を検査する

エージェントからの基になる応答には、ナレッジ ベースに送信されたクエリと、見つかった引用文献に関するメタデータが含まれています。 このメタデータを調べて、エージェントがユーザー入力をどのように処理したかを理解できます。

response.to_dict()

リソースのクリーンアップ

自分のサブスクリプションで作業する場合は、不要になったリソースを削除してプロジェクトを完了することをお勧めします。 リソースが稼働し続けていると、コストが発生する可能性があります。

Azure ポータルで、左側のウィンドウから [すべてのリソース] または [リソース グループ を選択して、リソースを検索および管理します。 リソースを個別に削除することも、リソース グループを削除してすべてのリソースを一度に削除することもできます。

次のコードを実行して、個々のオブジェクトを削除することもできます。

# Delete the agent
project_client.agents.delete_version(agent.name, agent.version)
print(f"AI agent '{agent.name}' version '{agent.version}' deleted successfully")

# Delete the knowledge base
index_client.delete_knowledge_base(base_name)
print(f"Knowledge base '{base_name}' deleted successfully")

# Delete the knowledge source
index_client.delete_knowledge_source(knowledge_source=knowledge_source_name)
print(f"Knowledge source '{knowledge_source_name}' deleted successfully.")

# Delete the search index
index_client.delete_index(index_name)
print(f"Index '{index_name}' deleted successfully")

データ品質の向上

既定では、ナレッジ ベースの検索結果は、グラウンディングのためにエージェントに渡せる1つの大きな統合文字列にまとめられます。 Azure AI 検索には、高品質の結果を生成するのに役立つ、次のインデックス作成と関連性チューニング機能が用意されています。 これらの機能は検索インデックスに実装できます。検索の関連性の向上は、取得応答の品質に明らかです。

  • スコアリング プロファイル には、組み込みのブースト条件が用意されています。 インデックスでは、既定のスコアリング プロファイルを指定する必要があります。このプロファイルは、クエリにそのプロファイルに関連付けられているフィールドがクエリに含まれるときに取得エンジンによって使用されます。

  • セマンティック構成 は必須ですが、優先順位を付けてランク付けに使用するフィールドを決定します。

  • プレーンテキスト コンテンツの場合、 アナライザー を使用してインデックス作成中のトークン化を制御できます。

  • マルチモーダルまたは画像コンテンツの場合、画像の記述をLLMで生成し、インデックス作成中にスキルセットを使用して従来のOCRや画像分析を行えます。

サブクエリの数を制御する

ナレッジ ベースで 取得理由作業 (プレビュー) を設定 することで、サブクエリの数を制御できます。 推論作業によって、クエリ計画の LLM 処理のレベルが決まります。これは、最小 (LLM 処理なし) から中 (より深い検索とフォローアップの反復) までです。

非最小の推論作業では、LLM は次の要因に基づいてサブクエリの数を決定します。

  • ユーザー クエリ
  • チャット履歴
  • セマンティック ランカー入力制約

エージェントに送信されるコンテキストを制御する

Responses API は、エージェントとナレッジ ベースに送信される内容を制御します。 パフォーマンスと関連性を最適化するには、MCP ツールに送信する前に、エージェントの指示を調整してチャット履歴を要約またはフィルター処理します。

コストを制御し、操作を制限する

クエリ プランに関する分析情報については、ナレッジ ベース応答の アクティビティ配列 の出力トークンを参照してください。

パフォーマンスの向上

パフォーマンスを最適化し、待機時間を短縮するには、次の戦略を検討してください。

  • メッセージ スレッドを要約します。

  • gpt-5-miniを使用するか、より高速に実行する小規模なモデルを使用します。

  • 取得maxOutputSizeにを設定して、時間制限処理の応答またはmaxRuntimeInSecondsのサイズを制御します。

  • インデックスを作成する前に、大きなドキュメントをより小さな部分にチャンクします。 出力予算を超えるドキュメントは、 固定された結果から暗黙的に省略できます。