你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

快速入门:在 Azure AI 搜索中使用智能体检索

注释

此功能目前处于公开预览状态。 此预览版未随附服务级别协议,建议不要用于生产工作负载。 某些功能可能不受支持或者受限。 有关详细信息,请参阅 Microsoft Azure 预览版补充使用条款

在本快速入门中,你将使用智能体检索创建对话搜索体验,该体验由 Azure AI 搜索中索引的文档和 Azure AI Foundry 模型中的 Azure OpenAI 大型语言模型 (LLM) 提供支持。

知识智能体通过将复杂的查询分解为子查询,对一个或多个知识源执行这些子查询,并返回包含元数据的检索结果,从而实现智能体检索。 默认情况下,该智能体会输出源内容中的原始数据,但本快速入门教程使用“答案生成”模式来生成自然语言的答案。

虽然可以提供你自己的数据,但本快速入门使用了美国宇航局“夜间地球”电子书中的示例 JSON 文档。 这些文件描述了一般科学主题,以及从太空观测到的夜晚地球的图像。

小窍门

想要立即开始? 请参阅 GitHub 上的 azure-search-dotnet-samples 存储库。

先决条件

配置访问权限

在开始之前,请确保你有权访问内容和操作。 我们建议使用 Microsoft Entra ID 进行身份验证,并使用基于角色的访问控制进行授权。 你必须是“所有者”或“用户访问管理员”才能分配角色。 如果角色设置不可行,请改用基于密钥的身份验证方式

若要配置此快速入门的访问权限,请选择以下两个选项卡。

Azure AI 搜索提供智能体检索管道。 配置自己和搜索服务的访问权限,以读取和写入数据、与 Azure AI Foundry 交互以及运行管道。

配置 Azure AI 搜索的访问权限:

  1. 登录到 Azure 门户 并选择搜索服务。

  2. 启用基于角色的访问

  3. 创建系统分配的托管标识

  4. 将以下角色分配给自己。

    • 搜索服务参与者

    • 搜索索引数据参与者

    • 搜索索引数据读取者

重要

代理检索具有两种基于标记的计费模型:

  • Azure AI 搜索的语义排序功能的收费标准。
  • Azure OpenAI 的查询规划和答案生成功能收费标准。

语义排名在初始公共预览版中是免费的。 预览版后,将应用标准标记计费。 有关详细信息,请参阅 代理检索的可用性和定价

获取终结点

每个 Azure AI 搜索服务和 Azure AI Foundry 资源都有一个终结点,该终结点是唯一的 URL,用于标识和提供对资源的网络访问权限。 在后面的部分中,指定这些终结点以便通过编程方式连接到你的资源。

若要获取本快速入门的终结点,请选择以下两个选项卡。

  1. 登录到 Azure 门户 并选择搜索服务。

  2. 在左窗格中,选择“ 概述”。

  3. 记下终结点,形式应与 https://my-service.search.windows.net 类似。

部署模型

若要使用智能体检索,必须将两个 Azure OpenAI 模型部署到 Azure AI Foundry 资源:

  • 用于文本到矢量转换的嵌入模型。 本快速入门使用 text-embedding-3-large,但您可以使用任何 text-embedding 模型。

  • 用于查询规划和答案生成的 LLM。 本快速入门使用的是 gpt-5-mini,但你也可以使用任何受支持的具备智能体检索的 LLM

有关部署说明,请参阅 使用 Azure AI Foundry 部署 Azure OpenAI 模型

设置环境

若要为本快速入门设置控制台应用程序,请执行以下作:

  1. 创建一个名为 quickstart-agentic-retrieval 包含应用程序的文件夹。

  2. 在 Visual Studio Code 中打开该文件夹。

  3. 选择 “终端>新建终端”,然后运行以下命令以创建控制台应用程序。

    dotnet new console
    
  4. 安装适用于 .NET 的 Azure AI 搜索客户端库

    dotnet add package Azure.Search.Documents --version 11.7.0-beta.7
    
  5. 安装包 dotenv.net 以从 .env 文件加载环境变量。

    dotnet add package dotenv.net
    
  6. 若要使用 Microsoft Entra ID 进行无密钥身份验证,请安装 Azure.Identity 包。

    dotnet add package Azure.Identity
    
  7. 若要使用 Microsoft Entra ID 进行无密钥身份验证,请登录到 Azure 帐户。 如果有多个订阅,请选择包含 Azure AI 搜索服务和 Azure AI Foundry 项目的订阅。

    az login
    

运行代码

若要创建并运行代理检索管道,请执行以下操作:

  1. .env文件夹中创建一个名为quickstart-agentic-retrieval的文件。

  2. 将以下环境变量添加到 .env 该文件。

    SEARCH_ENDPOINT = PUT-YOUR-SEARCH-SERVICE-URL-HERE
    AOAI_ENDPOINT = PUT-YOUR-AOAI-FOUNDRY-URL-HERE
    
  3. SEARCH_ENDPOINTAOAI_ENDPOINT 的值设置为你在获取终结点时获取的值。

  4. 将以下代码粘贴到 Program.cs 文件中。

    using dotenv.net;
    using System.Text.Json;
    using Azure.Identity;
    using Azure.Search.Documents;
    using Azure.Search.Documents.Indexes;
    using Azure.Search.Documents.Indexes.Models;
    using Azure.Search.Documents.Models;
    using Azure.Search.Documents.Agents;
    using Azure.Search.Documents.Agents.Models;
    
    namespace AzureSearch.Quickstart
    {
        class Program
        {
            static async Task Main(string[] args)
            {
                // Load environment variables from the .env file
                // Ensure your .env file is in the same directory with the required variables
                DotEnv.Load();
    
                string searchEndpoint = Environment.GetEnvironmentVariable("SEARCH_ENDPOINT")
                    ?? throw new InvalidOperationException("SEARCH_ENDPOINT isn't set.");
                string aoaiEndpoint = Environment.GetEnvironmentVariable("AOAI_ENDPOINT")
                    ?? throw new InvalidOperationException("AOAI_ENDPOINT isn't set.");
    
                string aoaiEmbeddingModel = "text-embedding-3-large";
                string aoaiEmbeddingDeployment = "text-embedding-3-large";
                string aoaiGptModel = "gpt-5-mini";
                string aoaiGptDeployment = "gpt-5-mini";
    
                string indexName = "earth-at-night";
                string knowledgeSourceName = "earth-knowledge-source";
                string knowledgeAgentName = "earth-knowledge-agent";
    
                var credential = new DefaultAzureCredential();
    
                // Define fields for the index
                var fields = new List<SearchField>
                {
                    new SimpleField("id", SearchFieldDataType.String) { IsKey = true, IsFilterable = true, IsSortable = true, IsFacetable = true },
                    new SearchField("page_chunk", SearchFieldDataType.String) { IsFilterable = false, IsSortable = false, IsFacetable = false },
                    new SearchField("page_embedding_text_3_large", SearchFieldDataType.Collection(SearchFieldDataType.Single)) { VectorSearchDimensions = 3072, VectorSearchProfileName = "hnsw_text_3_large" },
                    new SimpleField("page_number", SearchFieldDataType.Int32) { IsFilterable = true, IsSortable = true, IsFacetable = true }
                };
    
                // Define a vectorizer
                var vectorizer = new AzureOpenAIVectorizer(vectorizerName: "azure_openai_text_3_large")
                {
                    Parameters = new AzureOpenAIVectorizerParameters
                    {
                        ResourceUri = new Uri(aoaiEndpoint),
                        DeploymentName = aoaiEmbeddingDeployment,
                        ModelName = aoaiEmbeddingModel
                    }
                };
    
                // Define a vector search profile and algorithm
                var vectorSearch = new VectorSearch()
                {
                    Profiles =
                    {
                        new VectorSearchProfile(
                            name: "hnsw_text_3_large",
                            algorithmConfigurationName: "alg"
                        )
                        {
                            VectorizerName = "azure_openai_text_3_large"
                        }
                    },
                    Algorithms =
                    {
                        new HnswAlgorithmConfiguration(name: "alg")
                    },
                    Vectorizers =
                    {
                        vectorizer
                    }
                };
    
                // Define a semantic configuration
                var semanticConfig = new SemanticConfiguration(
                    name: "semantic_config",
                    prioritizedFields: new SemanticPrioritizedFields
                    {
                        ContentFields = { new SemanticField("page_chunk") }
                    }
                );
    
                var semanticSearch = new SemanticSearch()
                {
                    DefaultConfigurationName = "semantic_config",
                    Configurations = { semanticConfig }
                };
    
                // Create the index
                var index = new SearchIndex(indexName)
                {
                    Fields = fields,
                    VectorSearch = vectorSearch,
                    SemanticSearch = semanticSearch
                };
    
                // Create the index client, deleting and recreating the index if it exists
                var indexClient = new SearchIndexClient(new Uri(searchEndpoint), credential);
                await indexClient.CreateOrUpdateIndexAsync(index);
                Console.WriteLine($"Index '{indexName}' created or updated successfully.");
    
                // Upload sample documents from the GitHub URL
                string url = "https://raw.githubusercontent.com/Azure-Samples/azure-search-sample-data/refs/heads/main/nasa-e-book/earth-at-night-json/documents.json";
                var httpClient = new HttpClient();
                var response = await httpClient.GetAsync(url);
                response.EnsureSuccessStatusCode();
                var json = await response.Content.ReadAsStringAsync();
                var documents = JsonSerializer.Deserialize<List<Dictionary<string, object>>>(json);
                var searchClient = new SearchClient(new Uri(searchEndpoint), indexName, credential);
                var searchIndexingBufferedSender = new SearchIndexingBufferedSender<Dictionary<string, object>>(
                    searchClient,
                    new SearchIndexingBufferedSenderOptions<Dictionary<string, object>>
                    {
                        KeyFieldAccessor = doc => doc["id"].ToString(),
                    }
                );
                await searchIndexingBufferedSender.UploadDocumentsAsync(documents);
                await searchIndexingBufferedSender.FlushAsync();
                Console.WriteLine($"Documents uploaded to index '{indexName}' successfully.");
    
                // Create a knowledge source
                var indexKnowledgeSource = new SearchIndexKnowledgeSource(
                    name: knowledgeSourceName,
                    searchIndexParameters: new SearchIndexKnowledgeSourceParameters(searchIndexName: indexName)
                    {
                        SourceDataSelect = "id,page_chunk,page_number"
                    }
                );
                await indexClient.CreateOrUpdateKnowledgeSourceAsync(indexKnowledgeSource);
                Console.WriteLine($"Knowledge source '{knowledgeSourceName}' created or updated successfully.");
    
                // Create a knowledge agent
                var openAiParameters = new AzureOpenAIVectorizerParameters
                {
                    ResourceUri = new Uri(aoaiEndpoint),
                    DeploymentName = aoaiGptDeployment,
                    ModelName = aoaiGptModel
                };
    
                var agentModel = new KnowledgeAgentAzureOpenAIModel(azureOpenAIParameters: openAiParameters);
                var outputConfig = new KnowledgeAgentOutputConfiguration
                {
                    Modality = KnowledgeAgentOutputConfigurationModality.AnswerSynthesis,
                    IncludeActivity = true
                };
    
                var agent = new KnowledgeAgent(
                    name: knowledgeAgentName,
                    models: new[] { agentModel },
                    knowledgeSources: new KnowledgeSourceReference[] {
                    new KnowledgeSourceReference(knowledgeSourceName) {
                            IncludeReferences = true,
                            IncludeReferenceSourceData = true,
                            RerankerThreshold = (float?)2.5
                        }
                    }
                )
    
                {
                    OutputConfiguration = outputConfig
                };
    
                await indexClient.CreateOrUpdateKnowledgeAgentAsync(agent);
                Console.WriteLine($"Knowledge agent '{knowledgeAgentName}' created or updated successfully.");
    
                // Set up messages
                string instructions = @"A Q&A agent that can answer questions about the Earth at night.
                If you don't have the answer, respond with ""I don't know"".";
    
                var messages = new List<Dictionary<string, string>>
                {
                    new Dictionary<string, string>
                    {
                        { "role", "system" },
                        { "content", instructions }
                    }
                };
    
                // Use agentic retrieval to fetch results
                var agentClient = new KnowledgeAgentRetrievalClient(
                    endpoint: new Uri(searchEndpoint),
                    agentName: knowledgeAgentName,
                    tokenCredential: new DefaultAzureCredential()
                );
    
                messages.Add(new Dictionary<string, string>
                {
                    { "role", "user" },
                    { "content", @"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?" }
                });
    
                var retrievalResult = await agentClient.RetrieveAsync(
                    retrievalRequest: new KnowledgeAgentRetrievalRequest(
                        messages: messages
                            .Where(message => message["role"] != "system")
                            .Select(
                                message => new KnowledgeAgentMessage(content: new[] { new KnowledgeAgentMessageTextContent(message["content"]) }) { Role = message["role"] }
                            )
                            .ToList()
                    )
                );
    
                messages.Add(new Dictionary<string, string>
                {
                    { "role", "assistant" },
                    { "content", (retrievalResult.Value.Response[0].Content[0] as KnowledgeAgentMessageTextContent).Text }
                });
    
                // Print the response, activity, and results
                Console.WriteLine("Response:");
                Console.WriteLine((retrievalResult.Value.Response[0].Content[0] as KnowledgeAgentMessageTextContent).Text);
    
                Console.WriteLine("Activity:");
                foreach (var activity in retrievalResult.Value.Activity)
                {
                    Console.WriteLine($"Activity Type: {activity.GetType().Name}");
                    string activityJson = JsonSerializer.Serialize(
                        activity,
                        activity.GetType(),
                        new JsonSerializerOptions { WriteIndented = true }
                    );
                    Console.WriteLine(activityJson);
                }
    
                Console.WriteLine("Results:");
                foreach (var reference in retrievalResult.Value.References)
                {
                    Console.WriteLine($"Reference Type: {reference.GetType().Name}");
                    string referenceJson = JsonSerializer.Serialize(
                        reference,
                        reference.GetType(),
                        new JsonSerializerOptions { WriteIndented = true }
                    );
                    Console.WriteLine(referenceJson);
                }
    
                // Continue the conversation
                messages.Add(new Dictionary<string, string>
                {
                    { "role", "user" },
                    { "content", "How do I find lava at night?" }
                });
    
                retrievalResult = await agentClient.RetrieveAsync(
                    retrievalRequest: new KnowledgeAgentRetrievalRequest(
                        messages: messages
                            .Where(message => message["role"] != "system")
                            .Select(
                                message => new KnowledgeAgentMessage(content: new[] { new KnowledgeAgentMessageTextContent(message["content"]) }) { Role = message["role"] }
                            )
                            .ToList()
                    )
                );
    
                messages.Add(new Dictionary<string, string>
                {
                    { "role", "assistant" },
                    { "content", (retrievalResult.Value.Response[0].Content[0] as KnowledgeAgentMessageTextContent).Text }
                });
    
                // Print the new response, activity, and results
                Console.WriteLine("Response:");
                Console.WriteLine((retrievalResult.Value.Response[0].Content[0] as KnowledgeAgentMessageTextContent).Text);
    
                Console.WriteLine("Activity:");
                foreach (var activity in retrievalResult.Value.Activity)
                {
                    Console.WriteLine($"Activity Type: {activity.GetType().Name}");
                    string activityJson = JsonSerializer.Serialize(
                        activity,
                        activity.GetType(),
                        new JsonSerializerOptions { WriteIndented = true }
                    );
                    Console.WriteLine(activityJson);
                }
    
                Console.WriteLine("Results:");
                foreach (var reference in retrievalResult.Value.References)
                {
                    Console.WriteLine($"Reference Type: {reference.GetType().Name}");
                    string referenceJson = JsonSerializer.Serialize(
                        reference,
                        reference.GetType(),
                        new JsonSerializerOptions { WriteIndented = true }
                    );
                    Console.WriteLine(referenceJson);
                }
    
                // Clean up resources
                await indexClient.DeleteKnowledgeAgentAsync(knowledgeAgentName);
                Console.WriteLine($"Knowledge agent '{knowledgeAgentName}' deleted successfully.");
    
                await indexClient.DeleteKnowledgeSourceAsync(knowledgeSourceName);
                Console.WriteLine($"Knowledge source '{knowledgeSourceName}' deleted successfully.");
    
                await indexClient.DeleteIndexAsync(indexName);
                Console.WriteLine($"Index '{indexName}' deleted successfully.");
            }
        }
    }
    
  5. 生成并运行应用程序。

    dotnet run
    

输出

应用程序的输出应如下所示:

Index 'earth-at-night' created or updated successfully.
Documents uploaded to index 'earth-at-night' successfully.
Knowledge source 'earth-knowledge-source' created or updated successfully.
Knowledge agent 'earth-knowledge-agent' created or updated successfully.
Response:
Suburban belts display larger December brightening than urban cores because holiday lights increase most dramatically in the suburbs and outskirts of major cities, where there is more yard space and a prevalence of single-family homes. Central urban areas, despite having higher absolute light levels, do not see as large an increase in lighting but still experience a brightening of 20 to 30 percent during the holidays [ref_id:2][ref_id:7].

The Phoenix nighttime street grid is sharply visible from space because the metropolitan area is laid out along a regular grid of city blocks and streets, with street lighting clearly visible from low-Earth orbit. The grid pattern is especially evident at night, with major street grids oriented north-south and diagonal corridors like Grand Avenue cutting across cities. The urban grid encourages outward growth along city borders, with extensive surface streets and freeways linking multiple municipalities. In contrast, large stretches of interstate highways between Midwestern cities remain comparatively dim because, although the interstate highways are major transportation corridors, the lighting along these highways is less intense and less continuous than the dense urban street lighting seen in Phoenix. Additionally, navigable rivers and less densely populated areas show less light, indicating that the brightness corresponds closely to urban density and street lighting patterns rather than just the presence of transportation routes [ref_id:0][ref_id:1][ref_id:4].
Activity:
Activity type: KnowledgeAgentModelQueryPlanningActivityRecord
{
  "InputTokens": 2062,
  "OutputTokens": 121,
  "Id": 0,
  "ElapsedMs": 2435
}
Activity type: KnowledgeAgentSearchIndexActivityRecord
{
  "SearchIndexArguments": {
    "Search": "Reasons for larger December brightening in suburban belts compared to urban cores despite higher downtown light levels",      
    "Filter": null
  },
  "KnowledgeSourceName": "earth-knowledge-source",
  "QueryTime": "2025-09-22T15:54:56.528+00:00",
  "Count": 4,
  "Id": 1,
  "ElapsedMs": 1921
}
Activity type: KnowledgeAgentSearchIndexActivityRecord
{
  "SearchIndexArguments": {
    "Search": "Factors making Phoenix nighttime street grid sharply visible from space",
    "Filter": null
  },
  "KnowledgeSourceName": "earth-knowledge-source",
  "QueryTime": "2025-09-22T15:55:06.991+00:00",
  "Count": 5,
  "Id": 2,
  "ElapsedMs": 10451
}
Activity type: KnowledgeAgentSearchIndexActivityRecord
{
  "SearchIndexArguments": {
    "Search": "Reasons why large stretches of interstate between Midwestern cities appear comparatively dim at night from space",
    "Filter": null
  },
  "KnowledgeSourceName": "earth-knowledge-source",
  "QueryTime": "2025-09-22T15:55:07.504+00:00",
  "Count": 13,
  "Id": 3,
  "ElapsedMs": 512
}
Activity type: KnowledgeAgentSemanticRerankerActivityRecord
{
  "InputTokens": 68754,
  "Id": 4,
  "ElapsedMs": null
}
Activity type: KnowledgeAgentModelAnswerSynthesisActivityRecord
{
  "InputTokens": 7231,
  "OutputTokens": 279,
  "Id": 5,
  "ElapsedMs": 6429
}
Results:
Reference type: KnowledgeAgentSearchIndexReference
{
  "DocKey": "earth_at_night_508_page_104_verbalized",
  "Id": "0",
  "ActivitySource": 2,
  "SourceData": {
    "id": "earth_at_night_508_page_104_verbalized",
    "page_chunk": "\u003C!-- PageHeader=\u0022Urban Structure\u0022 --\u003E\n\n### Location of Phoenix, Arizona\n\nThe image depicts a globe highlighting the location of Phoenix, Arizona, in the southwestern United States, marked with a blue pinpoint on the map of North America. Phoenix is situated in the central part of Arizona, which is in the southwestern region of the United States.\n\n---\n\n### Grid of City Blocks-Phoenix, Arizona\n\nLike many large urban areas of the central and western United States, the Phoenix metropolitan area is laid out along a regular grid of city blocks and streets. While visible during the day, this grid is most evident at night, when the pattern of street lighting is clearly visible from the low-Earth-orbit vantage point of the ISS.\n\nThis astronaut photograph, taken on March 16, 2013, includes parts of several cities in the metropolitan area, including Phoenix (image right), Glendale (center), and Peoria (left). While the major street grid is oriented north-south, the northwest-southeast oriented Grand Avenue cuts across the three cities at image center. Grand Avenue is a major transportation corridor through the western metropolitan area; the lighting patterns of large industrial and commercial properties are visible along its length. Other brightly lit properties include large shopping centers, strip malls, and gas stations, which tend to be located at the intersections of north-south and east-west trending streets.\n\nThe urban grid encourages growth outwards along a city\u0027s borders by providing optimal access to new real estate. Fueled by the adoption of widespread personal automobile use during the twentieth century, the Phoenix metropolitan area today includes 25 other municipalities (many of them largely suburban and residential) linked by a network of surface streets and freeways.\n\nWhile much of the land area highlighted in this image is urbanized, there are several noticeably dark areas. The Phoenix Mountains are largely public parks and recreational land. To the west, agricultural fields provide a sharp contrast to the lit streets of residential developments. The Salt River channel appears as a dark ribbon within the urban grid.\n\n\n\u003C!-- PageFooter=\u0022Earth at Night\u0022 --\u003E\n\u003C!-- PageNumber=\u002288\u0022 --\u003E",
    "page_number": 104
  },
  "RerankerScore": 2.6642752
}
Reference type: KnowledgeAgentSearchIndexReference
{
  "DocKey": "earth_at_night_508_page_105_verbalized",
  "Id": "3",
  "ActivitySource": 2,
  "SourceData": {
    "id": "earth_at_night_508_page_105_verbalized",
    "page_chunk": "# Urban Structure\n\n## March 16, 2013\n\n### Phoenix Metropolitan Area at Night\n\nThis figure presents a nighttime satellite view of the Phoenix metropolitan area, highlighting urban structure and transport corridors. City lights illuminate the layout of several cities and major thoroughfares.\n\n**Labeled Urban Features:**\n\n- **Phoenix:** Central and brightest area in the right-center of the image.\n- **Glendale:** Located to the west of Phoenix, this city is also brightly lit.\n- **Peoria:** Further northwest, this area is labeled and its illuminated grid is seen.\n- **Grand Avenue:** Clearly visible as a diagonal, brightly lit thoroughfare running from Phoenix through Glendale and Peoria.\n- **Salt River Channel:** Identified in the southeast portion, running through illuminated sections.\n- **Phoenix Mountains:** Dark, undeveloped region to the northeast of Phoenix.\n- **Agricultural Fields:** Southwestern corner of the image, grid patterns are visible but with much less illumination, indicating agricultural land use.\n\n**Additional Notes:**\n\n- The overall pattern shows a grid-like urban development typical of western U.S. cities, with scattered bright nodes at major intersections or city centers.\n- There is a clear transition from dense urban development to sparsely populated or agricultural land, particularly evident towards the bottom and left of the image.\n- The illuminated areas follow the existing road and street grids, showcasing the extensive spread of the metropolitan area.\n\n**Figure Description:**  \nA satellite nighttime image captured on March 16, 2013, showing Phoenix and surrounding areas (including Glendale and Peoria). Major landscape and infrastructural features, such as the Phoenix Mountains, Grand Avenue, the Salt River Channel, and agricultural fields, are labeled. The image reveals the extent of urbanization and the characteristic street grid illuminated by city lights.\n\n---\n\nPage 89",
    "page_number": 105
  },
  "RerankerScore": 2.5905457
}
... // Trimmed for brevity
Response:
Lava can be found at night by using satellite imagery that captures thermal infrared and near-infrared wavelengths, which highlight the heat emitted by active lava flows. For example, the Landsat 8 satellite's night view combines thermal, shortwave infrared, and near-infrared data to distinguish very hot lava (appearing bright white), cooling lava (red), and lava flows obscured by clouds (purple), as demonstrated in the monitoring of Kilauea's lava flows in Hawaii [ref_id:0]. Similarly, the Operational Land Imager (OLI) and Thermal Infrared Sensor (TIRS) on Landsat 8 have been used to detect the thermal infrared signature of lava flows during Mount Etna's flank eruption in Italy, highlighting active vents and lava flows at night [ref_id:1]. Additionally, the VIIRS Day/Night Band (DNB) on polar-orbiting satellites can detect faint light sources such as moonlight, which, combined with thermal data, allows for the observation of glowing lava flows at active volcanoes during nighttime [ref_id:1][ref_id:3]. Thus, by using satellite instruments sensitive to thermal and near-infrared wavelengths and leveraging natural illumination sources like moonlight, lava can be effectively located and monitored at night from space.
Activity:
Activity type: KnowledgeAgentModelQueryPlanningActivityRecord
{
  "InputTokens": 2357,
  "OutputTokens": 88,
  "Id": 0,
  "ElapsedMs": 1917
}
Activity type: KnowledgeAgentSearchIndexActivityRecord
{
  "SearchIndexArguments": {
    "Search": "How to locate lava flows at night",
    "Filter": null
  },
  "KnowledgeSourceName": "earth-knowledge-source",
  "QueryTime": "2025-09-22T15:55:16.919+00:00",
  "Count": 16,
  "Id": 1,
  "ElapsedMs": 433
}
Activity type: KnowledgeAgentSearchIndexActivityRecord
{
  "SearchIndexArguments": {
    "Search": "Methods for detecting lava at night",
    "Filter": null
  },
  "KnowledgeSourceName": "earth-knowledge-source",
  "QueryTime": "2025-09-22T15:55:17.389+00:00",
  "Count": 13,
  "Id": 2,
  "ElapsedMs": 468
}
Activity type: KnowledgeAgentSearchIndexActivityRecord
{
  "SearchIndexArguments": {
    "Search": "Safety tips for finding lava at night",
    "Filter": null
  },
  "KnowledgeSourceName": "earth-knowledge-source",
  "QueryTime": "2025-09-22T15:55:17.801+00:00",
  "Count": 3,
  "Id": 3,
  "ElapsedMs": 411
}
Activity type: KnowledgeAgentSemanticRerankerActivityRecord
{
  "InputTokens": 67218,
  "Id": 4,
  "ElapsedMs": null
}
Activity type: KnowledgeAgentModelAnswerSynthesisActivityRecord
{
  "InputTokens": 7345,
  "OutputTokens": 267,
  "Id": 5,
  "ElapsedMs": 6044
}
Results:
Reference type: KnowledgeAgentSearchIndexReference
{
  "DocKey": "earth_at_night_508_page_60_verbalized",
  "Id": "0",
  "ActivitySource": 1,
  "SourceData": {
    "id": "earth_at_night_508_page_60_verbalized",
    "page_chunk": "\u003C!-- PageHeader=\u0022Volcanoes\u0022 --\u003E\n\n## Volcanoes\n\n### The Infrared Glows of Kilauea\u0027s Lava Flows\u2014Hawaii\n\nIn early May 2018, an eruption on Hawaii\u0027s Kilauea volcano began to unfold. The eruption took a dangerous turn on May 3, 2018, when new fissures opened in the residential neighborhood of Leilani Estates. During the summer-long eruptive event, other fissures emerged along the East Rift Zone. Lava from vents along the rift zone flowed downslope, reaching the ocean in several areas, and filling in Kapoho Bay.\n\nA time series of Landsat 8 imagery shows the progression of the lava flows from May 16 to August 13. The night view combines thermal, shortwave infrared, and near-infrared wavelengths to tease out the very hot lava (bright white), cooling lava (red), and lava flows obstructed by clouds (purple).\n\n#### Figure: Location of Kilauea Volcano, Hawaii\n\nA globe is shown centered on North America, with a marker placed in the Pacific Ocean indicating the location of Hawaii, to the southwest of the mainland United States.\n\n\u003C!-- PageFooter=\u0022Earth at Night\u0022 --\u003E\n\u003C!-- PageNumber=\u002244\u0022 --\u003E",
    "page_number": 60
  },
  "RerankerScore": 2.779123
}
Reference type: KnowledgeAgentSearchIndexReference
{
  "DocKey": "earth_at_night_508_page_64_verbalized",
  "Id": "2",
  "ActivitySource": 1,
  "SourceData": {
    "id": "earth_at_night_508_page_64_verbalized",
    "page_chunk": "\u003C!-- PageHeader=\u0022Volcanoes\u0022 --\u003E\n\n### Nighttime Glow at Mount Etna - Italy\n\nAt about 2:30 a.m. local time on March 16, 2017, the VIIRS DNB on the Suomi NPP satellite captured this nighttime image of lava flowing on Mount Etna in Sicily, Italy. Etna is one of the world\u0027s most active volcanoes.\n\n#### Figure: Location of Mount Etna\nA world globe is depicted, with a marker indicating the location of Mount Etna in Sicily, Italy, in southern Europe near the center of the Mediterranean Sea.\n\n\u003C!-- PageFooter=\u0022Earth at Night\u0022 --\u003E\n\u003C!-- PageNumber=\u002248\u0022 --\u003E",
    "page_number": 64
  },
  "RerankerScore": 2.7684891
}
... // Trimmed for brevity
Knowledge agent 'earth-knowledge-agent' deleted successfully.
Knowledge source 'earth-knowledge-source' deleted successfully.
Index 'earth-at-night' deleted successfully.

了解代码

运行代码后,让我们分解关键步骤:

  1. 创建搜索索引
  2. 将文档上传到索引
  3. 创建知识来源
  4. 创建知识代理
  5. 设置消息
  6. 运行检索管道
  7. 继续对话

创建搜索索引

在 Azure AI 搜索中,索引是结构化数据集合。 以下代码定义了一个名为 earth-at-night 的索引,该索引是您之前使用 indexName 变量指定的。

索引架构包含文档标识和页面内容、嵌入和数字的字段。 该架构还包含用于语义排序和向量搜索的配置,该配置利用你部署的 text-embedding-3-large 模型将文本转换为向量,并根据语义或概念相似度匹配相关文档。

// Define fields for the index
var fields = new List<SearchField>
{
    new SimpleField("id", SearchFieldDataType.String) { IsKey = true, IsFilterable = true, IsSortable = true, IsFacetable = true },
    new SearchField("page_chunk", SearchFieldDataType.String) { IsFilterable = false, IsSortable = false, IsFacetable = false },
    new SearchField("page_embedding_text_3_large", SearchFieldDataType.Collection(SearchFieldDataType.Single)) { VectorSearchDimensions = 3072, VectorSearchProfileName = "hnsw_text_3_large" },
    new SimpleField("page_number", SearchFieldDataType.Int32) { IsFilterable = true, IsSortable = true, IsFacetable = true }
};

// Define a vectorizer
var vectorizer = new AzureOpenAIVectorizer(vectorizerName: "azure_openai_text_3_large")
{
    Parameters = new AzureOpenAIVectorizerParameters
    {
        ResourceUri = new Uri(aoaiEndpoint),
        DeploymentName = aoaiEmbeddingDeployment,
        ModelName = aoaiEmbeddingModel
    }
};

// Define a vector search profile and algorithm
var vectorSearch = new VectorSearch()
{
    Profiles =
    {
        new VectorSearchProfile(
            name: "hnsw_text_3_large",
            algorithmConfigurationName: "alg"
        )
        {
            VectorizerName = "azure_openai_text_3_large"
        }
    },
    Algorithms =
    {
        new HnswAlgorithmConfiguration(name: "alg")
    },
    Vectorizers =
    {
        vectorizer
    }
};

// Define a semantic configuration
var semanticConfig = new SemanticConfiguration(
    name: "semantic_config",
    prioritizedFields: new SemanticPrioritizedFields
    {
        ContentFields = { new SemanticField("page_chunk") }
    }
);

var semanticSearch = new SemanticSearch()
{
    DefaultConfigurationName = "semantic_config",
    Configurations = { semanticConfig }
};

// Create the index
var index = new SearchIndex(indexName)
{
    Fields = fields,
    VectorSearch = vectorSearch,
    SemanticSearch = semanticSearch
};

// Create the index client, deleting and recreating the index if it exists
var indexClient = new SearchIndexClient(new Uri(searchEndpoint), credential);
await indexClient.CreateOrUpdateIndexAsync(index);
Console.WriteLine($"Index '{indexName}' created or updated successfully.");

将文档上传到索引

目前,索引 earth-at-night 为空。 以下代码使用 美国宇航局地球在夜间电子书中的 JSON 文档填充索引。 根据 Azure AI 搜索的要求,每个文档都符合索引架构中定义的字段和数据类型。

// Upload sample documents from the GitHub URL
string url = "https://raw.githubusercontent.com/Azure-Samples/azure-search-sample-data/refs/heads/main/nasa-e-book/earth-at-night-json/documents.json";
var httpClient = new HttpClient();
var response = await httpClient.GetAsync(url);
response.EnsureSuccessStatusCode();
var json = await response.Content.ReadAsStringAsync();
var documents = JsonSerializer.Deserialize<List<Dictionary<string, object>>>(json);
var searchClient = new SearchClient(new Uri(searchEndpoint), indexName, credential);
var searchIndexingBufferedSender = new SearchIndexingBufferedSender<Dictionary<string, object>>(
    searchClient,
    new SearchIndexingBufferedSenderOptions<Dictionary<string, object>>
    {
        KeyFieldAccessor = doc => doc["id"].ToString(),
    }
);
await searchIndexingBufferedSender.UploadDocumentsAsync(documents);
await searchIndexingBufferedSender.FlushAsync();
Console.WriteLine($"Documents uploaded to index '{indexName}' successfully.");

创建知识来源

知识来源是指可重复使用的源数据参考资料。 以下代码定义了一个名为 earth-knowledge-source 的知识源,目标是 earth-at-night 索引。

SourceDataSelect 指定检索和引文可访问的索引字段。 为了避免响应结果中出现冗长且难以理解的嵌入式数据,我们的示例仅包含人类可读的字段。

// Create a knowledge source
var indexKnowledgeSource = new SearchIndexKnowledgeSource(
    name: knowledgeSourceNames,
    searchIndexParameters: new SearchIndexKnowledgeSourceParameters(searchIndexName: indexName)
    {
        SourceDataSelect = "id,page_chunk,page_number"
    }
);
await indexClient.CreateOrUpdateKnowledgeSourceAsync(indexKnowledgeSource);
Console.WriteLine($"Knowledge source '{knowledgeSourceName}' created or updated successfully.");

创建知识代理

为在查询时将 earth-knowledge-sourcegpt-5-mini 部署作为目标,需要一个知识智能体。 添加并运行包含以下代码的代码单元格,以定义一个名为 earth-knowledge-agent 的知识智能体,之前使用 knowledgeAgentName 变量指定该智能体。

RerankerThreshold 通过排除重排序得分不高于 2.5 的响应来确保语义相关性。 同时,将 Modality 设置为 AnswerSynthesis,从而启用能够引用检索文档的自然语言回答。

// Create a knowledge agent
var openAiParameters = new AzureOpenAIVectorizerParameters
{
    ResourceUri = new Uri(aoaiEndpoint),
    DeploymentName = aoaiGptDeployment,
    ModelName = aoaiGptModel
};

var agentModel = new KnowledgeAgentAzureOpenAIModel(azureOpenAIParameters: openAiParameters);
var outputConfig = new KnowledgeAgentOutputConfiguration
{
    Modality = KnowledgeAgentOutputConfigurationModality.AnswerSynthesis,
    IncludeActivity = true
};

var agent = new KnowledgeAgent(
    name: knowledgeAgentName,
    models: new[] { agentModel },
    knowledgeSources: new KnowledgeSourceReference[] {
        new KnowledgeSourceReference(knowledgeSourceName) {
            IncludeReferences = true,
            IncludeReferenceSourceData = true,
            RerankerThreshold = (float?)2.5
        }
    }
)
{
    OutputConfiguration = outputConfig
};

await indexClient.CreateOrUpdateKnowledgeAgentAsync(agent);
Console.WriteLine($"Knowledge agent '{knowledgeAgentName}' created or updated successfully.");

设置消息

消息是检索路由的输入,包含对话历史记录。 每条消息都包含一个角色,用于指示其来源(例如 systemuser)以及自然语言中的内容。 使用的 LLM 决定了哪些角色有效。

以下代码创建一条系统消息,该消息指示 earth-knowledge-agent 在夜间回答有关地球的问题,并在答案不可用时使用“我不知道”进行回答。

// Set up messages
string instructions = @"A Q&A agent that can answer questions about the Earth at night.
If you don't have the answer, respond with ""I don't know"".";

var messages = new List<Dictionary<string, string>>
{
    new Dictionary<string, string>
    {
        { "role", "system" },
        { "content", instructions }
    }
};

运行检索管道

您可以通过将由两部分组成的用户查询发送到earth-knowledge-agent来运行代理检索。 根据对话历史记录和检索参数,智能体将:

  1. 分析整个对话以推断用户的信息需求。
  2. 将复合查询分解为有针对性的子查询。
  3. 并发地针对知识来源运行子查询。
  4. 使用语义排序器对结果进行重新排序和筛选。
  5. 将排名靠前的结果合成为自然语言答案。
// Use agentic retrieval to fetch results
var agentClient = new KnowledgeAgentRetrievalClient(
    endpoint: new Uri(searchEndpoint),
    agentName: knowledgeAgentName,
    tokenCredential: new DefaultAzureCredential()
);

messages.Add(new Dictionary<string, string>
{
    { "role", "user" },
    { "content", @"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?" }
});

var retrievalResult = await agentClient.RetrieveAsync(
    retrievalRequest: new KnowledgeAgentRetrievalRequest(
        messages: messages
            .Where(message => message["role"] != "system")
            .Select(
                message => new KnowledgeAgentMessage(content: new[] { new KnowledgeAgentMessageTextContent(message["content"]) }) { Role = message["role"] }
            )
            .ToList()
    )
);

messages.Add(new Dictionary<string, string>
{
    { "role", "assistant" },
    { "content", (retrievalResult.Value.Response[0].Content[0] as KnowledgeAgentMessageTextContent).Text }
});

查看响应、活动和结果

以下代码显示检索管道的响应、活动和结果,其中:

  • Response 会根据检索到的文档,生成一个由大型语言模型 (LLM) 合成的答案。 如果未启用答案合成功能,则此部分将直接显示从文档中提取的内容。

  • Activity 会追踪检索过程中的所有步骤,包括 gpt-5-mini 部署在检索过程中生成的子查询,以及用于语义排序、查询规划和答案合成所使用的标记。

  • Results 列出构成该响应的文档,每个文档都由其 DocKey标识。

// Print the response, activity, and results
Console.WriteLine("Response:");
Console.WriteLine((retrievalResult.Value.Response[0].Content[0] as KnowledgeAgentMessageTextContent).Text);

Console.WriteLine("Activity:");
foreach (var activity in retrievalResult.Value.Activity)
{
    Console.WriteLine($"Activity Type: {activity.GetType().Name}");
    string activityJson = JsonSerializer.Serialize(
        activity,
        activity.GetType(),
        new JsonSerializerOptions { WriteIndented = true }
    );
    Console.WriteLine(activityJson);
}

Console.WriteLine("Results:");
foreach (var reference in retrievalResult.Value.References)
{
    Console.WriteLine($"Reference Type: {reference.GetType().Name}");
    string referenceJson = JsonSerializer.Serialize(
        reference,
        reference.GetType(),
        new JsonSerializerOptions { WriteIndented = true }
    );
    Console.WriteLine(referenceJson);
}

继续对话

以下代码继续与 earth-knowledge-agent 对话。 发送此用户查询后,代理将从 earth-knowledge-source 中获取相关内容,并将响应追加到消息列表。

// Continue the conversation
messages.Add(new Dictionary<string, string>
{
    { "role", "user" },
    { "content", "How do I find lava at night?" }
});

retrievalResult = await agentClient.RetrieveAsync(
    retrievalRequest: new KnowledgeAgentRetrievalRequest(
        messages: messages
            .Where(message => message["role"] != "system")
            .Select(
                message => new KnowledgeAgentMessage(content: new[] { new KnowledgeAgentMessageTextContent(message["content"]) }) { Role = message["role"] }
            )
            .ToList()
    )
);

messages.Add(new Dictionary<string, string>
{
    { "role", "assistant" },
    { "content", (retrievalResult.Value.Response[0].Content[0] as KnowledgeAgentMessageTextContent).Text }
});

查看新的响应、活动和结果

以下代码显示检索管道的新响应、活动和结果。

// Print the response, activity, and results
Console.WriteLine("Response:");
Console.WriteLine((retrievalResult.Value.Response[0].Content[0] as KnowledgeAgentMessageTextContent).Text);

Console.WriteLine("Activities:");
foreach (var activity in retrievalResult.Value.Activity)
{
    Console.WriteLine($"Activity Type: {activity.GetType().Name}");
    string activityJson = JsonSerializer.Serialize(
        activity,
        activity.GetType(),
        new JsonSerializerOptions { WriteIndented = true }
    );
    Console.WriteLine(activityJson);
}

Console.WriteLine("Results:");
foreach (var reference in retrievalResult.Value.References)
{
    Console.WriteLine($"Reference Type: {reference.GetType().Name}");
    string referenceJson = JsonSerializer.Serialize(
        reference,
        reference.GetType(),
        new JsonSerializerOptions { WriteIndented = true }
    );
    Console.WriteLine(referenceJson);
}

清理资源

当你使用自己的订阅服务时,最好在完成一个项目后,先评估一下是否还需要你所创建的那些资源。 持续运行的资源可能会产生费用。

在 Azure 门户中,可以通过从左窗格中选择 “所有资源 ”或 “资源组 ”来管理 Azure AI 搜索和 Azure AI Foundry 资源。

否则,以下代码 Program.cs 将删除您在本快速入门中创建的对象。

删除知识代理

await indexClient.DeleteKnowledgeAgentAsync(knowledgeAgentName);
Console.WriteLine($"Knowledge agent '{knowledgeAgentName}' deleted successfully.");

删除知识来源

await indexClient.DeleteKnowledgeSourceAsync(knowledgeSourceName);
Console.WriteLine($"Knowledge source '{knowledgeSourceName}' deleted successfully.");

删除搜索索引

await indexClient.DeleteIndexAsync(indexName);
Console.WriteLine($"Index '{indexName}' deleted successfully.");     

注释

此功能目前处于公开预览状态。 此预览版未随附服务级别协议,建议不要用于生产工作负载。 某些功能可能不受支持或者受限。 有关详细信息,请参阅 Microsoft Azure 预览版补充使用条款

在本快速入门中,你将使用 代理检索 来创建由大型语言模型(LLM)和专有数据提供支持的对话搜索体验。 能动检索将复杂的用户查询分解为子查询,并行执行子查询,并从 Azure AI 搜索所索引的文档中提取基础数据。 输出适用于与代理和自定义聊天解决方案的集成。

虽然可以提供你自己的数据,但本快速入门使用了美国宇航局“夜间地球”电子书中的示例 JSON 文档。 这些文件描述了一般科学主题,以及从太空观测到的夜晚地球的图像。

小窍门

本快速入门的 Java 版本使用 2025-05-01-preview REST API 版本,该版本不支持 2025-08-01-preview 中引入的知识来源和其他智能体检索功能。 若要使用这些功能,请参阅 C#、Python 或 REST 版本。

先决条件

配置访问权限

在开始之前,请确保你有权访问内容和操作。 我们建议使用 Microsoft Entra ID 进行身份验证,并使用基于角色的访问控制进行授权。 你必须是“所有者”或“用户访问管理员”才能分配角色。 如果角色设置不可行,请改用基于密钥的身份验证方式

若要配置此快速入门的访问权限,请选择以下两个选项卡。

Azure AI 搜索提供智能体检索管道。 配置自己和搜索服务的访问权限,以读取和写入数据、与 Azure AI Foundry 交互以及运行管道。

配置 Azure AI 搜索的访问权限:

  1. 登录到 Azure 门户 并选择搜索服务。

  2. 启用基于角色的访问

  3. 创建系统分配的托管标识

  4. 将以下角色分配给自己。

    • 搜索服务参与者

    • 搜索索引数据参与者

    • 搜索索引数据读取者

重要

代理检索具有两种基于标记的计费模型:

  • Azure AI 搜索的语义排序功能的收费标准。
  • Azure OpenAI 的查询规划和答案生成功能收费标准。

语义排名在初始公共预览版中是免费的。 预览版后,将应用标准标记计费。 有关详细信息,请参阅 代理检索的可用性和定价

获取终结点

每个 Azure AI 搜索服务和 Azure AI Foundry 资源都有一个终结点,该终结点是唯一的 URL,用于标识和提供对资源的网络访问权限。 在后面的部分中,指定这些终结点以便通过编程方式连接到你的资源。

若要获取本快速入门的终结点,请选择以下两个选项卡。

  1. 登录到 Azure 门户 并选择搜索服务。

  2. 在左窗格中,选择“ 概述”。

  3. 记下终结点,形式应与 https://my-service.search.windows.net 类似。

部署模型

若要使用智能体检索,必须将两个 Azure OpenAI 模型部署到 Azure AI Foundry 资源:

  • 用于文本到矢量转换的嵌入模型。 本快速入门使用 text-embedding-3-large,但你可以使用任何 text-embedding 模型。

  • 用于查询规划和答案生成的 LLM。 本快速入门使用的是 gpt-5-mini,但你也可以使用任何受支持的具备智能体检索的 LLM

有关部署说明,请参阅 使用 Azure AI Foundry 部署 Azure OpenAI 模型

设置环境

本快速入门中的示例适用于 Java 运行时。 安装 Java 开发工具包,例如 Azul Zulu OpenJDKMicrosoft Build of OpenJDK 或你喜欢的 JDK 应该也能正常工作。

  1. 安装 Apache Maven。 然后运行 mvn -v 以确认安装成功。

  2. 创建一个新文件夹 quickstart-agentic-retrieval 以包含该应用程序,并在该文件夹中使用以下命令打开 Visual Studio Code:

    mkdir quickstart-agentic-retrieval && cd quickstart-agentic-retrieval
    
  3. 在项目的根目录中创建一个新的 pom.xml 文件,并将以下代码复制到该文件中:

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>azure.search.sample</groupId>
        <artifactId>azuresearchquickstart</artifactId>
        <version>1.0.0-SNAPSHOT</version>
        <build>
            <sourceDirectory>src</sourceDirectory>
            <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.7.0</version>
                <configuration>
                <source>1.8</source>
                <target>1.8</target>
                </configuration>
            </plugin>
            </plugins>
        </build>
        <dependencies>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.11</version>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>com.azure</groupId>
                <artifactId>azure-search-documents</artifactId>
                <version>11.8.0-beta.7</version>
            </dependency>
            <dependency>
                <groupId>com.azure</groupId>
                <artifactId>azure-core</artifactId>
                <version>1.53.0</version>
            </dependency>
            <dependency>
                <groupId>com.azure</groupId>
                <artifactId>azure-identity</artifactId>
                <version>1.15.1</version>
            </dependency>
            <dependency>
                <groupId>com.azure</groupId>
                <artifactId>azure-ai-openai</artifactId>
                <version>1.0.0-beta.16</version>
            </dependency>
            <dependency>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-databind</artifactId>
                <version>2.16.1</version>
            </dependency>
            <dependency>
                <groupId>io.github.cdimascio</groupId>
                <artifactId>dotenv-java</artifactId>
                <version>3.0.0</version>
            </dependency>
            <dependency>
                <groupId>org.apache.httpcomponents.client5</groupId>
                <artifactId>httpclient5</artifactId>
                <version>5.3.1</version>
            </dependency>
        </dependencies>
    </project>
    
  4. 安装依赖项,包括适用于 Java 的 Azure AI 搜索客户端库(Azure.Search.Documents),以及适用于 Java 的 Azure 标识客户端库

    mvn clean dependency:copy-dependencies
    

运行代码

  1. .env文件夹中创建一个名为quickstart-agentic-retrieval的新文件,并添加以下环境变量:

    AZURE_OPENAI_ENDPOINT=https://<your-ai-foundry-resource-name>.openai.azure.com/
    AZURE_OPENAI_GPT_DEPLOYMENT=gpt-5-mini
    AZURE_OPENAI_EMBEDDING_DEPLOYMENT=text-embedding-3-large
    AZURE_SEARCH_ENDPOINT=https://<your-search-service-name>.search.windows.net
    AZURE_SEARCH_INDEX_NAME=agentic-retrieval-sample
    

    <your-search-service-name><your-ai-foundry-resource-name> 替换为实际的 Azure AI 搜索服务名称和 Azure AI Foundry 资源名称。

  2. 将以下代码粘贴到文件夹中名为AgenticRetrievalQuickstart.javaquickstart-agentic-retrieval的新文件中:

    import com.azure.ai.openai.OpenAIAsyncClient;
    import com.azure.ai.openai.OpenAIClientBuilder;
    import com.azure.ai.openai.models.*;
    import com.azure.core.credential.TokenCredential;
    import com.azure.core.http.HttpClient;
    import com.azure.core.http.HttpHeaders;
    import com.azure.core.http.HttpMethod;
    import com.azure.core.http.HttpRequest;
    import com.azure.core.http.HttpResponse;
    import com.azure.core.util.BinaryData;
    import com.azure.identity.DefaultAzureCredential;
    import com.azure.identity.DefaultAzureCredentialBuilder;
    import com.azure.search.documents.SearchClient;
    import com.azure.search.documents.SearchClientBuilder;
    import com.azure.search.documents.SearchDocument;
    import com.azure.search.documents.indexes.SearchIndexClient;
    import com.azure.search.documents.indexes.SearchIndexClientBuilder;
    import com.azure.search.documents.indexes.models.*;
    import com.azure.search.documents.agents.SearchKnowledgeAgentClient;
    import com.azure.search.documents.agents.SearchKnowledgeAgentClientBuilder;
    import com.azure.search.documents.agents.models.*;
    import com.fasterxml.jackson.databind.JsonNode;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.fasterxml.jackson.databind.node.ObjectNode;
    import io.github.cdimascio.dotenv.Dotenv;
    
    import java.io.IOException;
    import java.net.URI;
    import java.net.http.HttpRequest.Builder;
    import java.time.Duration;
    import java.util.*;
    import java.util.concurrent.TimeUnit;
    
    public class AgenticRetrievalQuickstart {
    
        // Configuration - Update these values for your environment
        private static final String SEARCH_ENDPOINT;
        private static final String AZURE_OPENAI_ENDPOINT;
        private static final String AZURE_OPENAI_GPT_DEPLOYMENT;
        private static final String AZURE_OPENAI_GPT_MODEL = "gpt-5-mini";
        private static final String AZURE_OPENAI_EMBEDDING_DEPLOYMENT;
        private static final String AZURE_OPENAI_EMBEDDING_MODEL = "text-embedding-3-large";
        private static final String INDEX_NAME = "earth_at_night";
        private static final String AGENT_NAME = "earth-search-agent";
        private static final String SEARCH_API_VERSION = "2025-05-01-Preview";
    
        static {
            // Load environment variables from .env file
            Dotenv dotenv = Dotenv.configure().ignoreIfMissing().load();
    
            SEARCH_ENDPOINT = getEnvVar(dotenv, "AZURE_SEARCH_ENDPOINT", 
                "https://contoso-agentic-search-service.search.windows.net");
            AZURE_OPENAI_ENDPOINT = getEnvVar(dotenv, "AZURE_OPENAI_ENDPOINT",
                "https://contoso-proj-agentic-foundry-res.openai.azure.com/");
            AZURE_OPENAI_GPT_DEPLOYMENT = getEnvVar(dotenv, "AZURE_OPENAI_GPT_DEPLOYMENT", "gpt-5-mini");
            AZURE_OPENAI_EMBEDDING_DEPLOYMENT = getEnvVar(dotenv, "AZURE_OPENAI_EMBEDDING_DEPLOYMENT", "text-embedding-3-large");
        }
    
        private static String getEnvVar(Dotenv dotenv, String key, String defaultValue) {
            String value = dotenv.get(key);
            return (value != null && !value.isEmpty()) ? value : defaultValue;
        }
    
        public static void main(String[] args) {
            try {
                System.out.println("Starting Azure AI Search agentic retrieval quickstart...\n");
    
                // Initialize Azure credentials using managed identity (recommended)
                TokenCredential credential = new DefaultAzureCredentialBuilder().build();
    
                // Create search clients
                SearchIndexClient searchIndexClient = new SearchIndexClientBuilder()
                    .endpoint(SEARCH_ENDPOINT)
                    .credential(credential)
                    .buildClient();
    
                SearchClient searchClient = new SearchClientBuilder()
                    .endpoint(SEARCH_ENDPOINT)
                    .indexName(INDEX_NAME)
                    .credential(credential)
                    .buildClient();
    
                // Create Azure OpenAI client
                OpenAIAsyncClient openAIClient = new OpenAIClientBuilder()
                    .endpoint(AZURE_OPENAI_ENDPOINT)
                    .credential(credential)
                    .buildAsyncClient();
    
                // Step 1: Create search index with vector and semantic capabilities
                createSearchIndex(searchIndexClient);
    
                // Step 2: Upload documents
                uploadDocuments(searchClient);
    
                // Step 3: Create knowledge agent
                createKnowledgeAgent(credential);
    
                // Step 4: Run agentic retrieval with conversation
                runAgenticRetrieval(credential, openAIClient);
    
                // Step 5: Clean up - Delete knowledge agent and search index
                deleteKnowledgeAgent(credential);
                deleteSearchIndex(searchIndexClient);
    
                System.out.println("[DONE] Quickstart completed successfully!");
    
            } catch (Exception e) {
                System.err.println("[ERROR] Error in main execution: " + e.getMessage());
                e.printStackTrace();
            }
        }
    
        private static void createSearchIndex(SearchIndexClient indexClient) {
            System.out.println("[WAIT] Creating search index...");
    
            try {
                // Delete index if it exists
                try {
                    indexClient.deleteIndex(INDEX_NAME);
                    System.out.println("[DELETE] Deleted existing index '" + INDEX_NAME + "'");
                } catch (Exception e) {
                    // Index doesn't exist, which is fine
                }
    
                // Define fields
                List<SearchField> fields = Arrays.asList(
                    new SearchField("id", SearchFieldDataType.STRING)
                        .setKey(true)
                        .setFilterable(true)
                        .setSortable(true)
                        .setFacetable(true),
                    new SearchField("page_chunk", SearchFieldDataType.STRING)
                        .setSearchable(true)
                        .setFilterable(false)
                        .setSortable(false)
                        .setFacetable(false),
                    new SearchField("page_embedding_text_3_large", SearchFieldDataType.collection(SearchFieldDataType.SINGLE))
                        .setSearchable(true)
                        .setFilterable(false)
                        .setSortable(false)
                        .setFacetable(false)
                        .setVectorSearchDimensions(3072)
                        .setVectorSearchProfileName("hnsw_text_3_large"),
                    new SearchField("page_number", SearchFieldDataType.INT32)
                        .setFilterable(true)
                        .setSortable(true)
                        .setFacetable(true)
                );
    
                // Create vectorizer
                AzureOpenAIVectorizer vectorizer = new AzureOpenAIVectorizer("azure_openai_text_3_large")
                    .setParameters(new AzureOpenAIVectorizerParameters()
                        .setResourceUrl(AZURE_OPENAI_ENDPOINT)
                        .setDeploymentName(AZURE_OPENAI_EMBEDDING_DEPLOYMENT)
                        .setModelName(AzureOpenAIModelName.TEXT_EMBEDDING_3_LARGE));
    
                // Create vector search configuration
                VectorSearch vectorSearch = new VectorSearch()
                    .setProfiles(Arrays.asList(
                        new VectorSearchProfile("hnsw_text_3_large", "alg")
                            .setVectorizerName("azure_openai_text_3_large")
                    ))
                    .setAlgorithms(Arrays.asList(
                        new HnswAlgorithmConfiguration("alg")
                    ))
                    .setVectorizers(Arrays.asList(vectorizer));
    
                // Create semantic search configuration
                SemanticSearch semanticSearch = new SemanticSearch()
                    .setDefaultConfigurationName("semantic_config")
                    .setConfigurations(Arrays.asList(
                        new SemanticConfiguration("semantic_config",
                            new SemanticPrioritizedFields()
                                .setContentFields(Arrays.asList(
                                    new SemanticField("page_chunk")
                                ))
                        )
                    ));
    
                // Create the index
                SearchIndex index = new SearchIndex(INDEX_NAME)
                    .setFields(fields)
                    .setVectorSearch(vectorSearch)
                    .setSemanticSearch(semanticSearch);
    
                indexClient.createOrUpdateIndex(index);
                System.out.println("[DONE] Index '" + INDEX_NAME + "' created successfully.");
    
            } catch (Exception e) {
                System.err.println("[ERROR] Error creating index: " + e.getMessage());
                throw new RuntimeException(e);
            }
        }
    
        private static void uploadDocuments(SearchClient searchClient) {
            System.out.println("[WAIT] Uploading documents...");
    
            try {
                // Fetch documents from GitHub
                List<SearchDocument> documents = fetchEarthAtNightDocuments();
    
                searchClient.uploadDocuments(documents);
                System.out.println("[DONE] Uploaded " + documents.size() + " documents successfully.");
    
                // Wait for indexing to complete
                System.out.println("[WAIT] Waiting for document indexing to complete...");
                Thread.sleep(5000);
                System.out.println("[DONE] Document indexing completed.");
    
            } catch (Exception e) {
                System.err.println("[ERROR] Error uploading documents: " + e.getMessage());
                throw new RuntimeException(e);
            }
        }
    
        private static List<SearchDocument> fetchEarthAtNightDocuments() {
            System.out.println("[WAIT] Fetching Earth at Night documents from GitHub...");
    
            String documentsUrl = "https://raw.githubusercontent.com/Azure-Samples/azure-search-sample-data/refs/heads/main/nasa-e-book/earth-at-night-json/documents.json";
    
            try {
                java.net.http.HttpClient httpClient = java.net.http.HttpClient.newHttpClient();
                java.net.http.HttpRequest request = java.net.http.HttpRequest.newBuilder()
                    .uri(URI.create(documentsUrl))
                    .build();
    
                java.net.http.HttpResponse<String> response = httpClient.send(request, 
                    java.net.http.HttpResponse.BodyHandlers.ofString());
    
                if (response.statusCode() != 200) {
                    throw new IOException("Failed to fetch documents: " + response.statusCode());
                }
    
                ObjectMapper mapper = new ObjectMapper();
                JsonNode jsonArray = mapper.readTree(response.body());
    
                List<SearchDocument> documents = new ArrayList<>();
                for (int i = 0; i < jsonArray.size(); i++) {
                    JsonNode doc = jsonArray.get(i);
                    SearchDocument searchDoc = new SearchDocument();
    
                    searchDoc.put("id", doc.has("id") ? doc.get("id").asText() : String.valueOf(i + 1));
                    searchDoc.put("page_chunk", doc.has("page_chunk") ? doc.get("page_chunk").asText() : "");
    
                    // Handle embeddings
                    if (doc.has("page_embedding_text_3_large") && doc.get("page_embedding_text_3_large").isArray()) {
                        List<Double> embeddings = new ArrayList<>();
                        for (JsonNode embedding : doc.get("page_embedding_text_3_large")) {
                            embeddings.add(embedding.asDouble());
                        }
                        searchDoc.put("page_embedding_text_3_large", embeddings);
                    } else {
                        // Fallback embeddings
                        List<Double> fallbackEmbeddings = new ArrayList<>();
                        for (int j = 0; j < 3072; j++) {
                            fallbackEmbeddings.add(0.1);
                        }
                        searchDoc.put("page_embedding_text_3_large", fallbackEmbeddings);
                    }
    
                    searchDoc.put("page_number", doc.has("page_number") ? doc.get("page_number").asInt() : i + 1);
    
                    documents.add(searchDoc);
                }
    
                System.out.println("[DONE] Fetched " + documents.size() + " documents from GitHub");
                return documents;
    
            } catch (Exception e) {
                System.err.println("[ERROR] Error fetching documents from GitHub: " + e.getMessage());
                System.out.println("🔄 Falling back to sample documents...");
    
                // Fallback to sample documents
                List<SearchDocument> fallbackDocs = new ArrayList<>();
    
                SearchDocument doc1 = new SearchDocument();
                doc1.put("id", "1");
                doc1.put("page_chunk", "The Earth at night reveals the patterns of human settlement and economic activity. City lights trace the contours of civilization, creating a luminous map of where people live and work.");
                List<Double> embeddings1 = new ArrayList<>();
                for (int i = 0; i < 3072; i++) {
                    embeddings1.add(0.1);
                }
                doc1.put("page_embedding_text_3_large", embeddings1);
                doc1.put("page_number", 1);
    
                SearchDocument doc2 = new SearchDocument();
                doc2.put("id", "2");
                doc2.put("page_chunk", "From space, the aurora borealis appears as shimmering curtains of green and blue light dancing across the polar regions.");
                List<Double> embeddings2 = new ArrayList<>();
                for (int i = 0; i < 3072; i++) {
                    embeddings2.add(0.2);
                }
                doc2.put("page_embedding_text_3_large", embeddings2);
                doc2.put("page_number", 2);
    
                fallbackDocs.add(doc1);
                fallbackDocs.add(doc2);
    
                return fallbackDocs;
            }
        }
    
        private static void createKnowledgeAgent(TokenCredential credential) {
            System.out.println("[WAIT] Creating knowledge agent...");
    
            // Delete agent if it exists
            deleteKnowledgeAgent(credential);
    
            try {
                ObjectMapper mapper = new ObjectMapper();
                ObjectNode agentDefinition = mapper.createObjectNode();
                agentDefinition.put("name", AGENT_NAME);
                agentDefinition.put("description", "Knowledge agent for Earth at Night e-book content");
    
                ObjectNode model = mapper.createObjectNode();
                model.put("kind", "azureOpenAI");
                ObjectNode azureOpenAIParams = mapper.createObjectNode();
                azureOpenAIParams.put("resourceUri", AZURE_OPENAI_ENDPOINT);
                azureOpenAIParams.put("deploymentId", AZURE_OPENAI_GPT_DEPLOYMENT);
                azureOpenAIParams.put("modelName", AZURE_OPENAI_GPT_MODEL);
                model.set("azureOpenAIParameters", azureOpenAIParams);
                agentDefinition.set("models", mapper.createArrayNode().add(model));
    
                ObjectNode targetIndex = mapper.createObjectNode();
                targetIndex.put("indexName", INDEX_NAME);
                targetIndex.put("defaultRerankerThreshold", 2.5);
                agentDefinition.set("targetIndexes", mapper.createArrayNode().add(targetIndex));
    
                String token = getAccessToken(credential, "https://search.azure.com/.default");
    
                java.net.http.HttpClient httpClient = java.net.http.HttpClient.newHttpClient();
                java.net.http.HttpRequest request = java.net.http.HttpRequest.newBuilder()
                    .uri(URI.create(SEARCH_ENDPOINT + "/agents/" + AGENT_NAME + "?api-version=" + SEARCH_API_VERSION))
                    .header("Content-Type", "application/json")
                    .header("Authorization", "Bearer " + token)
                    .PUT(java.net.http.HttpRequest.BodyPublishers.ofString(mapper.writeValueAsString(agentDefinition)))
                    .build();
    
                java.net.http.HttpResponse<String> response = httpClient.send(request,
                    java.net.http.HttpResponse.BodyHandlers.ofString());
    
                if (response.statusCode() >= 400) {
                    throw new RuntimeException("Failed to create knowledge agent: " + response.statusCode() + " " + response.body());
                }
    
                System.out.println("[DONE] Knowledge agent '" + AGENT_NAME + "' created successfully.");
    
            } catch (Exception e) {
                System.err.println("[ERROR] Error creating knowledge agent: " + e.getMessage());
                throw new RuntimeException(e);
            }
        }
    
        private static void runAgenticRetrieval(TokenCredential credential, OpenAIAsyncClient openAIClient) {
            System.out.println("[SEARCH] Running agentic retrieval...");
    
            // Initialize messages with system instructions
            List<Map<String, String>> messages = new ArrayList<>();
    
            Map<String, String> systemMessage = new HashMap<>();
            systemMessage.put("role", "system");
            systemMessage.put("content", "A Q&A agent that can answer questions about the Earth at night.\n" +
                "Sources have a JSON format with a ref_id that must be cited in the answer.\n" +
                "If you do not have the answer, respond with \"I don't know\".");
            messages.add(systemMessage);
    
            Map<String, String> userMessage = new HashMap<>();
            userMessage.put("role", "user");
            userMessage.put("content", "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?");
            messages.add(userMessage);
    
            try {
                // Call agentic retrieval API (excluding system message)
                List<Map<String, String>> userMessages = messages.stream()
                    .filter(m -> !"system".equals(m.get("role")))
                    .collect(java.util.stream.Collectors.toList());
    
                String retrievalResponse = callAgenticRetrieval(credential, userMessages);
    
                // Add assistant response to conversation history
                Map<String, String> assistantMessage = new HashMap<>();
                assistantMessage.put("role", "assistant");
                assistantMessage.put("content", retrievalResponse);
                messages.add(assistantMessage);
    
                System.out.println(retrievalResponse);
    
                // Now do chat completion with full conversation history
                generateFinalAnswer(openAIClient, messages);
    
                // Continue conversation with second question
                continueConversation(credential, openAIClient, messages);
    
            } catch (Exception e) {
                System.err.println("[ERROR] Error in agentic retrieval: " + e.getMessage());
                throw new RuntimeException(e);
            }
        }
    
        private static String callAgenticRetrieval(TokenCredential credential, List<Map<String, String>> messages) {
            try {
                ObjectMapper mapper = new ObjectMapper();
                ObjectNode retrievalRequest = mapper.createObjectNode();
    
                // Convert messages to the correct format expected by the Knowledge agent
                com.fasterxml.jackson.databind.node.ArrayNode agentMessages = mapper.createArrayNode();
                for (Map<String, String> msg : messages) {
                    ObjectNode agentMessage = mapper.createObjectNode();
                    agentMessage.put("role", msg.get("role"));
    
                    com.fasterxml.jackson.databind.node.ArrayNode content = mapper.createArrayNode();
                    ObjectNode textContent = mapper.createObjectNode();
                    textContent.put("type", "text");
                    textContent.put("text", msg.get("content"));
                    content.add(textContent);
                    agentMessage.set("content", content);
    
                    agentMessages.add(agentMessage);
                }
                retrievalRequest.set("messages", agentMessages);
    
                com.fasterxml.jackson.databind.node.ArrayNode targetIndexParams = mapper.createArrayNode();
                ObjectNode indexParam = mapper.createObjectNode();
                indexParam.put("indexName", INDEX_NAME);
                indexParam.put("rerankerThreshold", 2.5);
                indexParam.put("maxDocsForReranker", 100);
                indexParam.put("includeReferenceSourceData", true);
                targetIndexParams.add(indexParam);
                retrievalRequest.set("targetIndexParams", targetIndexParams);
    
                String token = getAccessToken(credential, "https://search.azure.com/.default");
    
                java.net.http.HttpClient httpClient = java.net.http.HttpClient.newHttpClient();
                java.net.http.HttpRequest request = java.net.http.HttpRequest.newBuilder()
                    .uri(URI.create(SEARCH_ENDPOINT + "/agents/" + AGENT_NAME + "/retrieve?api-version=" + SEARCH_API_VERSION))
                    .header("Content-Type", "application/json")
                    .header("Authorization", "Bearer " + token)
                    .POST(java.net.http.HttpRequest.BodyPublishers.ofString(mapper.writeValueAsString(retrievalRequest)))
                    .build();
    
                java.net.http.HttpResponse<String> response = httpClient.send(request,
                    java.net.http.HttpResponse.BodyHandlers.ofString());
    
                if (response.statusCode() >= 400) {
                    throw new RuntimeException("Agentic retrieval failed: " + response.statusCode() + " " + response.body());
                }
    
                JsonNode responseJson = mapper.readTree(response.body());
    
                // Log activities and results
                logActivitiesAndResults(responseJson);
    
                // Extract response content
                if (responseJson.has("response") && responseJson.get("response").isArray()) {
                    com.fasterxml.jackson.databind.node.ArrayNode responseArray = (com.fasterxml.jackson.databind.node.ArrayNode) responseJson.get("response");
                    if (responseArray.size() > 0) {
                        JsonNode firstResponse = responseArray.get(0);
                        if (firstResponse.has("content") && firstResponse.get("content").isArray()) {
                            com.fasterxml.jackson.databind.node.ArrayNode contentArray = (com.fasterxml.jackson.databind.node.ArrayNode) firstResponse.get("content");
                            if (contentArray.size() > 0) {
                                JsonNode textContent = contentArray.get(0);
                                if (textContent.has("text")) {
                                    return textContent.get("text").asText();
                                }
                            }
                        }
                    }
                }
    
                return "No response content available";
    
            } catch (Exception e) {
                System.err.println("[ERROR] Error in agentic retrieval call: " + e.getMessage());
                throw new RuntimeException(e);
            }
        }
    
        private static void logActivitiesAndResults(JsonNode responseJson) {
            ObjectMapper mapper = new ObjectMapper();
    
            // Log activities
            System.out.println("\nActivities:");
            if (responseJson.has("activity") && responseJson.get("activity").isArray()) {
                for (JsonNode activity : responseJson.get("activity")) {
                    String activityType = "UnknownActivityRecord";
                    if (activity.has("InputTokens")) {
                        activityType = "KnowledgeAgentModelQueryPlanningActivityRecord";
                    } else if (activity.has("TargetIndex")) {
                        activityType = "KnowledgeAgentSearchActivityRecord";
                    } else if (activity.has("QueryTime")) {
                        activityType = "KnowledgeAgentSemanticRankerActivityRecord";
                    }
    
                    System.out.println("Activity Type: " + activityType);
                    try {
                        System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(activity));
                    } catch (Exception e) {
                        System.out.println(activity.toString());
                    }
                }
            }
    
            // Log results
            System.out.println("Results");
            if (responseJson.has("references") && responseJson.get("references").isArray()) {
                for (JsonNode reference : responseJson.get("references")) {
                    String referenceType = "KnowledgeAgentAzureSearchDocReference";
    
                    System.out.println("Reference Type: " + referenceType);
                    try {
                        System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(reference));
                    } catch (Exception e) {
                        System.out.println(reference.toString());
                    }
                }
            }
        }
    
        private static void generateFinalAnswer(OpenAIAsyncClient openAIClient, List<Map<String, String>> messages) {
            System.out.println("\n[ASSISTANT]: ");
    
            try {
                List<ChatRequestMessage> chatMessages = new ArrayList<>();
                for (Map<String, String> msg : messages) {
                    String role = msg.get("role");
                    String content = msg.get("content");
    
                    switch (role) {
                        case "system":
                            chatMessages.add(new ChatRequestSystemMessage(content));
                            break;
                        case "user":
                            chatMessages.add(new ChatRequestUserMessage(content));
                            break;
                        case "assistant":
                            chatMessages.add(new ChatRequestAssistantMessage(content));
                            break;
                    }
                }
    
                ChatCompletionsOptions chatOptions = new ChatCompletionsOptions(chatMessages)
                    .setMaxTokens(1000)
                    .setTemperature(0.7);
    
                ChatCompletions completion = openAIClient.getChatCompletions(AZURE_OPENAI_GPT_DEPLOYMENT, chatOptions).block();
    
                if (completion != null && completion.getChoices() != null && !completion.getChoices().isEmpty()) {
                    String answer = completion.getChoices().get(0).getMessage().getContent();
                    System.out.println(answer.replace(".", "\n"));
    
                    // Add this response to conversation history
                    Map<String, String> assistantResponse = new HashMap<>();
                    assistantResponse.put("role", "assistant");
                    assistantResponse.put("content", answer);
                    messages.add(assistantResponse);
                }
    
            } catch (Exception e) {
                System.err.println("[ERROR] Error generating final answer: " + e.getMessage());
                throw new RuntimeException(e);
            }
        }
    
        private static void continueConversation(TokenCredential credential, OpenAIAsyncClient openAIClient, List<Map<String, String>> messages) {
            System.out.println("\n === Continuing Conversation ===");
    
            // Add follow-up question
            String followUpQuestion = "How do I find lava at night?";
            System.out.println("[QUESTION] Follow-up question: " + followUpQuestion);
    
            Map<String, String> userMessage = new HashMap<>();
            userMessage.put("role", "user");
            userMessage.put("content", followUpQuestion);
            messages.add(userMessage);
    
            try {
                // FILTER OUT SYSTEM MESSAGE - only send user/assistant messages to agentic retrieval
                List<Map<String, String>> userAssistantMessages = messages.stream()
                    .filter(m -> !"system".equals(m.get("role")))
                    .collect(java.util.stream.Collectors.toList());
    
                String newRetrievalResponse = callAgenticRetrieval(credential, userAssistantMessages);
    
                // Add assistant response to conversation history
                Map<String, String> assistantMessage = new HashMap<>();
                assistantMessage.put("role", "assistant");
                assistantMessage.put("content", newRetrievalResponse);
                messages.add(assistantMessage);
    
                System.out.println(newRetrievalResponse);
    
                // Generate final answer for follow-up
                generateFinalAnswer(openAIClient, messages);
    
                System.out.println("\n === Conversation Complete ===");
    
            } catch (Exception e) {
                System.err.println("[ERROR] Error in conversation continuation: " + e.getMessage());
                throw new RuntimeException(e);
            }
        }
    
        private static void deleteKnowledgeAgent(TokenCredential credential) {
            System.out.println("[DELETE] Deleting knowledge agent...");
    
            try {
                String token = getAccessToken(credential, "https://search.azure.com/.default");
    
                java.net.http.HttpClient httpClient = java.net.http.HttpClient.newHttpClient();
                java.net.http.HttpRequest request = java.net.http.HttpRequest.newBuilder()
                    .uri(URI.create(SEARCH_ENDPOINT + "/agents/" + AGENT_NAME + "?api-version=" + SEARCH_API_VERSION))
                    .header("Authorization", "Bearer " + token)
                    .DELETE()
                    .build();
    
                java.net.http.HttpResponse<String> response = httpClient.send(request,
                    java.net.http.HttpResponse.BodyHandlers.ofString());
    
                if (response.statusCode() == 404) {
                    System.out.println("[INFO] Knowledge agent '" + AGENT_NAME + "' does not exist or was already deleted.");
                    return;
                }
    
                if (response.statusCode() >= 400) {
                    throw new RuntimeException("Failed to delete knowledge agent: " + response.statusCode() + " " + response.body());
                }
    
                System.out.println("[DONE] Knowledge agent '" + AGENT_NAME + "' deleted successfully.");
    
            } catch (Exception e) {
                System.err.println("[ERROR] Error deleting knowledge agent: " + e.getMessage());
                // Don't throw - this is cleanup
            }
        }
    
        private static void deleteSearchIndex(SearchIndexClient indexClient) {
            System.out.println("[DELETE] Deleting search index...");
    
            try {
                indexClient.deleteIndex(INDEX_NAME);
                System.out.println("[DONE] Search index '" + INDEX_NAME + "' deleted successfully.");
    
            } catch (Exception e) {
                if (e.getMessage() != null && (e.getMessage().contains("404") || e.getMessage().contains("IndexNotFound"))) {
                    System.out.println("[INFO] Search index '" + INDEX_NAME + "' does not exist or was already deleted.");
                    return;
                }
                System.err.println("[ERROR] Error deleting search index: " + e.getMessage());
                // Don't throw - this is cleanup
            }
        }
    
        private static String getAccessToken(TokenCredential credential, String scope) {
            try {
                return credential.getToken(new com.azure.core.credential.TokenRequestContext().addScopes(scope)).block().getToken();
            } catch (Exception e) {
                throw new RuntimeException("Failed to get access token", e);
            }
        }
    }
    
  3. 使用以下命令登录到 Azure:

    az login
    
  4. 运行新的控制台应用程序:

    javac Address.java App.java Hotel.java -cp ".;target\dependency\*"
    java -cp ".;target\dependency\*" App
    

输出

应用程序的输出应如下所示:

Starting Azure AI Search agentic retrieval quickstart...

[WAIT] Creating search index...
[DELETE] Deleted existing index 'earth_at_night'
[DONE] Index 'earth_at_night' created successfully.
[WAIT] Uploading documents...
[WAIT] Fetching Earth at Night documents from GitHub...
[DONE] Fetched 194 documents from GitHub
[DONE] Uploaded 194 documents successfully.
[WAIT] Waiting for document indexing to complete...
[DONE] Document indexing completed.
[WAIT] Creating knowledge agent...
[DELETE] Deleting knowledge agent...
[INFO] Knowledge agent 'earth-search-agent' does not exist or was already deleted.
[DONE] Knowledge agent 'earth-search-agent' created successfully.
[SEARCH] Running agentic retrieval...

Activities:
Activity Type: UnknownActivityRecord
{
  "type" : "ModelQueryPlanning",
  "id" : 0,
  "inputTokens" : 1379,
  "outputTokens" : 545
}
Activity Type: UnknownActivityRecord
{
  "type" : "AzureSearchQuery",
  "id" : 1,
  "targetIndex" : "earth_at_night",
  "query" : {
    "search" : "Why do suburban areas show greater December brightening compared to urban cores despite higher absolute light levels downtown?",
    "filter" : null
  },
  "queryTime" : "2025-07-21T15:07:04.024Z",
  "count" : 0,
  "elapsedMs" : 2609
}
Activity Type: UnknownActivityRecord
{
  "type" : "AzureSearchQuery",
  "id" : 2,
  "targetIndex" : "earth_at_night",
  "query" : {
    "search" : "Why is the Phoenix nighttime street grid sharply visible from space, while large stretches of interstate highways between Midwestern cities appear comparatively dim?",
    "filter" : null
  },
  "queryTime" : "2025-07-21T15:07:04.267Z",
  "count" : 0,
  "elapsedMs" : 243
}
Activity Type: UnknownActivityRecord
{
  "type" : "AzureSearchSemanticRanker",
  "id" : 3,
  "inputTokens" : 48602
}
Results
[]

[ASSISTANT]: 
The suburban belts display larger December brightening than urban cores despite higher absolute light levels downtown likely because suburban areas have more seasonal variation in lighting usage, such as increased outdoor and holiday lighting in December
 Urban cores, being brightly lit throughout the year, show less relative change


Regarding Phoenix's nighttime street grid visibility, it is sharply visible from space due to the structured and continuous lighting of the city's streets
 In contrast, large stretches of interstate highways between Midwestern cities are comparatively dim because highways typically have less intense and less frequent lighting compared to urban street grids


[Note: This explanation is based on general knowledge; no specific source with ref_id was provided
]

 === Continuing Conversation ===
[QUESTION] Follow-up question: How do I find lava at night?

Activities:
Activity Type: UnknownActivityRecord
{
  "type" : "ModelQueryPlanning",
  "id" : 0,
  "inputTokens" : 1545,
  "outputTokens" : 127
}
Activity Type: UnknownActivityRecord
{
  "type" : "AzureSearchQuery",
  "id" : 1,
  "targetIndex" : "earth_at_night",
  "query" : {
    "search" : "How can I find lava at night?",
    "filter" : null
  },
  "queryTime" : "2025-07-21T15:07:15.445Z",
  "count" : 6,
  "elapsedMs" : 370
}
Activity Type: UnknownActivityRecord
{
  "type" : "AzureSearchSemanticRanker",
  "id" : 2,
  "inputTokens" : 22994
}
Results
Reference Type: KnowledgeAgentAzureSearchDocReference
{
  "type" : "AzureSearchDoc",
  "id" : "0",
  "activitySource" : 1,
  "docKey" : "earth_at_night_508_page_44_verbalized",
  "sourceData" : {
    "id" : "earth_at_night_508_page_44_verbalized",
    "page_chunk" : "## Nature's Light Shows\n\nAt night, with the light of the Sun removed, nature's brilliant glow from Earth's surface becomes visible to the naked eye from space. Some of Earth's most spectacular light shows are natural, like the aurora borealis, or Northern Lights, in the Northern Hemisphere (aurora australis, or Southern Lights, in the Southern Hemisphere). The auroras are natural electrical phenomena caused by charged particles that race from the Sun toward Earth, inducing chemical reactions in the upper atmosphere and creating the appearance of streamers of reddish or greenish light in the sky, usually near the northern or southern magnetic pole. Other natural lights can indicate danger, like a raging forest fire encroaching on a city, town, or community, or lava spewing from an erupting volcano.\n\nWhatever the source, the ability of humans to monitor nature's light shows at night has practical applications for society. For example, tracking fires during nighttime hours allows for continuous monitoring and enhances our ability to protect humans and other animals, plants, and infrastructure. Combined with other data sources, our ability to observe the light of fires at night allows emergency managers to more efficiently and accurately issue warnings and evacuation orders and allows firefighting efforts to continue through the night. With enough moonlight (e.g., full-Moon phase), it's even possible to track the movement of smoke plumes at night, which can impact air quality, regardless of time of day.\n\nAnother natural source of light at night is emitted from glowing lava flows at the site of active volcanoes. Again, with enough moonlight, these dramatic scenes can be tracked and monitored for both scientific research and public safety.\n\n\n### Figure: The Northern Lights Viewed from Space\n\n**September 17, 2011**\n\nThis photo, taken from the International Space Station on September 17, 2011, shows a spectacular display of the aurora borealis (Northern Lights) as green and reddish light in the night sky above Earth. In the foreground, part of a Soyuz spacecraft is visible, silhouetted against the bright auroral light. The green glow is generated by energetic charged particles from the Sun interacting with Earth's upper atmosphere, exciting oxygen and nitrogen atoms, and producing characteristic colors. The image demonstrates the vividness and grandeur of natural night-time light phenomena as seen from orbit."
  }
}
Reference Type: KnowledgeAgentAzureSearchDocReference
{
  "type" : "AzureSearchDoc",
  "id" : "1",
  "activitySource" : 1,
  "docKey" : "earth_at_night_508_page_65_verbalized",
  "sourceData" : {
    "id" : "earth_at_night_508_page_65_verbalized",
    "page_chunk" : "# Volcanoes\n\n## Figure: Satellite Image of Sicily and Mount Etna Lava, March 16, 2017\n\nThe annotated satellite image below shows the island of Sicily and the surrounding region at night, highlighting city lights and volcanic activity.\n\n**Description:**\n\n- **Date of image:** March 16, 2017\n- **Geographical locations labeled:**\n    - Major cities: Palermo (northwest Sicily), Marsala (western Sicily), Catania (eastern Sicily)\n    - Significant feature: Mount Etna, labeled with an adjacent \"hot lava\" region showing the glow from active lava flows\n    - Surrounding water body: Mediterranean Sea\n    - Island: Malta to the south of Sicily\n- **Other details:** \n    - The image is shown at night, with bright spots indicating city lights.\n    - The position of \"hot lava\" near Mount Etna is distinctly visible as a bright spot different from other city lights, indicating volcanic activity.\n    - A scale bar is included showing a reference length of 50 km.\n    - North direction is indicated with an arrow.\n    - Cloud cover is visible in the southwest part of the image, partially obscuring the view near Marsala and Malta.\n\n**Summary of Features Visualized:**\n\n| Feature          | Description                                           |\n|------------------|------------------------------------------------------|\n| Cities           | Bright clusters indicating locations: Palermo, Marsala, Catania |\n| Mount Etna       | Marked on the map, located on the eastern side of Sicily, with visible hot lava activity |\n| Malta            | Clearly visible to the south of Sicily               |\n| Water bodies     | Mediterranean Sea labeled                            |\n| Scale & Direction| 50 km scale bar and North indicator                  |\n| Date             | March 16, 2017                                       |\n| Cloud Cover      | Visible in the lower left (southern) part of the image |\n\nThis figure demonstrates the visibility of volcanic activity at Mount Etna from space at night, distinguishing the light from hot lava against the background city lights of Sicily and Malta."
  }
}
Reference Type: KnowledgeAgentAzureSearchDocReference
{
  "type" : "AzureSearchDoc",
  "id" : "2",
  "activitySource" : 1,
  "docKey" : "earth_at_night_508_page_64_verbalized",
  "sourceData" : {
    "id" : "earth_at_night_508_page_64_verbalized",
    "page_chunk" : "<!-- PageHeader=\"Volcanoes\" -->\n\n### Nighttime Glow at Mount Etna - Italy\n\nAt about 2:30 a.m. local time on March 16, 2017, the VIIRS DNB on the Suomi NPP satellite captured this nighttime image of lava flowing on Mount Etna in Sicily, Italy. Etna is one of the world's most active volcanoes.\n\n#### Figure: Location of Mount Etna\nA world globe is depicted, with a marker indicating the location of Mount Etna in Sicily, Italy, in southern Europe near the center of the Mediterranean Sea.\n\n<!-- PageFooter=\"Earth at Night\" -->\n<!-- PageNumber=\"48\" -->"
  }
}
Reference Type: KnowledgeAgentAzureSearchDocReference
{
  "type" : "AzureSearchDoc",
  "id" : "3",
  "activitySource" : 1,
  "docKey" : "earth_at_night_508_page_66_verbalized",
  "sourceData" : {
    "id" : "earth_at_night_508_page_66_verbalized",
    "page_chunk" : "# Volcanoes\n\n---\n\n### Mount Etna Erupts - Italy\n\nThe highly active Mount Etna in Italy sent red lava rolling down its flank on March 19, 2017. An astronaut onboard the ISS took the photograph below of the volcano and its environs that night. City lights surround the mostly dark volcanic area.\n\n---\n\n#### Figure 1: Location of Mount Etna, Italy\n\nA world map highlighting the location of Mount Etna in southern Italy. The marker indicates its geographic placement on the east coast of Sicily, Italy, in the Mediterranean region, south of mainland Europe and north of northern Africa.\n\n---\n\n#### Figure 2: Nighttime View of Mount Etna's Eruption and Surrounding Cities\n\nThis is a nighttime satellite image taken on March 19, 2017, showing the eruption of Mount Etna (southeastern cone) with visible bright red and orange coloring indicating flowing lava from a lateral vent. The surrounding areas are illuminated by city lights, with the following geographic references labeled:\n\n| Location        | Position in Image         | Visible Characteristics                    |\n|-----------------|--------------------------|--------------------------------------------|\n| Mt. Etna (southeastern cone) | Top center-left | Bright red/orange lava flow                |\n| Lateral vent    | Left of the volcano       | Faint red/orange flow extending outwards   |\n| Resort          | Below the volcano, to the left   | Small cluster of lights                    |\n| Giarre          | Top right                 | Bright cluster of city lights              |\n| Acireale        | Center right              | Large, bright area of city lights          |\n| Biancavilla     | Bottom left               | Smaller cluster of city lights             |\n\nAn arrow pointing north is shown on the image for orientation.\n\n---\n\n<!-- Earth at Night Page Footer -->\n<!-- Page Number: 50 -->"
  }
}
Reference Type: KnowledgeAgentAzureSearchDocReference
{
  "type" : "AzureSearchDoc",
  "id" : "4",
  "activitySource" : 1,
  "docKey" : "earth_at_night_508_page_46_verbalized",
  "sourceData" : {
    "id" : "earth_at_night_508_page_46_verbalized",
    "page_chunk" : "For the first time in perhaps a decade, Mount Etna experienced a \"flank eruption\"�erupting from its side instead of its summit�on December 24, 2018. The activity was accompanied by 130 earthquakes occurring over three hours that morning. Mount Etna, Europe�s most active volcano, has seen periodic activity on this part of the mountain since 2013. The Operational Land Imager (OLI) on the Landsat 8 satellite acquired the main image of Mount Etna on December 28, 2018.\n\nThe inset image highlights the active vent and thermal infrared signature from lava flows, which can be seen near the newly formed fissure on the southeastern side of the volcano. The inset was created with data from OLI and the Thermal Infrared Sensor (TIRS) on Landsat 8. Ash spewing from the fissure cloaked adjacent villages and delayed aircraft from landing at the nearby Catania airport. Earthquakes occurred in the subsequent days after the initial eruption and displaced hundreds of people from their homes.\n\nFor nighttime images of Mount Etna�s March 2017 eruption, see pages 48�51.\n\n---\n\n### Hazards of Volcanic Ash Plumes and Satellite Observation\n\nWith the help of moonlight, satellite instruments can track volcanic ash plumes, which present significant hazards to airplanes in flight. The volcanic ash�composed of tiny pieces of glass and rock�is abrasive to engine turbine blades, and can melt on the blades and other engine parts, causing damage and even engine stalls. This poses a danger to both the plane�s integrity and passenger safety. Volcanic ash also reduces visibility for pilots and can cause etching of windshields, further reducing pilots� ability to see. Nightlight images can be combined with thermal images to provide a more complete view of volcanic activity on Earth�s surface.\n\nThe VIIRS Day/Night Band (DNB) on polar-orbiting satellites uses faint light sources such as moonlight, airglow (the atmosphere�s self-illumination through chemical reactions), zodiacal light (sunlight scattered by interplanetary dust), and starlight from the Milky Way. Using these dim light sources, the DNB can detect changes in clouds, snow cover, and sea ice:\n\n#### Table: Light Sources Used by VIIRS DNB\n\n| Light Source         | Description                                                                  |\n|----------------------|------------------------------------------------------------------------------|\n| Moonlight            | Reflected sunlight from the Moon, illuminating Earth's surface at night      |\n| Airglow              | Atmospheric self-illumination from chemical reactions                        |\n| Zodiacal Light       | Sunlight scattered by interplanetary dust                                    |\n| Starlight/Milky Way  | Faint illumination provided by stars in the Milky Way                        |\n\nGeostationary Operational Environmental Satellites (GOES), managed by NOAA, orbit over Earth�s equator and offer uninterrupted observations of North America. High-latitude areas such as Alaska benefit from polar-orbiting satellites like Suomi NPP, which provide overlapping coverage at the poles, enabling more data collection in these regions. During polar darkness (winter months), VIIRS DNB data allow scientists to:\n\n- Observe sea ice formation\n- Monitor snow cover extent at the highest latitudes\n- Detect open water for ship navigation\n\n#### Table: Satellite Coverage Overview\n\n| Satellite Type          | Orbit           | Coverage Area         | Special Utility                              |\n|------------------------|-----------------|----------------------|----------------------------------------------|\n| GOES                   | Geostationary   | Equatorial/North America | Continuous regional monitoring              |\n| Polar-Orbiting (e.g., Suomi NPP) | Polar-orbiting    | Poles/high latitudes      | Overlapping passes; useful during polar night|\n\n---\n\n### Weather Forecasting and Nightlight Data\n\nThe use of nightlight data by weather forecasters is growing as the VIIRS instrument enables observation of clouds at night illuminated by sources such as moonlight and lightning. Scientists use these data to study the nighttime behavior of weather systems, including severe storms, which can develop and strike populous areas at night as well as during the day. Combined with thermal data, visible nightlight data allow the detection of clouds at various heights in the atmosphere, such as dense marine fog. This capability enables weather forecasters to issue marine advisories with higher confidence, leading to greater utility. (See \"Marine Layer Clouds�California\" on page 56.)\n\nIn this section of the book, you will see how nightlight data are used to observe nature�s spectacular light shows across a wide range of sources.\n\n---\n\n#### Notable Data from Mount Etna Flank Eruption (December 2018)\n\n| Event/Observation                  | Details                                                                    |\n|-------------------------------------|----------------------------------------------------------------------------|\n| Date of Flank Eruption              | December 24, 2018                                                          |\n| Number of Earthquakes               | 130 earthquakes within 3 hours                                              |\n| Image Acquisition                   | December 28, 2018 by Landsat 8 OLI                                         |\n| Location of Eruption                | Southeastern side of Mount Etna                                            |\n| Thermal Imaging Data                | From OLI and TIRS (Landsat 8), highlighting active vent and lava flows     |\n| Impact on Villages/Air Transport    | Ash covered villages; delayed aircraft at Catania airport                  |\n| Displacement                        | Hundreds of residents displaced                                            |\n| Ongoing Seismic Activity            | Earthquakes continued after initial eruption                               |\n\n---\n\n<!-- PageFooter=\"Earth at Night\" -->\n<!-- PageNumber=\"30\" -->"
  }
}
Reference Type: KnowledgeAgentAzureSearchDocReference
{
  "type" : "AzureSearchDoc",
  "id" : "5",
  "activitySource" : 1,
  "docKey" : "earth_at_night_508_page_60_verbalized",
  "sourceData" : {
    "id" : "earth_at_night_508_page_60_verbalized",
    "page_chunk" : "<!-- PageHeader=\"Volcanoes\" -->\n\n## Volcanoes\n\n### The Infrared Glows of Kilauea's Lava Flows�Hawaii\n\nIn early May 2018, an eruption on Hawaii's Kilauea volcano began to unfold. The eruption took a dangerous turn on May 3, 2018, when new fissures opened in the residential neighborhood of Leilani Estates. During the summer-long eruptive event, other fissures emerged along the East Rift Zone. Lava from vents along the rift zone flowed downslope, reaching the ocean in several areas, and filling in Kapoho Bay.\n\nA time series of Landsat 8 imagery shows the progression of the lava flows from May 16 to August 13. The night view combines thermal, shortwave infrared, and near-infrared wavelengths to tease out the very hot lava (bright white), cooling lava (red), and lava flows obstructed by clouds (purple).\n\n#### Figure: Location of Kilauea Volcano, Hawaii\n\nA globe is shown centered on North America, with a marker placed in the Pacific Ocean indicating the location of Hawaii, to the southwest of the mainland United States.\n\n<!-- PageFooter=\"Earth at Night\" -->\n<!-- PageNumber=\"44\" -->"
  }
}
[{"ref_id":0,"content":"## Nature's Light Shows\n\nAt night, with the light of the Sun removed, nature's brilliant glow from Earth's surface becomes visible to the naked eye from space. Some of Earth's most spectacular light shows are natural, like the aurora borealis, or Northern Lights, in the Northern Hemisphere (aurora australis, or Southern Lights, in the Southern Hemisphere). The auroras are natural electrical phenomena caused by charged particles that race from the Sun toward Earth, inducing chemical reactions in the upper atmosphere and creating the appearance of streamers of reddish or greenish light in the sky, usually near the northern or southern magnetic pole. Other natural lights can indicate danger, like a raging forest fire encroaching on a city, town, or community, or lava spewing from an erupting volcano.\n\nWhatever the source, the ability of humans to monitor nature's light shows at night has practical applications for society. For example, tracking fires during nighttime hours allows for continuous monitoring and enhances our ability to protect humans and other animals, plants, and infrastructure. Combined with other data sources, our ability to observe the light of fires at night allows emergency managers to more efficiently and accurately issue warnings and evacuation orders and allows firefighting efforts to continue through the night. With enough moonlight (e.g., full-Moon phase), it's even possible to track the movement of smoke plumes at night, which can impact air quality, regardless of time of day.\n\nAnother natural source of light at night is emitted from glowing lava flows at the site of active volcanoes. Again, with enough moonlight, these dramatic scenes can be tracked and monitored for both scientific research and public safety.\n\n\n### Figure: The Northern Lights Viewed from Space\n\n**September 17, 2011**\n\nThis photo, taken from the International Space Station on September 17, 2011, shows a spectacular display of the aurora borealis (Northern Lights) as green and reddish light in the night sky above Earth. In the foreground, part of a Soyuz spacecraft is visible, silhouetted against the bright auroral light. The green glow is generated by energetic charged particles from the Sun interacting with Earth's upper atmosphere, exciting oxygen and nitrogen atoms, and producing characteristic colors. The image demonstrates the vividness and grandeur of natural night-time light phenomena as seen from orbit."},{"ref_id":1,"content":"# Volcanoes\n\n## Figure: Satellite Image of Sicily and Mount Etna Lava, March 16, 2017\n\nThe annotated satellite image below shows the island of Sicily and the surrounding region at night, highlighting city lights and volcanic activity.\n\n**Description:**\n\n- **Date of image:** March 16, 2017\n- **Geographical locations labeled:**\n    - Major cities: Palermo (northwest Sicily), Marsala (western Sicily), Catania (eastern Sicily)\n    - Significant feature: Mount Etna, labeled with an adjacent \"hot lava\" region showing the glow from active lava flows\n    - Surrounding water body: Mediterranean Sea\n    - Island: Malta to the south of Sicily\n- **Other details:** \n    - The image is shown at night, with bright spots indicating city lights.\n    - The position of \"hot lava\" near Mount Etna is distinctly visible as a bright spot different from other city lights, indicating volcanic activity.\n    - A scale bar is included showing a reference length of 50 km.\n    - North direction is indicated with an arrow.\n    - Cloud cover is visible in the southwest part of the image, partially obscuring the view near Marsala and Malta.\n\n**Summary of Features Visualized:**\n\n| Feature          | Description                                           |\n|------------------|------------------------------------------------------|\n| Cities           | Bright clusters indicating locations: Palermo, Marsala, Catania |\n| Mount Etna       | Marked on the map, located on the eastern side of Sicily, with visible hot lava activity |\n| Malta            | Clearly visible to the south of Sicily               |\n| Water bodies     | Mediterranean Sea labeled                            |\n| Scale & Direction| 50 km scale bar and North indicator                  |\n| Date             | March 16, 2017                                       |\n| Cloud Cover      | Visible in the lower left (southern) part of the image |\n\nThis figure demonstrates the visibility of volcanic activity at Mount Etna from space at night, distinguishing the light from hot lava against the background city lights of Sicily and Malta."},{"ref_id":2,"content":"<!-- PageHeader=\"Volcanoes\" -->\n\n### Nighttime Glow at Mount Etna - Italy\n\nAt about 2:30 a.m. local time on March 16, 2017, the VIIRS DNB on the Suomi NPP satellite captured this nighttime image of lava flowing on Mount Etna in Sicily, Italy. Etna is one of the world's most active volcanoes.\n\n#### Figure: Location of Mount Etna\nA world globe is depicted, with a marker indicating the location of Mount Etna in Sicily, Italy, in southern Europe near the center of the Mediterranean Sea.\n\n<!-- PageFooter=\"Earth at Night\" -->\n<!-- PageNumber=\"48\" -->"},{"ref_id":3,"content":"# Volcanoes\n\n---\n\n### Mount Etna Erupts - Italy\n\nThe highly active Mount Etna in Italy sent red lava rolling down its flank on March 19, 2017. An astronaut onboard the ISS took the photograph below of the volcano and its environs that night. City lights surround the mostly dark volcanic area.\n\n---\n\n#### Figure 1: Location of Mount Etna, Italy\n\nA world map highlighting the location of Mount Etna in southern Italy. The marker indicates its geographic placement on the east coast of Sicily, Italy, in the Mediterranean region, south of mainland Europe and north of northern Africa.\n\n---\n\n#### Figure 2: Nighttime View of Mount Etna's Eruption and Surrounding Cities\n\nThis is a nighttime satellite image taken on March 19, 2017, showing the eruption of Mount Etna (southeastern cone) with visible bright red and orange coloring indicating flowing lava from a lateral vent. The surrounding areas are illuminated by city lights, with the following geographic references labeled:\n\n| Location        | Position in Image         | Visible Characteristics                    |\n|-----------------|--------------------------|--------------------------------------------|\n| Mt. Etna (southeastern cone) | Top center-left | Bright red/orange lava flow                |\n| Lateral vent    | Left of the volcano       | Faint red/orange flow extending outwards   |\n| Resort          | Below the volcano, to the left   | Small cluster of lights                    |\n| Giarre          | Top right                 | Bright cluster of city lights              |\n| Acireale        | Center right              | Large, bright area of city lights          |\n| Biancavilla     | Bottom left               | Smaller cluster of city lights             |\n\nAn arrow pointing north is shown on the image for orientation.\n\n---\n\n<!-- Earth at Night Page Footer -->\n<!-- Page Number: 50 -->"},{"ref_id":4,"content":"For the first time in perhaps a decade, Mount Etna experienced a \"flank eruption\"�erupting from its side instead of its summit�on December 24, 2018. The activity was accompanied by 130 earthquakes occurring over three hours that morning. Mount Etna, Europe�s most active volcano, has seen periodic activity on this part of the mountain since 2013. The Operational Land Imager (OLI) on the Landsat 8 satellite acquired the main image of Mount Etna on December 28, 2018.\n\nThe inset image highlights the active vent and thermal infrared signature from lava flows, which can be seen near the newly formed fissure on the southeastern side of the volcano. The inset was created with data from OLI and the Thermal Infrared Sensor (TIRS) on Landsat 8. Ash spewing from the fissure cloaked adjacent villages and delayed aircraft from landing at the nearby Catania airport. Earthquakes occurred in the subsequent days after the initial eruption and displaced hundreds of people from their homes.\n\nFor nighttime images of Mount Etna�s March 2017 eruption, see pages 48�51.\n\n---\n\n### Hazards of Volcanic Ash Plumes and Satellite Observation\n\nWith the help of moonlight, satellite instruments can track volcanic ash plumes, which present significant hazards to airplanes in flight. The volcanic ash�composed of tiny pieces of glass and rock�is abrasive to engine turbine blades, and can melt on the blades and other engine parts, causing damage and even engine stalls. This poses a danger to both the plane�s integrity and passenger safety. Volcanic ash also reduces visibility for pilots and can cause etching of windshields, further reducing pilots� ability to see. Nightlight images can be combined with thermal images to provide a more complete view of volcanic activity on Earth�s surface.\n\nThe VIIRS Day/Night Band (DNB) on polar-orbiting satellites uses faint light sources such as moonlight, airglow (the atmosphere�s self-illumination through chemical reactions), zodiacal light (sunlight scattered by interplanetary dust), and starlight from the Milky Way. Using these dim light sources, the DNB can detect changes in clouds, snow cover, and sea ice:\n\n#### Table: Light Sources Used by VIIRS DNB\n\n| Light Source         | Description                                                                  |\n|----------------------|------------------------------------------------------------------------------|\n| Moonlight            | Reflected sunlight from the Moon, illuminating Earth's surface at night      |\n| Airglow              | Atmospheric self-illumination from chemical reactions                        |\n| Zodiacal Light       | Sunlight scattered by interplanetary dust                                    |\n| Starlight/Milky Way  | Faint illumination provided by stars in the Milky Way                        |\n\nGeostationary Operational Environmental Satellites (GOES), managed by NOAA, orbit over Earth�s equator and offer uninterrupted observations of North America. High-latitude areas such as Alaska benefit from polar-orbiting satellites like Suomi NPP, which provide overlapping coverage at the poles, enabling more data collection in these regions. During polar darkness (winter months), VIIRS DNB data allow scientists to:\n\n- Observe sea ice formation\n- Monitor snow cover extent at the highest latitudes\n- Detect open water for ship navigation\n\n#### Table: Satellite Coverage Overview\n\n| Satellite Type          | Orbit           | Coverage Area         | Special Utility                              |\n|------------------------|-----------------|----------------------|----------------------------------------------|\n| GOES                   | Geostationary   | Equatorial/North America | Continuous regional monitoring              |\n| Polar-Orbiting (e.g., Suomi NPP) | Polar-orbiting    | Poles/high latitudes      | Overlapping passes; useful during polar night|\n\n---\n\n### Weather Forecasting and Nightlight Data\n\nThe use of nightlight data by weather forecasters is growing as the VIIRS instrument enables observation of clouds at night illuminated by sources such as moonlight and lightning. Scientists use these data to study the nighttime behavior of weather systems, including severe storms, which can develop and strike populous areas at night as well as during the day. Combined with thermal data, visible nightlight data allow the detection of clouds at various heights in the atmosphere, such as dense marine fog. This capability enables weather forecasters to issue marine advisories with higher confidence, leading to greater utility. (See \"Marine Layer Clouds�California\" on page 56.)\n\nIn this section of the book, you will see how nightlight data are used to observe nature�s spectacular light shows across a wide range of sources.\n\n---\n\n#### Notable Data from Mount Etna Flank Eruption (December 2018)\n\n| Event/Observation                  | Details                                                                    |\n|-------------------------------------|----------------------------------------------------------------------------|\n| Date of Flank Eruption              | December 24, 2018                                                          |\n| Number of Earthquakes               | 130 earthquakes within 3 hours                                              |\n| Image Acquisition                   | December 28, 2018 by Landsat 8 OLI                                         |\n| Location of Eruption                | Southeastern side of Mount Etna                                            |\n| Thermal Imaging Data                | From OLI and TIRS (Landsat 8), highlighting active vent and lava flows     |\n| Impact on Villages/Air Transport    | Ash covered villages; delayed aircraft at Catania airport                  |\n| Displacement                        | Hundreds of residents displaced                                            |\n| Ongoing Seismic Activity            | Earthquakes continued after initial eruption                               |\n\n---\n\n<!-- PageFooter=\"Earth at Night\" -->\n<!-- PageNumber=\"30\" -->"},{"ref_id":5,"content":"<!-- PageHeader=\"Volcanoes\" -->\n\n## Volcanoes\n\n### The Infrared Glows of Kilauea's Lava Flows�Hawaii\n\nIn early May 2018, an eruption on Hawaii's Kilauea volcano began to unfold. The eruption took a dangerous turn on May 3, 2018, when new fissures opened in the residential neighborhood of Leilani Estates. During the summer-long eruptive event, other fissures emerged along the East Rift Zone. Lava from vents along the rift zone flowed downslope, reaching the ocean in several areas, and filling in Kapoho Bay.\n\nA time series of Landsat 8 imagery shows the progression of the lava flows from May 16 to August 13. The night view combines thermal, shortwave infrared, and near-infrared wavelengths to tease out the very hot lava (bright white), cooling lava (red), and lava flows obstructed by clouds (purple).\n\n#### Figure: Location of Kilauea Volcano, Hawaii\n\nA globe is shown centered on North America, with a marker placed in the Pacific Ocean indicating the location of Hawaii, to the southwest of the mainland United States.\n\n<!-- PageFooter=\"Earth at Night\" -->\n<!-- PageNumber=\"44\" -->"}]

[ASSISTANT]: 
To find lava at night, you can look for the visible glow of active lava flows from erupting volcanoes, which emit light detectable from space during nighttime
 For example:

- The active lava flows of Mount Etna in Sicily, Italy, have been clearly observed at night by satellites and astronauts aboard the International Space Station
 The bright red and orange glow of lava distinguishes it from surrounding city lights (refs 1, 3)


- Similarly, the Kilauea volcano in Hawaii emits an infrared glow from its lava flows, which can be captured in nighttime satellite imagery combining thermal and near-infrared wavelengths (ref 5)


- Nighttime satellite instruments like the VIIRS Day/Night Band (DNB) on the Suomi NPP satellite use faint light sources such as moonlight to detect the glow of lava and volcanic activity even when direct sunlight is absent (refs 2, 4)


Therefore, to find lava at night, monitoring nighttime satellite imagery over active volcanic regions is effective, as the glowing lava stands out distinctly against the dark landscape and city lights


References: [1], [2], [3], [4], [5]

 === Conversation Complete ===
[DELETE] Deleting knowledge agent...
[DONE] Knowledge agent 'earth-search-agent' deleted successfully.
[DELETE] Deleting search index...
[DONE] Search index 'earth_at_night' deleted successfully.
[DONE] Quickstart completed successfully!

了解代码

有了代码后,让我们分解关键组件:

创建搜索索引

在 Azure AI 搜索中,索引是结构化数据集合。 以下代码定义一 earth_at_night 个名为包含纯文本和矢量内容的索引。 可以使用现有索引,但它必须满足 代理检索工作负荷的条件。

List<SearchField> fields = Arrays.asList(
    new SearchField("id", SearchFieldDataType.STRING)
        .setKey(true)
        .setFilterable(true)
        .setSortable(true)
        .setFacetable(true),
    new SearchField("page_chunk", SearchFieldDataType.STRING)
        .setSearchable(true)
        .setFilterable(false)
        .setSortable(false)
        .setFacetable(false),
    new SearchField("page_embedding_text_3_large", SearchFieldDataType.collection(SearchFieldDataType.SINGLE))
        .setSearchable(true)
        .setFilterable(false)
        .setSortable(false)
        .setFacetable(false)
        .setVectorSearchDimensions(3072)
        .setVectorSearchProfileName("hnsw_text_3_large"),
    new SearchField("page_number", SearchFieldDataType.INT32)
        .setFilterable(true)
        .setSortable(true)
        .setFacetable(true)
);

// Create vectorizer
AzureOpenAIVectorizer vectorizer = new AzureOpenAIVectorizer("azure_openai_text_3_large")
    .setParameters(new AzureOpenAIVectorizerParameters()
        .setResourceUrl(AZURE_OPENAI_ENDPOINT)
        .setDeploymentName(AZURE_OPENAI_EMBEDDING_DEPLOYMENT)
        .setModelName(AzureOpenAIModelName.TEXT_EMBEDDING_3_LARGE));

// Create vector search configuration
VectorSearch vectorSearch = new VectorSearch()
    .setProfiles(Arrays.asList(
        new VectorSearchProfile("hnsw_text_3_large", "alg")
            .setVectorizerName("azure_openai_text_3_large")
    ))
    .setAlgorithms(Arrays.asList(
        new HnswAlgorithmConfiguration("alg")
    ))
    .setVectorizers(Arrays.asList(vectorizer));

// Create semantic search configuration
SemanticSearch semanticSearch = new SemanticSearch()
    .setDefaultConfigurationName("semantic_config")
    .setConfigurations(Arrays.asList(
        new SemanticConfiguration("semantic_config",
            new SemanticPrioritizedFields()
                .setContentFields(Arrays.asList(
                    new SemanticField("page_chunk")
                ))
        )
    ));

// Create the index
SearchIndex index = new SearchIndex(INDEX_NAME)
    .setFields(fields)
    .setVectorSearch(vectorSearch)
    .setSemanticSearch(semanticSearch);

indexClient.createOrUpdateIndex(index);

索引架构包含文档标识和页面内容、嵌入和数字的字段。 它还包括语义排名和矢量查询的配置,这些配置使用之前部署的 text-embedding-3-large 模型。

将文档上传到索引

目前,索引 earth_at_night 为空。 运行以下代码,使用 美国宇航局地球在夜间电子书中的 JSON 文档填充索引。 根据 Azure AI 搜索的要求,每个文档都符合索引架构中定义的字段和数据类型。

String documentsUrl = "https://raw.githubusercontent.com/Azure-Samples/azure-search-sample-data/refs/heads/main/nasa-e-book/earth-at-night-json/documents.json";
        
try {
    java.net.http.HttpClient httpClient = java.net.http.HttpClient.newHttpClient();
    java.net.http.HttpRequest request = java.net.http.HttpRequest.newBuilder()
        .uri(URI.create(documentsUrl))
        .build();
    
    java.net.http.HttpResponse<String> response = httpClient.send(request, 
        java.net.http.HttpResponse.BodyHandlers.ofString());
    
    if (response.statusCode() != 200) {
        throw new IOException("Failed to fetch documents: " + response.statusCode());
    }
    
    ObjectMapper mapper = new ObjectMapper();
    JsonNode jsonArray = mapper.readTree(response.body());
    
    List<SearchDocument> documents = new ArrayList<>();
    for (int i = 0; i < jsonArray.size(); i++) {
        JsonNode doc = jsonArray.get(i);
        SearchDocument searchDoc = new SearchDocument();
        
        searchDoc.put("id", doc.has("id") ? doc.get("id").asText() : String.valueOf(i + 1));
        searchDoc.put("page_chunk", doc.has("page_chunk") ? doc.get("page_chunk").asText() : "");
        
        // Handle embeddings
        if (doc.has("page_embedding_text_3_large") && doc.get("page_embedding_text_3_large").isArray()) {
            List<Double> embeddings = new ArrayList<>();
            for (JsonNode embedding : doc.get("page_embedding_text_3_large")) {
                embeddings.add(embedding.asDouble());
            }
            searchDoc.put("page_embedding_text_3_large", embeddings);
        } else {
            // Fallback embeddings
            List<Double> fallbackEmbeddings = new ArrayList<>();
            for (int j = 0; j < 3072; j++) {
                fallbackEmbeddings.add(0.1);
            }
            searchDoc.put("page_embedding_text_3_large", fallbackEmbeddings);
        }
        
        searchDoc.put("page_number", doc.has("page_number") ? doc.get("page_number").asInt() : i + 1);
        
        documents.add(searchDoc);
    }
    
    System.out.println("[DONE] Fetched " + documents.size() + " documents from GitHub");
    return documents;
    
}

创建知识代理

要在查询时将 Azure AI 搜索连接到 gpt-5-mini 部署并面向 earth_at_night 索引,需要使用知识代理。 以下代码定义一个名为 earth-search-agent 的知识代理,该代理定义使用代理定义处理查询并从索引中检索相关文档 earth_at_night

为确保响应的相关性和语义意义明确,已设置 defaultRerankerThreshold,以排除 reranker 分数为 2.5 或更低的响应。

ObjectMapper mapper = new ObjectMapper();
ObjectNode agentDefinition = mapper.createObjectNode();
agentDefinition.put("name", AGENT_NAME);
agentDefinition.put("description", "Knowledge agent for Earth at Night e-book content");

ObjectNode model = mapper.createObjectNode();
model.put("kind", "azureOpenAI");
ObjectNode azureOpenAIParams = mapper.createObjectNode();
azureOpenAIParams.put("resourceUri", AZURE_OPENAI_ENDPOINT);
azureOpenAIParams.put("deploymentId", AZURE_OPENAI_GPT_DEPLOYMENT);
azureOpenAIParams.put("modelName", AZURE_OPENAI_GPT_MODEL);
model.set("azureOpenAIParameters", azureOpenAIParams);
agentDefinition.set("models", mapper.createArrayNode().add(model));

ObjectNode targetIndex = mapper.createObjectNode();
targetIndex.put("indexName", INDEX_NAME);
targetIndex.put("defaultRerankerThreshold", 2.5);
agentDefinition.set("targetIndexes", mapper.createArrayNode().add(targetIndex));

String token = getAccessToken(credential, "https://search.azure.com/.default");

java.net.http.HttpClient httpClient = java.net.http.HttpClient.newHttpClient();
java.net.http.HttpRequest request = java.net.http.HttpRequest.newBuilder()
    .uri(URI.create(SEARCH_ENDPOINT + "/agents/" + AGENT_NAME + "?api-version=" + SEARCH_API_VERSION))
    .header("Content-Type", "application/json")
    .header("Authorization", "Bearer " + token)
    .PUT(java.net.http.HttpRequest.BodyPublishers.ofString(mapper.writeValueAsString(agentDefinition)))
    .build();

java.net.http.HttpResponse<String> response = httpClient.send(request,
    java.net.http.HttpResponse.BodyHandlers.ofString());

设置消息

消息是检索路由的输入,包含对话历史记录。 每条消息都包含一个角色,该角色指示其来源,例如助理或用户,以及自然语言中的内容。 使用的 LLM 决定了哪些角色有效。

用户消息表示要处理的查询,而助理消息指导知识代理如何响应。 在检索过程中,这些消息将发送到 LLM,以便从索引文档中提取相关响应。

此助理消息指示 earth-search-agent 在夜间回答有关地球的问题,使用 ref_id 引用来源,并在答案不可用时回答“我不知道”。

List<Map<String, String>> messages = new ArrayList<>();

Map<String, String> systemMessage = new HashMap<>();
systemMessage.put("role", "system");
systemMessage.put("content", "A Q&A agent that can answer questions about the Earth at night.\n" +
    "Sources have a JSON format with a ref_id that must be cited in the answer.\n" +
    "If you do not have the answer, respond with \"I don't know\".");
messages.add(systemMessage);

Map<String, String> userMessage = new HashMap<>();
userMessage.put("role", "user");
userMessage.put("content", "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?");
messages.add(userMessage);

运行检索管道

此步骤运行检索管道,以便从搜索索引中提取相关信息。 根据检索请求中的信息和参数,LLM:

  1. 分析整个对话历史记录,以确定所需的基础信息。
  2. 将复合用户查询分解为重点子查询。
  3. 针对索引中的文本字段和矢量嵌入同时运行每个子查询。
  4. 使用语义排名器对所有子查询的结果重新排序。
  5. 将结果合并到单个字符串中。

以下代码将一个由两部分构成的用户查询发送到 earth-search-agent,该代码会将查询解构为子查询,并在 earth_at_night 索引中的文本字段和向量嵌入上运行这些子查询,随后对结果进行排名和合并。 然后,响应将追加到 messages 列表中。

ObjectMapper mapper = new ObjectMapper();
ObjectNode retrievalRequest = mapper.createObjectNode();

// Convert messages to the correct format expected by the Knowledge agent
com.fasterxml.jackson.databind.node.ArrayNode agentMessages = mapper.createArrayNode();
for (Map<String, String> msg : messages) {
    ObjectNode agentMessage = mapper.createObjectNode();
    agentMessage.put("role", msg.get("role"));
    
    com.fasterxml.jackson.databind.node.ArrayNode content = mapper.createArrayNode();
    ObjectNode textContent = mapper.createObjectNode();
    textContent.put("type", "text");
    textContent.put("text", msg.get("content"));
    content.add(textContent);
    agentMessage.set("content", content);
    
    agentMessages.add(agentMessage);
}
retrievalRequest.set("messages", agentMessages);

com.fasterxml.jackson.databind.node.ArrayNode targetIndexParams = mapper.createArrayNode();
ObjectNode indexParam = mapper.createObjectNode();
indexParam.put("indexName", INDEX_NAME);
indexParam.put("rerankerThreshold", 2.5);
indexParam.put("maxDocsForReranker", 100);
indexParam.put("includeReferenceSourceData", true);
targetIndexParams.add(indexParam);
retrievalRequest.set("targetIndexParams", targetIndexParams);

String token = getAccessToken(credential, "https://search.azure.com/.default");

java.net.http.HttpClient httpClient = java.net.http.HttpClient.newHttpClient();
java.net.http.HttpRequest request = java.net.http.HttpRequest.newBuilder()
    .uri(URI.create(SEARCH_ENDPOINT + "/agents/" + AGENT_NAME + "/retrieve?api-version=" + SEARCH_API_VERSION))
    .header("Content-Type", "application/json")
    .header("Authorization", "Bearer " + token)
    .POST(java.net.http.HttpRequest.BodyPublishers.ofString(mapper.writeValueAsString(retrievalRequest)))
    .build();

java.net.http.HttpResponse<String> response = httpClient.send(request,
    java.net.http.HttpResponse.BodyHandlers.ofString());

查看响应、活动和结果

现在,你想要显示检索管道的响应、活动和结果。

来自 Azure AI 搜索的每个检索响应包括:

  • 表示搜索结果中基础数据的统一字符串。

  • 查询计划。

  • 引用数据,其中显示了源文档的哪些区块促成了统一字符串。

ObjectMapper mapper = new ObjectMapper();
        
// Log activities
System.out.println("\nActivities:");
if (responseJson.has("activity") && responseJson.get("activity").isArray()) {
    for (JsonNode activity : responseJson.get("activity")) {
        String activityType = "UnknownActivityRecord";
        if (activity.has("InputTokens")) {
            activityType = "KnowledgeAgentModelQueryPlanningActivityRecord";
        } else if (activity.has("TargetIndex")) {
            activityType = "KnowledgeAgentSearchActivityRecord";
        } else if (activity.has("QueryTime")) {
            activityType = "KnowledgeAgentSemanticRankerActivityRecord";
        }
        
        System.out.println("Activity Type: " + activityType);
        try {
            System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(activity));
        } catch (Exception e) {
            System.out.println(activity.toString());
        }
    }
}

// Log results
System.out.println("Results");
if (responseJson.has("references") && responseJson.get("references").isArray()) {
    for (JsonNode reference : responseJson.get("references")) {
        String referenceType = "KnowledgeAgentAzureSearchDocReference";
        
        System.out.println("Reference Type: " + referenceType);
        try {
            System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(reference));
        } catch (Exception e) {
            System.out.println(reference.toString());
        }
    }
}

输出应包括:

  • Response 根据用户查询在搜索索引中提供最相关的文档(或区块)的文本字符串。 如本快速入门稍后所示,可以将此字符串传递给 LLM 进行答案生成。

  • Activity 跟踪检索过程中采取的步骤,其中包括由您的 gpt-5-mini 部署生成的子查询,以及用于查询规划和执行的令牌。

  • Results 列出构成该响应的文档,每个文档都由其 DocKey标识。

创建 Azure OpenAI 客户端

若要将检索管道从应答 提取 扩展到应答 生成,请设置 Azure OpenAI 客户端以与 gpt-5-mini 部署交互。

OpenAIAsyncClient openAIClient = new OpenAIClientBuilder()
    .endpoint(AZURE_OPENAI_ENDPOINT)
    .credential(credential)
    .buildAsyncClient();

使用聊天补全 API 生成答案

用于生成答案的一个选项是聊天完成 API,该 API 将会话历史记录传递给 LLM 进行处理。

List<ChatRequestMessage> chatMessages = new ArrayList<>();
for (Map<String, String> msg : messages) {
    String role = msg.get("role");
    String content = msg.get("content");
    
    switch (role) {
        case "system":
            chatMessages.add(new ChatRequestSystemMessage(content));
            break;
        case "user":
            chatMessages.add(new ChatRequestUserMessage(content));
            break;
        case "assistant":
            chatMessages.add(new ChatRequestAssistantMessage(content));
            break;
    }
}

ChatCompletionsOptions chatOptions = new ChatCompletionsOptions(chatMessages)
    .setMaxTokens(1000)
    .setTemperature(0.7);

ChatCompletions completion = openAIClient.getChatCompletions(AZURE_OPENAI_GPT_DEPLOYMENT, chatOptions).block();

继续对话

通过向earth-search-agent发送另一个用户查询继续对话。 以下代码重新运行检索管道,从 earth_at_night 索引中提取相关内容,并将响应追加到 messages 列表中。 但是,与以前不同,现在可以使用 Azure OpenAI 客户端基于检索的内容生成答案。

String followUpQuestion = "How do I find lava at night?";
System.out.println("[QUESTION] Follow-up question: " + followUpQuestion);

Map<String, String> userMessage = new HashMap<>();
userMessage.put("role", "user");
userMessage.put("content", followUpQuestion);
messages.add(userMessage);

清理资源

在你自己的订阅中工作时,最好在结束项目时确定你是否仍需要创建的资源。 持续运行的资源可能会产生费用。 可以单独删除资源,也可以删除资源组以删除整个资源集。

在 Azure 门户中,可以通过从左窗格中选择 “所有资源 ”或 “资源组 ”来查找和管理资源。 还可以运行以下代码来删除在本快速入门中创建的对象。

删除知识代理

本快速入门中创建的知识代理通过以下代码片段进行删除:

String token = getAccessToken(credential, "https://search.azure.com/.default");
            
java.net.http.HttpClient httpClient = java.net.http.HttpClient.newHttpClient();
java.net.http.HttpRequest request = java.net.http.HttpRequest.newBuilder()
    .uri(URI.create(SEARCH_ENDPOINT + "/agents/" + AGENT_NAME + "?api-version=" + SEARCH_API_VERSION))
    .header("Authorization", "Bearer " + token)
    .DELETE()
    .build();

java.net.http.HttpResponse<String> response = httpClient.send(request,
    java.net.http.HttpResponse.BodyHandlers.ofString());

删除搜索索引

本快速入门中创建的搜索索引使用以下代码片段删除:

indexClient.deleteIndex(INDEX_NAME);
System.out.println("[DONE] Search index '" + INDEX_NAME + "' deleted successfully.");

注释

此功能目前处于公开预览状态。 此预览版未随附服务级别协议,建议不要用于生产工作负载。 某些功能可能不受支持或者受限。 有关详细信息,请参阅 Microsoft Azure 预览版补充使用条款

在本快速入门中,你将使用 代理检索 来创建由大型语言模型(LLM)和专有数据提供支持的对话搜索体验。 能动检索将复杂的用户查询分解为子查询,并行执行子查询,并从 Azure AI 搜索所索引的文档中提取基础数据。 输出适用于与代理和自定义聊天解决方案的集成。

虽然可以提供你自己的数据,但本快速入门使用了美国宇航局“夜间地球”电子书中的示例 JSON 文档。 这些文件描述了一般科学主题,以及从太空观测到的夜晚地球的图像。

小窍门

本快速入门的 JavaScript 版本使用 2025-05-01-preview REST API 版本,该版本不支持 2025-08-01-preview 中引入的知识来源和其他智能体检索功能。 若要使用这些功能,请参阅 C#、Python 或 REST 版本。

先决条件

配置访问权限

在开始之前,请确保你有权访问内容和操作。 我们建议使用 Microsoft Entra ID 进行身份验证,并使用基于角色的访问控制进行授权。 你必须是“所有者”或“用户访问管理员”才能分配角色。 如果角色设置不可行,请改用基于密钥的身份验证方式

若要配置此快速入门的访问权限,请选择以下两个选项卡。

Azure AI 搜索提供智能体检索管道。 配置自己和搜索服务的访问权限,以读取和写入数据、与 Azure AI Foundry 交互以及运行管道。

配置 Azure AI 搜索的访问权限:

  1. 登录到 Azure 门户 并选择搜索服务。

  2. 启用基于角色的访问

  3. 创建系统分配的托管标识

  4. 将以下角色分配给自己。

    • 搜索服务参与者

    • 搜索索引数据参与者

    • 搜索索引数据读取者

重要

代理检索具有两种基于标记的计费模型:

  • Azure AI 搜索的语义排序功能的收费标准。
  • Azure OpenAI 的查询规划和答案生成功能收费标准。

语义排名在初始公共预览版中是免费的。 预览版后,将应用标准标记计费。 有关详细信息,请参阅 代理检索的可用性和定价

获取终结点

每个 Azure AI 搜索服务和 Azure AI Foundry 资源都有一个终结点,该终结点是唯一的 URL,用于标识和提供对资源的网络访问权限。 在后面的部分中,指定这些终结点以便通过编程方式连接到你的资源。

若要获取本快速入门的终结点,请选择以下两个选项卡。

  1. 登录到 Azure 门户 并选择搜索服务。

  2. 在左窗格中,选择“ 概述”。

  3. 记下终结点,形式应与 https://my-service.search.windows.net 类似。

部署模型

若要使用智能体检索,必须将两个 Azure OpenAI 模型部署到 Azure AI Foundry 资源:

  • 用于文本到矢量转换的嵌入模型。 本快速入门使用 text-embedding-3-large,但你可以使用任何 text-embedding 模型。

  • 用于查询规划和答案生成的 LLM。 本快速入门使用的是 gpt-5-mini,但你也可以使用任何受支持的具备智能体检索的 LLM

有关部署说明,请参阅 使用 Azure AI Foundry 部署 Azure OpenAI 模型

设置环境

  1. 创建一个新文件夹 quickstart-agentic-retrieval 以包含该应用程序,并在该文件夹中使用以下命令打开 Visual Studio Code:

    mkdir quickstart-agentic-retrieval && cd quickstart-agentic-retrieval
    
  2. 使用以下命令创建 package.json

    npm init -y
    
  3. 安装适用于 JavaScript 的 Azure AI 搜索客户端库 (Azure.Search.Documents)

    npm install @azure/search-documents --version 12.2.0-alpha.20250606.1
    
  4. 使用以下命令安装 Azure OpenAI 客户端库:

    npm install @azure/openai --version 5.10.1
    
  5. 安装 dotenv 包,以从 .env 文件加载环境变量。

    npm install dotenv
    
  6. 若要使用 Microsoft Entra ID 进行推荐的无密钥身份验证,请使用以下命令安装 Azure.Identity 客户端库:

    npm install @azure/identity
    

运行代码

  1. .env文件夹中创建一个名为quickstart-agentic-retrieval的新文件,并添加以下环境变量:

    AZURE_OPENAI_ENDPOINT=https://<your-ai-foundry-resource-name>.openai.azure.com/
    AZURE_OPENAI_GPT_DEPLOYMENT=gpt-5-mini
    AZURE_OPENAI_EMBEDDING_DEPLOYMENT=text-embedding-3-large
    AZURE_SEARCH_ENDPOINT=https://<your-search-service-name>.search.windows.net
    AZURE_SEARCH_INDEX_NAME=agentic-retrieval-sample
    

    <your-search-service-name><your-ai-foundry-resource-name> 替换为实际的 Azure AI 搜索服务名称和 Azure AI Foundry 资源名称。

  2. 将以下代码粘贴到名为 index.js 的新文件中:

    import { DefaultAzureCredential, getBearerTokenProvider } from '@azure/identity';
    import { SearchIndexClient, SearchClient } from '@azure/search-documents';
    import { AzureOpenAI } from "openai/index.mjs";
    // Load the .env file if it exists
    import * as dotenv from "dotenv";
    dotenv.config();
    // Configuration - Update these values for your environment
    const config = {
        searchEndpoint: process.env.AZURE_SEARCH_ENDPOINT || "https://your-search-service.search.windows.net",
        azureOpenAIEndpoint: process.env.AZURE_OPENAI_ENDPOINT || "https://your-ai-foundry-resource.openai.azure.com/",
        azureOpenAIGptDeployment: process.env.AZURE_OPENAI_GPT_DEPLOYMENT || "gpt-5-mini",
        azureOpenAIGptModel: "gpt-5-mini",
        azureOpenAIApiVersion: process.env.OPENAI_API_VERSION || "2025-03-01-preview",
        azureOpenAIEmbeddingDeployment: process.env.AZURE_OPENAI_EMBEDDING_DEPLOYMENT || "text-embedding-3-large",
        azureOpenAIEmbeddingModel: "text-embedding-3-large",
        indexName: "earth_at_night",
        agentName: "earth-search-agent",
        searchApiVersion: "2025-05-01-Preview"
    };
    async function main() {
        try {
            console.log("🚀 Starting Azure AI Search agentic retrieval quickstart...\n");
            // Initialize Azure credentials using managed identity (recommended)
            const credential = new DefaultAzureCredential();
            // Create search clients
            const searchIndexClient = new SearchIndexClient(config.searchEndpoint, credential);
            const searchClient = new SearchClient(config.searchEndpoint, config.indexName, credential);
            // Create Azure OpenAI client
            const scope = "https://cognitiveservices.azure.com/.default";
            const azureADTokenProvider = getBearerTokenProvider(credential, scope);
            const openAIClient = new AzureOpenAI({
                endpoint: config.azureOpenAIEndpoint,
                apiVersion: config.azureOpenAIApiVersion,
                azureADTokenProvider,
            });
            // Create search index with vector and semantic capabilities
            await createSearchIndex(searchIndexClient);
            // Upload sample documents
            await uploadDocuments(searchClient);
            // Create knowledge agent for agentic retrieval
            await createKnowledgeAgent(credential);
            // Run agentic retrieval with conversation
            await runAgenticRetrieval(credential, openAIClient);
            // Clean up - Delete knowledge agent and search index
            await deleteKnowledgeAgent(credential);
            await deleteSearchIndex(searchIndexClient);
            console.log("✅ Quickstart completed successfully!");
        }
        catch (error) {
            console.error("❌ Error in main execution:", error);
            throw error;
        }
    }
    async function createSearchIndex(indexClient) {
        console.log("📊 Creating search index...");
        const index = {
            name: config.indexName,
            fields: [
                {
                    name: "id",
                    type: "Edm.String",
                    key: true,
                    filterable: true,
                    sortable: true,
                    facetable: true
                },
                {
                    name: "page_chunk",
                    type: "Edm.String",
                    searchable: true,
                    filterable: false,
                    sortable: false,
                    facetable: false
                },
                {
                    name: "page_embedding_text_3_large",
                    type: "Collection(Edm.Single)",
                    searchable: true,
                    filterable: false,
                    sortable: false,
                    facetable: false,
                    vectorSearchDimensions: 3072,
                    vectorSearchProfileName: "hnsw_text_3_large"
                },
                {
                    name: "page_number",
                    type: "Edm.Int32",
                    filterable: true,
                    sortable: true,
                    facetable: true
                }
            ],
            vectorSearch: {
                profiles: [
                    {
                        name: "hnsw_text_3_large",
                        algorithmConfigurationName: "alg",
                        vectorizerName: "azure_openai_text_3_large"
                    }
                ],
                algorithms: [
                    {
                        name: "alg",
                        kind: "hnsw"
                    }
                ],
                vectorizers: [
                    {
                        vectorizerName: "azure_openai_text_3_large",
                        kind: "azureOpenAI",
                        parameters: {
                            resourceUrl: config.azureOpenAIEndpoint,
                            deploymentId: config.azureOpenAIEmbeddingDeployment,
                            modelName: config.azureOpenAIEmbeddingModel
                        }
                    }
                ]
            },
            semanticSearch: {
                defaultConfigurationName: "semantic_config",
                configurations: [
                    {
                        name: "semantic_config",
                        prioritizedFields: {
                            contentFields: [
                                { name: "page_chunk" }
                            ]
                        }
                    }
                ]
            }
        };
        try {
            await indexClient.createOrUpdateIndex(index);
            console.log(`✅ Index '${config.indexName}' created or updated successfully.`);
        }
        catch (error) {
            console.error("❌ Error creating index:", error);
            throw error;
        }
    }
    async function deleteSearchIndex(indexClient) {
        console.log("🗑️ Deleting search index...");
        try {
            await indexClient.deleteIndex(config.indexName);
            console.log(`✅ Search index '${config.indexName}' deleted successfully.`);
        }
        catch (error) {
            if (error?.statusCode === 404 || error?.code === 'IndexNotFound') {
                console.log(`ℹ️ Search index '${config.indexName}' does not exist or was already deleted.`);
                return;
            }
            console.error("❌ Error deleting search index:", error);
            throw error;
        }
    }
    // Fetch Earth at Night documents from GitHub
    async function fetchEarthAtNightDocuments() {
        console.log("📡 Fetching Earth at Night documents from GitHub...");
        const documentsUrl = "https://raw.githubusercontent.com/Azure-Samples/azure-search-sample-data/refs/heads/main/nasa-e-book/earth-at-night-json/documents.json";
        try {
            const response = await fetch(documentsUrl);
            if (!response.ok) {
                throw new Error(`Failed to fetch documents: ${response.status} ${response.statusText}`);
            }
            const documents = await response.json();
            console.log(`✅ Fetched ${documents.length} documents from GitHub`);
            // Validate and transform documents to match our interface
            const transformedDocuments = documents.map((doc, index) => {
                return {
                    id: doc.id || String(index + 1),
                    page_chunk: doc.page_chunk || doc.content || '',
                    page_embedding_text_3_large: doc.page_embedding_text_3_large || new Array(3072).fill(0.1),
                    page_number: doc.page_number || index + 1
                };
            });
            return transformedDocuments;
        }
        catch (error) {
            console.error("❌ Error fetching documents from GitHub:", error);
            console.log("🔄 Falling back to sample documents...");
            // Fallback to sample documents if fetch fails
            return [
                {
                    id: "1",
                    page_chunk: "The Earth at night reveals the patterns of human settlement and economic activity. City lights trace the contours of civilization, creating a luminous map of where people live and work.",
                    page_embedding_text_3_large: new Array(3072).fill(0.1),
                    page_number: 1
                },
                {
                    id: "2",
                    page_chunk: "From space, the aurora borealis appears as shimmering curtains of green and blue light dancing across the polar regions.",
                    page_embedding_text_3_large: new Array(3072).fill(0.2),
                    page_number: 2
                }
                // Add more fallback documents as needed
            ];
        }
    }
    async function uploadDocuments(searchClient) {
        console.log("📄 Uploading documents...");
        try {
            // Fetch documents from GitHub
            const documents = await fetchEarthAtNightDocuments();
            const result = await searchClient.uploadDocuments(documents);
            console.log(`✅ Uploaded ${result.results.length} documents successfully.`);
            // Wait for indexing to complete
            console.log("⏳ Waiting for document indexing to complete...");
            await new Promise(resolve => setTimeout(resolve, 5000));
            console.log("✅ Document indexing completed.");
        }
        catch (error) {
            console.error("❌ Error uploading documents:", error);
            throw error;
        }
    }
    async function createKnowledgeAgent(credential) {
        // In case the agent already exists, delete it first
        await deleteKnowledgeAgent(credential);
        console.log("🤖 Creating knowledge agent...");
        const agentDefinition = {
            name: config.agentName,
            description: "Knowledge agent for Earth at Night e-book content",
            models: [
                {
                    kind: "azureOpenAI",
                    azureOpenAIParameters: {
                        resourceUri: config.azureOpenAIEndpoint,
                        deploymentId: config.azureOpenAIGptDeployment,
                        modelName: config.azureOpenAIGptModel
                    }
                }
            ],
            targetIndexes: [
                {
                    indexName: config.indexName,
                    defaultRerankerThreshold: 2.5
                }
            ]
        };
        try {
            const token = await getAccessToken(credential, "https://search.azure.com/.default");
            const response = await fetch(`${config.searchEndpoint}/agents/${config.agentName}?api-version=${config.searchApiVersion}`, {
                method: 'PUT',
                headers: {
                    'Content-Type': 'application/json',
                    'Authorization': `Bearer ${token}`
                },
                body: JSON.stringify(agentDefinition)
            });
            if (!response.ok) {
                const errorText = await response.text();
                throw new Error(`Failed to create knowledge agent: ${response.status} ${response.statusText}\n${errorText}`);
            }
            console.log(`✅ Knowledge agent '${config.agentName}' created successfully.`);
        }
        catch (error) {
            console.error("❌ Error creating knowledge agent:", error);
            throw error;
        }
    }
    async function runAgenticRetrieval(credential, openAIClient) {
        console.log("🔍 Running agentic retrieval...");
        const messages = [
            {
                role: "system",
                content: `A Q&A agent that can answer questions about the Earth at night.
    Sources have a JSON format with a ref_id that must be cited in the answer.
    If you do not have the answer, respond with "I don't know".`
            },
            {
                role: "user",
                content: "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?"
            }
        ];
        try {
            // Call agentic retrieval API
            const userMessages = messages.filter(m => m.role !== "system");
            const retrievalResponse = await callAgenticRetrieval(credential, userMessages);
            // Extract the assistant response from agentic retrieval
            let assistantContent = '';
            if (typeof retrievalResponse.response === 'string') {
                assistantContent = retrievalResponse.response;
            }
            else if (Array.isArray(retrievalResponse.response)) {
                assistantContent = JSON.stringify(retrievalResponse.response);
            }
            // Add assistant response to conversation history
            messages.push({
                role: "assistant",
                content: assistantContent
            });
            console.log(assistantContent);
            // Log activities and results...
            console.log("\nActivities:");
            if (retrievalResponse.activity && Array.isArray(retrievalResponse.activity)) {
                retrievalResponse.activity.forEach((activity) => {
                    const activityType = activity.activityType || activity.type || 'UnknownActivityRecord';
                    console.log(`Activity Type: ${activityType}`);
                    console.log(JSON.stringify(activity, null, 2));
                });
            }
            console.log("Results");
            if (retrievalResponse.references && Array.isArray(retrievalResponse.references)) {
                retrievalResponse.references.forEach((reference) => {
                    const referenceType = reference.referenceType || reference.type || 'AzureSearchDoc';
                    console.log(`Reference Type: ${referenceType}`);
                    console.log(JSON.stringify(reference, null, 2));
                });
            }
            // Now do chat completion with full conversation history
            await generateFinalAnswer(openAIClient, messages);
            // Continue conversation with second question
            await continueConversation(credential, openAIClient, messages);
        }
        catch (error) {
            console.error("❌ Error in agentic retrieval:", error);
            throw error;
        }
    }
    async function generateFinalAnswer(openAIClient, messages) {
        console.log("\n[ASSISTANT]: ");
        try {
            const completion = await openAIClient.chat.completions.create({
                model: config.azureOpenAIGptDeployment,
                messages: messages.map(m => ({ role: m.role, content: m.content })),
                max_tokens: 1000,
                temperature: 0.7
            });
            const answer = completion.choices[0].message.content;
            console.log(answer?.replace(/\./g, "\n"));
            // Add this response to conversation history
            if (answer) {
                messages.push({
                    role: "assistant",
                    content: answer
                });
            }
        }
        catch (error) {
            console.error("❌ Error generating final answer:", error);
            throw error;
        }
    }
    async function callAgenticRetrieval(credential, messages) {
        // Convert messages to the correct format expected by the Knowledge agent
        const agentMessages = messages.map(msg => ({
            role: msg.role,
            content: [
                {
                    type: "text",
                    text: msg.content
                }
            ]
        }));
        const retrievalRequest = {
            messages: agentMessages,
            targetIndexParams: [
                {
                    indexName: config.indexName,
                    rerankerThreshold: 2.5,
                    maxDocsForReranker: 100,
                    includeReferenceSourceData: true
                }
            ]
        };
        const token = await getAccessToken(credential, "https://search.azure.com/.default");
        const response = await fetch(`${config.searchEndpoint}/agents/${config.agentName}/retrieve?api-version=${config.searchApiVersion}`, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'Authorization': `Bearer ${token}`
            },
            body: JSON.stringify(retrievalRequest)
        });
        if (!response.ok) {
            const errorText = await response.text();
            throw new Error(`Agentic retrieval failed: ${response.status} ${response.statusText}\n${errorText}`);
        }
        return await response.json();
    }
    async function deleteKnowledgeAgent(credential) {
        console.log("🗑️ Deleting knowledge agent...");
        try {
            const token = await getAccessToken(credential, "https://search.azure.com/.default");
            const response = await fetch(`${config.searchEndpoint}/agents/${config.agentName}?api-version=${config.searchApiVersion}`, {
                method: 'DELETE',
                headers: {
                    'Authorization': `Bearer ${token}`
                }
            });
            if (!response.ok) {
                if (response.status === 404) {
                    console.log(`ℹ️ Knowledge agent '${config.agentName}' does not exist or was already deleted.`);
                    return;
                }
                const errorText = await response.text();
                throw new Error(`Failed to delete knowledge agent: ${response.status} ${response.statusText}\n${errorText}`);
            }
            console.log(`✅ Knowledge agent '${config.agentName}' deleted successfully.`);
        }
        catch (error) {
            console.error("❌ Error deleting knowledge agent:", error);
            throw error;
        }
    }
    async function continueConversation(credential, openAIClient, messages) {
        console.log("\n💬 === Continuing Conversation ===");
        // Add follow-up question
        const followUpQuestion = "How do I find lava at night?";
        console.log(`❓ Follow-up question: ${followUpQuestion}`);
        messages.push({
            role: "user",
            content: followUpQuestion
        });
        try {
            // Don't include system messages in this retrieval
            const userAssistantMessages = messages.filter((m) => m.role !== "system");
            const newRetrievalResponse = await callAgenticRetrieval(credential, userAssistantMessages);
            // Extract assistant response and add to conversation
            let assistantContent = '';
            if (typeof newRetrievalResponse.response === 'string') {
                assistantContent = newRetrievalResponse.response;
            }
            else if (Array.isArray(newRetrievalResponse.response)) {
                assistantContent = JSON.stringify(newRetrievalResponse.response);
            }
            // Add assistant response to conversation history
            messages.push({
                role: "assistant",
                content: assistantContent
            });
            console.log(assistantContent);
            // Log activities and results like the first retrieval
            console.log("\nActivities:");
            if (newRetrievalResponse.activity && Array.isArray(newRetrievalResponse.activity)) {
                newRetrievalResponse.activity.forEach((activity) => {
                    const activityType = activity.activityType || activity.type || 'UnknownActivityRecord';
                    console.log(`Activity Type: ${activityType}`);
                    console.log(JSON.stringify(activity, null, 2));
                });
            }
            console.log("Results");
            if (newRetrievalResponse.references && Array.isArray(newRetrievalResponse.references)) {
                newRetrievalResponse.references.forEach((reference) => {
                    const referenceType = reference.referenceType || reference.type || 'AzureSearchDoc';
                    console.log(`Reference Type: ${referenceType}`);
                    console.log(JSON.stringify(reference, null, 2));
                });
            }
            // Generate final answer for follow-up
            await generateFinalAnswer(openAIClient, messages);
            console.log("\n🎉 === Conversation Complete ===");
        }
        catch (error) {
            console.error("❌ Error in conversation continuation:", error);
            throw error;
        }
    }
    async function getAccessToken(credential, scope) {
        const tokenResponse = await credential.getToken(scope);
        return tokenResponse.token;
    }
    // Error handling wrapper
    async function runWithErrorHandling() {
        try {
            await main();
        }
        catch (error) {
            console.error("💥 Application failed:", error);
            process.exit(1);
        }
    }
    // Execute the application - ES module style
    runWithErrorHandling();
    export { main, createSearchIndex, deleteSearchIndex, fetchEarthAtNightDocuments, uploadDocuments, createKnowledgeAgent, deleteKnowledgeAgent, runAgenticRetrieval };
    
  3. 使用以下命令登录到 Azure:

    az login
    
  4. 使用以下命令运行 JavaScript 代码:

    node index.js
    

输出

应用程序的输出应如下所示:

[dotenv@17.2.0] injecting env (0) from .env (tip: ⚙️  override existing env vars with { override: true })
🚀 Starting Azure AI Search agentic retrieval quickstart...

📊 Creating search index...
✅ Index 'earth_at_night' created or updated successfully.
📄 Uploading documents...
📡 Fetching Earth at Night documents from GitHub...
✅ Fetched 194 documents from GitHub
✅ Uploaded 194 documents successfully.
⏳ Waiting for document indexing to complete...
✅ Document indexing completed.
🗑️ Deleting knowledge agent...
ℹ️ Knowledge agent 'earth-search-agent' does not exist or was already deleted.
🤖 Creating knowledge agent...
✅ Knowledge agent 'earth-search-agent' created successfully.
🔍 Running agentic retrieval...
[{"role":"assistant","content":[{"type":"text","text":"[]"}]}]

Activities:
Activity Type: ModelQueryPlanning
{
  "type": "ModelQueryPlanning",
  "id": 0,
  "inputTokens": 1379,
  "outputTokens": 551
}
Activity Type: AzureSearchQuery
{
  "type": "AzureSearchQuery",
  "id": 1,
  "targetIndex": "earth_at_night",
  "query": {
    "search": "Why do suburban areas show greater December brightening compared to urban cores despite higher absolute light levels downtown?",
    "filter": null
  },
  "queryTime": "2025-07-20T16:12:59.804Z",
  "count": 0,
  "elapsedMs": 549
}
Activity Type: AzureSearchQuery
{
  "type": "AzureSearchQuery",
  "id": 2,
  "targetIndex": "earth_at_night",
  "query": {
    "search": "Why is the Phoenix nighttime street grid sharply visible from space, while large stretches of interstate highways between Midwestern cities appear comparatively dim?",
    "filter": null
  },
  "queryTime": "2025-07-20T16:13:00.061Z",
  "count": 0,
  "elapsedMs": 256
}
Activity Type: AzureSearchSemanticRanker
{
  "type": "AzureSearchSemanticRanker",
  "id": 3,
  "inputTokens": 47630
}
Results

[ASSISTANT]: 
Suburban belts show larger December brightening than urban cores despite higher absolute light levels downtown because suburban areas often have more seasonal variation in lighting usage, such as increased decorative and outdoor lighting during the holiday season in December
 Urban cores typically have more constant and dense lighting throughout the year, so the relative increase in brightness during December is less pronounced compared to suburban areas
\n\nThe Phoenix nighttime street grid is sharply visible from space because the city has a well-planned, extensive grid of streets with consistent and bright street lighting
 In contrast, large stretches of interstate highways between Midwestern cities appear comparatively dim because these highways have less continuous lighting and lower intensity lights, making them less visible from space
\n\n(Note: These explanations are based on general knowledge about urban lighting patterns and visibility from space; specific studies or sources were not provided
)

💬 === Continuing Conversation ===
❓ Follow-up question: How do I find lava at night?
[{"role":"assistant","content":[{"type":"text","text":"[{\"ref_id\":0,\"content\":\"<!-- PageHeader=\\\"Volcanoes\\\" -->\\n\\n### Nighttime Glow at Mount Etna - Italy\\n\\nAt about 2:30 a.m. local time on March 16, 2017, the VIIRS DNB on the Suomi NPP satellite captured this nighttime image of lava flowing on Mount Etna in Sicily, Italy. Etna is one of the world's most active volcanoes.\\n\\n#### Figure: Location of Mount Etna\\nA world globe is depicted, with a marker indicating the location of Mount Etna in Sicily, Italy, in southern Europe near the center of the Mediterranean Sea.\\n\\n<!-- PageFooter=\\\"Earth at Night\\\" -->\\n<!-- PageNumber=\\\"48\\\" -->\"},{\"ref_id\":1,\"content\":\"<!-- PageHeader=\\\"Volcanoes\\\" -->\\n\\n## Volcanoes\\n\\n### The Infrared Glows of Kilauea's Lava Flows—Hawaii\\n\\nIn early May 2018, an eruption on Hawaii's Kilauea volcano began to unfold. The eruption took a dangerous turn on May 3, 2018, when new fissures opened in the residential neighborhood of Leilani Estates. During the summer-long eruptive event, other fissures emerged along the East Rift Zone. Lava from vents along the rift zone flowed downslope, reaching the ocean in several areas, and filling in Kapoho Bay.\\n\\nA time series of Landsat 8 imagery shows the progression of the lava flows from May 16 to August 13. The night view combines thermal, shortwave infrared, and near-infrared wavelengths to tease out the very hot lava (bright white), cooling lava (red), and lava flows obstructed by clouds (purple).\\n\\n#### Figure: Location of Kilauea Volcano, Hawaii\\n\\nA globe is shown centered on North America, with a marker placed in the Pacific Ocean indicating the location of Hawaii, to the southwest of the mainland United States.\\n\\n<!-- PageFooter=\\\"Earth at Night\\\" -->\\n<!-- PageNumber=\\\"44\\\" -->\"},{\"ref_id\":2,\"content\":\"For the first time in perhaps a decade, Mount Etna experienced a \\\"flank eruption\\\"—erupting from its side instead of its summit—on December 24, 2018. The activity was accompanied by 130 earthquakes occurring over three hours that morning. Mount Etna, Europe’s most active volcano, has seen periodic activity on this part of the mountain since 2013. The Operational Land Imager (OLI) on the Landsat 8 satellite acquired the main image of Mount Etna on December 28, 2018.\\n\\nThe inset image highlights the active vent and thermal infrared signature from lava flows, which can be seen near the newly formed fissure on the southeastern side of the volcano. The inset was created with data from OLI and the Thermal Infrared Sensor (TIRS) on Landsat 8. Ash spewing from the fissure cloaked adjacent villages and delayed aircraft from landing at the nearby Catania airport. Earthquakes occurred in the subsequent days after the initial eruption and displaced hundreds of people from their homes.\\n\\nFor nighttime images of Mount Etna’s March 2017 eruption, see pages 48–51.\\n\\n---\\n\\n### Hazards of Volcanic Ash Plumes and Satellite Observation\\n\\nWith the help of moonlight, satellite instruments can track volcanic ash plumes, which present significant hazards to airplanes in flight. The volcanic ash—composed of tiny pieces of glass and rock—is abrasive to engine turbine blades, and can melt on the blades and other engine parts, causing damage and even engine stalls. This poses a danger to both the plane’s integrity and passenger safety. Volcanic ash also reduces visibility for pilots and can cause etching of windshields, further reducing pilots’ ability to see. Nightlight images can be combined with thermal images to provide a more complete view of volcanic activity on Earth’s surface.\\n\\nThe VIIRS Day/Night Band (DNB) on polar-orbiting satellites uses faint light sources such as moonlight, airglow (the atmosphere’s self-illumination through chemical reactions), zodiacal light (sunlight scattered by interplanetary dust), and starlight from the Milky Way. Using these dim light sources, the DNB can detect changes in clouds, snow cover, and sea ice:\\n\\n#### Table: Light Sources Used by VIIRS DNB\\n\\n| Light Source         | Description                                                                  |\\n|----------------------|------------------------------------------------------------------------------|\\n| Moonlight            | Reflected sunlight from the Moon, illuminating Earth's surface at night      |\\n| Airglow              | Atmospheric self-illumination from chemical reactions                        |\\n| Zodiacal Light       | Sunlight scattered by interplanetary dust                                    |\\n| Starlight/Milky Way  | Faint illumination provided by stars in the Milky Way                        |\\n\\nGeostationary Operational Environmental Satellites (GOES), managed by NOAA, orbit over Earth’s equator and offer uninterrupted observations of North America. High-latitude areas such as Alaska benefit from polar-orbiting satellites like Suomi NPP, which provide overlapping coverage at the poles, enabling more data collection in these regions. During polar darkness (winter months), VIIRS DNB data allow scientists to:\\n\\n- Observe sea ice formation\\n- Monitor snow cover extent at the highest latitudes\\n- Detect open water for ship navigation\\n\\n#### Table: Satellite Coverage Overview\\n\\n| Satellite Type          | Orbit           | Coverage Area         | Special Utility                              |\\n|------------------------|-----------------|----------------------|----------------------------------------------|\\n| GOES                   | Geostationary   | Equatorial/North America | Continuous regional monitoring              |\\n| Polar-Orbiting (e.g., Suomi NPP) | Polar-orbiting    | Poles/high latitudes      | Overlapping passes; useful during polar night|\\n\\n---\\n\\n### Weather Forecasting and Nightlight Data\\n\\nThe use of nightlight data by weather forecasters is growing as the VIIRS instrument enables observation of clouds at night illuminated by sources such as moonlight and lightning. Scientists use these data to study the nighttime behavior of weather systems, including severe storms, which can develop and strike populous areas at night as well as during the day. Combined with thermal data, visible nightlight data allow the detection of clouds at various heights in the atmosphere, such as dense marine fog. This capability enables weather forecasters to issue marine advisories with higher confidence, leading to greater utility. (See \\\"Marine Layer Clouds—California\\\" on page 56.)\\n\\nIn this section of the book, you will see how nightlight data are used to observe nature’s spectacular light shows across a wide range of sources.\\n\\n---\\n\\n#### Notable Data from Mount Etna Flank Eruption (December 2018)\\n\\n| Event/Observation                  | Details                                                                    |\\n|-------------------------------------|----------------------------------------------------------------------------|\\n| Date of Flank Eruption              | December 24, 2018                                                          |\\n| Number of Earthquakes               | 130 earthquakes within 3 hours                                              |\\n| Image Acquisition                   | December 28, 2018 by Landsat 8 OLI                                         |\\n| Location of Eruption                | Southeastern side of Mount Etna                                            |\\n| Thermal Imaging Data                | From OLI and TIRS (Landsat 8), highlighting active vent and lava flows     |\\n| Impact on Villages/Air Transport    | Ash covered villages; delayed aircraft at Catania airport                  |\\n| Displacement                        | Hundreds of residents displaced                                            |\\n| Ongoing Seismic Activity            | Earthquakes continued after initial eruption                               |\\n\\n---\\n\\n<!-- PageFooter=\\\"Earth at Night\\\" -->\\n<!-- PageNumber=\\\"30\\\" -->\"},{\"ref_id\":3,\"content\":\"# Volcanoes\\n\\n---\\n\\n### Mount Etna Erupts - Italy\\n\\nThe highly active Mount Etna in Italy sent red lava rolling down its flank on March 19, 2017. An astronaut onboard the ISS took the photograph below of the volcano and its environs that night. City lights surround the mostly dark volcanic area.\\n\\n---\\n\\n#### Figure 1: Location of Mount Etna, Italy\\n\\nA world map highlighting the location of Mount Etna in southern Italy. The marker indicates its geographic placement on the east coast of Sicily, Italy, in the Mediterranean region, south of mainland Europe and north of northern Africa.\\n\\n---\\n\\n#### Figure 2: Nighttime View of Mount Etna's Eruption and Surrounding Cities\\n\\nThis is a nighttime satellite image taken on March 19, 2017, showing the eruption of Mount Etna (southeastern cone) with visible bright red and orange coloring indicating flowing lava from a lateral vent. The surrounding areas are illuminated by city lights, with the following geographic references labeled:\\n\\n| Location        | Position in Image         | Visible Characteristics                    |\\n|-----------------|--------------------------|--------------------------------------------|\\n| Mt. Etna (southeastern cone) | Top center-left | Bright red/orange lava flow                |\\n| Lateral vent    | Left of the volcano       | Faint red/orange flow extending outwards   |\\n| Resort          | Below the volcano, to the left   | Small cluster of lights                    |\\n| Giarre          | Top right                 | Bright cluster of city lights              |\\n| Acireale        | Center right              | Large, bright area of city lights          |\\n| Biancavilla     | Bottom left               | Smaller cluster of city lights             |\\n\\nAn arrow pointing north is shown on the image for orientation.\\n\\n---\\n\\n<!-- Earth at Night Page Footer -->\\n<!-- Page Number: 50 -->\"},{\"ref_id\":4,\"content\":\"## Nature's Light Shows\\n\\nAt night, with the light of the Sun removed, nature's brilliant glow from Earth's surface becomes visible to the naked eye from space. Some of Earth's most spectacular light shows are natural, like the aurora borealis, or Northern Lights, in the Northern Hemisphere (aurora australis, or Southern Lights, in the Southern Hemisphere). The auroras are natural electrical phenomena caused by charged particles that race from the Sun toward Earth, inducing chemical reactions in the upper atmosphere and creating the appearance of streamers of reddish or greenish light in the sky, usually near the northern or southern magnetic pole. Other natural lights can indicate danger, like a raging forest fire encroaching on a city, town, or community, or lava spewing from an erupting volcano.\\n\\nWhatever the source, the ability of humans to monitor nature's light shows at night has practical applications for society. For example, tracking fires during nighttime hours allows for continuous monitoring and enhances our ability to protect humans and other animals, plants, and infrastructure. Combined with other data sources, our ability to observe the light of fires at night allows emergency managers to more efficiently and accurately issue warnings and evacuation orders and allows firefighting efforts to continue through the night. With enough moonlight (e.g., full-Moon phase), it's even possible to track the movement of smoke plumes at night, which can impact air quality, regardless of time of day.\\n\\nAnother natural source of light at night is emitted from glowing lava flows at the site of active volcanoes. Again, with enough moonlight, these dramatic scenes can be tracked and monitored for both scientific research and public safety.\\n\\n\\n### Figure: The Northern Lights Viewed from Space\\n\\n**September 17, 2011**\\n\\nThis photo, taken from the International Space Station on September 17, 2011, shows a spectacular display of the aurora borealis (Northern Lights) as green and reddish light in the night sky above Earth. In the foreground, part of a Soyuz spacecraft is visible, silhouetted against the bright auroral light. The green glow is generated by energetic charged particles from the Sun interacting with Earth's upper atmosphere, exciting oxygen and nitrogen atoms, and producing characteristic colors. The image demonstrates the vividness and grandeur of natural night-time light phenomena as seen from orbit.\"}]"}]}]

Activities:
Activity Type: ModelQueryPlanning
{
  "type": "ModelQueryPlanning",
  "id": 0,
  "inputTokens": 1598,
  "outputTokens": 159
}
Activity Type: AzureSearchQuery
{
  "type": "AzureSearchQuery",
  "id": 1,
  "targetIndex": "earth_at_night",
  "query": {
    "search": "How can I locate lava flows during nighttime?",
    "filter": null
  },
  "queryTime": "2025-07-20T16:13:10.659Z",
  "count": 5,
  "elapsedMs": 260
}
Activity Type: AzureSearchSemanticRanker
{
  "type": "AzureSearchSemanticRanker",
  "id": 2,
  "inputTokens": 24146
}
Results
Reference Type: AzureSearchDoc
{
  "type": "AzureSearchDoc",
  "id": "0",
  "activitySource": 1,
  "docKey": "earth_at_night_508_page_64_verbalized",
  "sourceData": {
    "id": "earth_at_night_508_page_64_verbalized",
    "page_chunk": "<!-- PageHeader=\"Volcanoes\" -->\n\n### Nighttime Glow at Mount Etna - Italy\n\nAt about 2:30 a.m. local time on March 16, 2017, the VIIRS DNB on the Suomi NPP satellite captured this nighttime image of lava flowing on Mount Etna in Sicily, Italy. Etna is one of the world's most active volcanoes.\n\n#### Figure: Location of Mount Etna\nA world globe is depicted, with a marker indicating the location of Mount Etna in Sicily, Italy, in southern Europe near the center of the Mediterranean Sea.\n\n<!-- PageFooter=\"Earth at Night\" -->\n<!-- PageNumber=\"48\" -->"
  }
}
Reference Type: AzureSearchDoc
{
  "type": "AzureSearchDoc",
  "id": "1",
  "activitySource": 1,
  "docKey": "earth_at_night_508_page_60_verbalized",
  "sourceData": {
    "id": "earth_at_night_508_page_60_verbalized",
    "page_chunk": "<!-- PageHeader=\"Volcanoes\" -->\n\n## Volcanoes\n\n### The Infrared Glows of Kilauea's Lava Flows—Hawaii\n\nIn early May 2018, an eruption on Hawaii's Kilauea volcano began to unfold. The eruption took a dangerous turn on May 3, 2018, when new fissures opened in the residential neighborhood of Leilani Estates. During the summer-long eruptive event, other fissures emerged along the East Rift Zone. Lava from vents along the rift zone flowed downslope, reaching the ocean in several areas, and filling in Kapoho Bay.\n\nA time series of Landsat 8 imagery shows the progression of the lava flows from May 16 to August 13. The night view combines thermal, shortwave infrared, and near-infrared wavelengths to tease out the very hot lava (bright white), cooling lava (red), and lava flows obstructed by clouds (purple).\n\n#### Figure: Location of Kilauea Volcano, Hawaii\n\nA globe is shown centered on North America, with a marker placed in the Pacific Ocean indicating the location of Hawaii, to the southwest of the mainland United States.\n\n<!-- PageFooter=\"Earth at Night\" -->\n<!-- PageNumber=\"44\" -->"
  }
}
Reference Type: AzureSearchDoc
{
  "type": "AzureSearchDoc",
  "id": "2",
  "activitySource": 1,
  "docKey": "earth_at_night_508_page_46_verbalized",
  "sourceData": {
    "id": "earth_at_night_508_page_46_verbalized",
    "page_chunk": "For the first time in perhaps a decade, Mount Etna experienced a \"flank eruption\"—erupting from its side instead of its summit—on December 24, 2018. The activity was accompanied by 130 earthquakes occurring over three hours that morning. Mount Etna, Europe’s most active volcano, has seen periodic activity on this part of the mountain since 2013. The Operational Land Imager (OLI) on the Landsat 8 satellite acquired the main image of Mount Etna on December 28, 2018.\n\nThe inset image highlights the active vent and thermal infrared signature from lava flows, which can be seen near the newly formed fissure on the southeastern side of the volcano. The inset was created with data from OLI and the Thermal Infrared Sensor (TIRS) on Landsat 8. Ash spewing from the fissure cloaked adjacent villages and delayed aircraft from landing at the nearby Catania airport. Earthquakes occurred in the subsequent days after the initial eruption and displaced hundreds of people from their homes.\n\nFor nighttime images of Mount Etna’s March 2017 eruption, see pages 48–51.\n\n---\n\n### Hazards of Volcanic Ash Plumes and Satellite Observation\n\nWith the help of moonlight, satellite instruments can track volcanic ash plumes, which present significant hazards to airplanes in flight. The volcanic ash—composed of tiny pieces of glass and rock—is abrasive to engine turbine blades, and can melt on the blades and other engine parts, causing damage and even engine stalls. This poses a danger to both the plane’s integrity and passenger safety. Volcanic ash also reduces visibility for pilots and can cause etching of windshields, further reducing pilots’ ability to see. Nightlight images can be combined with thermal images to provide a more complete view of volcanic activity on Earth’s surface.\n\nThe VIIRS Day/Night Band (DNB) on polar-orbiting satellites uses faint light sources such as moonlight, airglow (the atmosphere’s self-illumination through chemical reactions), zodiacal light (sunlight scattered by interplanetary dust), and starlight from the Milky Way. Using these dim light sources, the DNB can detect changes in clouds, snow cover, and sea ice:\n\n#### Table: Light Sources Used by VIIRS DNB\n\n| Light Source         | Description                                                                  |\n|----------------------|------------------------------------------------------------------------------|\n| Moonlight            | Reflected sunlight from the Moon, illuminating Earth's surface at night      |\n| Airglow              | Atmospheric self-illumination from chemical reactions                        |\n| Zodiacal Light       | Sunlight scattered by interplanetary dust                                    |\n| Starlight/Milky Way  | Faint illumination provided by stars in the Milky Way                        |\n\nGeostationary Operational Environmental Satellites (GOES), managed by NOAA, orbit over Earth’s equator and offer uninterrupted observations of North America. High-latitude areas such as Alaska benefit from polar-orbiting satellites like Suomi NPP, which provide overlapping coverage at the poles, enabling more data collection in these regions. During polar darkness (winter months), VIIRS DNB data allow scientists to:\n\n- Observe sea ice formation\n- Monitor snow cover extent at the highest latitudes\n- Detect open water for ship navigation\n\n#### Table: Satellite Coverage Overview\n\n| Satellite Type          | Orbit           | Coverage Area         | Special Utility                              |\n|------------------------|-----------------|----------------------|----------------------------------------------|\n| GOES                   | Geostationary   | Equatorial/North America | Continuous regional monitoring              |\n| Polar-Orbiting (e.g., Suomi NPP) | Polar-orbiting    | Poles/high latitudes      | Overlapping passes; useful during polar night|\n\n---\n\n### Weather Forecasting and Nightlight Data\n\nThe use of nightlight data by weather forecasters is growing as the VIIRS instrument enables observation of clouds at night illuminated by sources such as moonlight and lightning. Scientists use these data to study the nighttime behavior of weather systems, including severe storms, which can develop and strike populous areas at night as well as during the day. Combined with thermal data, visible nightlight data allow the detection of clouds at various heights in the atmosphere, such as dense marine fog. This capability enables weather forecasters to issue marine advisories with higher confidence, leading to greater utility. (See \"Marine Layer Clouds—California\" on page 56.)\n\nIn this section of the book, you will see how nightlight data are used to observe nature’s spectacular light shows across a wide range of sources.\n\n---\n\n#### Notable Data from Mount Etna Flank Eruption (December 2018)\n\n| Event/Observation                  | Details                                                                    |\n|-------------------------------------|----------------------------------------------------------------------------|\n| Date of Flank Eruption              | December 24, 2018                                                          |\n| Number of Earthquakes               | 130 earthquakes within 3 hours                                              |\n| Image Acquisition                   | December 28, 2018 by Landsat 8 OLI                                         |\n| Location of Eruption                | Southeastern side of Mount Etna                                            |\n| Thermal Imaging Data                | From OLI and TIRS (Landsat 8), highlighting active vent and lava flows     |\n| Impact on Villages/Air Transport    | Ash covered villages; delayed aircraft at Catania airport                  |\n| Displacement                        | Hundreds of residents displaced                                            |\n| Ongoing Seismic Activity            | Earthquakes continued after initial eruption                               |\n\n---\n\n<!-- PageFooter=\"Earth at Night\" -->\n<!-- PageNumber=\"30\" -->"
  }
}
Reference Type: AzureSearchDoc
{
  "type": "AzureSearchDoc",
  "id": "3",
  "activitySource": 1,
  "docKey": "earth_at_night_508_page_66_verbalized",
  "sourceData": {
    "id": "earth_at_night_508_page_66_verbalized",
    "page_chunk": "# Volcanoes\n\n---\n\n### Mount Etna Erupts - Italy\n\nThe highly active Mount Etna in Italy sent red lava rolling down its flank on March 19, 2017. An astronaut onboard the ISS took the photograph below of the volcano and its environs that night. City lights surround the mostly dark volcanic area.\n\n---\n\n#### Figure 1: Location of Mount Etna, Italy\n\nA world map highlighting the location of Mount Etna in southern Italy. The marker indicates its geographic placement on the east coast of Sicily, Italy, in the Mediterranean region, south of mainland Europe and north of northern Africa.\n\n---\n\n#### Figure 2: Nighttime View of Mount Etna's Eruption and Surrounding Cities\n\nThis is a nighttime satellite image taken on March 19, 2017, showing the eruption of Mount Etna (southeastern cone) with visible bright red and orange coloring indicating flowing lava from a lateral vent. The surrounding areas are illuminated by city lights, with the following geographic references labeled:\n\n| Location        | Position in Image         | Visible Characteristics                    |\n|-----------------|--------------------------|--------------------------------------------|\n| Mt. Etna (southeastern cone) | Top center-left | Bright red/orange lava flow                |\n| Lateral vent    | Left of the volcano       | Faint red/orange flow extending outwards   |\n| Resort          | Below the volcano, to the left   | Small cluster of lights                    |\n| Giarre          | Top right                 | Bright cluster of city lights              |\n| Acireale        | Center right              | Large, bright area of city lights          |\n| Biancavilla     | Bottom left               | Smaller cluster of city lights             |\n\nAn arrow pointing north is shown on the image for orientation.\n\n---\n\n<!-- Earth at Night Page Footer -->\n<!-- Page Number: 50 -->"
  }
}
Reference Type: AzureSearchDoc
{
  "type": "AzureSearchDoc",
  "id": "4",
  "activitySource": 1,
  "docKey": "earth_at_night_508_page_44_verbalized",
  "sourceData": {
    "id": "earth_at_night_508_page_44_verbalized",
    "page_chunk": "## Nature's Light Shows\n\nAt night, with the light of the Sun removed, nature's brilliant glow from Earth's surface becomes visible to the naked eye from space. Some of Earth's most spectacular light shows are natural, like the aurora borealis, or Northern Lights, in the Northern Hemisphere (aurora australis, or Southern Lights, in the Southern Hemisphere). The auroras are natural electrical phenomena caused by charged particles that race from the Sun toward Earth, inducing chemical reactions in the upper atmosphere and creating the appearance of streamers of reddish or greenish light in the sky, usually near the northern or southern magnetic pole. Other natural lights can indicate danger, like a raging forest fire encroaching on a city, town, or community, or lava spewing from an erupting volcano.\n\nWhatever the source, the ability of humans to monitor nature's light shows at night has practical applications for society. For example, tracking fires during nighttime hours allows for continuous monitoring and enhances our ability to protect humans and other animals, plants, and infrastructure. Combined with other data sources, our ability to observe the light of fires at night allows emergency managers to more efficiently and accurately issue warnings and evacuation orders and allows firefighting efforts to continue through the night. With enough moonlight (e.g., full-Moon phase), it's even possible to track the movement of smoke plumes at night, which can impact air quality, regardless of time of day.\n\nAnother natural source of light at night is emitted from glowing lava flows at the site of active volcanoes. Again, with enough moonlight, these dramatic scenes can be tracked and monitored for both scientific research and public safety.\n\n\n### Figure: The Northern Lights Viewed from Space\n\n**September 17, 2011**\n\nThis photo, taken from the International Space Station on September 17, 2011, shows a spectacular display of the aurora borealis (Northern Lights) as green and reddish light in the night sky above Earth. In the foreground, part of a Soyuz spacecraft is visible, silhouetted against the bright auroral light. The green glow is generated by energetic charged particles from the Sun interacting with Earth's upper atmosphere, exciting oxygen and nitrogen atoms, and producing characteristic colors. The image demonstrates the vividness and grandeur of natural night-time light phenomena as seen from orbit."
  }
}

[ASSISTANT]: 
To find lava at night, satellite instruments like the VIIRS Day/Night Band (DNB) and thermal infrared sensors are used to detect the glow of very hot lava flows on the Earth's surface
 For example, nighttime satellite images have captured lava flowing from active volcanoes such as Mount Etna in Italy and Kilauea in Hawaii, where the hot lava emits bright light visible from space even at night
 Scientists combine thermal, shortwave infrared, and near-infrared data to distinguish very hot lava (bright white), cooling lava (red), and areas obscured by clouds
 Additionally, moonlight and other faint natural light sources help illuminate the surroundings to improve observation of volcanic activity at night
 Monitoring lava flow at night is important for scientific research and public safety, as it helps track volcanic eruptions and associated hazards such as ash plumes that can affect air travel and nearby communities [refs 0,1,2,3,4]


🎉 === Conversation Complete ===
🗑️ Deleting knowledge agent...
✅ Knowledge agent 'earth-search-agent' deleted successfully.
🗑️ Deleting search index...
✅ Search index 'earth_at_night' deleted successfully.
✅ Quickstart completed successfully!

了解代码

有了代码后,让我们分解关键组件:

创建搜索索引

在 Azure AI 搜索中,索引是结构化数据集合。 以下代码定义一 earth_at_night 个名为包含纯文本和矢量内容的索引。 可以使用现有索引,但它必须满足 代理检索工作负荷的条件。

const index = {
    name: config.indexName,
    fields: [
        {
            name: "id",
            type: "Edm.String",
            key: true,
            filterable: true,
            sortable: true,
            facetable: true
        },
        {
            name: "page_chunk",
            type: "Edm.String",
            searchable: true,
            filterable: false,
            sortable: false,
            facetable: false
        },
        {
            name: "page_embedding_text_3_large",
            type: "Collection(Edm.Single)",
            searchable: true,
            filterable: false,
            sortable: false,
            facetable: false,
            vectorSearchDimensions: 3072,
            vectorSearchProfileName: "hnsw_text_3_large"
        },
        {
            name: "page_number",
            type: "Edm.Int32",
            filterable: true,
            sortable: true,
            facetable: true
        }
    ],
    vectorSearch: {
        profiles: [
            {
                name: "hnsw_text_3_large",
                algorithmConfigurationName: "alg",
                vectorizerName: "azure_openai_text_3_large"
            }
        ],
        algorithms: [
            {
                name: "alg",
                kind: "hnsw"
            }
        ],
        vectorizers: [
            {
                vectorizerName: "azure_openai_text_3_large",
                kind: "azureOpenAI",
                parameters: {
                    resourceUrl: config.azureOpenAIEndpoint,
                    deploymentId: config.azureOpenAIEmbeddingDeployment,
                    modelName: config.azureOpenAIEmbeddingModel
                }
            }
        ]
    },
    semanticSearch: {
        defaultConfigurationName: "semantic_config",
        configurations: [
            {
                name: "semantic_config",
                prioritizedFields: {
                    contentFields: [
                        { name: "page_chunk" }
                    ]
                }
            }
        ]
    }
};

索引架构包含文档标识和页面内容、嵌入和数字的字段。 它还包括语义排名和矢量查询的配置,这些配置使用之前部署的 text-embedding-3-large 模型。

将文档上传到索引

目前,索引 earth_at_night 为空。 运行以下代码,使用 美国宇航局地球在夜间电子书中的 JSON 文档填充索引。 根据 Azure AI 搜索的要求,每个文档都符合索引架构中定义的字段和数据类型。

console.log("📡 Fetching Earth at Night documents from GitHub...");
const documentsUrl = "https://raw.githubusercontent.com/Azure-Samples/azure-search-sample-data/refs/heads/main/nasa-e-book/earth-at-night-json/documents.json";
try {
    const response = await fetch(documentsUrl);
    if (!response.ok) {
        throw new Error(`Failed to fetch documents: ${response.status} ${response.statusText}`);
    }
    const documents = await response.json();
    console.log(`✅ Fetched ${documents.length} documents from GitHub`);
    // Validate and transform documents to match our interface
    const transformedDocuments = documents.map((doc, index) => {
        return {
            id: doc.id || String(index + 1),
            page_chunk: doc.page_chunk || doc.content || '',
            page_embedding_text_3_large: doc.page_embedding_text_3_large || new Array(3072).fill(0.1),
            page_number: doc.page_number || index + 1
        };
    });
    return transformedDocuments;
}

创建知识代理

要在查询时将 Azure AI 搜索连接到 gpt-5-mini 部署并面向 earth_at_night 索引,需要使用知识代理。 以下代码定义一个名为 earth-search-agent 的知识代理,该代理定义使用代理定义处理查询并从索引中检索相关文档 earth_at_night

为确保响应的相关性和语义意义明确,已设置 defaultRerankerThreshold,以排除 reranker 分数为 2.5 或更低的响应。

const agentDefinition = {
    name: config.agentName,
    description: "Knowledge agent for Earth at Night e-book content",
    models: [
        {
            kind: "azureOpenAI",
            azureOpenAIParameters: {
                resourceUri: config.azureOpenAIEndpoint,
                deploymentId: config.azureOpenAIGptDeployment,
                modelName: config.azureOpenAIGptModel
            }
        }
    ],
    targetIndexes: [
        {
            indexName: config.indexName,
            defaultRerankerThreshold: 2.5
        }
    ]
};

设置消息

消息是检索路由的输入,包含对话历史记录。 每条消息都包含一个角色,该角色指示其来源,例如助理或用户,以及自然语言中的内容。 使用的 LLM 决定了哪些角色有效。

用户消息表示要处理的查询,而助理消息指导知识代理如何响应。 在检索过程中,这些消息将发送到 LLM,以便从索引文档中提取相关响应。

此助理消息指示 earth-search-agent 在夜间回答有关地球的问题,使用 ref_id 引用来源,并在答案不可用时回答“我不知道”。

const messages = [
    {
        role: "system",
        content: `A Q&A agent that can answer questions about the Earth at night.
Sources have a JSON format with a ref_id that must be cited in the answer.
If you do not have the answer, respond with "I don't know".`
    },
    {
        role: "user",
        content: "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?"
    }
];

运行检索管道

此步骤运行检索管道,以便从搜索索引中提取相关信息。 根据检索请求中的信息和参数,LLM:

  1. 分析整个对话历史记录,以确定所需的基础信息。
  2. 将复合用户查询分解为重点子查询。
  3. 针对索引中的文本字段和矢量嵌入同时运行每个子查询。
  4. 使用语义排名器对所有子查询的结果重新排序。
  5. 将结果合并到单个字符串中。

以下代码将一个由两部分构成的用户查询发送到 earth-search-agent,该代码会将查询解构为子查询,并在 earth_at_night 索引中的文本字段和向量嵌入上运行这些子查询,随后对结果进行排名和合并。 然后,响应将追加到 messages 列表中。

const agentMessages = messages.map(msg => ({
    role: msg.role,
    content: [
        {
            type: "text",
            text: msg.content
        }
    ]
}));
const retrievalRequest = {
    messages: agentMessages,
    targetIndexParams: [
        {
            indexName: config.indexName,
            rerankerThreshold: 2.5,
            maxDocsForReranker: 100,
            includeReferenceSourceData: true
        }
    ]
};
const token = await getAccessToken(credential, "https://search.azure.com/.default");
const response = await fetch(`${config.searchEndpoint}/agents/${config.agentName}/retrieve?api-version=${config.searchApiVersion}`, {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${token}`
    },
    body: JSON.stringify(retrievalRequest)
});
if (!response.ok) {
    const errorText = await response.text();
    throw new Error(`Agentic retrieval failed: ${response.status} ${response.statusText}\n${errorText}`);
}
return await response.json();

查看响应、活动和结果

现在,你想要显示检索管道的响应、活动和结果。

来自 Azure AI 搜索的每个检索响应包括:

  • 表示搜索结果中基础数据的统一字符串。

  • 查询计划。

  • 引用数据,其中显示了源文档的哪些区块促成了统一字符串。

console.log("\nActivities:");
if (retrievalResponse.activity && Array.isArray(retrievalResponse.activity)) {
    retrievalResponse.activity.forEach((activity) => {
        const activityType = activity.activityType || activity.type || 'UnknownActivityRecord';
        console.log(`Activity Type: ${activityType}`);
        console.log(JSON.stringify(activity, null, 2));
    });
}
console.log("Results");
if (retrievalResponse.references && Array.isArray(retrievalResponse.references)) {
    retrievalResponse.references.forEach((reference) => {
        const referenceType = reference.referenceType || reference.type || 'AzureSearchDoc';
        console.log(`Reference Type: ${referenceType}`);
        console.log(JSON.stringify(reference, null, 2));
    });
}

输出应包括:

  • Response 根据用户查询在搜索索引中提供最相关的文档(或区块)的文本字符串。 如本快速入门稍后所示,可以将此字符串传递给 LLM 进行答案生成。

  • Activity 跟踪检索过程中采取的步骤,其中包括由您的 gpt-5-mini 部署生成的子查询,以及用于查询规划和执行的令牌。

  • Results 列出构成该响应的文档,每个文档都由其 DocKey标识。

创建 Azure OpenAI 客户端

若要将检索管道从应答 提取 扩展到应答 生成,请设置 Azure OpenAI 客户端以与 gpt-5-mini 部署交互。

const scope = "https://cognitiveservices.azure.com/.default";
const azureADTokenProvider = getBearerTokenProvider(credential, scope);
const openAIClient = new AzureOpenAI({
    endpoint: config.azureOpenAIEndpoint,
    apiVersion: config.azureOpenAIApiVersion,
    azureADTokenProvider,
});

使用聊天补全 API 生成答案

用于生成答案的一个选项是聊天完成 API,该 API 将会话历史记录传递给 LLM 进行处理。

const completion = await openAIClient.chat.completions.create({
    model: config.azureOpenAIGptDeployment,
    messages: messages.map(m => ({ role: m.role, content: m.content })),
    max_tokens: 1000,
    temperature: 0.7
});
const answer = completion.choices[0].message.content;
console.log(answer?.replace(/\./g, "\n"));

继续对话

通过向earth-search-agent发送另一个用户查询继续对话。 以下代码重新运行检索管道,从 earth_at_night 索引中提取相关内容,并将响应追加到 messages 列表中。 但是,与以前不同,现在可以使用 Azure OpenAI 客户端基于检索的内容生成答案。

const followUpQuestion = "How do I find lava at night?";
console.log(`❓ Follow-up question: ${followUpQuestion}`);
messages.push({
    role: "user",
    content: followUpQuestion
});

清理资源

在你自己的订阅中工作时,最好在结束项目时确定你是否仍需要创建的资源。 持续运行的资源可能会产生费用。 可以单独删除资源,也可以删除资源组以删除整个资源集。

在 Azure 门户中,可以通过从左窗格中选择 “所有资源 ”或 “资源组 ”来查找和管理资源。 还可以运行以下代码来删除在本快速入门中创建的对象。

删除知识代理

本快速入门中创建的知识代理通过以下代码片段进行删除:

const token = await getAccessToken(credential, "https://search.azure.com/.default");
const response = await fetch(`${config.searchEndpoint}/agents/${config.agentName}?api-version=${config.searchApiVersion}`, {
    method: 'DELETE',
    headers: {
        'Authorization': `Bearer ${token}`
    }
});

删除搜索索引

本快速入门中创建的搜索索引使用以下代码片段删除:

await indexClient.deleteIndex(config.indexName);
console.log(`✅ Search index '${config.indexName}' deleted successfully.`);

注释

此功能目前处于公开预览状态。 此预览版未随附服务级别协议,建议不要用于生产工作负载。 某些功能可能不受支持或者受限。 有关详细信息,请参阅 Microsoft Azure 预览版补充使用条款

在本快速入门中,你将使用智能体检索创建对话搜索体验,该体验由 Azure AI 搜索中索引的文档和 Azure AI Foundry 模型中的 Azure OpenAI 大型语言模型 (LLM) 提供支持。

知识智能体通过将复杂的查询分解为子查询,对一个或多个知识源执行这些子查询,并返回包含元数据的检索结果,从而实现智能体检索。 默认情况下,该智能体会输出源内容中的原始数据,但本快速入门教程使用“答案生成”模式来生成自然语言的答案。

虽然可以提供你自己的数据,但本快速入门使用了美国宇航局“夜间地球”电子书中的示例 JSON 文档。 这些文件描述了一般科学主题,以及从太空观测到的夜晚地球的图像。

小窍门

想要立即开始? 请参阅 GitHub 上的 azure-search-python-samples 存储库。

先决条件

配置访问权限

在开始之前,请确保你有权访问内容和操作。 我们建议使用 Microsoft Entra ID 进行身份验证,并使用基于角色的访问控制进行授权。 你必须是“所有者”或“用户访问管理员”才能分配角色。 如果角色设置不可行,请改用基于密钥的身份验证方式

若要配置此快速入门的访问权限,请选择以下两个选项卡。

Azure AI 搜索提供智能体检索管道。 配置自己和搜索服务的访问权限,以读取和写入数据、与 Azure AI Foundry 交互以及运行管道。

配置 Azure AI 搜索的访问权限:

  1. 登录到 Azure 门户 并选择搜索服务。

  2. 启用基于角色的访问

  3. 创建系统分配的托管标识

  4. 将以下角色分配给自己。

    • 搜索服务参与者

    • 搜索索引数据参与者

    • 搜索索引数据读取者

重要

代理检索具有两种基于标记的计费模型:

  • Azure AI 搜索的语义排序功能的收费标准。
  • Azure OpenAI 的查询规划和答案生成功能收费标准。

语义排名在初始公共预览版中是免费的。 预览版后,将应用标准标记计费。 有关详细信息,请参阅 代理检索的可用性和定价

获取终结点

每个 Azure AI 搜索服务和 Azure AI Foundry 资源都有一个终结点,该终结点是唯一的 URL,用于标识和提供对资源的网络访问权限。 在后面的部分中,指定这些终结点以便通过编程方式连接到你的资源。

若要获取本快速入门的终结点,请选择以下两个选项卡。

  1. 登录到 Azure 门户 并选择搜索服务。

  2. 在左窗格中,选择“ 概述”。

  3. 记下终结点,形式应与 https://my-service.search.windows.net 类似。

部署模型

若要使用智能体检索,必须将两个 Azure OpenAI 模型部署到 Azure AI Foundry 资源:

  • 用于文本到矢量转换的嵌入模型。 本快速入门使用 text-embedding-3-large,但你可以使用任何 text-embedding 模型。

  • 用于查询规划和答案生成的 LLM。 本快速入门使用 gpt-5-mini,但你可以使用任何 受支持的 LLM 进行代理检索

有关部署说明,请参阅 使用 Azure AI Foundry 部署 Azure OpenAI 模型

从本地系统进行连接

你已在 Azure AI Foundry 中配置基于角色的访问权限,以便与 Azure AI 搜索和 Azure OpenAI 进行交互。 使用 Azure CLI 登录到这两个服务的同一订阅和租户。 有关详细信息,请参阅 快速入门:在没有密钥的情况下连接

从本地系统进行连接:

  1. 在 Visual Studio Code 中,打开要在其中保存文件的文件夹。

  2. 选择“终端”“新终端”>

  3. 运行以下命令以登录到 Azure 帐户。 如果有多个订阅,请选择包含 Azure AI 搜索服务和 Azure AI Foundry 项目的订阅。

    az login
    

安装软件包并加载连接

在运行任何代码之前,请安装 Python 包并定义终结点、凭据和部署详细信息,以便在 Azure AI Foundry 中连接到 Azure AI 搜索和 Azure OpenAI。 需要在以下部分用到这些值。

安装包并加载连接:

  1. 在 Visual Studio Code 的同一文件夹中,创建名为 quickstart-agentic-retrieval.ipynb 的文件。

  2. 添加代码单元格,然后粘贴下方的 pip install 命令。

    ! pip install azure-search-documents==11.7.0b1 --quiet
    ! pip install azure-identity --quiet
    ! pip install openai --quiet
    ! pip install aiohttp --quiet
    ! pip install ipykernel --quiet
    ! pip install requests --quiet
    
  3. 选择“执行单元格”以安装包。

  4. 添加另一个代码单元格,然后粘贴以下导入语句和变量。

    from azure.identity import DefaultAzureCredential, get_bearer_token_provider
    import os
    
    search_endpoint = "PUT-YOUR-SEARCH-SERVICE-URL-HERE"
    credential = DefaultAzureCredential()
    token_provider = get_bearer_token_provider(credential, "https://search.azure.com/.default")
    aoai_endpoint = "PUT-YOUR-AOAI-FOUNDRY-URL-HERE"
    aoai_embedding_model = "text-embedding-3-large"
    aoai_embedding_deployment = "text-embedding-3-large"
    aoai_gpt_model = "gpt-5-mini"
    aoai_gpt_deployment = "gpt-5-mini"
    index_name = "earth-at-night"
    knowledge_source_name = "earth-knowledge-source"
    knowledge_agent_name = "earth-knowledge-agent"
    search_api_version = "2025-08-01-preview"
    
  5. search_endpointaoai_endpoint 的值设置为你在获取终结点时获取的值。

  6. 选择“执行单元格”以加载变量。

创建搜索索引

在 Azure AI 搜索中,索引是结构化数据集合。 添加并运行具有以下代码的代码单元格以定义名为 earth-at-night 的索引,之前使用 index_name 变量指定该索引。

索引架构包含文档标识和页面内容、嵌入和数字的字段。 该架构还包含用于语义排序和向量搜索的配置,该配置利用你部署的 text-embedding-3-large 模型将文本转换为向量,并根据语义相似度匹配相关文档。

from azure.search.documents.indexes.models import SearchIndex, SearchField, VectorSearch, VectorSearchProfile, HnswAlgorithmConfiguration, AzureOpenAIVectorizer, AzureOpenAIVectorizerParameters, SemanticSearch, SemanticConfiguration, SemanticPrioritizedFields, SemanticField
from azure.search.documents.indexes import SearchIndexClient
from openai import AzureOpenAI
from azure.identity import get_bearer_token_provider

azure_openai_token_provider = get_bearer_token_provider(credential, "https://cognitiveservices.azure.com/.default")
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=aoai_endpoint,
                    deployment_name=aoai_embedding_deployment,
                    model_name=aoai_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=search_endpoint, credential=credential)
index_client.create_or_update_index(index)
print(f"Index '{index_name}' created or updated successfully.")

将文档上传到索引

目前,索引 earth-at-night 为空。 添加并运行包含以下代码的代码单元格,使用 NASA 的《地球之夜》电子书的 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=search_endpoint, index_name=index_name, credential=credential) as client:
    client.upload_documents(documents=documents)

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

创建知识来源

知识来源是指可重复使用的源数据参考资料。 添加并运行包含以下代码的代码单元格,以定义名为 earth-knowledge-source 且以 earth-at-night 索引为目标的知识来源。

source_data_select 指定检索和引文可访问的索引字段。 为了避免响应结果中出现冗长且难以理解的嵌入式数据,我们的示例仅包含人类可读的字段。

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

ks = SearchIndexKnowledgeSource(
    name=knowledge_source_name,
    description="Knowledge source for Earth at night data",
    search_index_parameters=SearchIndexKnowledgeSourceParameters(
        search_index_name=index_name,
        source_data_select="id,page_chunk,page_number",
    ),
)

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

创建知识代理

为在查询时将 earth-knowledge-sourcegpt-5-mini 部署作为目标,需要一个知识智能体。 添加并运行包含以下代码的代码单元格,以定义一个名为 earth-knowledge-agent 的知识智能体,之前使用 knowledge_agent_name 变量指定该智能体。

reranker_threshold 通过排除重排序得分不高于 2.5 的响应来确保语义相关性。 同时,将 modality 设置为 ANSWER_SYNTHESIS,从而启用能够引用检索文档的自然语言回答。

from azure.search.documents.indexes.models import KnowledgeAgent, KnowledgeAgentAzureOpenAIModel, KnowledgeSourceReference, AzureOpenAIVectorizerParameters, KnowledgeAgentOutputConfiguration, KnowledgeAgentOutputConfigurationModality
from azure.search.documents.indexes import SearchIndexClient

aoai_params = AzureOpenAIVectorizerParameters(
    resource_url=aoai_endpoint,
    deployment_name=aoai_gpt_deployment,
    model_name=aoai_gpt_model,
)

output_cfg = KnowledgeAgentOutputConfiguration(
    modality=KnowledgeAgentOutputConfigurationModality.ANSWER_SYNTHESIS,
    include_activity=True,
)

agent = KnowledgeAgent(
    name=knowledge_agent_name,
    models=[KnowledgeAgentAzureOpenAIModel(azure_open_ai_parameters=aoai_params)],
    knowledge_sources=[
        KnowledgeSourceReference(
            name=knowledge_source_name,
            reranker_threshold=2.5,
        )
    ],
    output_configuration=output_cfg,
)

index_client = SearchIndexClient(endpoint=search_endpoint, credential=credential)
index_client.create_or_update_agent(agent, api_version=search_api_version)
print(f"Knowledge agent '{knowledge_agent_name}' created or updated successfully.")

设置消息

消息是检索路由的输入,包含对话历史记录。 每条消息都包含一个角色,用于指示其来源(例如 systemuser)以及自然语言中的内容。 使用的 LLM 决定了哪些角色有效。

添加并运行包含以下代码的代码单元格,以创建系统消息,该消息指示 earth-knowledge-agent 回答有关《地球之夜》的问题,并在没有答案时回答“我不知道”。

instructions = """
A Q&A agent that can answer questions about the Earth at night.
If you don't have the answer, respond with "I don't know".
"""

messages = [
    {
        "role": "system",
        "content": instructions
    }
]

运行检索管道

你已准备好运行智能体检索。 添加并运行包含以下代码的代码单元格,以向 earth-knowledge-agent 发送两部分用户查询。

根据对话历史记录和检索参数,智能体将:

  1. 分析整个对话以推断用户的信息需求。
  2. 将复合查询分解为有针对性的子查询。
  3. 并发地针对知识来源运行子查询。
  4. 使用语义排序器对结果进行重新排序和筛选。
  5. 将排名靠前的结果合成为自然语言答案。
from azure.search.documents.agent import KnowledgeAgentRetrievalClient
from azure.search.documents.agent.models import KnowledgeAgentRetrievalRequest, KnowledgeAgentMessage, KnowledgeAgentMessageTextContent, SearchIndexKnowledgeSourceParams

agent_client = KnowledgeAgentRetrievalClient(endpoint=search_endpoint, agent_name=knowledge_agent_name, credential=credential)
query_1 = """
    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?
    """

messages.append({
    "role": "user",
    "content": query_1
})

req = KnowledgeAgentRetrievalRequest(
    messages=[
        KnowledgeAgentMessage(
            role=m["role"],
            content=[KnowledgeAgentMessageTextContent(text=m["content"])]
        ) for m in messages if m["role"] != "system"
    ],
    knowledge_source_params=[
        SearchIndexKnowledgeSourceParams(
            knowledge_source_name=knowledge_source_name,
            kind="searchIndex"
        )
    ]
)

result = agent_client.retrieve(retrieval_request=req, api_version=search_api_version)
print(f"Retrieved content from '{knowledge_source_name}' successfully.")

查看响应、活动和结果

添加并运行包含以下代码的代码单元格,以显示检索管道的响应、活动和结果。

import textwrap
import json

print("Response")
print(textwrap.fill(result.response[0].content[0].text, width=120))

print("Activity")
print(json.dumps([a.as_dict() for a in result.activity], indent=2))

print("Results")
print(json.dumps([r.as_dict() for r in result.references], indent=2))

输出应类似于以下示例,其中:

  • Response 会根据检索到的文档,生成一个由大型语言模型 (LLM) 合成的答案。 如果未启用答案合成功能,则此部分将直接显示从文档中提取的内容。

  • Activity 会追踪检索过程中的所有步骤,包括 gpt-5-mini 部署在检索过程中生成的子查询,以及用于语义排序、查询规划和答案合成所使用的标记。

  • Results 列出构成该响应的文档,每个文档都由其 doc_key标识。

Response
Suburban belts display larger December brightening than urban cores despite higher absolute light levels downtown
because the urban grid encourages outward growth along city borders, fueled by widespread personal automobile use,
leading to extensive suburban and residential municipalities linked by surface streets and freeways. This expansion
results in increased lighting in suburban areas during December, reflecting growth and development patterns rather than
just absolute light intensity downtown [ref_id:0].  The Phoenix nighttime street grid is sharply visible from space
because the metropolitan area is laid out along a regular grid of city blocks and streets, with major street lighting
clearly visible from low-Earth orbit. The grid pattern is especially evident at night due to street lighting, and major
transportation corridors like Grand Avenue and brightly lit commercial properties enhance this visibility. In contrast,
large stretches of interstate highways between Midwestern cities remain comparatively dim because, although the United
States has extensive road networks, the lighting along interstate highways is less intense and continuous than the dense
urban street grids. Additionally, navigable rivers and less urbanized areas show less light, indicating that lighting
intensity correlates with urban density and development patterns rather than just the presence of transportation
corridors [ref_id:0][ref_id:1][ref_id:2].
Activity
[
  {
    "id": 0,
    "type": "modelQueryPlanning",
    "elapsed_ms": 4572,
    "input_tokens": 2071,
    "output_tokens": 166
  },
  {
    "id": 1,
    "type": "searchIndex",
    "elapsed_ms": 608,
    "knowledge_source_name": "earth-knowledge-source",
    "query_time": "2025-09-05T17:38:49.330Z",
    "count": 0,
    "search_index_arguments": {
      "search": "Reasons for larger December brightening in suburban belts compared to urban cores despite higher downtown light levels"
    }
  },
    ... // Trimmed for brevity
  {
    "id": 4,
    "type": "semanticReranker",
    "input_tokens": 68989
  },
  {
    "id": 5,
    "type": "modelAnswerSynthesis",
    "elapsed_ms": 5619,
    "input_tokens": 3931,
    "output_tokens": 249
  }
]
Results
[
  {
    "type": "searchIndex",
    "id": "0",
    "activity_source": 2,
    "reranker_score": 2.6642752,
    "doc_key": "earth_at_night_508_page_104_verbalized"
  },
  ... // Trimmed for brevity
]

继续对话

添加并运行包含以下代码的代码单元格,以继续与 earth-knowledge-agent 对话。 发送此用户查询后,智能体会从 earth-knowledge-source 中提取相关内容并将响应追加到 messages 列表中。

query_2 = "How do I find lava at night?"
messages.append({
    "role": "user",
    "content": query_2
})

req = KnowledgeAgentRetrievalRequest(
    messages=[
        KnowledgeAgentMessage(
            role=m["role"],
            content=[KnowledgeAgentMessageTextContent(text=m["content"])]
        ) for m in messages if m["role"] != "system"
    ],
    knowledge_source_params=[
        SearchIndexKnowledgeSourceParams(
            knowledge_source_name=knowledge_source_name,
            kind="searchIndex"
        )
    ]
)

result = agent_client.retrieve(retrieval_request=req, api_version=search_api_version)
print(f"Retrieved content from '{knowledge_source_name}' successfully.")

查看新的响应、活动和结果

添加并运行包含以下代码的代码单元格,以显示检索管道的新响应、活动和结果。

import textwrap
import json

print("Response")
print(textwrap.fill(result.response[0].content[0].text, width=120))

print("Activity")
print(json.dumps([a.as_dict() for a in result.activity], indent=2))

print("Results")
print(json.dumps([r.as_dict() for r in result.references], indent=2))

清理资源

当你使用自己的订阅服务时,最好在完成一个项目后,先评估一下是否还需要你所创建的那些资源。 持续运行的资源可能会产生费用。

Azure 门户中,可以通过在左侧窗格中选择“所有资源”或“资源组”来管理 Azure AI 搜索和 Azure AI Foundry 资源

否则,请添加并运行包含以下代码的代码单元格,以删除在本快速入门中创建的对象。

删除知识代理

from azure.search.documents.indexes import SearchIndexClient

index_client = SearchIndexClient(endpoint=search_endpoint, credential=credential)
index_client.delete_agent(knowledge_agent_name)
print(f"Knowledge agent '{knowledge_agent_name}' deleted successfully.")

删除知识来源

from azure.search.documents.indexes import SearchIndexClient

index_client = SearchIndexClient(endpoint=search_endpoint, credential=credential)
index_client.delete_knowledge_source(knowledge_source=knowledge_source_name)
print(f"Knowledge source '{knowledge_source_name}' deleted successfully.")

删除搜索索引

from azure.search.documents.indexes import SearchIndexClient

index_client = SearchIndexClient(endpoint=search_endpoint, credential=credential)
index_client.delete_index(index_name)
print(f"Index '{index_name}' deleted successfully.")

注释

此功能目前处于公开预览状态。 此预览版未随附服务级别协议,建议不要用于生产工作负载。 某些功能可能不受支持或者受限。 有关详细信息,请参阅 Microsoft Azure 预览版补充使用条款

在本快速入门中,你将使用 代理检索 来创建由大型语言模型(LLM)和专有数据提供支持的对话搜索体验。 能动检索将复杂的用户查询分解为子查询,并行执行子查询,并从 Azure AI 搜索所索引的文档中提取基础数据。 输出适用于与代理和自定义聊天解决方案的集成。

虽然可以提供你自己的数据,但本快速入门使用了美国宇航局“夜间地球”电子书中的示例 JSON 文档。 这些文件描述了一般科学主题,以及从太空观测到的夜晚地球的图像。

小窍门

本快速入门的 TypeScript 版本使用 2025-05-01-preview REST API 版本,该版本不支持 2025-08-01-preview 中引入的知识来源和其他智能体检索功能。 若要使用这些功能,请参阅 C#、Python 或 REST 版本。

先决条件

配置访问权限

在开始之前,请确保你有权访问内容和操作。 我们建议使用 Microsoft Entra ID 进行身份验证,并使用基于角色的访问控制进行授权。 你必须是“所有者”或“用户访问管理员”才能分配角色。 如果角色设置不可行,请改用基于密钥的身份验证方式

若要配置此快速入门的访问权限,请选择以下两个选项卡。

Azure AI 搜索提供智能体检索管道。 配置自己和搜索服务的访问权限,以读取和写入数据、与 Azure AI Foundry 交互以及运行管道。

配置 Azure AI 搜索的访问权限:

  1. 登录到 Azure 门户 并选择搜索服务。

  2. 启用基于角色的访问

  3. 创建系统分配的托管标识

  4. 将以下角色分配给自己。

    • 搜索服务参与者

    • 搜索索引数据参与者

    • 搜索索引数据读取者

重要

代理检索具有两种基于标记的计费模型:

  • Azure AI 搜索的语义排序功能的收费标准。
  • Azure OpenAI 的查询规划和答案生成功能收费标准。

语义排名在初始公共预览版中是免费的。 预览版后,将应用标准标记计费。 有关详细信息,请参阅 代理检索的可用性和定价

获取终结点

每个 Azure AI 搜索服务和 Azure AI Foundry 资源都有一个终结点,该终结点是唯一的 URL,用于标识和提供对资源的网络访问权限。 在后面的部分中,指定这些终结点以便通过编程方式连接到你的资源。

若要获取本快速入门的终结点,请选择以下两个选项卡。

  1. 登录到 Azure 门户 并选择搜索服务。

  2. 在左窗格中,选择“ 概述”。

  3. 记下终结点,形式应与 https://my-service.search.windows.net 类似。

部署模型

若要使用智能体检索,必须将两个 Azure OpenAI 模型部署到 Azure AI Foundry 资源:

  • 用于文本到矢量转换的嵌入模型。 本快速入门使用 text-embedding-3-large,但你可以使用任意 text-embedding 模型。

  • 用于查询规划和答案生成的 LLM。 本快速入门使用 gpt-5-mini,但你可以使用任何 受支持的 LLM 来实现代理型检索

有关部署说明,请参阅 使用 Azure AI Foundry 部署 Azure OpenAI 模型

设置环境

  1. 创建一个新文件夹 quickstart-agentic-retrieval 以包含该应用程序,并在该文件夹中使用以下命令打开 Visual Studio Code:

    mkdir quickstart-agentic-retrieval && cd quickstart-agentic-retrieval
    
  2. 使用以下命令创建 package.json

    npm init -y
    
  3. 使用以下命令将 package.json 更新为 ECMAScript:

    npm pkg set type=module
    
  4. 安装适用于 JavaScript 的 Azure AI 搜索客户端库 (Azure.Search.Documents)

    npm install @azure/search-documents --version 12.2.0-alpha.20250606.1
    
  5. 使用以下命令安装 Azure OpenAI 客户端库:

    npm install @azure/openai --version 5.10.1
    
  6. 安装 dotenv 包,以从 .env 文件加载环境变量。

    npm install dotenv
    
  7. 若要使用 Microsoft Entra ID 进行推荐的无密钥身份验证,请使用以下命令安装 Azure.Identity 客户端库:

    npm install @azure/identity
    

运行代码

  1. .env文件夹中创建一个名为quickstart-agentic-retrieval的新文件,并添加以下环境变量:

    AZURE_OPENAI_ENDPOINT=https://<your-ai-foundry-resource-name>.openai.azure.com/
    AZURE_OPENAI_GPT_DEPLOYMENT=gpt-5-mini
    AZURE_OPENAI_EMBEDDING_DEPLOYMENT=text-embedding-3-large
    AZURE_SEARCH_ENDPOINT=https://<your-search-service-name>.search.windows.net
    AZURE_SEARCH_INDEX_NAME=agentic-retrieval-sample
    

    <your-search-service-name><your-ai-foundry-resource-name> 替换为实际的 Azure AI 搜索服务名称和 Azure AI Foundry 资源名称。

  2. 将以下代码粘贴到名为 index.ts 的新文件中:

    import { DefaultAzureCredential, getBearerTokenProvider } from '@azure/identity';
    import { 
        SearchIndexClient, 
        SearchClient,
        SearchIndex,
        SearchField,
        VectorSearch,
        VectorSearchProfile,
        HnswAlgorithmConfiguration,
        AzureOpenAIVectorizer,
        AzureOpenAIParameters,
        SemanticSearch,
        SemanticConfiguration,
        SemanticPrioritizedFields,
        SemanticField
    } from '@azure/search-documents';
    import { AzureOpenAI } from "openai/index.mjs";
    
    // Load the .env file if it exists
    import * as dotenv from "dotenv";
    dotenv.config();
    
    // Configuration - Update these values for your environment
    const config = {
        searchEndpoint: process.env.AZURE_SEARCH_ENDPOINT || "https://your-search-service.search.windows.net",
        azureOpenAIEndpoint: process.env.AZURE_OPENAI_ENDPOINT || "https://your-ai-foundry-resource.openai.azure.com/",
        azureOpenAIGptDeployment: process.env.AZURE_OPENAI_GPT_DEPLOYMENT || "gpt-5-mini",
        azureOpenAIGptModel: "gpt-5-mini",
        azureOpenAIApiVersion: process.env.OPENAI_API_VERSION || "2025-03-01-preview",
        azureOpenAIEmbeddingDeployment: process.env.AZURE_OPENAI_EMBEDDING_DEPLOYMENT || "text-embedding-3-large",
        azureOpenAIEmbeddingModel: "text-embedding-3-large",
        indexName: "earth_at_night",
        agentName: "earth-search-agent",
        searchApiVersion: "2025-05-01-Preview"
    };
    
    // Earth at Night document interface
    interface EarthAtNightDocument {
        id: string;
        page_chunk: string;
        page_embedding_text_3_large: number[];
        page_number: number;
    }
    
    // Knowledge agent message interface
    interface KnowledgeAgentMessage {
        role: 'user' | 'assistant' | 'system';
        content: string;
    }
    
    // Agentic retrieval response interface
    interface AgenticRetrievalResponse {
        response?: string | any[];
        references?: Array<{
            docKey?: string;
            content?: string;
            score?: number;
            referenceType?: string;
            type?: string;
            SourceData?: any;
            Id?: string;
            ActivitySource?: number;
            // Allow any additional properties
            [key: string]: any;
        }>;
        activity?: Array<{
            step?: string;
            description?: string;
            tokensUsed?: number;
            activityType?: string;
            type?: string;
            InputTokens?: number;
            OutputTokens?: number;
            TargetIndex?: string;
            QueryTime?: string;
            Query?: any;
            Count?: number;
            ElapsedMs?: number | null;
            Id?: number;
            // Allow any additional properties
            [key: string]: any;
        }>;
        // Add any other possible response fields
        [key: string]: any;
    }
    
    async function main(): Promise<void> {
        try {
            console.log("🚀 Starting Azure AI Search agentic retrieval quickstart...\n");
    
            // Initialize Azure credentials using managed identity (recommended)
            const credential = new DefaultAzureCredential();
    
            // Create search clients
            const searchIndexClient = new SearchIndexClient(config.searchEndpoint, credential);
            const searchClient = new SearchClient<EarthAtNightDocument>(config.searchEndpoint, config.indexName, credential);
    
            // Create Azure OpenAI client
            const scope = "https://cognitiveservices.azure.com/.default";
            const azureADTokenProvider = getBearerTokenProvider(credential, scope);
            const openAIClient = new AzureOpenAI({
                endpoint: config.azureOpenAIEndpoint,
                apiVersion: config.azureOpenAIApiVersion,
                azureADTokenProvider,
            });
    
            // Create search index with vector and semantic capabilities
            await createSearchIndex(searchIndexClient);
    
            // Upload sample documents
            await uploadDocuments(searchClient);
    
            // Create knowledge agent for agentic retrieval
            await createKnowledgeAgent(credential);
    
            // Run agentic retrieval with conversation
            await runAgenticRetrieval(credential, openAIClient);
    
            // Clean up - Delete knowledge agent and search index
            await deleteKnowledgeAgent(credential);
            await deleteSearchIndex(searchIndexClient);
    
            console.log("✅ Quickstart completed successfully!");
    
        } catch (error) {
            console.error("❌ Error in main execution:", error);
            throw error;
        }
    }
    
    async function createSearchIndex(indexClient: SearchIndexClient): Promise<void> {
        console.log("📊 Creating search index...");
    
        const index: SearchIndex = {
            name: config.indexName,
            fields: [
                {
                    name: "id",
                    type: "Edm.String",
                    key: true,
                    filterable: true,
                    sortable: true,
                    facetable: true
                } as SearchField,
                {
                    name: "page_chunk",
                    type: "Edm.String",
                    searchable: true,
                    filterable: false,
                    sortable: false,
                    facetable: false
                } as SearchField,
                {
                    name: "page_embedding_text_3_large",
                    type: "Collection(Edm.Single)",
                    searchable: true,
                    filterable: false,
                    sortable: false,
                    facetable: false,
                    vectorSearchDimensions: 3072,
                    vectorSearchProfileName: "hnsw_text_3_large"
                } as SearchField,
                {
                    name: "page_number",
                    type: "Edm.Int32",
                    filterable: true,
                    sortable: true,
                    facetable: true
                } as SearchField
            ],
            vectorSearch: {
                profiles: [
                    {
                        name: "hnsw_text_3_large",
                        algorithmConfigurationName: "alg",
                        vectorizerName: "azure_openai_text_3_large"
                    } as VectorSearchProfile
                ],
                algorithms: [
                    {
                        name: "alg",
                        kind: "hnsw"
                    } as HnswAlgorithmConfiguration
                ],
                vectorizers: [
                    {
                        vectorizerName: "azure_openai_text_3_large",
                        kind: "azureOpenAI",
                        parameters: {
                            resourceUrl: config.azureOpenAIEndpoint,
                            deploymentId: config.azureOpenAIEmbeddingDeployment,
                            modelName: config.azureOpenAIEmbeddingModel
                        } as AzureOpenAIParameters
                    } as AzureOpenAIVectorizer
                ]
            } as VectorSearch,
            semanticSearch: {
                defaultConfigurationName: "semantic_config",
                configurations: [
                    {
                        name: "semantic_config",
                        prioritizedFields: {
                            contentFields: [
                                { name: "page_chunk" } as SemanticField
                            ]
                        } as SemanticPrioritizedFields
                    } as SemanticConfiguration
                ]
            } as SemanticSearch
        };
    
        try {
            await indexClient.createOrUpdateIndex(index);
            console.log(`✅ Index '${config.indexName}' created or updated successfully.`);
        } catch (error) {
            console.error("❌ Error creating index:", error);
            throw error;
        }
    }
    
    async function deleteSearchIndex(indexClient: SearchIndexClient): Promise<void> {
        console.log("🗑️ Deleting search index...");
    
        try {
            await indexClient.deleteIndex(config.indexName);
            console.log(`✅ Search index '${config.indexName}' deleted successfully.`);
    
        } catch (error: any) {
            if (error?.statusCode === 404 || error?.code === 'IndexNotFound') {
                console.log(`ℹ️ Search index '${config.indexName}' does not exist or was already deleted.`);
                return;
            }
            console.error("❌ Error deleting search index:", error);
            throw error;
        }
    }
    
    // Fetch Earth at Night documents from GitHub
    async function fetchEarthAtNightDocuments(): Promise<EarthAtNightDocument[]> {
        console.log("📡 Fetching Earth at Night documents from GitHub...");
    
        const documentsUrl = "https://raw.githubusercontent.com/Azure-Samples/azure-search-sample-data/refs/heads/main/nasa-e-book/earth-at-night-json/documents.json";
    
        try {
            const response = await fetch(documentsUrl);
    
            if (!response.ok) {
                throw new Error(`Failed to fetch documents: ${response.status} ${response.statusText}`);
            }
    
            const documents = await response.json();
            console.log(`✅ Fetched ${documents.length} documents from GitHub`);
    
            // Validate and transform documents to match our interface
            const transformedDocuments: EarthAtNightDocument[] = documents.map((doc: any, index: number) => {
                return {
                    id: doc.id || String(index + 1),
                    page_chunk: doc.page_chunk || doc.content || '',
                    page_embedding_text_3_large: doc.page_embedding_text_3_large || new Array(3072).fill(0.1),
                    page_number: doc.page_number || index + 1
                };
            });
    
            return transformedDocuments;
    
        } catch (error) {
            console.error("❌ Error fetching documents from GitHub:", error);
            console.log("🔄 Falling back to sample documents...");
    
            // Fallback to sample documents if fetch fails
            return [
                {
                    id: "1",
                    page_chunk: "The Earth at night reveals the patterns of human settlement and economic activity. City lights trace the contours of civilization, creating a luminous map of where people live and work.",
                    page_embedding_text_3_large: new Array(3072).fill(0.1),
                    page_number: 1
                },
                {
                    id: "2", 
                    page_chunk: "From space, the aurora borealis appears as shimmering curtains of green and blue light dancing across the polar regions.",
                    page_embedding_text_3_large: new Array(3072).fill(0.2),
                    page_number: 2
                }
                // Add more fallback documents as needed
            ];
        }
    }
    
    async function uploadDocuments(searchClient: SearchClient<EarthAtNightDocument>): Promise<void> {
        console.log("📄 Uploading documents...");
    
        try {
            // Fetch documents from GitHub
            const documents = await fetchEarthAtNightDocuments();
    
            const result = await searchClient.uploadDocuments(documents);
            console.log(`✅ Uploaded ${result.results.length} documents successfully.`);
    
            // Wait for indexing to complete
            console.log("⏳ Waiting for document indexing to complete...");
            await new Promise(resolve => setTimeout(resolve, 5000));
            console.log("✅ Document indexing completed.");
    
        } catch (error) {
            console.error("❌ Error uploading documents:", error);
            throw error;
        }
    }
    
    async function createKnowledgeAgent(credential: DefaultAzureCredential): Promise<void> {
    
        // In case the agent already exists, delete it first
        await deleteKnowledgeAgent(credential);
    
        console.log("🤖 Creating knowledge agent...");
    
        const agentDefinition = {
            name: config.agentName,
            description: "Knowledge agent for Earth at Night e-book content",
            models: [
                {
                    kind: "azureOpenAI",
                    azureOpenAIParameters: {
                        resourceUri: config.azureOpenAIEndpoint,
                        deploymentId: config.azureOpenAIGptDeployment,
                        modelName: config.azureOpenAIGptModel
                    }
                }
            ],
            targetIndexes: [
                {
                    indexName: config.indexName,
                    defaultRerankerThreshold: 2.5
                }
            ]
        };
    
        try {
            const token = await getAccessToken(credential, "https://search.azure.com/.default");
            const response = await fetch(`${config.searchEndpoint}/agents/${config.agentName}?api-version=${config.searchApiVersion}`, {
                method: 'PUT',
                headers: {
                    'Content-Type': 'application/json',
                    'Authorization': `Bearer ${token}`
                },
                body: JSON.stringify(agentDefinition)
            });
    
            if (!response.ok) {
                const errorText = await response.text();
                throw new Error(`Failed to create knowledge agent: ${response.status} ${response.statusText}\n${errorText}`);
            }
    
            console.log(`✅ Knowledge agent '${config.agentName}' created successfully.`);
    
        } catch (error) {
            console.error("❌ Error creating knowledge agent:", error);
            throw error;
        }
    }
    
    async function runAgenticRetrieval(credential: DefaultAzureCredential, openAIClient: AzureOpenAI): Promise<void> {
        console.log("🔍 Running agentic retrieval...");
    
        const messages: KnowledgeAgentMessage[] = [
            {
                role: "system",
                content: `A Q&A agent that can answer questions about the Earth at night.
    Sources have a JSON format with a ref_id that must be cited in the answer.
    If you do not have the answer, respond with "I don't know".`
            },
            {
                role: "user",
                content: "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?"
            }
        ];
    
        try {
            // Call agentic retrieval API
            const userMessages = messages.filter(m => m.role !== "system");
            const retrievalResponse = await callAgenticRetrieval(credential, userMessages);
    
            // Extract the assistant response from agentic retrieval
            let assistantContent = '';
            if (typeof retrievalResponse.response === 'string') {
                assistantContent = retrievalResponse.response;
            } else if (Array.isArray(retrievalResponse.response)) {
                assistantContent = JSON.stringify(retrievalResponse.response);
            }
    
            // Add assistant response to conversation history
            messages.push({
                role: "assistant",
                content: assistantContent
            });
    
            console.log(assistantContent);
    
            // Log activities and results...
            console.log("\nActivities:");
            if (retrievalResponse.activity && Array.isArray(retrievalResponse.activity)) {
                retrievalResponse.activity.forEach((activity) => {
                    const activityType = activity.activityType || activity.type || 'UnknownActivityRecord';
                    console.log(`Activity Type: ${activityType}`);
                    console.log(JSON.stringify(activity, null, 2));
                });
            }
    
            console.log("Results");
            if (retrievalResponse.references && Array.isArray(retrievalResponse.references)) {
                retrievalResponse.references.forEach((reference) => {
                    const referenceType = reference.referenceType || reference.type || 'AzureSearchDoc';
                    console.log(`Reference Type: ${referenceType}`);
                    console.log(JSON.stringify(reference, null, 2));
                });
            }
    
            // Now do chat completion with full conversation history
            await generateFinalAnswer(openAIClient, messages);
    
            // Continue conversation with second question
            await continueConversation(credential, openAIClient, messages);
    
        } catch (error) {
            console.error("❌ Error in agentic retrieval:", error);
            throw error;
        }
    }
    
    async function generateFinalAnswer(
        openAIClient: AzureOpenAI,
        messages: KnowledgeAgentMessage[]
    ): Promise<void> {
    
        console.log("\n[ASSISTANT]: ");
    
        try {
            const completion = await openAIClient.chat.completions.create({
                model: config.azureOpenAIGptDeployment,
                messages: messages.map(m => ({ role: m.role, content: m.content })) as any,
                max_tokens: 1000,
                temperature: 0.7
            });
    
            const answer = completion.choices[0].message.content;
            console.log(answer?.replace(/\./g, "\n"));
    
            // Add this response to conversation history
            if (answer) {
                messages.push({
                    role: "assistant",
                    content: answer
                });
            }
    
        } catch (error) {
            console.error("❌ Error generating final answer:", error);
            throw error;
        }
    }
    
    async function callAgenticRetrieval(
        credential: DefaultAzureCredential, 
        messages: KnowledgeAgentMessage[]
    ): Promise<AgenticRetrievalResponse> {
    
        // Convert messages to the correct format expected by the Knowledge agent
        const agentMessages = messages.map(msg => ({
            role: msg.role,
            content: [
                {
                    type: "text",
                    text: msg.content
                }
            ]
        }));
    
        const retrievalRequest = {
            messages: agentMessages,
            targetIndexParams: [
                {
                    indexName: config.indexName,
                    rerankerThreshold: 2.5,
                    maxDocsForReranker: 100,
                    includeReferenceSourceData: true
                }
            ]
        };
    
        const token = await getAccessToken(credential, "https://search.azure.com/.default");
        const response = await fetch(
            `${config.searchEndpoint}/agents/${config.agentName}/retrieve?api-version=${config.searchApiVersion}`,
            {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'Authorization': `Bearer ${token}`
                },
                body: JSON.stringify(retrievalRequest)
            }
        );
    
        if (!response.ok) {
            const errorText = await response.text();
            throw new Error(`Agentic retrieval failed: ${response.status} ${response.statusText}\n${errorText}`);
        }
    
        return await response.json() as AgenticRetrievalResponse;
    }
    
    async function deleteKnowledgeAgent(credential: DefaultAzureCredential): Promise<void> {
        console.log("🗑️ Deleting knowledge agent...");
    
        try {
            const token = await getAccessToken(credential, "https://search.azure.com/.default");
            const response = await fetch(`${config.searchEndpoint}/agents/${config.agentName}?api-version=${config.searchApiVersion}`, {
                method: 'DELETE',
                headers: {
                    'Authorization': `Bearer ${token}`
                }
            });
    
            if (!response.ok) {
                if (response.status === 404) {
                    console.log(`ℹ️ Knowledge agent '${config.agentName}' does not exist or was already deleted.`);
                    return;
                }
                const errorText = await response.text();
                throw new Error(`Failed to delete knowledge agent: ${response.status} ${response.statusText}\n${errorText}`);
            }
    
            console.log(`✅ Knowledge agent '${config.agentName}' deleted successfully.`);
    
        } catch (error) {
            console.error("❌ Error deleting knowledge agent:", error);
            throw error;
        }
    }
    
    async function continueConversation(
        credential: DefaultAzureCredential,
        openAIClient: AzureOpenAI,
        messages: KnowledgeAgentMessage[]
    ): Promise<void> {
        console.log("\n💬 === Continuing Conversation ===");
    
        // Add follow-up question
        const followUpQuestion = "How do I find lava at night?"; 
        console.log(`❓ Follow-up question: ${followUpQuestion}`);
    
        messages.push({
            role: "user",
            content: followUpQuestion
        });
    
        try {
            // Don't include system messages in this retrieval
            const userAssistantMessages = messages.filter((m: KnowledgeAgentMessage) => m.role !== "system");
            const newRetrievalResponse = await callAgenticRetrieval(credential, userAssistantMessages);
    
            // Extract assistant response and add to conversation
            let assistantContent = '';
            if (typeof newRetrievalResponse.response === 'string') {
                assistantContent = newRetrievalResponse.response;
            } else if (Array.isArray(newRetrievalResponse.response)) {
                assistantContent = JSON.stringify(newRetrievalResponse.response);
            }
    
            // Add assistant response to conversation history
            messages.push({
                role: "assistant",
                content: assistantContent
            });
    
            console.log(assistantContent);
    
            // Log activities and results like the first retrieval
            console.log("\nActivities:");
            if (newRetrievalResponse.activity && Array.isArray(newRetrievalResponse.activity)) {
                newRetrievalResponse.activity.forEach((activity) => {
                    const activityType = activity.activityType || activity.type || 'UnknownActivityRecord';
                    console.log(`Activity Type: ${activityType}`);
                    console.log(JSON.stringify(activity, null, 2));
                });
            }
    
            console.log("Results");
            if (newRetrievalResponse.references && Array.isArray(newRetrievalResponse.references)) {
                newRetrievalResponse.references.forEach((reference) => {
                    const referenceType = reference.referenceType || reference.type || 'AzureSearchDoc';
                    console.log(`Reference Type: ${referenceType}`);
                    console.log(JSON.stringify(reference, null, 2));
                });
            }
    
            // Generate final answer for follow-up
            await generateFinalAnswer(openAIClient, messages);
    
            console.log("\n🎉 === Conversation Complete ===");
    
        } catch (error) {
            console.error("❌ Error in conversation continuation:", error);
            throw error;
        }
    }
    
    async function getAccessToken(credential: DefaultAzureCredential, scope: string): Promise<string> {
        const tokenResponse = await credential.getToken(scope);
        return tokenResponse.token;
    }
    
    // Error handling wrapper
    async function runWithErrorHandling(): Promise<void> {
        try {
            await main();
        } catch (error) {
            console.error("💥 Application failed:", error);
            process.exit(1);
        }
    }
    
    // Execute the application - ES module style
    runWithErrorHandling();
    
    export {
        main,
        createSearchIndex,
        deleteSearchIndex,
        fetchEarthAtNightDocuments,
        uploadDocuments,
        createKnowledgeAgent,
        deleteKnowledgeAgent,
        runAgenticRetrieval,
        EarthAtNightDocument,
        KnowledgeAgentMessage,
        AgenticRetrievalResponse
    };
    
  3. 创建 tsconfig.json 文件以转译 TypeScript 代码,然后复制以下 ECMAScript 代码。

    {
        "compilerOptions": {
          "module": "NodeNext",
          "target": "ES2022", // Supports top-level await
          "moduleResolution": "NodeNext",
          "skipLibCheck": true, // Avoid type errors from node_modules
          "strict": true // Enable strict type-checking options
        },
        "include": ["*.ts"]
    }
    
  4. 从 TypeScript 转译到 JavaScript。

    tsc
    
  5. 使用以下命令登录到 Azure:

    az login
    
  6. 使用以下命令运行 JavaScript 代码:

    node index.js
    

输出

应用程序的输出应如下所示:

[dotenv@17.2.0] injecting env (0) from .env (tip: ⚙️  override existing env vars with { override: true })
🚀 Starting Azure AI Search agentic retrieval quickstart...

📊 Creating search index...
✅ Index 'earth_at_night' created or updated successfully.
📄 Uploading documents...
📡 Fetching Earth at Night documents from GitHub...
✅ Fetched 194 documents from GitHub
✅ Uploaded 194 documents successfully.
⏳ Waiting for document indexing to complete...
✅ Document indexing completed.
🗑️ Deleting knowledge agent...
ℹ️ Knowledge agent 'earth-search-agent' does not exist or was already deleted.
🤖 Creating knowledge agent...
✅ Knowledge agent 'earth-search-agent' created successfully.
🔍 Running agentic retrieval...
[{"role":"assistant","content":[{"type":"text","text":"[]"}]}]

Activities:
Activity Type: ModelQueryPlanning
{
  "type": "ModelQueryPlanning",
  "id": 0,
  "inputTokens": 1379,
  "outputTokens": 551
}
Activity Type: AzureSearchQuery
{
  "type": "AzureSearchQuery",
  "id": 1,
  "targetIndex": "earth_at_night",
  "query": {
    "search": "Why do suburban areas show greater December brightening compared to urban cores despite higher absolute light levels downtown?",
    "filter": null
  },
  "queryTime": "2025-07-20T16:12:59.804Z",
  "count": 0,
  "elapsedMs": 549
}
Activity Type: AzureSearchQuery
{
  "type": "AzureSearchQuery",
  "id": 2,
  "targetIndex": "earth_at_night",
  "query": {
    "search": "Why is the Phoenix nighttime street grid sharply visible from space, while large stretches of interstate highways between Midwestern cities appear comparatively dim?",
    "filter": null
  },
  "queryTime": "2025-07-20T16:13:00.061Z",
  "count": 0,
  "elapsedMs": 256
}
Activity Type: AzureSearchSemanticRanker
{
  "type": "AzureSearchSemanticRanker",
  "id": 3,
  "inputTokens": 47630
}
Results

[ASSISTANT]: 
Suburban belts show larger December brightening than urban cores despite higher absolute light levels downtown because suburban areas often have more seasonal variation in lighting usage, such as increased decorative and outdoor lighting during the holiday season in December
 Urban cores typically have more constant and dense lighting throughout the year, so the relative increase in brightness during December is less pronounced compared to suburban areas
\n\nThe Phoenix nighttime street grid is sharply visible from space because the city has a well-planned, extensive grid of streets with consistent and bright street lighting
 In contrast, large stretches of interstate highways between Midwestern cities appear comparatively dim because these highways have less continuous lighting and lower intensity lights, making them less visible from space
\n\n(Note: These explanations are based on general knowledge about urban lighting patterns and visibility from space; specific studies or sources were not provided
)

💬 === Continuing Conversation ===
❓ Follow-up question: How do I find lava at night?
[{"role":"assistant","content":[{"type":"text","text":"[{\"ref_id\":0,\"content\":\"<!-- PageHeader=\\\"Volcanoes\\\" -->\\n\\n### Nighttime Glow at Mount Etna - Italy\\n\\nAt about 2:30 a.m. local time on March 16, 2017, the VIIRS DNB on the Suomi NPP satellite captured this nighttime image of lava flowing on Mount Etna in Sicily, Italy. Etna is one of the world's most active volcanoes.\\n\\n#### Figure: Location of Mount Etna\\nA world globe is depicted, with a marker indicating the location of Mount Etna in Sicily, Italy, in southern Europe near the center of the Mediterranean Sea.\\n\\n<!-- PageFooter=\\\"Earth at Night\\\" -->\\n<!-- PageNumber=\\\"48\\\" -->\"},{\"ref_id\":1,\"content\":\"<!-- PageHeader=\\\"Volcanoes\\\" -->\\n\\n## Volcanoes\\n\\n### The Infrared Glows of Kilauea's Lava Flows—Hawaii\\n\\nIn early May 2018, an eruption on Hawaii's Kilauea volcano began to unfold. The eruption took a dangerous turn on May 3, 2018, when new fissures opened in the residential neighborhood of Leilani Estates. During the summer-long eruptive event, other fissures emerged along the East Rift Zone. Lava from vents along the rift zone flowed downslope, reaching the ocean in several areas, and filling in Kapoho Bay.\\n\\nA time series of Landsat 8 imagery shows the progression of the lava flows from May 16 to August 13. The night view combines thermal, shortwave infrared, and near-infrared wavelengths to tease out the very hot lava (bright white), cooling lava (red), and lava flows obstructed by clouds (purple).\\n\\n#### Figure: Location of Kilauea Volcano, Hawaii\\n\\nA globe is shown centered on North America, with a marker placed in the Pacific Ocean indicating the location of Hawaii, to the southwest of the mainland United States.\\n\\n<!-- PageFooter=\\\"Earth at Night\\\" -->\\n<!-- PageNumber=\\\"44\\\" -->\"},{\"ref_id\":2,\"content\":\"For the first time in perhaps a decade, Mount Etna experienced a \\\"flank eruption\\\"—erupting from its side instead of its summit—on December 24, 2018. The activity was accompanied by 130 earthquakes occurring over three hours that morning. Mount Etna, Europe’s most active volcano, has seen periodic activity on this part of the mountain since 2013. The Operational Land Imager (OLI) on the Landsat 8 satellite acquired the main image of Mount Etna on December 28, 2018.\\n\\nThe inset image highlights the active vent and thermal infrared signature from lava flows, which can be seen near the newly formed fissure on the southeastern side of the volcano. The inset was created with data from OLI and the Thermal Infrared Sensor (TIRS) on Landsat 8. Ash spewing from the fissure cloaked adjacent villages and delayed aircraft from landing at the nearby Catania airport. Earthquakes occurred in the subsequent days after the initial eruption and displaced hundreds of people from their homes.\\n\\nFor nighttime images of Mount Etna’s March 2017 eruption, see pages 48–51.\\n\\n---\\n\\n### Hazards of Volcanic Ash Plumes and Satellite Observation\\n\\nWith the help of moonlight, satellite instruments can track volcanic ash plumes, which present significant hazards to airplanes in flight. The volcanic ash—composed of tiny pieces of glass and rock—is abrasive to engine turbine blades, and can melt on the blades and other engine parts, causing damage and even engine stalls. This poses a danger to both the plane’s integrity and passenger safety. Volcanic ash also reduces visibility for pilots and can cause etching of windshields, further reducing pilots’ ability to see. Nightlight images can be combined with thermal images to provide a more complete view of volcanic activity on Earth’s surface.\\n\\nThe VIIRS Day/Night Band (DNB) on polar-orbiting satellites uses faint light sources such as moonlight, airglow (the atmosphere’s self-illumination through chemical reactions), zodiacal light (sunlight scattered by interplanetary dust), and starlight from the Milky Way. Using these dim light sources, the DNB can detect changes in clouds, snow cover, and sea ice:\\n\\n#### Table: Light Sources Used by VIIRS DNB\\n\\n| Light Source         | Description                                                                  |\\n|----------------------|------------------------------------------------------------------------------|\\n| Moonlight            | Reflected sunlight from the Moon, illuminating Earth's surface at night      |\\n| Airglow              | Atmospheric self-illumination from chemical reactions                        |\\n| Zodiacal Light       | Sunlight scattered by interplanetary dust                                    |\\n| Starlight/Milky Way  | Faint illumination provided by stars in the Milky Way                        |\\n\\nGeostationary Operational Environmental Satellites (GOES), managed by NOAA, orbit over Earth’s equator and offer uninterrupted observations of North America. High-latitude areas such as Alaska benefit from polar-orbiting satellites like Suomi NPP, which provide overlapping coverage at the poles, enabling more data collection in these regions. During polar darkness (winter months), VIIRS DNB data allow scientists to:\\n\\n- Observe sea ice formation\\n- Monitor snow cover extent at the highest latitudes\\n- Detect open water for ship navigation\\n\\n#### Table: Satellite Coverage Overview\\n\\n| Satellite Type          | Orbit           | Coverage Area         | Special Utility                              |\\n|------------------------|-----------------|----------------------|----------------------------------------------|\\n| GOES                   | Geostationary   | Equatorial/North America | Continuous regional monitoring              |\\n| Polar-Orbiting (e.g., Suomi NPP) | Polar-orbiting    | Poles/high latitudes      | Overlapping passes; useful during polar night|\\n\\n---\\n\\n### Weather Forecasting and Nightlight Data\\n\\nThe use of nightlight data by weather forecasters is growing as the VIIRS instrument enables observation of clouds at night illuminated by sources such as moonlight and lightning. Scientists use these data to study the nighttime behavior of weather systems, including severe storms, which can develop and strike populous areas at night as well as during the day. Combined with thermal data, visible nightlight data allow the detection of clouds at various heights in the atmosphere, such as dense marine fog. This capability enables weather forecasters to issue marine advisories with higher confidence, leading to greater utility. (See \\\"Marine Layer Clouds—California\\\" on page 56.)\\n\\nIn this section of the book, you will see how nightlight data are used to observe nature’s spectacular light shows across a wide range of sources.\\n\\n---\\n\\n#### Notable Data from Mount Etna Flank Eruption (December 2018)\\n\\n| Event/Observation                  | Details                                                                    |\\n|-------------------------------------|----------------------------------------------------------------------------|\\n| Date of Flank Eruption              | December 24, 2018                                                          |\\n| Number of Earthquakes               | 130 earthquakes within 3 hours                                              |\\n| Image Acquisition                   | December 28, 2018 by Landsat 8 OLI                                         |\\n| Location of Eruption                | Southeastern side of Mount Etna                                            |\\n| Thermal Imaging Data                | From OLI and TIRS (Landsat 8), highlighting active vent and lava flows     |\\n| Impact on Villages/Air Transport    | Ash covered villages; delayed aircraft at Catania airport                  |\\n| Displacement                        | Hundreds of residents displaced                                            |\\n| Ongoing Seismic Activity            | Earthquakes continued after initial eruption                               |\\n\\n---\\n\\n<!-- PageFooter=\\\"Earth at Night\\\" -->\\n<!-- PageNumber=\\\"30\\\" -->\"},{\"ref_id\":3,\"content\":\"# Volcanoes\\n\\n---\\n\\n### Mount Etna Erupts - Italy\\n\\nThe highly active Mount Etna in Italy sent red lava rolling down its flank on March 19, 2017. An astronaut onboard the ISS took the photograph below of the volcano and its environs that night. City lights surround the mostly dark volcanic area.\\n\\n---\\n\\n#### Figure 1: Location of Mount Etna, Italy\\n\\nA world map highlighting the location of Mount Etna in southern Italy. The marker indicates its geographic placement on the east coast of Sicily, Italy, in the Mediterranean region, south of mainland Europe and north of northern Africa.\\n\\n---\\n\\n#### Figure 2: Nighttime View of Mount Etna's Eruption and Surrounding Cities\\n\\nThis is a nighttime satellite image taken on March 19, 2017, showing the eruption of Mount Etna (southeastern cone) with visible bright red and orange coloring indicating flowing lava from a lateral vent. The surrounding areas are illuminated by city lights, with the following geographic references labeled:\\n\\n| Location        | Position in Image         | Visible Characteristics                    |\\n|-----------------|--------------------------|--------------------------------------------|\\n| Mt. Etna (southeastern cone) | Top center-left | Bright red/orange lava flow                |\\n| Lateral vent    | Left of the volcano       | Faint red/orange flow extending outwards   |\\n| Resort          | Below the volcano, to the left   | Small cluster of lights                    |\\n| Giarre          | Top right                 | Bright cluster of city lights              |\\n| Acireale        | Center right              | Large, bright area of city lights          |\\n| Biancavilla     | Bottom left               | Smaller cluster of city lights             |\\n\\nAn arrow pointing north is shown on the image for orientation.\\n\\n---\\n\\n<!-- Earth at Night Page Footer -->\\n<!-- Page Number: 50 -->\"},{\"ref_id\":4,\"content\":\"## Nature's Light Shows\\n\\nAt night, with the light of the Sun removed, nature's brilliant glow from Earth's surface becomes visible to the naked eye from space. Some of Earth's most spectacular light shows are natural, like the aurora borealis, or Northern Lights, in the Northern Hemisphere (aurora australis, or Southern Lights, in the Southern Hemisphere). The auroras are natural electrical phenomena caused by charged particles that race from the Sun toward Earth, inducing chemical reactions in the upper atmosphere and creating the appearance of streamers of reddish or greenish light in the sky, usually near the northern or southern magnetic pole. Other natural lights can indicate danger, like a raging forest fire encroaching on a city, town, or community, or lava spewing from an erupting volcano.\\n\\nWhatever the source, the ability of humans to monitor nature's light shows at night has practical applications for society. For example, tracking fires during nighttime hours allows for continuous monitoring and enhances our ability to protect humans and other animals, plants, and infrastructure. Combined with other data sources, our ability to observe the light of fires at night allows emergency managers to more efficiently and accurately issue warnings and evacuation orders and allows firefighting efforts to continue through the night. With enough moonlight (e.g., full-Moon phase), it's even possible to track the movement of smoke plumes at night, which can impact air quality, regardless of time of day.\\n\\nAnother natural source of light at night is emitted from glowing lava flows at the site of active volcanoes. Again, with enough moonlight, these dramatic scenes can be tracked and monitored for both scientific research and public safety.\\n\\n\\n### Figure: The Northern Lights Viewed from Space\\n\\n**September 17, 2011**\\n\\nThis photo, taken from the International Space Station on September 17, 2011, shows a spectacular display of the aurora borealis (Northern Lights) as green and reddish light in the night sky above Earth. In the foreground, part of a Soyuz spacecraft is visible, silhouetted against the bright auroral light. The green glow is generated by energetic charged particles from the Sun interacting with Earth's upper atmosphere, exciting oxygen and nitrogen atoms, and producing characteristic colors. The image demonstrates the vividness and grandeur of natural night-time light phenomena as seen from orbit.\"}]"}]}]

Activities:
Activity Type: ModelQueryPlanning
{
  "type": "ModelQueryPlanning",
  "id": 0,
  "inputTokens": 1598,
  "outputTokens": 159
}
Activity Type: AzureSearchQuery
{
  "type": "AzureSearchQuery",
  "id": 1,
  "targetIndex": "earth_at_night",
  "query": {
    "search": "How can I locate lava flows during nighttime?",
    "filter": null
  },
  "queryTime": "2025-07-20T16:13:10.659Z",
  "count": 5,
  "elapsedMs": 260
}
Activity Type: AzureSearchSemanticRanker
{
  "type": "AzureSearchSemanticRanker",
  "id": 2,
  "inputTokens": 24146
}
Results
Reference Type: AzureSearchDoc
{
  "type": "AzureSearchDoc",
  "id": "0",
  "activitySource": 1,
  "docKey": "earth_at_night_508_page_64_verbalized",
  "sourceData": {
    "id": "earth_at_night_508_page_64_verbalized",
    "page_chunk": "<!-- PageHeader=\"Volcanoes\" -->\n\n### Nighttime Glow at Mount Etna - Italy\n\nAt about 2:30 a.m. local time on March 16, 2017, the VIIRS DNB on the Suomi NPP satellite captured this nighttime image of lava flowing on Mount Etna in Sicily, Italy. Etna is one of the world's most active volcanoes.\n\n#### Figure: Location of Mount Etna\nA world globe is depicted, with a marker indicating the location of Mount Etna in Sicily, Italy, in southern Europe near the center of the Mediterranean Sea.\n\n<!-- PageFooter=\"Earth at Night\" -->\n<!-- PageNumber=\"48\" -->"
  }
}
Reference Type: AzureSearchDoc
{
  "type": "AzureSearchDoc",
  "id": "1",
  "activitySource": 1,
  "docKey": "earth_at_night_508_page_60_verbalized",
  "sourceData": {
    "id": "earth_at_night_508_page_60_verbalized",
    "page_chunk": "<!-- PageHeader=\"Volcanoes\" -->\n\n## Volcanoes\n\n### The Infrared Glows of Kilauea's Lava Flows—Hawaii\n\nIn early May 2018, an eruption on Hawaii's Kilauea volcano began to unfold. The eruption took a dangerous turn on May 3, 2018, when new fissures opened in the residential neighborhood of Leilani Estates. During the summer-long eruptive event, other fissures emerged along the East Rift Zone. Lava from vents along the rift zone flowed downslope, reaching the ocean in several areas, and filling in Kapoho Bay.\n\nA time series of Landsat 8 imagery shows the progression of the lava flows from May 16 to August 13. The night view combines thermal, shortwave infrared, and near-infrared wavelengths to tease out the very hot lava (bright white), cooling lava (red), and lava flows obstructed by clouds (purple).\n\n#### Figure: Location of Kilauea Volcano, Hawaii\n\nA globe is shown centered on North America, with a marker placed in the Pacific Ocean indicating the location of Hawaii, to the southwest of the mainland United States.\n\n<!-- PageFooter=\"Earth at Night\" -->\n<!-- PageNumber=\"44\" -->"
  }
}
Reference Type: AzureSearchDoc
{
  "type": "AzureSearchDoc",
  "id": "2",
  "activitySource": 1,
  "docKey": "earth_at_night_508_page_46_verbalized",
  "sourceData": {
    "id": "earth_at_night_508_page_46_verbalized",
    "page_chunk": "For the first time in perhaps a decade, Mount Etna experienced a \"flank eruption\"—erupting from its side instead of its summit—on December 24, 2018. The activity was accompanied by 130 earthquakes occurring over three hours that morning. Mount Etna, Europe’s most active volcano, has seen periodic activity on this part of the mountain since 2013. The Operational Land Imager (OLI) on the Landsat 8 satellite acquired the main image of Mount Etna on December 28, 2018.\n\nThe inset image highlights the active vent and thermal infrared signature from lava flows, which can be seen near the newly formed fissure on the southeastern side of the volcano. The inset was created with data from OLI and the Thermal Infrared Sensor (TIRS) on Landsat 8. Ash spewing from the fissure cloaked adjacent villages and delayed aircraft from landing at the nearby Catania airport. Earthquakes occurred in the subsequent days after the initial eruption and displaced hundreds of people from their homes.\n\nFor nighttime images of Mount Etna’s March 2017 eruption, see pages 48–51.\n\n---\n\n### Hazards of Volcanic Ash Plumes and Satellite Observation\n\nWith the help of moonlight, satellite instruments can track volcanic ash plumes, which present significant hazards to airplanes in flight. The volcanic ash—composed of tiny pieces of glass and rock—is abrasive to engine turbine blades, and can melt on the blades and other engine parts, causing damage and even engine stalls. This poses a danger to both the plane’s integrity and passenger safety. Volcanic ash also reduces visibility for pilots and can cause etching of windshields, further reducing pilots’ ability to see. Nightlight images can be combined with thermal images to provide a more complete view of volcanic activity on Earth’s surface.\n\nThe VIIRS Day/Night Band (DNB) on polar-orbiting satellites uses faint light sources such as moonlight, airglow (the atmosphere’s self-illumination through chemical reactions), zodiacal light (sunlight scattered by interplanetary dust), and starlight from the Milky Way. Using these dim light sources, the DNB can detect changes in clouds, snow cover, and sea ice:\n\n#### Table: Light Sources Used by VIIRS DNB\n\n| Light Source         | Description                                                                  |\n|----------------------|------------------------------------------------------------------------------|\n| Moonlight            | Reflected sunlight from the Moon, illuminating Earth's surface at night      |\n| Airglow              | Atmospheric self-illumination from chemical reactions                        |\n| Zodiacal Light       | Sunlight scattered by interplanetary dust                                    |\n| Starlight/Milky Way  | Faint illumination provided by stars in the Milky Way                        |\n\nGeostationary Operational Environmental Satellites (GOES), managed by NOAA, orbit over Earth’s equator and offer uninterrupted observations of North America. High-latitude areas such as Alaska benefit from polar-orbiting satellites like Suomi NPP, which provide overlapping coverage at the poles, enabling more data collection in these regions. During polar darkness (winter months), VIIRS DNB data allow scientists to:\n\n- Observe sea ice formation\n- Monitor snow cover extent at the highest latitudes\n- Detect open water for ship navigation\n\n#### Table: Satellite Coverage Overview\n\n| Satellite Type          | Orbit           | Coverage Area         | Special Utility                              |\n|------------------------|-----------------|----------------------|----------------------------------------------|\n| GOES                   | Geostationary   | Equatorial/North America | Continuous regional monitoring              |\n| Polar-Orbiting (e.g., Suomi NPP) | Polar-orbiting    | Poles/high latitudes      | Overlapping passes; useful during polar night|\n\n---\n\n### Weather Forecasting and Nightlight Data\n\nThe use of nightlight data by weather forecasters is growing as the VIIRS instrument enables observation of clouds at night illuminated by sources such as moonlight and lightning. Scientists use these data to study the nighttime behavior of weather systems, including severe storms, which can develop and strike populous areas at night as well as during the day. Combined with thermal data, visible nightlight data allow the detection of clouds at various heights in the atmosphere, such as dense marine fog. This capability enables weather forecasters to issue marine advisories with higher confidence, leading to greater utility. (See \"Marine Layer Clouds—California\" on page 56.)\n\nIn this section of the book, you will see how nightlight data are used to observe nature’s spectacular light shows across a wide range of sources.\n\n---\n\n#### Notable Data from Mount Etna Flank Eruption (December 2018)\n\n| Event/Observation                  | Details                                                                    |\n|-------------------------------------|----------------------------------------------------------------------------|\n| Date of Flank Eruption              | December 24, 2018                                                          |\n| Number of Earthquakes               | 130 earthquakes within 3 hours                                              |\n| Image Acquisition                   | December 28, 2018 by Landsat 8 OLI                                         |\n| Location of Eruption                | Southeastern side of Mount Etna                                            |\n| Thermal Imaging Data                | From OLI and TIRS (Landsat 8), highlighting active vent and lava flows     |\n| Impact on Villages/Air Transport    | Ash covered villages; delayed aircraft at Catania airport                  |\n| Displacement                        | Hundreds of residents displaced                                            |\n| Ongoing Seismic Activity            | Earthquakes continued after initial eruption                               |\n\n---\n\n<!-- PageFooter=\"Earth at Night\" -->\n<!-- PageNumber=\"30\" -->"
  }
}
Reference Type: AzureSearchDoc
{
  "type": "AzureSearchDoc",
  "id": "3",
  "activitySource": 1,
  "docKey": "earth_at_night_508_page_66_verbalized",
  "sourceData": {
    "id": "earth_at_night_508_page_66_verbalized",
    "page_chunk": "# Volcanoes\n\n---\n\n### Mount Etna Erupts - Italy\n\nThe highly active Mount Etna in Italy sent red lava rolling down its flank on March 19, 2017. An astronaut onboard the ISS took the photograph below of the volcano and its environs that night. City lights surround the mostly dark volcanic area.\n\n---\n\n#### Figure 1: Location of Mount Etna, Italy\n\nA world map highlighting the location of Mount Etna in southern Italy. The marker indicates its geographic placement on the east coast of Sicily, Italy, in the Mediterranean region, south of mainland Europe and north of northern Africa.\n\n---\n\n#### Figure 2: Nighttime View of Mount Etna's Eruption and Surrounding Cities\n\nThis is a nighttime satellite image taken on March 19, 2017, showing the eruption of Mount Etna (southeastern cone) with visible bright red and orange coloring indicating flowing lava from a lateral vent. The surrounding areas are illuminated by city lights, with the following geographic references labeled:\n\n| Location        | Position in Image         | Visible Characteristics                    |\n|-----------------|--------------------------|--------------------------------------------|\n| Mt. Etna (southeastern cone) | Top center-left | Bright red/orange lava flow                |\n| Lateral vent    | Left of the volcano       | Faint red/orange flow extending outwards   |\n| Resort          | Below the volcano, to the left   | Small cluster of lights                    |\n| Giarre          | Top right                 | Bright cluster of city lights              |\n| Acireale        | Center right              | Large, bright area of city lights          |\n| Biancavilla     | Bottom left               | Smaller cluster of city lights             |\n\nAn arrow pointing north is shown on the image for orientation.\n\n---\n\n<!-- Earth at Night Page Footer -->\n<!-- Page Number: 50 -->"
  }
}
Reference Type: AzureSearchDoc
{
  "type": "AzureSearchDoc",
  "id": "4",
  "activitySource": 1,
  "docKey": "earth_at_night_508_page_44_verbalized",
  "sourceData": {
    "id": "earth_at_night_508_page_44_verbalized",
    "page_chunk": "## Nature's Light Shows\n\nAt night, with the light of the Sun removed, nature's brilliant glow from Earth's surface becomes visible to the naked eye from space. Some of Earth's most spectacular light shows are natural, like the aurora borealis, or Northern Lights, in the Northern Hemisphere (aurora australis, or Southern Lights, in the Southern Hemisphere). The auroras are natural electrical phenomena caused by charged particles that race from the Sun toward Earth, inducing chemical reactions in the upper atmosphere and creating the appearance of streamers of reddish or greenish light in the sky, usually near the northern or southern magnetic pole. Other natural lights can indicate danger, like a raging forest fire encroaching on a city, town, or community, or lava spewing from an erupting volcano.\n\nWhatever the source, the ability of humans to monitor nature's light shows at night has practical applications for society. For example, tracking fires during nighttime hours allows for continuous monitoring and enhances our ability to protect humans and other animals, plants, and infrastructure. Combined with other data sources, our ability to observe the light of fires at night allows emergency managers to more efficiently and accurately issue warnings and evacuation orders and allows firefighting efforts to continue through the night. With enough moonlight (e.g., full-Moon phase), it's even possible to track the movement of smoke plumes at night, which can impact air quality, regardless of time of day.\n\nAnother natural source of light at night is emitted from glowing lava flows at the site of active volcanoes. Again, with enough moonlight, these dramatic scenes can be tracked and monitored for both scientific research and public safety.\n\n\n### Figure: The Northern Lights Viewed from Space\n\n**September 17, 2011**\n\nThis photo, taken from the International Space Station on September 17, 2011, shows a spectacular display of the aurora borealis (Northern Lights) as green and reddish light in the night sky above Earth. In the foreground, part of a Soyuz spacecraft is visible, silhouetted against the bright auroral light. The green glow is generated by energetic charged particles from the Sun interacting with Earth's upper atmosphere, exciting oxygen and nitrogen atoms, and producing characteristic colors. The image demonstrates the vividness and grandeur of natural night-time light phenomena as seen from orbit."
  }
}

[ASSISTANT]: 
To find lava at night, satellite instruments like the VIIRS Day/Night Band (DNB) and thermal infrared sensors are used to detect the glow of very hot lava flows on the Earth's surface
 For example, nighttime satellite images have captured lava flowing from active volcanoes such as Mount Etna in Italy and Kilauea in Hawaii, where the hot lava emits bright light visible from space even at night
 Scientists combine thermal, shortwave infrared, and near-infrared data to distinguish very hot lava (bright white), cooling lava (red), and areas obscured by clouds
 Additionally, moonlight and other faint natural light sources help illuminate the surroundings to improve observation of volcanic activity at night
 Monitoring lava flow at night is important for scientific research and public safety, as it helps track volcanic eruptions and associated hazards such as ash plumes that can affect air travel and nearby communities [refs 0,1,2,3,4]


🎉 === Conversation Complete ===
🗑️ Deleting knowledge agent...
✅ Knowledge agent 'earth-search-agent' deleted successfully.
🗑️ Deleting search index...
✅ Search index 'earth_at_night' deleted successfully.
✅ Quickstart completed successfully!

了解代码

有了代码后,让我们分解关键组件:

创建搜索索引

在 Azure AI 搜索中,索引是结构化数据集合。 以下代码定义一 earth_at_night 个名为包含纯文本和矢量内容的索引。 可以使用现有索引,但它必须满足 代理检索工作负荷的条件。

const index: SearchIndex = {
    name: config.indexName,
    fields: [
        {
            name: "id",
            type: "Edm.String",
            key: true,
            filterable: true,
            sortable: true,
            facetable: true
        } as SearchField,
        {
            name: "page_chunk",
            type: "Edm.String",
            searchable: true,
            filterable: false,
            sortable: false,
            facetable: false
        } as SearchField,
        {
            name: "page_embedding_text_3_large",
            type: "Collection(Edm.Single)",
            searchable: true,
            filterable: false,
            sortable: false,
            facetable: false,
            vectorSearchDimensions: 3072,
            vectorSearchProfileName: "hnsw_text_3_large"
        } as SearchField,
        {
            name: "page_number",
            type: "Edm.Int32",
            filterable: true,
            sortable: true,
            facetable: true
        } as SearchField
    ],
    vectorSearch: {
        profiles: [
            {
                name: "hnsw_text_3_large",
                algorithmConfigurationName: "alg",
                vectorizerName: "azure_openai_text_3_large"
            } as VectorSearchProfile
        ],
        algorithms: [
            {
                name: "alg",
                kind: "hnsw"
            } as HnswAlgorithmConfiguration
        ],
        vectorizers: [
            {
                vectorizerName: "azure_openai_text_3_large",
                kind: "azureOpenAI",
                parameters: {
                    resourceUrl: config.azureOpenAIEndpoint,
                    deploymentId: config.azureOpenAIEmbeddingDeployment,
                    modelName: config.azureOpenAIEmbeddingModel
                } as AzureOpenAIParameters
            } as AzureOpenAIVectorizer
        ]
    } as VectorSearch,
    semanticSearch: {
        defaultConfigurationName: "semantic_config",
        configurations: [
            {
                name: "semantic_config",
                prioritizedFields: {
                    contentFields: [
                        { name: "page_chunk" } as SemanticField
                    ]
                } as SemanticPrioritizedFields
            } as SemanticConfiguration
        ]
    } as SemanticSearch
};

try {
    await indexClient.createOrUpdateIndex(index);
    console.log(`✅ Index '${config.indexName}' created or updated successfully.`);
} catch (error) {
    console.error("❌ Error creating index:", error);
    throw error;
}

索引架构包含文档标识和页面内容、嵌入和数字的字段。 它还包括语义排名和矢量查询的配置,这些配置使用之前部署的 text-embedding-3-large 模型。

将文档上传到索引

目前,索引 earth_at_night 为空。 运行以下代码,使用 美国宇航局地球在夜间电子书中的 JSON 文档填充索引。 根据 Azure AI 搜索的要求,每个文档都符合索引架构中定义的字段和数据类型。

const documentsUrl = "https://raw.githubusercontent.com/Azure-Samples/azure-search-sample-data/refs/heads/main/nasa-e-book/earth-at-night-json/documents.json";
    
try {
    const response = await fetch(documentsUrl);
    
    if (!response.ok) {
        throw new Error(`Failed to fetch documents: ${response.status} ${response.statusText}`);
    }
    
    const documents = await response.json();
    console.log(`✅ Fetched ${documents.length} documents from GitHub`);
    
    // Validate and transform documents to match our interface
    const transformedDocuments: EarthAtNightDocument[] = documents.map((doc: any, index: number) => {
        return {
            id: doc.id || String(index + 1),
            page_chunk: doc.page_chunk || doc.content || '',
            page_embedding_text_3_large: doc.page_embedding_text_3_large || new Array(3072).fill(0.1),
            page_number: doc.page_number || index + 1
        };
    });
    
    return transformedDocuments;
    
}

创建知识代理

要在查询时将 Azure AI 搜索连接到 gpt-5-mini 部署并面向 earth_at_night 索引,需要使用知识代理。 以下代码定义一个名为 earth-search-agent 的知识代理,该代理定义使用代理定义处理查询并从索引中检索相关文档 earth_at_night

为确保响应的相关性和语义意义明确,已设置 defaultRerankerThreshold,以排除 reranker 分数为 2.5 或更低的响应。

const agentDefinition = {
    name: config.agentName,
    description: "Knowledge agent for Earth at Night e-book content",
    models: [
        {
            kind: "azureOpenAI",
            azureOpenAIParameters: {
                resourceUri: config.azureOpenAIEndpoint,
                deploymentId: config.azureOpenAIGptDeployment,
                modelName: config.azureOpenAIGptModel
            }
        }
    ],
    targetIndexes: [
        {
            indexName: config.indexName,
            defaultRerankerThreshold: 2.5
        }
    ]
};   

设置消息

消息是检索路由的输入,包含对话历史记录。 每条消息都包含一个角色,该角色指示其来源,例如助理或用户,以及自然语言中的内容。 使用的 LLM 决定了哪些角色有效。

用户消息表示要处理的查询,而助理消息指导知识代理如何响应。 在检索过程中,这些消息将发送到 LLM,以便从索引文档中提取相关响应。

此助理消息指示 earth-search-agent 在夜间回答有关地球的问题,使用 ref_id 引用来源,并在答案不可用时回答“我不知道”。

const messages: KnowledgeAgentMessage[] = [
    {
        role: "system",
        content: `A Q&A agent that can answer questions about the Earth at night.
Sources have a JSON format with a ref_id that must be cited in the answer.
If you do not have the answer, respond with "I don't know".`
    },
    {
        role: "user",
        content: "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?"
    }
];

运行检索管道

此步骤运行检索管道,以便从搜索索引中提取相关信息。 根据检索请求中的信息和参数,LLM:

  1. 分析整个对话历史记录,以确定所需的基础信息。
  2. 将复合用户查询分解为重点子查询。
  3. 针对索引中的文本字段和矢量嵌入同时运行每个子查询。
  4. 使用语义排名器对所有子查询的结果重新排序。
  5. 将结果合并到单个字符串中。

以下代码将一个由两部分构成的用户查询发送到 earth-search-agent,该代码会将查询解构为子查询,并在 earth_at_night 索引中的文本字段和向量嵌入上运行这些子查询,随后对结果进行排名和合并。 然后,响应将追加到 messages 列表中。

const agentMessages = messages.map(msg => ({
    role: msg.role,
    content: [
        {
            type: "text",
            text: msg.content
        }
    ]
}));

const retrievalRequest = {
    messages: agentMessages,
    targetIndexParams: [
        {
            indexName: config.indexName,
            rerankerThreshold: 2.5,
            maxDocsForReranker: 100,
            includeReferenceSourceData: true
        }
    ]
};

const token = await getAccessToken(credential, "https://search.azure.com/.default");
const response = await fetch(
    `${config.searchEndpoint}/agents/${config.agentName}/retrieve?api-version=${config.searchApiVersion}`,
    {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'Authorization': `Bearer ${token}`
        },
        body: JSON.stringify(retrievalRequest)
    }
);

if (!response.ok) {
    const errorText = await response.text();
    throw new Error(`Agentic retrieval failed: ${response.status} ${response.statusText}\n${errorText}`);
}

return await response.json() as AgenticRetrievalResponse;

查看响应、活动和结果

现在,你想要显示检索管道的响应、活动和结果。

来自 Azure AI 搜索的每个检索响应包括:

  • 表示搜索结果中基础数据的统一字符串。

  • 查询计划。

  • 引用数据,其中显示了源文档的哪些区块促成了统一字符串。

console.log("\nActivities:");
if (retrievalResponse.activity && Array.isArray(retrievalResponse.activity)) {
    retrievalResponse.activity.forEach((activity) => {
        const activityType = activity.activityType || activity.type || 'UnknownActivityRecord';
        console.log(`Activity Type: ${activityType}`);
        console.log(JSON.stringify(activity, null, 2));
    });
}

console.log("Results");
if (retrievalResponse.references && Array.isArray(retrievalResponse.references)) {
    retrievalResponse.references.forEach((reference) => {
        const referenceType = reference.referenceType || reference.type || 'AzureSearchDoc';
        console.log(`Reference Type: ${referenceType}`);
        console.log(JSON.stringify(reference, null, 2));
    });
}

输出应包括:

  • Response 根据用户查询在搜索索引中提供最相关的文档(或区块)的文本字符串。 如本快速入门稍后所示,可以将此字符串传递给 LLM 进行答案生成。

  • Activity 跟踪检索过程中采取的步骤,其中包括由您的 gpt-5-mini 部署生成的子查询,以及用于查询规划和执行的令牌。

  • Results 列出构成该响应的文档,每个文档都由其 DocKey标识。

创建 Azure OpenAI 客户端

若要将检索管道从应答 提取 扩展到应答 生成,请设置 Azure OpenAI 客户端以与 gpt-5-mini 部署交互。

const scope = "https://cognitiveservices.azure.com/.default";
const azureADTokenProvider = getBearerTokenProvider(credential, scope);
const openAIClient = new AzureOpenAI({
    endpoint: config.azureOpenAIEndpoint,
    apiVersion: config.azureOpenAIApiVersion,
    azureADTokenProvider,
});

使用聊天补全 API 生成答案

用于生成答案的一个选项是聊天完成 API,该 API 将会话历史记录传递给 LLM 进行处理。

const completion = await openAIClient.chat.completions.create({
    model: config.azureOpenAIGptDeployment,
    messages: messages.map(m => ({ role: m.role, content: m.content })) as any,
    max_tokens: 1000,
    temperature: 0.7
});

const answer = completion.choices[0].message.content;
console.log(answer?.replace(/\./g, "\n"));

继续对话

通过向earth-search-agent发送另一个用户查询继续对话。 以下代码重新运行检索管道,从 earth_at_night 索引中提取相关内容,并将响应追加到 messages 列表中。 但是,与以前不同,现在可以使用 Azure OpenAI 客户端基于检索的内容生成答案。

const followUpQuestion = "How do I find lava at night?"; 
console.log(`❓ Follow-up question: ${followUpQuestion}`);

messages.push({
    role: "user",
    content: followUpQuestion
}); 

清理资源

在你自己的订阅中工作时,最好在结束项目时确定你是否仍需要创建的资源。 持续运行的资源可能会产生费用。 可以单独删除资源,也可以删除资源组以删除整个资源集。

在 Azure 门户中,可以通过从左窗格中选择 “所有资源 ”或 “资源组 ”来查找和管理资源。 还可以运行以下代码来删除在本快速入门中创建的对象。

删除知识代理

本快速入门中创建的知识代理通过以下代码片段进行删除:

const token = await getAccessToken(credential, "https://search.azure.com/.default");
const response = await fetch(`${config.searchEndpoint}/agents/${config.agentName}?api-version=${config.searchApiVersion}`, {
    method: 'DELETE',
    headers: {
        'Authorization': `Bearer ${token}`
    }
});

删除搜索索引

本快速入门中创建的搜索索引使用以下代码片段删除:

await indexClient.deleteIndex(config.indexName);
console.log(`✅ Search index '${config.indexName}' deleted successfully.`);

注释

此功能目前处于公开预览状态。 此预览版未随附服务级别协议,建议不要用于生产工作负载。 某些功能可能不受支持或者受限。 有关详细信息,请参阅 Microsoft Azure 预览版补充使用条款

在本快速入门中,你将使用智能体检索创建对话搜索体验,该体验由 Azure AI 搜索中索引的文档和 Azure AI Foundry 模型中的 Azure OpenAI 大型语言模型 (LLM) 提供支持。

知识智能体通过将复杂的查询分解为子查询,对一个或多个知识源执行这些子查询,并返回包含元数据的检索结果,从而实现智能体检索。 默认情况下,该智能体会输出源内容中的原始数据,但本快速入门教程使用“答案生成”模式来生成自然语言的答案。

虽然可以提供你自己的数据,但本快速入门使用了美国宇航局“夜间地球”电子书中的示例 JSON 文档。 这些文件描述了一般科学主题,以及从太空观测到的夜晚地球的图像。

小窍门

想要立即开始? 请参阅 GitHub 上的 azure-search-rest-samples 存储库。

先决条件

配置访问权限

在开始之前,请确保你有权访问内容和操作。 我们建议使用 Microsoft Entra ID 进行身份验证,并使用基于角色的访问控制进行授权。 你必须是“所有者”或“用户访问管理员”才能分配角色。 如果角色设置不可行,请改用基于密钥的身份验证方式

若要配置此快速入门的访问权限,请选择以下两个选项卡。

Azure AI 搜索提供智能体检索管道。 配置自己和搜索服务的访问权限,以读取和写入数据、与 Azure AI Foundry 交互以及运行管道。

配置 Azure AI 搜索的访问权限:

  1. 登录到 Azure 门户 并选择搜索服务。

  2. 启用基于角色的访问

  3. 创建系统分配的托管标识

  4. 将以下角色分配给自己。

    • 搜索服务参与者

    • 搜索索引数据参与者

    • 搜索索引数据读取者

重要

代理检索具有两种基于标记的计费模型:

  • Azure AI 搜索的语义排序功能的收费标准。
  • Azure OpenAI 的查询规划和答案生成功能收费标准。

语义排名在初始公共预览版中是免费的。 预览版后,将应用标准标记计费。 有关详细信息,请参阅 代理检索的可用性和定价

获取终结点

每个 Azure AI 搜索服务和 Azure AI Foundry 资源都有一个终结点,该终结点是唯一的 URL,用于标识和提供对资源的网络访问权限。 在后面的部分中,指定这些终结点以便通过编程方式连接到你的资源。

若要获取本快速入门的终结点,请选择以下两个选项卡。

  1. 登录到 Azure 门户 并选择搜索服务。

  2. 在左窗格中,选择“ 概述”。

  3. 记下终结点,形式应与 https://my-service.search.windows.net 类似。

部署模型

若要使用智能体检索,必须将两个 Azure OpenAI 模型部署到 Azure AI Foundry 资源:

  • 用于文本到矢量转换的嵌入模型。 本快速入门使用 text-embedding-3-large,但你可以使用任何 text-embedding 模型。

  • 用于查询规划和答案生成的 LLM。 本快速入门使用的是 gpt-5-mini,但你也可以使用任何受支持的具备智能体检索的 LLM

有关部署说明,请参阅 使用 Azure AI Foundry 部署 Azure OpenAI 模型

从本地系统进行连接

你已在 Azure AI Foundry 中配置基于角色的访问权限,以便与 Azure AI 搜索和 Azure OpenAI 进行交互。 在命令行中,使用 Azure CLI 登录到这两个服务的同一订阅和租户。 有关详细信息,请参阅 快速入门:在没有密钥的情况下连接

从本地系统进行连接:

  1. 打开命令行工具,例如 PowerShell。

  2. 登录 Azure 帐户。 如果有多个订阅,请选择包含 Azure AI 搜索服务和 Azure AI Foundry 项目的订阅。

    az login
    
  3. 生成 Microsoft Entra ID 令牌。

    az account get-access-token --scope https://search.azure.com/.default --query accessToken --output tsv
    
  4. 请记住这个令牌,以便在下一部分中使用。

加载连接

在发送任何请求之前,请在 Azure AI Foundry 中定义连接到 Azure AI 搜索和 Azure OpenAI 的终结点、凭据和部署详细信息。 需要在以下部分用到这些值。

若要加载连接:

  1. 在 Visual Studio Code 中,创建名为 agentic-retrieval.rest 的文件。

  2. 将以下变量和 HTTP 请求粘贴到文件中。

    @search-url = PUT-YOUR-SEARCH-SERVICE-URL-HERE
    @token = PUT-YOUR-MICROSOFT-ENTRA-TOKEN-HERE
    @aoai-url = PUT-YOUR-AOAI-FOUNDRY-URL-HERE
    @aoai-embedding-model = text-embedding-3-large
    @aoai-embedding-deployment = text-embedding-3-large
    @aoai-gpt-model = gpt-5-mini
    @aoai-gpt-deployment = gpt-5-mini
    @index-name = earth-at-night
    @knowledge-source-name = earth-knowledge-source
    @knowledge-agent-name = earth-knowledge-agent
    @api-version = 2025-08-01-Preview
    
    ### List existing indexes by name
    GET {{search-url}}/indexes?api-version={{api-version}}  HTTP/1.1
        Content-Type: application/json
        Authorization: Bearer {{token}}
    
  3. @search-urlaoai-url 的值设置为你在获取终结点时获取的值。

  4. @token 的值设置为你在“从本地系统进行连接”中获取的值。

  5. ### List existing indexes by name 下,选择“发送请求”即可验证与搜索服务之间的连接。

    相邻窗格中应该会显示响应。 如果有现有索引,则会列出它们。 否则,列表将为空。 如果 HTTP 状态码是 200 OK,则可以继续。

创建搜索索引

在 Azure AI 搜索中,索引是结构化数据集合。 使用索引 - 创建 (REST API) 定义一个名为 earth-at-night 的索引,之前使用 @index-name 变量指定该索引。

索引架构包含文档标识和页面内容、嵌入和数字的字段。 该架构还包含用于语义排序和向量搜索的配置,该配置利用你部署的 text-embedding-3-large 模型将文本转换为向量,并根据语义相似度匹配相关文档。

### Create an index
PUT {{search-url}}/indexes/{{index-name}}?api-version={{api-version}}  HTTP/1.1
    Content-Type: application/json
    Authorization: Bearer {{token}}

    {
        "name": "{{index-name}}",
        "fields": [
            {
                "name": "id",
                "type": "Edm.String",
                "key": true
            },
            {
                "name": "page_chunk",
                "type": "Edm.String",
                "searchable": true
            },
            {
                "name": "page_embedding_text_3_large",
                "type": "Collection(Edm.Single)",
                "stored": false,
                "dimensions": 3072,
                "vectorSearchProfile": "hnsw_text_3_large"
            },
            {
                "name": "page_number",
                "type": "Edm.Int32",
                "filterable": true
            }
        ],
        "semantic": {
            "defaultConfiguration": "semantic_config",
            "configurations": [
                {
                    "name": "semantic_config",
                    "prioritizedFields": {
                    "prioritizedContentFields": [
                        {
                            "fieldName": "page_chunk"
                        }
                    ]
                    }
                }
            ]
        },
        "vectorSearch": {
            "profiles": [
                {
                    "name": "hnsw_text_3_large",
                    "algorithm": "alg",
                    "vectorizer": "azure_openai_text_3_large"
                }
            ],
            "algorithms": [
                {
                    "name": "alg",
                    "kind": "hnsw"
                }
            ],
            "vectorizers": [
                {
                    "name": "azure_openai_text_3_large",
                    "kind": "azureOpenAI",
                    "azureOpenAIParameters": {
                    "resourceUri": "{{aoai-url}}",
                    "deploymentId": "{{aoai-embedding-deployment}}",
                    "modelName": "{{aoai-embedding-model}}"
                    }
                }
            ]
        }
    }

将文档上传到索引

目前,索引 earth-at-night 为空。 使用文档 - 索引 (REST API) 将 NASA 的《地球之夜》电子书中的 JSON 文档数据添加到索引中。 根据 Azure AI 搜索的要求,每个文档都符合索引架构中定义的字段和数据类型。

### Upload documents
POST {{search-url}}/indexes/{{index-name}}/docs/index?api-version={{api-version}}  HTTP/1.1
    Content-Type: application/json
    Authorization: Bearer {{token}}

    {
        "value": [
            {
                "@search.action": "upload",
                "id": "earth_at_night_508_page_104_verbalized",
                "page_chunk": "<!-- PageHeader=\"Urban Structure\" -->\n\n### Location of Phoenix, Arizona\n\nThe image depicts a globe highlighting the location of Phoenix, Arizona, in the southwestern United States, marked with a blue pinpoint on the map of North America. Phoenix is situated in the central part of Arizona, which is in the southwestern region of the United States.\n\n---\n\n### Grid of City Blocks-Phoenix, Arizona\n\nLike many large urban areas of the central and western United States, the Phoenix metropolitan area is laid out along a regular grid of city blocks and streets. While visible during the day, this grid is most evident at night, when the pattern of street lighting is clearly visible from the low-Earth-orbit vantage point of the ISS.\n\nThis astronaut photograph, taken on March 16, 2013, includes parts of several cities in the metropolitan area, including Phoenix (image right), Glendale (center), and Peoria (left). While the major street grid is oriented north-south, the northwest-southeast oriented Grand Avenue cuts across the three cities at image center. Grand Avenue is a major transportation corridor through the western metropolitan area; the lighting patterns of large industrial and commercial properties are visible along its length. Other brightly lit properties include large shopping centers, strip malls, and gas stations, which tend to be located at the intersections of north-south and east-west trending streets.\n\nThe urban grid encourages growth outwards along a city's borders by providing optimal access to new real estate. Fueled by the adoption of widespread personal automobile use during the twentieth century, the Phoenix metropolitan area today includes 25 other municipalities (many of them largely suburban and residential) linked by a network of surface streets and freeways.\n\nWhile much of the land area highlighted in this image is urbanized, there are several noticeably dark areas. The Phoenix Mountains are largely public parks and recreational land. To the west, agricultural fields provide a sharp contrast to the lit streets of residential developments. The Salt River channel appears as a dark ribbon within the urban grid.\n\n\n<!-- PageFooter=\"Earth at Night\" -->\n<!-- PageNumber=\"88\" -->",
                "page_embedding_text_3_large": [
                -0.002984904684126377, 0.0007500237552449107, -0.004803949501365423, 0.010587676428258419, -0.008392670191824436, -0.043565936386585236, 0.05432070791721344, 0.024532422423362732, -0.03305421024560928, -0.011362385004758835, 0.0029678153805434704, 0.0520421527326107, 0.019276559352874756, -0.05398651957511902, -0.025550175458192825, 0.018592992797493935, -0.02951485849916935, 0.036365706473588943, -0.02734263800084591, 0.028664197772741318, 0.027874300256371498, 0.008255957625806332, -0.05046235769987106, 0.01759042963385582, -0.003096933476626873, 0.03682141751050949, -0.002149434993043542, 0.009190164506435394, 0.0026716035790741444, -0.0031633912585675716, -0.014354884624481201, 0.004758378490805626, 0.01637520082294941, -0.010299060493707657, 0.004705212078988552, 0.016587866470217705, 0.0440824069082737, 0.019033513963222504, 0.039130352437496185, 0.04028481990098953, 0.018760086968541145, -0.05720687285065651, 0.030608562752604485, 0.010526915080845356, 0.020431026816368103, -0.04772809147834778, 0.03262887895107269, -0.02760087326169014, 0.03305421024560928, 0.009068641811609268, -0.003104528645053506, -0.035727713257074356, -0.04490268602967262, -0.039403777569532394, 0.026491977274417877, 0.01214468851685524, 0.037732839584350586, 0.08652425557374954, 0.005525491200387478, -0.0031994683668017387, 0.04684705287218094, 0.02872495912015438, 0.010481344535946846, 0.024076711386442184, 0.015813158825039864, 0.023180481046438217, -0.015949871391057968, 0.014749834313988686, -0.0006285008857958019, 0.0005739105399698019, 0.007192632649093866, 0.05787524953484535, 0.0043748221360147, 0.00038687934284098446, 0.04110509902238846, -0.0028273046482354403, 0.01397512573748827, -0.009106617420911789, -0.00770910456776619, -0.015304281376302242, 0.002582360291853547, -0.01092945970594883, -0.008552169427275658, 0.06665527075529099, 0.04657362401485443, -0.012197853997349739, -0.028861673548817635, -0.08925852179527283, -0.003831766778603196, 0.056538499891757965, -0.023453906178474426, -0.03083641827106476, -0.022223487496376038, -0.010253489017486572, 0.010807937011122704, 0.00313301058486104, 0.033904869109392166, -0.010116775520145893, 0.01742333546280861, 0.02594512514770031, -0.007777461316436529, -0.0002520649286452681, 0.005202696193009615, -0.02594512514770031, 0.010648438706994057, -0.01740814559161663, 0.0031254154164344072, -0.007542010862380266, 0.026142599061131477, 0.01731700450181961, 0.013504224829375744, -0.036183424293994904, -0.006357163190841675, -0.010428178124129772, -0.061338648200035095, 0.005457134917378426, 0.05316624045372009, 0.007861007936298847, 0.04311022534966469, 0.03867464140057564, -0.0021570303943008184, 0.016496725380420685, 0.05246748402714729, 0.007200228050351143, -0.003930503968149424, 0.007785056717693806, 0.017484096810221672, -0.003875439055263996, -0.0031538973562419415, 0.03180859982967377, -0.02497294172644615, 0.03627456724643707, 0.02533750981092453, 0.008385075256228447, -0.007298965007066727, 0.009866135194897652, -0.030168043449521065, 0.02594512514770031, 0.026233742013573647, 0.02079559490084648, -0.03396563231945038, -0.012607993558049202, -0.016162537038326263, -0.03378334641456604, -0.020582929253578186, -0.013846008107066154, 0.010215513408184052, 0.03317573294043541, 0.015706826001405716, -0.015296686440706253, 0.008491408079862595, 0.014727048575878143, 0.021828539669513702, 0.009942086413502693, -0.014096648432314396, -0.00913699809461832, -0.014354884624481201, 0.01672457903623581, -0.06118674576282501, 0.009212949313223362, 0.029970569536089897, -0.016572676599025726, 0.013071299530565739, -0.015828348696231842, 0.0012218741467222571, -0.04663438722491264, 0.01722586154937744, -0.02793506160378456, -0.035909995436668396, 0.007386309560388327, 0.04283680021762848, -0.051252253353595734, -0.036608751863241196, 0.006281211506575346, 0.029043957591056824, -0.022405771538615227, 0.011878857389092445, -0.0073141553439199924, -0.028785720467567444, -0.009904110804200172, -0.023013386875391006, -0.03527200222015381, 0.019534794613718987, -0.005905250087380409, -0.020491788163781166, 0.00045927087194286287, 0.0038450583815574646, -0.013435868546366692, 0.03840121626853943, -0.0059508210979402065, -0.023453906178474426, 0.004492547363042831, 0.05404727905988693, -0.01075477059930563, 0.04760656878352165, -0.04028481990098953, 0.03411753475666046, -0.008878761902451515, -0.02558055706322193, -0.013785246759653091, -0.010071204975247383, -0.01092945970594883, -0.04396088421344757, 0.017909428104758263, 0.03317573294043541, 0.03742903098464012, 0.02349947765469551, -0.013557391241192818, -0.004367226734757423, 0.03970758616924286, -0.002141839824616909, -0.032780785113573074, -0.008324313908815384, -0.025702079758048058, -0.02767682448029518, 0.02166144549846649, 0.03369220718741417, -0.043839361518621445, 0.011871261522173882, -0.024608373641967773, 0.015296686440706253, 0.02942371554672718, -0.015737207606434822, 0.017620811238884926, -0.01663343794643879, -0.03126174956560135, -0.02532231993973255, 0.018334757536649704, -0.04927751049399376, -0.03894806653261185, -0.02002088725566864, -0.025140035897493362, 0.016056204214692116, 0.02898319624364376, 0.029271813109517097, 0.020567739382386208, -0.006436912342905998, 0.022603247314691544, -0.023712143301963806, -0.004386214539408684, 0.030243994668126106, 0.0013244090368971229, -0.019276559352874756, -0.017043577507138252, 0.06234121322631836, -0.01757523976266384, -0.02829962968826294, 0.027099592611193657, 0.02088673785328865, 0.030168043449521065, 0.01005601417273283, -0.01537263859063387, 0.015737207606434822, 0.027904679998755455, 0.05744991824030876, -0.002301338594406843, -0.0022975411266088486, 0.004716604948043823, -0.0006194816087372601, 0.01985379308462143, -0.0403759628534317, 0.03612266108393669, 0.003028576960787177, 0.022694388404488564, 0.014218171127140522, 0.006710338871926069, -0.0023374157026410103, 0.0069951582700014114, 0.011202885769307613, -0.023195670917630196, 0.029742714017629623, -0.057753726840019226, 0.025747649371623993, -0.024000760167837143, 0.015395424328744411, -0.0019073388539254665, 0.019899364560842514, -0.009987657889723778, 0.004492547363042831, -0.018137283623218536, -0.002177916932851076, 0.004283679649233818, 0.03211240842938423, -0.03039589896798134, -0.04830532521009445, 0.037034083157777786, -0.016208108514547348, -0.018349947407841682, -0.010716794990003109, -0.0410747192800045, -0.022846292704343796, -0.08069115877151489, -0.008126839064061642, 0.024532422423362732, 0.03244659677147865, -0.010663628578186035, 0.01184847578406334, -0.05781448632478714, -0.04894332215189934, 0.002551979385316372, -0.008635716512799263, 0.028573056682944298, -0.06471090763807297, 0.033206112682819366, 0.0027589481323957443, 0.0271755438297987, -0.03211240842938423, 0.026598310098052025, -0.04472040385007858, -0.0648931935429573, -0.0012171270791441202, -0.012288996949791908, 0.0015370739856734872, -0.019200608134269714, -0.002876673359423876, 0.011954808607697487, 0.03196050599217415, -0.005316623952239752, -0.011932022869586945, -0.02916548028588295, 0.025534985587000847, -0.044446974992752075, -0.016344821080565453, 0.0257780309766531, -0.02141840010881424, 0.01109655387699604, 0.0007789803203195333, -0.022238679230213165, 0.0008444887353107333, -0.036791037768125534, -0.03806702792644501, 0.008347099646925926, 0.0020070255268365145, -0.021114591509103775, 0.05814867466688156, -0.028512295335531235, 0.031140226870775223, 0.03402639180421829, -0.0044887494295835495, 0.030517421662807465, 0.02401595003902912, -0.018000569194555283, -0.02106902189552784, -0.009676255285739899, 0.02673502266407013, -0.03305421024560928, 0.004750783089548349, 0.03314535319805145, -0.024274185299873352, -0.0007766068447381258, 0.0010823127813637257, 0.016177726909518242, -0.000631823786534369, -0.026507167145609856, 0.025200797244906425, 0.016162537038326263, -0.03621380403637886, -0.015813158825039864, 0.032598499208688736, -0.024775467813014984, 0.03305421024560928, -0.03387448936700821, -0.031565554440021515, 0.006262223701924086, -0.0447811633348465, 0.03232507407665253, -0.014878951944410801, 0.0027342636603862047, 0.005290040746331215, 0.020825974643230438, -0.0506446398794651, 0.030335137620568275, -0.04447735846042633, -0.013299155049026012, -0.01180290523916483, -0.022512104362249374, 0.003322890028357506, -0.004298869986087084, -0.008643311448395252, -0.003376056207343936, -0.0018057533307000995, 0.07036171853542328, 0.03445172309875488, -0.010640842840075493, 0.04554068297147751, 0.045662205666303635, -0.003444412723183632, -0.02305895835161209, 0.018395518884062767, 0.011939618736505508, -0.021175352856516838, -0.03445172309875488, 0.021874109283089638, -0.03867464140057564, 0.0188968013972044, -0.014408051036298275, -0.0021646255627274513, 0.006604006513953209, 0.03663913533091545, 0.022755149751901627, 0.00563562149181962, 0.05122187361121178, 0.0026165384333580732, 0.042624134570360184, -0.016056204214692116, 0.06070065498352051, 0.02384885586798191, -0.04630019888281822, 0.0049976264126598835, -0.038340453058481216, -0.014742238447070122, -0.0049368650652468204, -0.002063989406451583, -0.01803095079958439, -0.009342067874968052, 0.019534794613718987, -0.019868982955813408, 0.023742523044347763, 0.0024361531250178814, -0.006436912342905998, 0.005582455080002546, 0.0036969524808228016, -0.0536523312330246, 0.03132250905036926, -0.0433836504817009, -0.0010073103476315737, 0.012623184360563755, 0.0250792745500803, -0.01018513273447752, 0.017043577507138252, 0.0026279313024133444, -0.011962403543293476, -0.006569828372448683, 0.03332763537764549, -0.03091237135231495, 0.0039039209950715303, 0.014643501490354538, 0.010511725209653378, 0.013481439091265202, -0.03855311870574951, -0.022618437185883522, 0.03882654383778572, -0.010785151273012161, -0.024745086207985878, -0.01646634377539158, 0.05407766252756119, -0.003926706500351429, 0.01502326037734747, 0.03265926241874695, -0.034968193620443344, -0.037489794194698334, 0.04219880327582359, -0.031474415212869644, -0.0060381656512618065, 0.017043577507138252, -0.013921959325671196, -0.018395518884062767, -0.009061045944690704, 0.015486566349864006, -0.02646159753203392, 0.033114973455667496, -0.02116016298532486, 0.005882464814931154, -0.0690857321023941, 0.007568594068288803, -0.003814677707850933, -0.010823126882314682, 0.02915029041469097, 0.012600398622453213, -0.021372828632593155, 0.029408525675535202, 0.014590335078537464, -0.013390297070145607, 0.062280453741550446, -0.011180100962519646, 0.014438431710004807, -0.01636001095175743, -0.033388398587703705, 0.03888730704784393, -0.02839077264070511, -0.039312634617090225, 0.035120099782943726, 0.026051457971334457, -0.01792461797595024, 0.011742143891751766, 0.02456280216574669, 0.0014563752338290215, 0.0029070540331304073, -0.035818856209516525, 0.0275249220430851, 0.041317764669656754, 0.004484951961785555, 0.005028007086366415, -0.01323839370161295, 0.0003873540263157338, 0.01275230199098587, -0.04572296515107155, -8.188550418708473e-05, -0.008278743363916874, 0.0322035513818264, -0.05887781083583832, 0.01584353856742382, -0.014240956865251064, 0.0069951582700014114, -0.01022310834378004, 0.006417924538254738, 0.01923098787665367, 0.00792176928371191, -0.01127124298363924, -0.010777556337416172, 0.02018798142671585, -0.009744612500071526, -0.006653374992311001, -0.01602582447230816, 0.01602582447230816, -0.02673502266407013, 0.011514288373291492, 0.004579891916364431, 0.020415835082530975, -0.012995348311960697, -0.0016813823021948338, -0.009805373847484589, -0.00036077090771868825, -0.01827399618923664, 0.0027969239745289087, 0.003070350270718336, 0.01828918606042862, -0.013648533262312412, 0.003320991061627865, -0.009539542719721794, -0.02699325978755951, 0.03603151813149452, 0.026355264708399773, -0.019382892176508904, 0.021570302546024323, -0.008316718973219395, -0.024669134989380836, 0.01271432638168335, 0.039130352437496185, -0.005605240818113089, -0.03551504760980606, 0.0018370834877714515, 0.0001732649834593758, 0.025702079758048058, 0.010352225974202156, 0.018258806318044662, -0.008461027406156063, -0.002624133601784706, 0.008400266058743, 0.0012892812956124544, -0.005757144186645746, -0.005077376030385494, -0.0036342921666800976, 0.010443368926644325, -0.013830817304551601, -0.031292129307985306, 0.006797683425247669, 0.00988132506608963, -0.016663817688822746, 0.026598310098052025, -0.002910851500928402, -0.016496725380420685, -0.01913984678685665, -0.01593468151986599, -0.017438527196645737, -0.007093895226716995, -0.027874300256371498, 0.028405962511897087, 0.0023583024740219116, 0.02081078477203846, -0.01214468851685524, -0.008134434930980206, 0.023985568434000015, 0.02281591109931469, 0.018395518884062767, 0.019079085439443588, -0.020066456869244576, -0.050614260137081146, -0.012091522105038166, -0.006638184655457735, -0.0011829488212242723, 0.007397702429443598, 0.01698281615972519, -0.0028197094798088074, 0.0017298015300184488, -0.020506978034973145, 0.004435583483427763, 0.0005658406880684197, 0.009919301606714725, 0.012349758297204971, 0.030365517362952232, 0.026233742013573647, 0.04630019888281822, 0.03414791449904442, 0.011347194202244282, 0.029028765857219696, -0.0015256812330335379, 0.0027494539972394705, 0.0026962878182530403, -0.02627931348979473, 0.026005886495113373, 0.02027912251651287, 0.011248457245528698, -0.02561093680560589, 0.008278743363916874, 0.016253678128123283, 0.07868603616952896, -0.001408905372954905, 0.03284154459834099, -0.004644450731575489, -0.011164910160005093, -0.011233266443014145, 0.024577993899583817, -0.02395518869161606, 0.013846008107066154, -0.03505933657288551, -0.004386214539408684, 0.028861673548817635, 0.013982720673084259, -0.05587012320756912, 0.01092945970594883, -0.009911705739796162, 0.01775752380490303, -0.00600398750975728, -0.035484667867422104, -0.0010338934371247888, 0.00200322805903852, 0.020127220079302788, -0.01231937762349844, -0.055930882692337036, 0.015038450248539448, -0.02673502266407013, 0.008992689661681652, -0.05103959143161774, 0.008719263598322868, -0.008514193817973137, -0.013709294609725475, 0.00500522181391716, -0.01453716866672039, -0.045297637581825256, -0.013040918856859207, 0.0412873812019825, 0.009463590569794178, -0.02254248596727848, 0.0054685273207724094, 0.007697712164372206, -0.012425709515810013, -0.02732744626700878, 0.023286812007427216, 0.022922243922948837, -0.0006603057263419032, 0.004731795284897089, 0.0024855216033756733, -0.003024779260158539, 0.01537263859063387, -0.03091237135231495, -0.012045950628817081, -0.021266495808959007, -0.024836229160428047, -0.03755055367946625, -0.017620811238884926, 0.027843918651342392, 0.0030399695970118046, -0.014127029106020927, 0.017803095281124115, 0.010595272295176983, -0.005001423880457878, 0.005407765973359346, 0.024274185299873352, 0.0004153612535446882, 0.012395328842103481, 0.015456185676157475, 0.032082028687000275, 0.008331908844411373, 0.024866608902812004, -0.033479541540145874, 0.008916737511754036, 0.008947118185460567, -0.006923004053533077, 0.011947213672101498, 0.015220735222101212, 0.009326877072453499, 0.013686508871614933, -0.02594512514770031, 0.007234406191855669, -0.013504224829375744, 0.038613881915807724, -0.014544764533638954, 0.03244659677147865, -0.0011525681475177407, -0.01838032901287079, -0.020856356248259544, -0.014954904094338417, 0.0023222253657877445, -0.009425614960491657, 0.01035982184112072, -0.006714136339724064, -0.0026279313024133444, 0.01626886986196041, -0.02037026546895504, -0.015949871391057968, -0.022314630448818207, 0.014430836774408817, -0.00010496772301848978, -0.018562613055109978, 0.04137852415442467, -0.012175069190561771, 0.010268679820001125, -0.028330011293292046, -0.0020241145975887775, 0.003621000563725829, -0.004329251125454903, -0.005065983161330223, 0.034087155014276505, -7.624845602549613e-05, -0.009326877072453499, -0.04611791670322418, -0.0033817526418715715, -0.007936960086226463, -0.0006455900729633868, 0.012137092649936676, -0.00012140415492467582, -0.03183898329734802, -0.01626886986196041, -0.011407955549657345, -0.02899838611483574, -0.01838032901287079, -0.007219215855002403, -4.57490750704892e-05, 0.004815342370420694, -0.022329820320010185, -0.009653470478951931, 0.016846103593707085, -0.005700180307030678, -0.008559764362871647, -0.020431026816368103, -0.019291749224066734, 0.009714231826364994, -0.0012645969400182366, -0.020142409950494766, -0.002806417876854539, -0.01898794248700142, 0.026233742013573647, -0.02134244702756405, -0.010435773059725761, 0.040163297206163406, 0.01838032901287079, -0.0038716415874660015, -0.006736922077834606, 0.007219215855002403, 0.0035735308192670345, -0.02489699050784111, -0.0037842970341444016, -0.034087155014276505, 0.008536978624761105, 0.009592708200216293, -0.0002598974679131061, -0.03039589896798134, -0.0035811259876936674, 0.01219025906175375, 0.004606474656611681, 0.01323079876601696, -0.03998101130127907, 0.04469002038240433, -0.010769961401820183, 0.0019633532501757145, -0.0002748504630289972, 0.004454571288079023, 0.02664388157427311, -0.0019177822396159172, 0.012387733906507492, 0.0025671699550002813, -0.023013386875391006, -0.020598120987415314, -0.005992594640702009, 0.0157523974776268, 0.0038203741423785686, 0.013671319000422955, -0.005859679076820612, -0.013678913936018944, -0.004496344830840826, -0.021722206845879555, -0.0014782113721594214, 0.004564701579511166, 0.006919206120073795, -0.03250735625624657, 0.039555683732032776, -0.026188170537352562, -0.06938953697681427, 0.007678723894059658, 0.02097787894308567, 0.010975031182169914, -0.0006498623406514525, -0.027813538908958435, 0.011749738827347755, -0.010207917541265488, 0.01358777191489935, -0.007576189003884792, -0.009630684740841389, 0.012782682664692402, 0.044811543077230453, 0.010131966322660446, 0.003269723616540432, 0.009402829222381115, -0.012600398622453213, -0.03518085926771164, 0.015205544419586658, -0.014757429249584675, 0.01705876737833023, 0.014240956865251064, 0.022952625527977943, -0.004268489312380552, -0.001107946503907442, 0.03755055367946625, -0.016603056341409683, 0.0009769296739250422, -0.010542105883359909, 0.028603436425328255, 0.011149720288813114, -0.01792461797595024, -0.009197759442031384, 0.02412228286266327, 0.00500522181391716, 0.0014297920279204845, -0.004929270129650831, -0.015691636130213737, -0.011461121961474419, -0.015691636130213737, 0.012068736366927624, 0.007185037713497877, -0.0030304756946861744, 0.014476407319307327, 0.0034159307833760977, 0.05626507103443146, 0.0014782113721594214, 0.025793220847845078, -0.008833191357553005, 0.029271813109517097, -0.012630779296159744, 0.013291560113430023, 0.020005695521831512, 0.010853508487343788, 0.027221115306019783, -0.019079085439443588, 0.015858730301260948, 0.019276559352874756, -0.0007253393996506929, -0.011468717828392982, 0.015813158825039864, 0.032264310866594315, 0.04241146892309189, 0.03864426165819168, -0.019428463652729988, 0.04271527752280235, -0.0178486667573452, 0.0076141650788486, -0.008020507171750069, 0.00018252160225529224, -0.021965252235531807, -0.00827114749699831, -0.003489983966574073, -0.0001274565584026277, 0.005100161302834749, 0.011407955549657345, 0.00624703336507082, 0.007496439851820469, 0.02410709112882614, 0.019215798005461693, -0.019428463652729988, -0.016299249604344368, -0.01705876737833023, 0.0013680813135579228, 0.02986423671245575, -0.009410424157977104, 0.009592708200216293, -0.007196430116891861, 0.01201556995511055, 0.01541820913553238, -0.023028576746582985, 0.013656128197908401, -0.0010490837739780545, 0.011537074111402035, 0.028330011293292046, 0.020871546119451523, -0.02778315730392933, -0.007750878110527992, -0.011787714436650276, -0.02202601358294487, -0.003393145278096199, -0.027828728780150414, -0.013694103807210922, 0.0005321371136233211, -0.039494920521974564, 0.008453432470560074, 0.008954714052379131, -0.02175258658826351, 0.00085967913037166, -0.016511915251612663, 0.0049748411402106285, 0.029757903888821602, 0.014689072035253048, 0.012121902778744698, 0.011073768138885498, 0.021281685680150986, -0.007758473511785269, 0.030152853578329086, -0.028861673548817635, 0.027737585827708244, 0.009030665270984173, 0.04830532521009445, 0.04189499840140343, -0.010731984861195087, 0.006212854757905006, 0.003949492238461971, -0.021433589980006218, 0.020415835082530975, -0.0033342826645821333, -0.006193866953253746, -0.009083831682801247, -0.033996012061834335, 0.009752207435667515, 0.019717080518603325, -0.026947688311338425, 0.012091522105038166, 0.007929365150630474, -0.014119434170424938, 0.009623088873922825, -0.007488844450563192, -0.018182853236794472, 0.02662869170308113, -0.034087155014276505, 1.7727024896885268e-06, -0.0016813823021948338, 0.008757239207625389, 0.010215513408184052, -0.013496629893779755, -0.022481724619865417, -0.03341877833008766, -0.007678723894059658, -0.014453621581196785, 0.014939713291823864, -0.0037368270568549633, 0.010154752060770988, -0.01681572198867798, -0.032598499208688736, 0.010162346996366978, -0.0094484006986022, -0.002876673359423876, 0.01882084831595421, -0.008400266058743, 0.023529859259724617, -0.039221495389938354, 0.0031159212812781334, 0.03797588497400284, -0.000209816760616377, 0.0016424570931121707, -0.02236020192503929, -0.01838032901287079, -0.004241906572133303, -0.014240956865251064, -0.0061027249321341515, -0.0022690591868013144, -0.018592992797493935, 0.012000380083918571, -0.025383081287145615, -0.008529383689165115, -0.029469287022948265, -0.043657079339027405, -0.01005601417273283, 0.006000190041959286, 0.02456280216574669, -0.01838032901287079, 0.021919680759310722, -0.018304375931620598, 0.01257761288434267, 0.014795404858887196, 0.0023545047733932734, -0.005187505856156349, 0.015349852852523327, 0.010823126882314682, 0.020962689071893692, 0.006915408652275801, 0.00277413846924901, 0.038705021142959595, 0.03527200222015381, -0.03524162247776985, 0.01757523976266384, -0.010488939471542835, 0.017803095281124115, 0.01687648333609104, -0.004872306250035763, -0.04074053093791008, 0.004982436075806618, -0.06264501810073853, -0.01836513727903366, -0.012691540643572807, 0.014370075426995754, 0.008453432470560074, -0.008643311448395252, -0.006592613644897938, 0.023712143301963806, 0.00448115449398756, -0.029879426583647728, -0.01035982184112072, -0.006505269091576338, 0.012243425473570824, -0.015965061262249947, -0.0006550840334966779, 0.004652046132832766, -0.013519415631890297, 0.03323649615049362, 0.0034254249185323715, 0.0174992885440588, -0.006858444772660732, 0.007428083103150129, 0.029226241633296013, -0.024502040818333626, 0.01882084831595421, 0.003157694824039936, 0.03314535319805145, -0.016162537038326263, -0.009949682280421257, -0.008780024945735931, -0.00687743304297328, 0.0018978448351845145, 0.012152283452451229, -0.003020981792360544, -0.007936960086226463, -0.0016899269539862871, 0.021099401637911797, -0.0005853033508174121, 0.028846481814980507, -0.011187695898115635, -0.028193296864628792, -0.021433589980006218, 0.03797588497400284, -0.005202696193009615, -0.00019106616673525423, 0.00047090096632018685, 0.02046140655875206, 0.01376246102154255, 0.0012864330783486366, -0.015509351156651974, 0.03448210284113884, 0.0009873730596154928, -0.03089717961847782, -0.01932213082909584, 0.03335801884531975, -0.02829962968826294, 0.00448115449398756, -0.018425898626446724, -0.0054191588424146175, 0.02204120345413685, -0.011081363074481487, -0.012076331302523613, -0.002903256332501769, -0.0012494066031649709, 0.02281591109931469, 0.024623563513159752, 0.023985568434000015, -0.0017649292713031173, 0.017119528725743294, -0.0025918541941791773, 0.010549700818955898, 0.023970378562808037, 0.0015807462623342872, 0.0002632203686516732, -0.027570493519306183, 0.01992974430322647, 0.0029089527670294046, 0.006596411112695932, 0.0006773948553018272, -0.0038526535499840975, 0.010086394846439362, 0.005905250087380409, 0.005134339910000563, -0.0005159973516128957, 0.01070920005440712, -0.017377765849232674, -0.01288142055273056, 0.010762365534901619, 0.011575049720704556, -0.03718598559498787, 0.03882654383778572, -0.003734928322955966, -0.0017468907171860337, 0.011499098502099514, -0.005833095870912075, -0.008468622341752052, 0.006417924538254738, -0.006797683425247669, 0.022846292704343796, 0.022071585059165955, 0.011726953089237213, -0.004446976352483034, -0.01882084831595421, -0.01698281615972519, 0.08925852179527283, -0.00021812399791087955, 0.011377574875950813, 0.01362574752420187, -0.002124750753864646, -0.00016377100837416947, -0.011400360614061356, 0.011149720288813114, 0.01058008149266243, -0.01958036608994007, 0.0257780309766531, 0.014810595661401749, -0.008985094726085663, 0.0010661729611456394, 0.027373017743229866, -0.029028765857219696, -0.013944745063781738, 0.037216369062662125, -0.002675401046872139, 0.019398082047700882, 0.012152283452451229, 0.014977688901126385, -0.00391911156475544, -0.01345865335315466, 0.0028216082137078047, -0.015076426789164543, 0.03776321932673454, 0.011537074111402035, -0.0031538973562419415, -0.012304186820983887, -0.017271433025598526, -0.019018324092030525, -0.008362289518117905, -0.007644545752555132, -0.022420963272452354, -0.00122946931514889, -0.018957562744617462, 0.004439380951225758, 0.012615589424967766, 0.009342067874968052, -0.0181980449706316, 0.028770530596375465, 0.0033475742675364017, -0.02515522576868534, -0.005020412150770426, -0.013162441551685333, -0.01414221990853548, 0.020947499200701714, 0.013732080347836018, -0.005760941654443741, -0.007010348606854677, -0.02114497311413288, -0.0006152093410491943, -0.024699516594409943, -0.018592992797493935, 0.003148200921714306, -0.012607993558049202, -0.004184942692518234, 0.02270958013832569, 0.017301812767982483, -0.014043482020497322, -0.00896990392357111, -0.008559764362871647, -0.021995631977915764, -0.009174973703920841, -0.009524351917207241, -0.013428272679448128, -0.008635716512799263, -0.0040824078023433685, 0.026431215927004814, -0.03284154459834099, -0.004086205270141363, 0.011514288373291492, -0.012213044799864292, 0.007485046982765198, 0.027388207614421844, 0.0049102818593382835, 0.01602582447230816, 0.007150859106332064, 0.017438527196645737, -0.00228424952365458, 0.00759517727419734, -0.011369979940354824, -0.004302667919546366, -0.0073901074938476086, -0.025033703073859215, 0.004720402415841818, 0.007371119223535061, -0.01967150904238224, 0.001319661969318986, -0.03177822008728981, 0.018699325621128082, -0.030076900497078896, 0.011901642195880413, -0.008088863454759121, -0.011780119501054287, 0.0382796935737133, -0.010982626117765903, 0.008088863454759121, 0.008802809752523899, 0.029013575986027718, -0.00255577708594501, 0.01775752380490303, -0.028330011293292046, -0.001745941350236535, -0.021312067285180092, -0.009425614960491657, 0.03083641827106476, -0.017362574115395546, 0.003930503968149424, -0.024243805557489395, -0.007211620453745127, 0.002403873484581709, 0.02204120345413685, 0.02166144549846649, 0.013109276071190834, 0.021129783242940903, -0.021388018503785133, -0.02097787894308567, 0.02125130593776703, -0.010124371387064457, 0.027129972353577614, 0.008529383689165115, -0.0078002470545470715, 0.02421342395246029, 0.020339883863925934, 0.005612835753709078, -0.010526915080845356, 0.008430646732449532, 0.014119434170424938, -0.025048894807696342, -0.0014620715519413352, 0.014871357008814812, -0.0010709199123084545, 0.009964872151613235, -0.01375486608594656, 0.018046140670776367, -0.026081837713718414, 0.006292604375630617, 0.028254058212041855, -0.008681287057697773, -0.006535649765282869, 0.021813347935676575, 0.011233266443014145, -0.0028216082137078047, 0.005795120261609554, -0.03666951507329941, 0.010428178124129772, 0.004834330175071955, 0.0018304376862943172, -0.0008891104371286929, -0.03232507407665253, -0.020506978034973145, -0.022527296096086502, 0.009919301606714725, 0.012866229750216007, -0.007378714624792337, -0.005939428694546223, 0.012129497714340687, -0.014909332618117332, 0.005126744508743286, -0.017711952328681946, 0.0015019462443888187, -0.00339504424482584, 0.020506978034973145, 0.02184372954070568, 0.012152283452451229, -0.012395328842103481, -0.0033456755336374044, -0.00840786099433899, 0.0066078039817512035, -0.024441279470920563, -0.014073862694203854, 0.0019244280410930514, 0.03587961569428444, 0.006387543864548206, 0.008362289518117905, -0.012509256601333618, 0.02236020192503929, -0.009790183044970036, -0.03423905745148659, -0.01593468151986599, -0.009228140115737915, 0.011909238062798977, 0.02854267507791519, 0.016572676599025726, -0.0039001235272735357, 0.009699041023850441, 0.012463685125112534, -0.00021171556727495044, -0.0019671509508043528, 0.025459034368395805, -0.006596411112695932, -0.014392860233783722, 0.0011364283272996545, -0.00900787953287363, -0.006448305211961269, -0.02360581047832966, 0.02401595003902912, -0.0031975696329027414, -0.01127883791923523, -0.010162346996366978, 0.0069040157832205296, 0.008878761902451515, -0.019960125908255577, -0.003357068169862032, -0.02778315730392933, 0.0020677868742495775, -0.0024171650875359774, -0.015000474639236927, 0.03153517469763756, 0.005791322328150272, -0.004891294054687023, -0.03575809299945831, 0.03335801884531975, -0.00223108334466815, -0.0022861482575535774, 0.0013899174518883228, 0.008726858533918858, 0.011286432854831219, 0.0036779644433408976, -0.007238203659653664, 0.019868982955813408, 0.001202886109240353, -0.036608751863241196, 0.0026735023129731417, 0.004993828944861889, -0.022588057443499565, -0.006543245166540146, -0.007990126498043537, 0.02517041750252247, 0.005331814289093018, 0.020522167906165123, -0.007731890305876732, -0.019261369481682777, -0.01079274620860815, -0.00421912083402276, 0.025383081287145615, -0.010093990713357925, 0.04222918301820755, -0.006660970393568277, 0.0013832716504111886, -0.00664198212325573, 0.006193866953253746, -0.02646159753203392, -8.930266631068662e-05, -0.006368556059896946, -0.007553403731435537, -0.015091616660356522, -0.005647014360874891, -0.029104718938469887, 0.013291560113430023, -0.035302381962537766, -0.007602772209793329, -0.006577423308044672, -0.019382892176508904, -0.01566125452518463, -0.015152378007769585, -0.0064862812869250774, -0.012737112119793892, -0.019443653523921967, 0.016056204214692116, 0.0001465631794417277, -0.010314250364899635, 0.004503939766436815, 0.011324409395456314, -0.03515047952532768, -0.010207917541265488, 0.024137472733855247, 0.002639323938637972, -0.02237539179623127, -0.02515522576868534, -0.009501566179096699, -0.01109655387699604, 0.006520459428429604, -0.001006360980682075, -0.00272097229026258, 0.0031444032210856676, -0.001634861808270216, 0.0027589481323957443, 0.004841925576329231, 0.011294028721749783, 0.012737112119793892, 0.01053451094776392, 0.01619291678071022, 0.014590335078537464, -0.021266495808959007, 0.019443653523921967, 0.030426278710365295, 0.014172600582242012, 0.000182165575097315, 0.017286622896790504, 0.007686319295316935, 0.028147725388407707, -0.0031425044871866703, -0.008818000555038452, -0.03414791449904442, 0.010147156193852425, -0.01637520082294941, -0.005369790364056826, -0.0017791702412068844, 0.026947688311338425, 0.042168423533439636, -0.009418019093573093, -0.02229944057762623, -0.018577802926301956, 0.00013884932559449226, 0.021129783242940903, -0.017894236370921135, -0.008901547640562057, -0.009539542719721794, -0.003169087693095207, -0.0014582739677280188, 0.006041963584721088, 0.009828158654272556, -0.01888160966336727, -0.017833475023508072, 0.020613310858607292, -0.023803284391760826, -0.013025728985667229, -0.002684895182028413, -0.019990505650639534, -0.01906389370560646, -0.0012266210978850722, -0.012683945707976818, 0.006049558520317078, -0.0031823792960494757, 0.001622519688680768, -0.02924143150448799, -0.020704451948404312, -0.03275040164589882, -0.009197759442031384, 0.0009256622288376093, -0.024577993899583817, 0.010101585648953915, 0.017651190981268883, 0.019170226529240608, -0.0074128927662968636, -0.03247697651386261, 0.017438527196645737, -0.01057248655706644, -0.015494161285459995, -0.03100351244211197, -0.02038545534014702, -0.007424285635352135, 0.015873920172452927, -0.010861103422939777, -0.010845912620425224, 0.014863761141896248, 0.013359916396439075, -0.028178106993436813, 0.017043577507138252, -0.03545428812503815, 0.0034406152553856373, 0.006455900613218546, 0.014438431710004807, 0.011020601727068424, -0.007891388610005379, 0.02447166107594967, 0.021114591509103775, 0.007526820525527, 0.012220639735460281, -0.03305421024560928, -0.007424285635352135, -0.01363334245979786, 0.01983860321342945, -0.006524256896227598, 0.0060381656512618065, 0.004473559092730284, -0.016694199293851852, 0.0008981297141872346, -0.0038089812733232975, -0.0017155606765300035, -0.007260989397764206, 0.011871261522173882, 0.0055672647431492805, -0.00826355256140232, 0.04125700145959854, -0.0012361151166260242, -0.017651190981268883, -0.017636001110076904, 0.014461217448115349, 0.01200797501951456, -0.005768537055701017, -0.026659071445465088, -0.03475553169846535, -0.012509256601333618, -0.011195290833711624, 0.03193012252449989, 0.015509351156651974, 0.02097787894308567, -0.011195290833711624, -0.02559574693441391, -0.021220924332737923, -0.0161017756909132, 0.024608373641967773, 0.02942371554672718, 0.0014013102045282722, -0.006566030438989401, 0.04839646816253662, -0.023180481046438217, -0.012805468402802944, 0.003148200921714306, 0.0069305989891290665, -4.082407758687623e-05, 0.006497674155980349, -0.0042001330293715, 0.007067312486469746, -0.02079559490084648, 0.01201556995511055, 0.009980062954127789, -0.03551504760980606, -0.023529859259724617, 0.0012085825437679887, -0.0011041489196941257, -0.012554828077554703, -0.01740814559161663, -0.0017991075292229652, 0.015600494109094143, -0.0089243333786726, 0.0054457420483231544, 0.02523117884993553, 0.024395707994699478, -0.0017544858856126666, 0.007306560408324003, -0.026355264708399773, 0.013739675283432007, -0.012858634814620018, -0.009630684740841389, 0.0001252017536899075, 0.0020943700801581144, 0.01096743531525135, 0.010139561258256435, -0.00827114749699831, 0.012851039879024029, -0.013291560113430023, -0.012509256601333618, 0.004697617143392563, 0.011073768138885498, 0.015114402398467064, -0.010147156193852425, -0.012129497714340687, -0.00840786099433899, 0.005290040746331215, -0.015114402398467064, -0.0012313680490478873, 0.003875439055263996, 0.016162537038326263, 0.0040254439227283, 0.001309218700043857, -0.0060381656512618065, -0.00448115449398756, 0.0032070635352283716, 0.01379284169524908, 0.017392955720424652, -4.346458808868192e-05, -0.021281685680150986, -0.0012664957903325558, 0.006763505283743143, -0.019185416400432587, 0.02037026546895504, -0.0016823316691443324, -0.008704072795808315, 0.018137283623218536, -0.011081363074481487, 0.0040444317273795605, 0.03256811946630478, -0.008886356838047504, 0.010853508487343788, -0.006000190041959286, 0.009645874612033367, 0.01180290523916483, 0.00502420961856842, 0.00598499970510602, -0.004781163763254881, 0.0015275799669325352, -0.005738156381994486, -0.013823222368955612, 0.008468622341752052, -0.012266211211681366, 0.010040824301540852, -0.005290040746331215, -0.017347384244203568, -0.00592423789203167, 0.019428463652729988, 0.03177822008728981, 0.007473654113709927, 0.0058027151972055435, 0.028679389506578445, -0.018243614584207535, -0.004371024202555418, 0.01602582447230816, 0.01502326037734747, -0.014218171127140522, 0.00858255010098219, -0.02239058166742325, -0.0044052028097212315, 0.010352225974202156, -0.007272382266819477, -0.011028196662664413, 0.0007091996376402676, -0.014172600582242012, -0.0007509731221944094, 0.025124846026301384, -0.002405772218480706, -0.004484951961785555, 0.009524351917207241, 0.0029754105489701033, -0.002367796376347542, -0.0010243995347991586, 0.002379189245402813, 0.00827114749699831, -0.03065413422882557, 0.016906864941120148, 0.01628405973315239, 0.010769961401820183, -0.022253869101405144, -0.01184088084846735, 0.011377574875950813, -0.0087496442720294, 0.012159878388047218, 0.006019177846610546, 0.023894427344202995, 0.01001044362783432, 0.017089148983359337, 0.007553403731435537, -0.0028292033821344376, 0.008567359298467636, 0.006600209046155214, 0.032264310866594315, -0.01661824807524681, 0.005028007086366415, 0.0022462736815214157, -0.006345770321786404, -0.010694009251892567, -0.013527010567486286, 0.011134529486298561, 0.004090002737939358, 0.002563372254371643, 0.0071166809648275375, 0.004424190614372492, -0.0027228710241615772, -0.011901642195880413, 0.01253963727504015, 0.005806512665003538, 0.009205354377627373, -0.000719168339855969, 0.002172220731154084, 0.017377765849232674, -0.022086774930357933, 0.01061805710196495, 0.0010557295754551888, 0.0025481819175183773, -0.002544384216889739, -0.012106711976230145, 0.008020507171750069, 0.01288142055273056, -0.011856071650981903, 0.016679009422659874, 0.007997721433639526, -0.014924522489309311, -0.008043292909860611, 0.051677584648132324, -0.01593468151986599, -0.0032678248826414347, -0.006436912342905998, 0.004268489312380552, -0.011407955549657345, -0.008514193817973137, -0.006919206120073795, -0.0014326402451843023, 0.012380138970911503, 6.770388426957652e-05, -0.03232507407665253, -0.008977498859167099, 0.008780024945735931, -0.013253583572804928, -0.006436912342905998, -0.003717839252203703, -0.0044014048762619495, 0.010823126882314682, -0.01950441487133503, -0.014628310687839985, 0.012463685125112534, 0.006960979662835598, 0.021296877413988113, 0.004667236469686031, 0.00827114749699831, -0.014066267758607864, -0.015949871391057968, -0.007006550673395395, 0.007868603803217411, -0.01593468151986599, -0.026172980666160583, 0.008855976164340973, -0.000833095982670784, -0.0031273141503334045, -0.018243614584207535, -0.01345865335315466, 0.007568594068288803, 0.008772429078817368, -0.0015028956113383174, -0.0010111079318448901, 0.001840881071984768, 0.007185037713497877, -0.004902686923742294, 0.0018836038652807474, 0.011149720288813114, -0.020613310858607292, -0.014658691361546516, -0.021281685680150986, -0.0030152853578329086, 0.016998006030917168, 0.017089148983359337, 0.0008340454078279436, -0.01257761288434267, 0.0026962878182530403, 0.0023469096049666405, -0.0004457419563550502, 0.02160068415105343, 0.0036760657094419003, 0.00949397124350071, 0.005939428694546223, 0.019003132358193398, -0.03135289251804352, -0.011757333762943745, 0.009023070335388184, 0.016344821080565453, -0.007504034787416458, 0.002474128967151046, -0.0008796164183877409, -0.007777461316436529, -0.009212949313223362, -0.0036779644433408976, -0.011187695898115635, 0.0031633912585675716, -0.008164815604686737, -0.010595272295176983, 0.005472325254231691, 0.010610462166368961, 0.004690021742135286, -0.011711763218045235, 0.0012769391760230064, -0.006216652225703001, -0.01803095079958439, 0.005282445810735226, -0.009774993173778057, -0.012235830537974834, -0.0011867464054375887, -0.01844109036028385, -0.009402829222381115, -0.006167283747345209, -0.0010177537333220243, -0.001499098027125001, 0.003470995929092169, -0.013170037418603897, -0.002641222905367613, 0.0003273046750109643, 0.013185227289795876, -0.005848286207765341, -0.00753441546112299, -0.013739675283432007, 0.007671128958463669, 0.017195479944348335, 0.0215854924172163, 0.013595366850495338, 0.005658406764268875, 0.003121617715805769, 0.019625937566161156, 0.021524731069803238, 0.011468717828392982, -0.009630684740841389, -0.017879046499729156, -0.008491408079862595, -0.005100161302834749, 0.002193107269704342, 0.03560619056224823, 0.0027095794212073088, -0.0016851798864081502, 0.026081837713718414, -0.02517041750252247, -0.005138137377798557, 0.02169182524085045, -0.013185227289795876, -0.01436247956007719, -0.011020601727068424, 0.011688977479934692, -0.025140035897493362, 0.015137188136577606, 0.02071964368224144, -0.013375107198953629, -0.005821703001856804, 0.001578847412019968, 0.024076711386442184, 0.009243330918252468, -0.01950441487133503, 0.004811544436961412, -0.011932022869586945, 0.0031026299111545086, -0.010671223513782024, 0.016830911859869957, -0.0032735213171690702, 0.010458558797836304, -0.004686224274337292, 0.021388018503785133, 0.01898794248700142, 0.005126744508743286, -0.008172410540282726, 0.013504224829375744, 0.010337036103010178, -0.0034652994945645332, -0.0006337225786410272, 0.010602867230772972, 0.009714231826364994, -0.010678819380700588, -0.006026772782206535, -0.011438336223363876, 0.015152378007769585, 0.006395139265805483, -0.0017089148750528693, 0.014453621581196785, 0.007967340759932995, -0.013511819764971733, -0.004086205270141363, -0.009600304067134857, -0.010777556337416172, -0.00014217222633305937, -0.012448495253920555, -0.005282445810735226, -0.006979967933148146, 0.016329631209373474, -0.0013234595535323024, -0.03697332367300987, -0.016694199293851852, -3.245751577196643e-05, 0.00021824266877956688, -0.020051266998052597, -2.18509685510071e-05, 0.0002836323983501643, 0.01200797501951456, -0.014058672823011875, -0.017742333933711052, -0.012038355693221092, 0.00391911156475544, 0.0072647868655622005, 0.01740814559161663, -0.009061045944690704, -0.007576189003884792, -0.0011554163647815585, 0.013656128197908401, 0.022496914491057396, -0.031033894047141075, 0.008301528170704842, 0.0011411753948777914, 0.03457324579358101, -0.00792176928371191, 0.012311781756579876, 0.009364853613078594, -0.01872970722615719, 0.0009209152194671333, 0.02229944057762623, 0.00762176001444459, 0.017256243154406548, -0.006828064098954201, -0.010937054641544819, 0.0038336655125021935, 0.005612835753709078, 0.008430646732449532, -0.02038545534014702, 0.010283869691193104, 0.011696572415530682, 0.017089148983359337, -0.00379758863709867, 0.009463590569794178, -0.004834330175071955, -0.011810500174760818, -0.022739959880709648, -0.01235735323280096, -0.002682996215298772, -0.011810500174760818, -0.011985189281404018, -0.03265926241874695, -0.009524351917207241, -0.00552928913384676, -0.005498907994478941, 0.002538688015192747, 0.03463400900363922, 0.020309504121541977, 0.009873730130493641, 0.004777366295456886, -0.004314060788601637, 0.012030760757625103, 0.02559574693441391, 0.0022899459581822157, -0.020233551040291786, -0.029727522283792496, 0.0019633532501757145, -0.0011734548024833202, 0.003332383930683136, -0.0019633532501757145, -0.01271432638168335, -0.00788379367440939, 0.008734453469514847, 0.00019616918871179223, 0.00029241430456750095, 0.0010690211784094572, -0.020157599821686745, -0.018182853236794472, 0.019990505650639534, 0.01567644625902176, 0.011483907699584961, -0.004371024202555418, -0.016830911859869957, -0.0023393144365400076, -0.030927561223506927, -0.01053451094776392, -0.014757429249584675, 0.013094085268676281, -0.008157219737768173, -0.02011202834546566, 0.0075609986670315266, -0.009699041023850441, -0.0025045096408575773, 0.0031595935579389334, -0.0017117629759013653, 0.005191303323954344, 0.013306749984622002, 0.015782777220010757, 0.01219025906175375, -0.004014051053673029, -0.008248362690210342, 0.0062242476269602776, 0.013329535722732544, 0.014446026645600796, -0.010261083953082561, -0.006885027978569269, -0.008499003015458584, 0.003005791222676635, -0.00201272196136415, -0.011210481636226177, 0.016557486727833748, -0.012418114580214024, 0.013694103807210922, 0.00672932667657733, 0.0090990224853158, -0.004796354100108147, -0.021266495808959007, -0.01305610965937376, 0.0005330864805728197, 0.003987467847764492, -0.003070350270718336, 0.015327067114412785, -0.02524636872112751, -0.035909995436668396, 0.009569923393428326, -0.018258806318044662, 0.005734358914196491, -0.045996394008398056, -0.01541061419993639, 0.01202316489070654, 0.032780785113573074, -0.008893952704966068, 0.011066173203289509, 0.013808031566441059, 0.01467388216406107, -0.010139561258256435, -0.025140035897493362, -1.90324462892022e-05, 0.021782968193292618, -0.0075002373196184635, 0.007454666309058666, 0.001183898188173771, 0.0012883319286629558, -0.004450773820281029, 0.00017468907753936946, -0.005624228622764349, -0.018866419792175293, 0.020750023424625397, -0.006774898152798414, -0.008468622341752052, -0.005191303323954344, -0.020780405029654503, 0.0040254439227283, -0.013640938326716423, 0.020066456869244576, 0.0027057817205786705, 0.0025481819175183773, 0.003041868330910802, -0.007659736089408398, 0.027054021134972572, -0.024274185299873352, 0.0016054305015131831, -0.0015038450947031379, 0.012106711976230145, -0.005020412150770426, 0.00918256863951683, 0.004967245738953352, -0.01941327191889286, 0.006786290556192398, 0.010640842840075493, 0.003960884641855955, -0.012076331302523613, 0.0035545427817851305, 0.01144593209028244, 0.030243994668126106, 0.008802809752523899, -0.010466153733432293, 0.01058008149266243, -0.027281876653432846, -0.003262128448113799, 0.019443653523921967, 0.0035127694718539715, 0.006649577524513006, -0.02592993527650833, 0.008331908844411373, 0.02726668491959572, -0.009304092265665531, -0.020522167906165123, 0.026856545358896255, -0.003953289706259966, -0.01074717566370964, 0.01897275261580944, -0.021448779851198196, 0.0048874965868890285, 0.020947499200701714, -0.002352606039494276, 0.011924427933990955, -0.0002855311904568225, 0.005255862604826689, 0.002405772218480706, -0.0005995442625135183, -0.002310832729563117, -0.01235735323280096, -0.007340738549828529, -0.014947308227419853, 0.007823032326996326, -0.015266305766999722, -0.0003391721402294934, -0.004735592752695084, -0.01236494816839695, -0.01453716866672039, -0.0064217220060527325, 0.01626886986196041, 0.018258806318044662, 0.004876103717833757, -0.006520459428429604, -0.00391911156475544, 0.00948637630790472, -0.00517991092056036, -0.0008554068044759333, -0.004731795284897089, -0.004090002737939358, 0.0019462641794234514, 0.0027494539972394705, -0.0036266969982534647, 0.016162537038326263, -0.003227950306609273, 0.012220639735460281, -0.00014668185031041503, 0.003191873198375106, 0.0014487800654023886, 0.003829868044704199, 0.018957562744617462, 0.007188835181295872, 0.0037501186598092318, 0.011073768138885498, 0.010040824301540852, -0.008931928314268589, -0.040862053632736206, -0.01127883791923523, -0.02384885586798191, 0.006360960658639669, -0.007014146074652672, 0.01179531030356884, -0.0017715750727802515, 0.000940852565690875, 0.016086585819721222, 0.006957182195037603, 0.018304375931620598, 0.0026545142754912376, -0.008073673583567142, -0.00589765515178442, 0.026613499969244003, -0.009805373847484589, 0.012425709515810013, -0.02185891941189766, 0.017742333933711052, 0.0171499103307724, -0.02778315730392933, -0.012152283452451229, -0.0025159025099128485, -0.010253489017486572, -0.002141839824616909, 0.01994493417441845, -0.01681572198867798, -0.0037767018657177687, -0.009121807292103767, 0.021023450419306755, -0.006000190041959286, -0.00448115449398756, 0.005305231083184481, -0.007944555021822453, -0.004819139838218689, 0.0023298205342143774, 0.003227950306609273, 0.009721826761960983, -0.01687648333609104, 0.007469856645911932, 0.006767302751541138, -0.008871166966855526, 0.002476027701050043, -0.018942371010780334, 0.006087534595280886, -0.019170226529240608, 0.014825785532593727, 0.007743283174932003, 0.007128073833882809, 0.011263648048043251, 0.0063989367336034775, -0.009045856073498726, 0.020248742774128914, 0.006793885957449675, 0.015889110043644905, 0.0004813443520106375, -0.010853508487343788, 0.0021285484544932842, 0.010944650508463383, -0.00913699809461832, -0.0034539068583399057, -0.0016073293518275023, -0.007090097758919001, 0.0041051930747926235, 0.0005345105892047286, -0.008536978624761105, -0.02471470646560192, 0.013656128197908401, -0.0047242003493011, 0.0016377100255340338, 0.009812968783080578, -0.011164910160005093, -0.011590240523219109, -0.0028443937189877033, 0.005096363835036755, 0.03594037890434265, 0.016056204214692116, 0.0039039209950715303, 0.012911801226437092, 0.004165954422205687, -0.004678628873080015, 0.013048513792455196, -0.017787905409932137, 0.000356498610926792, 0.014377670362591743, -0.009471185505390167, -0.0033361816313117743, -0.003700749948620796, 0.01958036608994007, -0.0013766258489340544, -0.027221115306019783, -0.010952245444059372, 0.005009019281715155, -0.01092945970594883, 0.007405297830700874, -0.017529668286442757, -0.011476312763988972, 0.012433304451406002, 0.021023450419306755, -0.007131871301680803, -0.001692775054834783, -0.00231842789798975, -0.01742333546280861, 0.0020772810094058514, 0.005783727392554283, -0.005335611756891012, 0.014392860233783722, 0.010245894081890583, 0.036608751863241196, 0.00528624327853322, -0.019033513963222504, 0.01341308280825615, 0.0036760657094419003, 0.005009019281715155, -0.01801575906574726, -0.007215418387204409, 0.006045761052519083, -0.00037073958083055913, -0.004777366295456886, -0.002088673645630479, 0.01880565844476223, 0.0004727997584268451, 0.02037026546895504, -0.006569828372448683, 0.0008805658435449004, 0.015722015872597694, 0.003767207730561495, -0.00809645839035511, -0.00044052026350982487, 0.011240862309932709, 0.0008473369525745511, -0.01793980784714222, 0.0002572866214904934, -0.0027418588288128376, -0.015030855312943459, -0.0012313680490478873, 0.006600209046155214, 0.0006560334004461765, 0.006152093410491943, 0.019398082047700882, 0.0073901074938476086, 0.011126934550702572, -0.02272477000951767, -0.004014051053673029, 0.0011164910392835736, 0.007511630188673735, 0.011681382544338703, 0.004895091522485018, 0.010800342075526714, -0.0018741099629551172, 0.008947118185460567, 0.015220735222101212, -0.0038431596476584673, -0.0036532802041620016, 0.016846103593707085, 0.006941991858184338, 0.019808221608400345, 0.0052330768667161465, -0.006482483819127083, -0.014278932474553585, -0.0060153803788125515, -0.022846292704343796, 0.014127029106020927, -0.023803284391760826, -0.0009550935355946422, 0.0013395993737503886, -0.01836513727903366, 0.0069078137166798115, 0.01792461797595024, -0.020522167906165123, 0.005962213966995478, 0.0014041583053767681, 0.02195006236433983, -0.009076236747205257, -0.0073521314188838005, -0.010610462166368961, 0.00519889872521162, 0.02011202834546566, -0.02088673785328865, -0.0028728756587952375, -7.945267134346068e-05, -0.000648912915494293, 0.017651190981268883, 0.01882084831595421, 0.025990696623921394, -0.0020848761778324842, 0.006566030438989401, 0.014506787993013859, 0.03350992128252983, -0.01619291678071022, 0.029909808188676834, -0.000627076777163893, 0.0008145827450789511, 0.0028026204090565443, -0.02925662137567997, 0.002639323938637972, -0.0012456090189516544, -0.021296877413988113, -0.008423051796853542, 0.008369885385036469, -0.007967340759932995, -9.212119039148092e-06, -0.009812968783080578, -0.022238679230213165, -0.006030570715665817, 0.006436912342905998, 0.013344726525247097, 0.0015968859661370516, -0.004295072518289089, 0.012000380083918571, -0.0073141553439199924, 0.005650811828672886, -0.014749834313988686, -0.0322035513818264, 0.012448495253920555, -0.014559954404830933, 0.010071204975247383, -0.00681667122989893, -0.028952814638614655, -0.0157523974776268, 0.005377385299652815, -0.006945789325982332, -0.011088958941400051, -0.014924522489309311, -0.016937244683504105, 0.0033817526418715715, 0.004359631799161434, 0.0035735308192670345, -0.0012579512549564242, 0.01344346348196268, -0.006239437963813543, 0.0045760939829051495, 0.013420677743852139, -0.01162062119692564, -0.003655178938060999, 0.008187600411474705, -0.010261083953082561, 0.0031007309444248676, 0.004921674728393555, -0.02071964368224144, 0.008073673583567142, -0.018486661836504936, 0.0014297920279204845, 0.002538688015192747, 0.02219310775399208, -0.012843444012105465, 0.009737016633152962, 0.006706541404128075, -0.0023374157026410103, 0.018091712146997452, 0.0006826165481470525, -0.0075002373196184635, -0.003619101829826832, 0.0027171745896339417, -0.015349852852523327, -0.005248267203569412, 0.0174992885440588, -0.03475553169846535, 0.012797873467206955, -0.006216652225703001, 0.01670938916504383, 0.021205734461545944, -0.013557391241192818, -0.0013747269986197352, -0.03082122839987278, -0.009433209896087646, 0.006774898152798414, 0.015737207606434822, 0.015706826001405716, 0.007302762940526009, -0.007162251975387335, -0.002536789048463106, 0.021433589980006218, 0.004302667919546366, -0.004671033937484026, 0.011286432854831219, -0.006174879148602486, -0.0005644165794365108, -0.010701604187488556, -0.0067824930883944035, 0.008992689661681652, -0.017438527196645737, 0.006068546324968338, -0.013990316540002823, -0.014385265298187733, -0.002001329092308879, 0.014134624972939491, 0.011939618736505508, 0.004803949501365423, 0.00047730939695611596, -0.011688977479934692, 0.008711667731404305, 0.011567454785108566, -0.005498907994478941, 0.0049748411402106285, -0.029484476894140244, -0.008673692122101784, 0.026689453050494194, -0.004659641068428755, -0.005347004625946283, 0.0003961359616369009, 0.0036494825035333633, 0.001312066800892353, 0.02855786494910717, 0.019306940957903862, 0.008552169427275658, 0.05304471775889397, 0.015889110043644905, -0.010633247904479504, -0.005081173498183489, 0.0002791227598208934, 0.0026564132422208786, 0.010944650508463383, 0.0059508210979402065, 0.021965252235531807, 0.012547232210636139, 0.007815437391400337, 0.004538118373602629, 0.017347384244203568, -0.015478970482945442, -0.018167663365602493, 0.0028235071804374456, 0.013116871006786823, -0.0019918351899832487, 0.007321750745177269, 0.014096648432314396, -0.01018513273447752, -0.009904110804200172, 0.016694199293851852, -0.010595272295176983, -0.01005601417273283, -0.008977498859167099, -0.00483053270727396, -0.014757429249584675, 0.010610462166368961, 0.011597835458815098, 0.0073141553439199924, 0.002544384216889739, -0.032082028687000275, 0.012782682664692402, -0.0062508308328688145, -0.006136903073638678, -0.011878857389092445, 0.01544858980923891, -0.005039399955421686, -0.007629355415701866, -0.004055824596434832, -0.009797777980566025, 0.005703977774828672, -0.008704072795808315, -0.002508307108655572, 0.00983575452119112, 0.005981201771646738, -0.002367796376347542, -0.007967340759932995, 0.007724294904619455, -0.008423051796853542, 0.01271432638168335, -0.009266115725040436, -0.018349947407841682, -0.0028728756587952375, 0.002962118946015835, -0.012213044799864292, -0.007074907422065735, -0.00228424952365458, -0.010952245444059372, 0.006053355988115072, -0.009053451009094715, 0.011514288373291492, 0.019352510571479797, 0.009258520789444447, -0.0039001235272735357, 0.0007324598846025765, -0.00792176928371191, 0.011180100962519646, -0.01558530330657959, -0.0054457420483231544, 0.008719263598322868, 0.0003204215317964554, -0.011673787608742714, 0.008590145036578178, 0.009387638419866562, -0.0019481629133224487, -0.03463400900363922, 0.016208108514547348, -0.020248742774128914, -0.0033893478102982044, -0.0012655464233830571, -0.0056546092964708805, 0.011947213672101498, 0.00826355256140232, 0.012167473323643208, 0.007355928886681795, 0.013344726525247097, -0.004260894376784563, -0.0051229470409452915, 0.01810690201818943, 0.0069040157832205296, -0.004564701579511166, -0.005453336983919144, -0.0011601633159443736, 0.036699894815683365, 0.01023070327937603, 0.005422956310212612, -0.013352321460843086, 0.0025652709882706404, 0.0012380138505250216, -0.012592803686857224, 0.0031102250795811415, -0.005438146647065878, 0.008134434930980206, -0.014780214987695217, -0.01092945970594883, 0.013640938326716423, 0.0023924808483570814, 0.0001991360477404669, 0.004033038858324289, -0.0016130257863551378, -0.01271432638168335, -0.026932498440146446, -0.01663343794643879, 0.013732080347836018, -0.014932118356227875, 0.00509256636723876, -0.02760087326169014, 0.00949397124350071, -0.0026450203731656075, -0.019990505650639534, 0.005290040746331215, 0.004705212078988552, -0.007238203659653664, -0.01509921159595251, 0.01035982184112072, -0.01001044362783432, -0.0029792082495987415, -0.011050982400774956, -0.03168707713484764, -0.02088673785328865, 0.010033228434622288, 0.011742143891751766, -0.0007091996376402676, -0.03013766184449196, 0.008673692122101784, 0.0009432260412722826, -0.01733219437301159, 0.015691636130213737, -0.00421912083402276, -0.004226716235280037, -0.0038013861048966646, -0.005434349179267883, 0.008719263598322868, -0.00456849904730916, 0.01897275261580944, -0.0058900597505271435, 0.02743377909064293, 0.014871357008814812, -0.022223487496376038, 0.004116585943847895, 0.013777650892734528, 0.01992974430322647, -0.0050583877600729465, 0.0038963258266448975, 0.003560239216312766, -0.02009683847427368, -0.001692775054834783, -0.004496344830840826, 0.0036001140251755714, 0.008544574491679668, -0.02541346289217472, -0.01654229499399662, -0.0056318240240216255, 0.009683851152658463, -0.029469287022948265, -0.004674831405282021, -0.007238203659653664, 0.005324219353497028, 0.006676160730421543, -0.002755150431767106, 0.010868698358535767, 0.0019918351899832487, -0.0045533087104558945, -0.009121807292103767, -0.0006308744195848703, -0.012873824685811996, -0.005582455080002546, -0.007340738549828529, -0.002474128967151046, -0.0062508308328688145, 0.020339883863925934, -0.007321750745177269, 0.00689642084762454, -0.0033912465441972017, -0.01672457903623581, -0.021555112674832344, 0.022952625527977943, -0.023636190220713615, -0.002037406200543046, 0.008134434930980206, -0.012813063338398933, 0.003096933476626873, -0.0001596173970028758, -0.006945789325982332, 0.00195955578237772, -0.011559859849512577, -0.004234311170876026, 0.022481724619865417, -0.02114497311413288, 0.016329631209373474, -0.007511630188673735, 0.014172600582242012, -0.013564986176788807, -0.0076483432203531265, -0.03054780140519142, 0.0035450488794595003, -0.011218076571822166, 0.01827399618923664, -0.005886262282729149, -0.026248931884765625, 0.021220924332737923, 0.0018105002818629146, 0.0005307130049914122, -0.029712332412600517, -0.001513338997028768, 0.0018617677269503474, -0.014689072035253048, 0.01035982184112072, -0.010344631038606167, 0.022436153143644333, 0.03475553169846535, -0.021023450419306755, 0.017377765849232674, -0.011605430394411087, 0.007074907422065735, -0.008567359298467636, -0.011263648048043251, -0.004355833865702152, -0.00988132506608963, 0.013071299530565739, 0.01253204233944416, -0.005403968505561352, -0.02176777832210064, -0.02907433733344078, 0.007747080642729998, 0.009342067874968052, 0.0005378334899432957, 0.010382606647908688, 0.026583120226860046, 0.00163201370742172, 0.011195290833711624, 0.005753346718847752, -0.018091712146997452, -0.004173549823462963, 0.0005098262336105108, -0.013010538183152676, 0.011704168282449245, -0.01363334245979786, 0.015615683980286121, -0.02132725715637207, -0.02655273862183094, 0.022071585059165955, 0.0049102818593382835, 0.008385075256228447, 0.009410424157977104, -0.00918256863951683, 0.0007709104684181511, 0.005225481931120157, -0.016208108514547348, -0.01637520082294941, -0.007249596528708935, -0.017210671678185463, -0.008559764362871647, -0.011088958941400051, -0.0036874585784971714, 0.009243330918252468, 0.007750878110527992, 0.0045267255045473576, -0.006406531669199467, -0.006748314946889877, -0.016253678128123283, 0.012828254140913486, -0.0004716130206361413, 0.022648818790912628, 0.003839361947029829, 0.02734263800084591, 0.028937624767422676, 0.003846957115456462, -0.01619291678071022, -0.002626032568514347, -0.0005259659956209362, 0.0002826830022968352, 0.00037952151615172625, -0.007363524287939072, 0.00826355256140232, 0.002903256332501769, -0.013549796305596828, -0.0015835943631827831, 0.008893952704966068, -0.004276084713637829, 0.0008929080213420093, -0.022876672446727753, 0.009372448548674583, 0.009174973703920841, -0.011172505095601082, 0.023377954959869385, 0.006019177846610546, -0.009888920933008194, -0.01913984678685665, 0.016496725380420685, -0.007853413000702858, 0.0038811354897916317, 0.006463495548814535, 0.003831766778603196, 0.02134244702756405, 0.006566030438989401, 0.0014364378293976188, -0.011461121961474419, 0.011088958941400051, 0.016663817688822746, 0.009615493938326836, -0.005662204697728157, -0.0027570491656661034, 0.023621000349521637, -0.020263932645320892, -0.0012361151166260242, -0.0024266589898616076, 0.009395234286785126, -0.0024855216033756733, -0.019109465181827545, -0.004697617143392563, 0.015965061262249947, 0.00456849904730916, 0.00983575452119112, -0.007724294904619455, 0.0037842970341444016, 0.012911801226437092, -0.017013195902109146, 0.01358777191489935, 0.0017668281216174364, -0.015737207606434822, -0.018213234841823578, -0.003848856082186103, 0.0046140700578689575, -0.009114212356507778, -0.022071585059165955, -0.0032773190177977085, 0.004416595678776503, 0.014453621581196785, 0.017620811238884926, -0.008947118185460567, 0.008878761902451515, 0.03350992128252983, -0.019079085439443588, 0.02671983279287815, -0.0029640179127454758, 0.010033228434622288, -0.007306560408324003, -0.016329631209373474, 0.0018731605960056186, -0.014438431710004807, -0.025534985587000847, 0.01396753080189228, 0.02629450336098671, -0.003941896837204695, 0.013390297070145607, 0.014453621581196785, 0.011871261522173882, 0.0028045191429555416, 0.010071204975247383, 0.006653374992311001, 0.03293268755078316, -0.014939713291823864, 0.013306749984622002, -0.00788379367440939, -0.001630114857107401, 0.010982626117765903, -0.0035203646402806044, -0.01376246102154255, 0.027190733700990677, -0.016405582427978516, -0.0018399315886199474, -0.002897560130804777, 0.0033285864628851414, 0.010420583188533783, -0.02079559490084648, -0.01201556995511055, -0.00953194685280323, -0.007101490627974272, 0.039312634617090225, -0.006064748857170343, -0.0014202981255948544, -0.008559764362871647, -0.006114117335528135, -0.025641318410634995, 0.002684895182028413, -0.010428178124129772, -0.007807841990143061, 9.054875408764929e-05, 0.006638184655457735, 0.0007400550530292094, -0.017620811238884926, -0.0226336270570755, -0.01376246102154255, -0.012410519644618034, -0.02018798142671585, -0.01731700450181961, 0.010861103422939777, 0.014020697213709354, 0.014233361929655075, 0.002946928609162569, -0.02795025147497654, 0.005525491200387478, -0.016132155433297157, -0.0085749551653862, -0.01536504365503788, 0.017134718596935272, 0.0016557485796511173, 0.007325548212975264, -0.03976834565401077, -0.0030646538361907005, -0.005973606836050749, -0.0078761987388134, -0.004671033937484026, 0.0018038545968011022, -0.012106711976230145, 0.0037767018657177687, 0.0005872021429240704, -0.011818095110356808, 0.0039343019016087055, 0.006972372531890869, -0.011742143891751766, 0.0072268107905983925, -0.018562613055109978, -0.025793220847845078, 0.0034690971951931715, 0.015889110043644905, -0.013420677743852139, -0.003786195768043399, 0.0007870502304285765, -0.010526915080845356, -0.016663817688822746, -0.005183708388358355, 0.006022975314408541, -0.024775467813014984, -0.02421342395246029, 0.009896515868604183, -0.02002088725566864, 0.007792651653289795, 0.02793506160378456, -0.0014839076902717352, 0.005411563441157341, 0.012478875927627087, 0.006938194390386343, -0.0006546093500219285, 0.0016358112916350365, 0.00025277698296122253, 0.010428178124129772, -0.010086394846439362, -0.004853317979723215, 0.01362574752420187, -0.02176777832210064, 0.01601063273847103, -0.005248267203569412, -0.016481533646583557, -0.005411563441157341, 0.009061045944690704, 0.01005601417273283, 0.004424190614372492, 0.019048703834414482, -0.030061710625886917, 0.009790183044970036, 0.013846008107066154, -0.005711573176085949, -0.007982530631124973, -0.01366372313350439, 0.010633247904479504, -0.009212949313223362, 0.007762270979583263, 0.01558530330657959, -0.008726858533918858, -0.004959650803357363, -0.012797873467206955, -0.019306940957903862, 0.004769771359860897, 0.005240672267973423, -0.009288901463150978, 0.003507073037326336, -0.02210196480154991, -0.012167473323643208, 0.02125130593776703, 0.005878666881471872, -0.015258710831403732, 0.015501756221055984, -0.02592993527650833, -0.02664388157427311, -0.017560049891471863, 0.016041014343500137, 0.016922054812312126, 0.008658502250909805, -0.018349947407841682, -0.021479161456227303, 0.015722015872597694, 0.012380138970911503, 0.0031633912585675716, 0.05371309071779251, 0.0004884648369625211, -4.657979661715217e-05, -0.014575145207345486, 0.0026450203731656075, -0.001096553634852171, 0.0014174499083310366, -0.01932213082909584, -0.003262128448113799, -0.014514382928609848, 0.0015940377488732338, -0.001965251984074712, -0.021919680759310722, 0.0016139751533046365, -0.008893952704966068, 0.028223678469657898, 0.0014250450767576694, -0.007279977202415466, -0.00988132506608963, -0.013701699674129486, -0.021782968193292618, -0.005628026090562344, 0.010838317684829235, -0.011651001870632172, 0.019914554432034492, 0.01879046857357025, -0.009752207435667515, -0.002563372254371643, -0.000522643094882369, -0.015319472178816795, 0.014651096425950527, -0.012782682664692402, 0.00138232228346169, -0.0018342352705076337, 0.0020506978034973145, 0.0006356213707476854, -0.04441659525036812, -0.006281211506575346, 0.013109276071190834, -0.016314439475536346, 0.006030570715665817, -0.017453717067837715, 0.005301433615386486, -0.0017326497472822666, 0.0010614260099828243, -0.014529573731124401, 0.0001401547488057986, -0.009220545180141926, -0.015182758681476116, -0.030593372881412506, -0.007553403731435537, 0.004648248199373484, -0.019048703834414482, 0.019534794613718987, -0.020825974643230438, 0.00792176928371191, 0.00349188270047307, 0.010071204975247383, -0.002132345922291279, 0.008278743363916874, 0.02204120345413685, 0.0007970188744366169, -0.018228424713015556, 0.015030855312943459, 0.00010728187771746889, 0.018046140670776367, -0.010724389925599098, -0.002833001082763076, 0.01366372313350439, 0.0038792367558926344, 0.014727048575878143, 0.0029943985864520073, 0.0022500711493194103, 0.009896515868604183, -0.002897560130804777, 0.0021038639824837446, -0.01271432638168335, -0.005392575636506081, 0.017818285152316093, -0.0044052028097212315, 0.00984334945678711, 0.011909238062798977, -0.010481344535946846, -0.006539447233080864, -0.01184088084846735, -0.016557486727833748, -0.009767397306859493, -0.011681382544338703, 0.011992784217000008, -0.008772429078817368, 0.009258520789444447, 0.007298965007066727, 0.007131871301680803, -0.02090192772448063, 0.013549796305596828, 0.0034425139892846346, -0.022071585059165955, -0.0076255579479038715, 0.007386309560388327, 0.0013101680669933558, 0.007724294904619455, 0.01127124298363924, -0.01231937762349844, -0.012790278531610966, 0.02307414822280407, -0.009759802371263504, 0.013306749984622002, 0.005666002165526152, 0.006923004053533077, -0.002937434706836939, -0.009288901463150978, -0.01626886986196041, -0.007891388610005379, -0.021403208374977112, 0.00858255010098219, 0.010382606647908688, -0.0007993924082256854, -0.008559764362871647, -0.0034690971951931715, 0.008461027406156063, -0.016056204214692116, 0.011894047260284424, 0.019109465181827545, 0.005882464814931154, -0.026431215927004814, -0.014218171127140522, 0.0014848571736365557, 0.0071432641707360744, 0.005806512665003538, -0.0004839551984332502, -0.01144593209028244, 0.013853603042662144, 0.02125130593776703, 0.018501851707696915, 0.014225766994059086, 0.016557486727833748, 0.00843824166804552, -0.030927561223506927, 0.015630874782800674, 0.012964967638254166, -0.03803664818406105, 0.012721921317279339, -0.009957277216017246, -0.01768157258629799, 0.0018997436854988337, 0.0005406816489994526, 0.0030190828256309032, -0.015828348696231842, 0.0021665242966264486, -0.0067559098824858665, -0.008536978624761105, 0.010458558797836304, 0.0315047949552536, -0.010131966322660446, -0.012205449864268303, -0.0329023078083992, 0.0007523972308263183, -0.008278743363916874, 0.02099306881427765, 0.011050982400774956, -0.015600494109094143, 0.01363334245979786, -0.003907718695700169, 0.007409095298498869, -0.001107946503907442, -0.011544669046998024, -0.01932213082909584, -0.003300104523077607, -0.018836038187146187, 0.011043387465178967, -0.003972277510911226, 0.003315294859930873, -0.002624133601784706, 0.018167663365602493, 0.009509162046015263, -0.006679958198219538, 0.009630684740841389, -0.0005800816579721868, -0.004283679649233818, -0.01501566544175148, 0.00511914910748601, 0.0029450298752635717, 0.0174992885440588, -0.02594512514770031, 0.009114212356507778, -0.007693914230912924, -0.003619101829826832, 0.011681382544338703, 0.016861293464899063, -0.0014354884624481201, 0.007652140688151121, -0.02497294172644615, 0.010443368926644325, 0.008909142576158047, -0.018911991268396378, 4.767753853229806e-05, -0.01305610965937376, 0.004283679649233818, -0.02656792849302292, -0.02550460398197174, -0.002367796376347542, 0.00517991092056036, -0.01853223145008087, 0.007378714624792337
                ],
                "page_number": 104
            },
            {
                "@search.action": "upload",
                "id": "earth_at_night_508_page_105_verbalized",
                "page_chunk": "# Urban Structure\n\n## March 16, 2013\n\n### Phoenix Metropolitan Area at Night\n\nThis figure presents a nighttime satellite view of the Phoenix metropolitan area, highlighting urban structure and transport corridors. City lights illuminate the layout of several cities and major thoroughfares.\n\n**Labeled Urban Features:**\n\n- **Phoenix:** Central and brightest area in the right-center of the image.\n- **Glendale:** Located to the west of Phoenix, this city is also brightly lit.\n- **Peoria:** Further northwest, this area is labeled and its illuminated grid is seen.\n- **Grand Avenue:** Clearly visible as a diagonal, brightly lit thoroughfare running from Phoenix through Glendale and Peoria.\n- **Salt River Channel:** Identified in the southeast portion, running through illuminated sections.\n- **Phoenix Mountains:** Dark, undeveloped region to the northeast of Phoenix.\n- **Agricultural Fields:** Southwestern corner of the image, grid patterns are visible but with much less illumination, indicating agricultural land use.\n\n**Additional Notes:**\n\n- The overall pattern shows a grid-like urban development typical of western U.S. cities, with scattered bright nodes at major intersections or city centers.\n- There is a clear transition from dense urban development to sparsely populated or agricultural land, particularly evident towards the bottom and left of the image.\n- The illuminated areas follow the existing road and street grids, showcasing the extensive spread of the metropolitan area.\n\n**Figure Description:**  \nA satellite nighttime image captured on March 16, 2013, showing Phoenix and surrounding areas (including Glendale and Peoria). Major landscape and infrastructural features, such as the Phoenix Mountains, Grand Avenue, the Salt River Channel, and agricultural fields, are labeled. The image reveals the extent of urbanization and the characteristic street grid illuminated by city lights.\n\n---\n\nPage 89",
                "page_embedding_text_3_large": [
                -0.012408008798956871, -0.010935738682746887, -0.01799791119992733, 0.021761255338788033, 0.008125041611492634, -0.04487668350338936, 0.03457866609096527, 0.03738148882985115, -0.025697806850075722, -0.0032535595819354057, -0.00041063150274567306, 0.07577073574066162, 0.032972551882267, -0.049852482974529266, -0.020564543083310127, 0.003302766475826502, -0.040751177817583084, 0.030327189713716507, -0.015344676561653614, 0.03243718296289444, 0.027981005609035492, -0.01735231839120388, -0.02837466076016426, 0.020958198234438896, -0.004117632284760475, 0.02560332790017128, 0.020596034824848175, 0.015486392192542553, 0.004263285081833601, 0.009408357553184032, -0.01991894841194153, 0.006778741255402565, 0.021336106583476067, -0.02295796573162079, -0.003273242386057973, 0.02432788535952568, 0.019604025408625603, 0.008589554578065872, 0.041003115475177765, 0.019037161022424698, 0.0077431960962712765, -0.06295332312583923, 0.02824869193136692, 0.008188026025891304, -0.00022856600116938353, -0.039743419736623764, 0.018722238019108772, -0.010534211061894894, 0.027303919196128845, 0.0054796794429421425, -0.010565703734755516, -0.02750862017273903, -0.049411591142416, -0.02887853980064392, 0.025902505964040756, 0.01876947656273842, 0.04966352880001068, 0.07766028493642807, 0.00472386134788394, -0.005298597738146782, 0.03256314992904663, 0.012911887839436531, 0.0014516032533720136, 0.018155373632907867, 0.017887689173221588, 0.0418219193816185, -0.012439501471817493, -0.0007174364291131496, -0.010384622029960155, -0.008920225314795971, -0.009266640990972519, 0.0633942186832428, 0.00955794658511877, 0.009030448272824287, 0.06909434497356415, -0.017824703827500343, 0.025414373725652695, -0.007003124337643385, -0.012974872253835201, -0.005278915166854858, 0.017824703827500343, -0.016139859333634377, -0.009014702402055264, 0.07192866504192352, 0.015620235353708267, -0.010211413726210594, -0.03596433252096176, -0.09422528743743896, 0.016895677894353867, 0.03662567213177681, -0.03854670748114586, -0.03634224086999893, -0.013478751294314861, 0.009683915413916111, 0.0032594643998891115, 0.0016395736020058393, 0.05630842596292496, 0.00037963115028105676, 0.02637489326298237, 0.02623317763209343, 0.006991314701735973, 0.008613173849880695, 0.0029150161426514387, -0.028689585626125336, 0.03369687870144844, -0.021257376298308372, -0.010305890813469887, 0.0011199488071724772, 0.0005688316305167973, 0.03750745952129364, 0.01686418429017067, -0.030075250193476677, -0.007231444586068392, -0.02017088793218136, -0.03240568935871124, -0.0022910728584975004, 0.018722238019108772, 0.00937686488032341, 0.06676390767097473, 0.03259464353322983, 0.019194623455405235, -0.0023501210380345583, 0.0367831327021122, -0.007833736948668957, -0.01837582141160965, 0.003137431340292096, 0.01836007460951805, -0.014628224074840546, -0.0023383114021271467, 0.04487668350338936, -0.04878174141049385, 0.02837466076016426, 0.009455596096813679, 0.01572258584201336, -0.009353245608508587, -0.014392031356692314, -0.0132976695895195, 0.008668285794556141, 0.021745508536696434, 0.0123450243845582, -0.020076410844922066, -0.014415650628507137, 0.0002598123683128506, -0.028595108538866043, -0.034893590956926346, 0.006046542432159185, 0.02141483873128891, 0.044561758637428284, 0.013911771588027477, -0.01040036790072918, -0.011274282820522785, -0.005522981286048889, 0.04538056254386902, -0.004034964833408594, -0.019966186955571175, -0.006751185283064842, -0.0053025344386696815, -0.00039709958946332335, -0.043522510677576065, 0.0038656932301819324, 0.015549377538263798, 0.004452239256352186, -0.0015155721921473742, -0.027918020263314247, 0.013163827359676361, -0.04002685099840164, 0.026674071326851845, -0.04966352880001068, -0.04487668350338936, 0.010738911107182503, 0.047962937504053116, -0.022280879318714142, -0.03508254513144493, -0.003668865654617548, 0.02865809202194214, -0.040593717247247696, 0.011974988505244255, 0.027697574347257614, -0.03939700499176979, 0.0065386113710701466, -0.024800272658467293, -0.041506994515657425, 0.0040743304416537285, -0.0155257573351264, 0.0019062749342992902, -0.00855806190520525, 0.03015398234128952, -0.004231792408972979, 0.028815554454922676, -0.005263168830424547, -0.00288155535236001, 0.03473612666130066, 0.06181959807872772, -0.02966585010290146, 0.031098755076527596, -0.028563614934682846, 0.027807798236608505, -0.02686302550137043, -0.01597452536225319, -0.012722933664917946, -0.01924186199903488, -0.007144840434193611, -0.021084168925881386, 0.037696413695812225, 0.02571355178952217, 0.02270602621138096, 0.01977723278105259, -0.0039660753682255745, -0.008447838947176933, 0.01623433642089367, 0.0011051867622882128, -0.061882585287094116, -0.009904362261295319, -0.026894517242908478, -0.021761255338788033, 0.01760425604879856, 0.016013890504837036, -0.02840615250170231, 0.013541735708713531, -0.03213800489902496, 0.028185706585645676, 0.029193462803959846, 0.007758942432701588, 0.017462540417909622, -0.0062551796436309814, -0.027020487934350967, -0.028579361736774445, 0.010841261595487595, -0.06071736663579941, -0.018218358978629112, -0.027713319286704063, -0.022863488644361496, 0.01273867953568697, 0.025398628786206245, 0.025697806850075722, 0.012612709775567055, 0.004385318141430616, 0.02028111182153225, -0.011447491124272346, -0.019037161022424698, 0.016753962263464928, -0.005393075291067362, -0.026658324524760246, -0.026579594239592552, 0.049600545316934586, -0.019320592284202576, -0.019415071234107018, 0.03347643092274666, 0.014612478204071522, 0.035271499305963516, 0.009164291433990002, -0.020202379673719406, 0.0329095683991909, 0.018564775586128235, 0.028957270085811615, 0.017667241394519806, -0.003540927777066827, 0.008077803067862988, 0.005456059705466032, 0.007652655243873596, -0.03243718296289444, 0.042010873556137085, -0.01273867953568697, 0.027225187048316002, 0.0006318164523690939, 0.015313183888792992, -0.02317841351032257, 0.005873334128409624, 0.003970012068748474, -0.03911357372999191, 0.03253166005015373, -0.06770867854356766, 0.01850179024040699, -0.023792514577507973, 0.012518232688307762, -0.0032791472040116787, 0.015895793214440346, -0.016801200807094574, -0.0006948012742213905, -0.002169039798900485, 0.001939735608175397, -0.007530622184276581, 0.025650566443800926, -0.04424683377146721, -0.03829476982355118, 0.026768548414111137, -0.017383810132741928, -0.013982629403471947, -0.015029752627015114, -0.04103460907936096, -0.015919413417577744, -0.06701584905385971, 0.006707882974296808, 0.006877155043184757, 0.032626137137413025, -0.005306471139192581, 0.004995483439415693, -0.05983557924628258, -0.04777398332953453, 0.007298365700989962, -0.008337615057826042, 0.04134953394532204, -0.052403368055820465, 0.010242906399071217, 0.013502370566129684, 0.04345952346920967, -0.018564775586128235, 0.04638832062482834, -0.016753962263464928, -0.046199362725019455, -0.002481995616108179, -0.026815786957740784, 0.008935971185564995, -0.00938473828136921, 0.01760425604879856, 0.008046310395002365, 0.030342936515808105, 0.006621278822422028, -0.008408472873270512, -0.017131870612502098, 0.02017088793218136, -0.04843532666563988, -0.0032437180634588003, 0.006892900913953781, -0.019178876653313637, 0.010660180822014809, -0.00824313797056675, -0.008211645297706127, -0.02369803749024868, -0.02165103144943714, -0.01280953735113144, 0.008605300448834896, 0.001155377714894712, -0.0020037044305354357, 0.03479911386966705, -0.009180037304759026, 0.026689816266298294, 0.027461381629109383, -0.00021737143106292933, 0.01607687585055828, 0.015895793214440346, -0.02155655436217785, -0.031114500015974045, -0.020580289885401726, 0.008935971185564995, -0.02382400818169117, -0.010998724028468132, 0.015029752627015114, -0.00855806190520525, 0.003346068551763892, 0.0010677895043045282, 0.020816482603549957, -0.020060664042830467, -0.018470298498868942, 0.009597311727702618, 0.021509315818548203, -0.03117748536169529, -0.03602731600403786, 0.0557415634393692, -0.01291976124048233, 0.02902025543153286, -0.055174700915813446, -0.04160147160291672, 0.018045149743556976, -0.03690910339355469, 0.035680901259183884, -0.012313531711697578, 0.003662960836663842, -0.00025538375484757125, 0.009148544631898403, -0.04361698776483536, 0.023146919906139374, -0.03637373447418213, -0.009282387793064117, 0.004153061658143997, -0.031618379056453705, 0.0380113385617733, -0.01057357620447874, -0.012431629002094269, 0.007203888613730669, -0.024753034114837646, 0.05234038457274437, 0.027020487934350967, 0.0038617567624896765, 0.011597080156207085, 0.05794603377580643, -0.00849507749080658, -0.025965491309762, 0.018942683935165405, 0.004700242076069117, -0.0008862160611897707, -0.016407545655965805, 0.033633891493082047, -0.020092157647013664, 0.034925080835819244, 0.0014319204492494464, -0.008282504044473171, -0.00969178881496191, 0.016171352937817574, 0.04131804034113884, -0.0030783829279243946, 0.04245176911354065, 0.028075482696294785, 0.06487436592578888, -0.002304850611835718, 0.05051382631063461, 0.021493569016456604, -0.03451567888259888, 0.0068495990708470345, -0.01876947656273842, 0.0035743885673582554, -0.007971515879034996, -0.008534442633390427, -0.02102118358016014, 0.0013266177847981453, 0.01476206723600626, -0.011904130689799786, 0.035775378346443176, 0.003956234082579613, 0.016061129048466682, -0.0011622667079791427, -0.00256466306746006, -0.055552609264850616, 0.024264901876449585, -0.013218938373029232, 0.0024583761114627123, -0.00038430580752901733, 0.01475419383496046, -0.0048025925643742085, 0.00835336185991764, 0.03977491334080696, -0.014714828692376614, 0.009636676870286465, -0.0017389714485034347, -0.0025764727033674717, -0.005121453199535608, 0.018202612176537514, 0.013069350272417068, 0.007967579178512096, -0.030138235539197922, -0.03634224086999893, 0.020722005516290665, 0.013793675228953362, -0.012085212394595146, -0.013707071542739868, 0.03942849487066269, 0.0027929830830544233, -0.0077353231608867645, 0.012321405112743378, -0.030468905344605446, -0.03407478705048561, 0.042010873556137085, -0.05104919523000717, -0.02141483873128891, 0.021115660667419434, -0.021477822214365005, -0.005873334128409624, -0.019430816173553467, 0.009605185128748417, -0.022658787667751312, 0.014478635042905807, -0.022611549124121666, 0.004660876467823982, -0.07274746894836426, 0.0070661092177033424, 0.013588974252343178, -0.011093201115727425, 0.029980773106217384, 0.01607687585055828, 0.0012419818667694926, 0.04446728155016899, -6.22774678049609e-05, -0.04978949949145317, 0.07281044870615005, -0.027587350457906723, 0.0034385775215923786, -0.022580057382583618, -0.04128654673695564, 0.02065902017056942, -0.026296161115169525, -0.03665716573596001, 0.03501955792307854, 0.016675230115652084, -0.014132218435406685, -0.0018472266383469105, 0.024264901876449585, 0.0009073750698007643, 0.014549492858350277, -0.04471922293305397, 0.01760425604879856, 0.035428959876298904, 0.006845662370324135, -0.006511055398732424, -0.0072747464291751385, -0.012203308753669262, 0.00535764591768384, -0.03470463678240776, 0.0006490388768725097, -0.014305426739156246, 0.046703241765499115, -0.06474839150905609, 0.03508254513144493, -0.001677954918704927, -0.01071529183536768, -0.003456291975453496, 0.006416578311473131, 0.003907027188688517, 0.012400136329233646, -0.030232712626457214, -0.007621163036674261, 0.014699081890285015, -0.00040325045119971037, -0.007825863547623158, -0.0354919470846653, 0.015872174873948097, -0.02026536501944065, 0.030216965824365616, 0.0033874022774398327, 0.006861408706754446, -0.004420747049152851, 0.00862891972064972, -0.02346184477210045, -0.002019450766965747, -0.01248674001544714, -0.012526106089353561, 0.013092969544231892, 0.014360538683831692, -0.02713070996105671, 0.005495425313711166, -0.03949148207902908, -0.037570443004369736, 0.04106610268354416, 0.028028244152665138, -0.003505498869344592, 0.004212109837681055, -0.022989459335803986, -0.02587101422250271, 0.03391732648015022, 0.0158485546708107, -0.004861640743911266, -0.03281509131193161, 0.019855964928865433, 0.0018245914252474904, 0.033381953835487366, 0.018706491217017174, 0.023099681362509727, 0.012785918079316616, 0.012061593122780323, -0.0012439502170309424, -0.006270925980061293, -0.005404884926974773, -0.0016661452827975154, -0.0017173204105347395, 0.029429657384753227, -0.02560332790017128, -0.011101074516773224, 0.00409007677808404, -0.0004212109779473394, -0.015754077583551407, 0.03640522435307503, -0.015313183888792992, -0.014966767281293869, -0.031508155167102814, 0.011959242634475231, -0.017525525763630867, -0.0008035484934225678, -0.01599027030169964, 0.02700474113225937, -0.004822275135666132, 0.028280183672904968, -0.022721773013472557, 0.0072235711850225925, 0.011935623362660408, 0.024705795571208, 0.023414606228470802, 0.031004276126623154, -0.012289912439882755, -0.02242259494960308, -0.015069117769598961, -0.013604721054434776, 0.004767163656651974, 0.0019613865297287703, 0.033130016177892685, 0.012896141968667507, -0.00424753874540329, -0.01273867953568697, -0.00267882295884192, 0.0035625786986202, 0.026563847437500954, 0.0021651030983775854, 0.03081532195210457, 0.01545489951968193, 0.0532536655664444, 0.004940371494740248, 0.01659649983048439, 0.014407777227461338, -0.014360538683831692, 0.005727681796997786, 0.010227159596979618, -0.026658324524760246, 0.017887689173221588, 0.022973712533712387, 0.01900566928088665, -0.012707186862826347, 0.018816715106368065, 0.029114732518792152, 0.07564476877450943, 0.0007440081681124866, 0.029949281364679337, -0.006794487126171589, -0.03081532195210457, -0.001780305290594697, 0.02776055969297886, -0.011974988505244255, 0.02092670649290085, -0.03917655721306801, -0.0028205388225615025, 0.04027879238128662, 0.016187097877264023, -0.03001226671040058, 0.0136204669252038, 0.0017753845313563943, 0.02991778962314129, -0.00721963495016098, -0.029429657384753227, -0.01451800111681223, -0.016659485176205635, 0.0057867299765348434, -0.027225187048316002, -0.06726778298616409, 0.012982745654881, -0.018580522388219833, 0.018596267327666283, -0.051269643008708954, -0.007215698249638081, -0.019950442016124725, -0.02320990525186062, 0.0018442742293700576, 0.006369339767843485, -0.013447258621454239, -0.022847743704915047, 0.03464164957404137, -0.016565008088946342, -0.006570104043930769, 0.009502834640443325, 0.0008581681759096682, -0.027571603655815125, -0.040089838206768036, 0.015116356313228607, -0.008833620697259903, -0.014242442324757576, 0.01810813508927822, -0.0028854920528829098, 0.010235032998025417, 0.015447027049958706, -0.03190181031823158, -0.016832692548632622, -0.020706258714199066, -0.004857704043388367, -0.01082551572471857, -0.02609146200120449, 0.02457982487976551, -0.02330438233911991, -0.004286904353648424, 0.010746784508228302, 0.032106511294841766, -0.008014817722141743, -0.010628688149154186, 0.012911887839436531, -0.020485812798142433, 0.013321288861334324, 0.004456175956875086, 0.03220098838210106, -0.006026859860867262, 0.02242259494960308, -0.02878406271338463, -0.01216394267976284, 0.009983093477785587, -0.0018954493571072817, 0.014651843346655369, 0.0016622086986899376, 0.0008586602052673697, 0.0017625908367335796, -0.028343169018626213, 0.007821926847100258, -0.01620284467935562, 0.05363157391548157, -0.005932382773607969, 0.00022364531469065696, -0.0015362390549853444, -0.011841146275401115, -0.0354604534804821, -0.0030350808519870043, 0.007373160216957331, -0.008069929666817188, -0.0016100493958219886, -0.004188490565866232, 0.012533978559076786, 0.049222636967897415, -0.04679771885275841, -0.005578092765063047, -0.026579594239592552, -0.010975104756653309, 0.0026768548414111137, -0.029240701347589493, 0.035932838916778564, -0.011045962572097778, 0.00803450122475624, -0.034011803567409515, 0.008920225314795971, -0.005889080464839935, 0.003944424446672201, 0.0007213730132207274, 0.01710037887096405, 0.026138700544834137, -0.015021879225969315, -0.02862660028040409, 0.005751301068812609, 0.0003437101258896291, -0.00023643911117687821, 0.02091095969080925, -0.002879587234929204, -0.022123416885733604, 9.939791925717145e-05, -0.015746204182505608, -0.033759862184524536, -0.014864416792988777, -0.000627879926469177, -0.007046426646411419, 0.006266989279538393, -0.027666080743074417, -0.03265762701630592, 0.006207941100001335, -0.0013423638883978128, -0.017289333045482635, -0.022485580295324326, -0.019714247435331345, -0.0016543356468901038, -0.007459764368832111, -0.026390638202428818, -0.0050505949184298515, -0.013659832067787647, 0.01724209450185299, -0.029177717864513397, -0.029429657384753227, 0.019178876653313637, 0.023146919906139374, -0.00020580780983436853, -0.0171161238104105, 0.0020548796746879816, -0.0027063789311796427, -0.016250083222985268, -0.012463120743632317, -0.02017088793218136, 0.0148880360648036, 0.0023678354918956757, 0.015061244368553162, -0.00969178881496191, 0.002747712656855583, -0.009211529977619648, -0.005152945406734943, 0.01750977896153927, -0.050860241055488586, 0.05038785561919212, 0.003877502866089344, -0.002647330751642585, -0.003251591231673956, -0.009739027358591557, 0.023587815463542938, 2.2681300833937712e-05, 0.0052277399227023125, 0.0024012962821871042, -0.008376981131732464, -0.009243021719157696, 0.025304151698946953, 0.0246900487691164, 0.02317841351032257, 0.02028111182153225, -0.017147617414593697, -0.006680327467620373, -0.0010392494732514024, -0.022721773013472557, 0.0055190445855259895, 0.018438804894685745, 0.007503066677600145, -0.01153409481048584, 0.03464164957404137, -0.025288404896855354, -0.05520619451999664, 0.015124229714274406, 0.017037393525242805, 0.011864765547215939, 0.01812388189136982, -0.035554930567741394, 0.026815786957740784, -0.008329742588102818, 0.008636793121695518, 0.018029404804110527, -0.011187678202986717, 0.00938473828136921, 0.024753034114837646, 0.023666545748710632, 0.017320824787020683, -0.007987262681126595, 0.0007868181564845145, -0.03750745952129364, 0.003698389744386077, -0.025052212178707123, 0.015596616081893444, 0.01000671274960041, 0.018045149743556976, -0.0027634589932858944, 0.0031315265223383904, 0.021383345127105713, -0.02229662612080574, 0.008069929666817188, -0.010683800093829632, 0.006605532951653004, -0.012896141968667507, -0.0040231551975011826, -0.003849947126582265, 0.004160934593528509, 0.005117516499012709, -0.004412873648107052, -0.025571836158633232, 0.0011347108520567417, 0.007073982618749142, -0.005830032285302877, 0.004944308195263147, 0.009431976824998856, -0.006869281642138958, 0.027902275323867798, -0.020312603563070297, 0.04282967746257782, 0.00012609265104401857, 0.02522541955113411, -0.009526453912258148, 0.034263741225004196, -0.014691208489239216, 0.014273934066295624, 0.014336919412016869, 0.004306586924940348, 0.022784758359193802, -0.00962880440056324, 0.012022227048873901, -0.006514992099255323, 0.01026652567088604, -0.013903899118304253, 0.02763458900153637, 0.027272425591945648, 0.027650335803627968, 0.037822384387254715, -0.008731270208954811, 0.0316498726606369, -0.010250778868794441, 0.0055190445855259895, -0.008613173849880695, 0.018722238019108772, -0.019037161022424698, 0.006432324647903442, 0.0012734743067994714, 0.014966767281293869, -0.007471574004739523, 0.0042003002017736435, -0.010392495431005955, 0.004361698869615793, 0.02612295374274254, 0.013494497165083885, -0.015494265593588352, -0.020737752318382263, -0.02269028127193451, -0.010927866213023663, 0.03116173855960369, 0.0002306573005625978, 0.0005560378776863217, 0.0043656351044774055, 0.04068819433450699, 0.017840450629591942, -0.005499362014234066, 0.0036531195510178804, 0.004121568985283375, 0.009109179489314556, 0.002728029852733016, 0.0183915663510561, -0.020107902586460114, -0.01887969858944416, -0.012069465592503548, -0.003096097381785512, 3.210749491699971e-05, -0.02635914646089077, -0.00372397736646235, 0.013588974252343178, -0.019588278606534004, 0.018407313153147697, -0.00324568641372025, 0.008723397739231586, -0.00987287051975727, -0.01001458615064621, -0.0015283660031855106, 0.011730922386050224, 0.0064953095279634, 0.009487087838351727, 0.02902025543153286, 0.017651494592428207, -0.0050112297758460045, 0.02154080756008625, -0.018706491217017174, 0.01801365800201893, -0.008266757242381573, 0.0329410582780838, 0.014147965237498283, -0.011478982865810394, 0.020470065996050835, -0.003619658760726452, -0.002357994206249714, 0.02026536501944065, 3.678214852698147e-05, 0.005467869341373444, -0.002413105918094516, -0.02459557168185711, 0.023493336513638496, 0.012148196808993816, -0.025697806850075722, 0.01773022674024105, 0.006022923160344362, 0.005393075291067362, 0.012274166569113731, -0.016816945746541023, -0.004275094717741013, 0.03741298243403435, -0.025052212178707123, -0.0023127237800508738, 0.023115428164601326, 0.011045962572097778, -0.013911771588027477, 0.0028913968708366156, -0.011093201115727425, -0.020344097167253494, 0.003117748536169529, -0.016313068568706512, 0.014281807467341423, 0.0009152481216005981, 0.03564940765500069, -0.03196479380130768, -0.03637373447418213, 0.015793442726135254, 0.00481046549975872, 0.013250431045889854, -0.008565935306251049, -0.015415534377098083, 0.005798540078103542, -0.03624776378273964, 0.004475858528167009, 0.03448418900370598, 0.001021535019390285, 0.0027103153988718987, -0.016265830025076866, -0.020989689975976944, 0.009959474205970764, -0.0032909568399190903, 0.004050711169838905, 0.018549028784036636, -0.034673143178224564, 0.023729531094431877, -0.03040592186152935, -0.021509315818548203, -0.019871709868311882, -0.03816879913210869, -0.030894054099917412, 0.0057788570411503315, 8.349794370587915e-06, -0.007932150736451149, 0.0069243935868144035, -0.023162666708230972, 0.013242557644844055, 0.035680901259183884, -0.015943031758069992, -0.005885143764317036, 0.014714828692376614, 0.01659649983048439, 0.028091229498386383, -0.002649298869073391, 0.017824703827500343, 0.041884902864694595, 0.04462474212050438, -0.02698899433016777, 0.006416578311473131, -0.0001847718667704612, 0.004318396560847759, 0.013770055957138538, 0.0076605286449193954, -0.032012034207582474, 0.0006962774787098169, -0.05470231547951698, -0.018974175676703453, -0.022501327097415924, 0.01927335374057293, 0.015565123409032822, 0.004983673803508282, -0.013809421099722385, -0.0018452584045007825, -0.004849831108003855, -0.012274166569113731, 0.009809885174036026, -0.01032163668423891, -0.001655319705605507, -0.011967115104198456, -0.02295796573162079, -0.01812388189136982, -0.02294222079217434, 0.03574388474225998, 0.005408821161836386, 0.013793675228953362, -0.00930600706487894, 0.0018718300852924585, 0.024044454097747803, -0.01388027984648943, 0.009817758575081825, 0.015580869279801846, 0.025241166353225708, -0.026453623548150063, 0.01090424694120884, -0.031020022928714752, 0.0048025925643742085, 0.01007757056504488, 0.022737519815564156, -0.0183915663510561, -0.00835336185991764, 0.0017586542526260018, 0.020611781626939774, 0.008062057197093964, 0.021194390952587128, -0.003353941487148404, -0.02520967274904251, -0.01083338912576437, 0.02687877044081688, -0.0030252395663410425, -0.02080073580145836, -0.002733934670686722, 0.031508155167102814, 0.005959938280284405, -0.00803843792527914, -0.014171584509313107, 0.04160147160291672, -0.015517884865403175, -0.005467869341373444, -0.024107439443469048, 0.025571836158633232, -0.031712856143713, 0.01887969858944416, -0.017194855958223343, -0.001075662556104362, 0.03253166005015373, -0.024422364309430122, -0.018423059955239296, -0.005306471139192581, -0.0012734743067994714, 0.019194623455405235, 0.01914738491177559, 0.036310747265815735, -0.0015391914639621973, 0.009746900759637356, 0.0017891625175252557, 0.0033992119133472443, 0.010203540325164795, 0.014565239660441875, 0.011951369233429432, -0.008447838947176933, 0.011014469899237156, 0.01033738348633051, 0.0034425139892846346, 0.010494844987988472, -0.013415765948593616, 0.02180849388241768, -0.007085792254656553, 0.006444134283810854, -0.0032122258562594652, -0.006605532951653004, -0.03204352781176567, 0.006026859860867262, 0.0038401056081056595, -0.010864880867302418, -0.02432788535952568, 0.030500398948788643, -0.008010881952941418, 0.0034129898995161057, 0.011770287528634071, -0.01323468517512083, -0.015635980293154716, 0.0005309423431754112, -0.013714944012463093, 0.023288637399673462, 0.023650798946619034, 0.006570104043930769, 0.004546716809272766, -0.019855964928865433, -0.010990850627422333, 0.096303790807724, 0.013470877893269062, 0.01051059179008007, 0.015242326073348522, 0.007388906553387642, -0.0029799691401422024, -0.030594876036047935, 0.009683915413916111, 0.028689585626125336, -0.007211761549115181, 0.014171584509313107, 0.004763226956129074, -0.018832460045814514, -0.009431976824998856, 0.013533863238990307, -0.04349101707339287, -0.005058468319475651, 0.03198054060339928, -0.0027378713712096214, 0.026327654719352722, 0.007684147916734219, 0.003531086491420865, -0.01965126395225525, -0.0031020021997392178, -0.010628688149154186, -0.02015514113008976, 0.04569548740983009, 0.004345952533185482, 0.006133146584033966, -0.018470298498868942, -0.021714016795158386, -0.027162203565239906, -0.002909111324697733, -0.009613057598471642, -0.02650086209177971, 0.01153409481048584, -0.002015514299273491, 0.01697440817952156, 0.01999768055975437, 0.010250778868794441, -0.017651494592428207, 0.028075482696294785, -0.005223803222179413, -0.020580289885401726, -0.002773300278931856, -0.005082087591290474, -0.006322101224213839, 0.018564775586128235, 0.004593955352902412, -0.004778973292559385, -0.00424753874540329, -0.02155655436217785, 0.014210949651896954, -0.030972784385085106, -0.01773022674024105, 0.02902025543153286, -0.014911655336618423, 0.006778741255402565, 0.023036697879433632, 0.008872986771166325, 0.011943495832383633, 0.002852031262591481, -0.010526337660849094, -0.022249387577176094, 0.00994372833520174, 0.009857123717665672, -0.0048419577069580555, -0.005751301068812609, 0.010030332021415234, 0.009998840279877186, -0.03479911386966705, 0.002857936080545187, 0.0054363771341741085, -0.00408614007756114, -0.002852031262591481, 0.023477591574192047, -0.003580293385311961, -0.0016061129281297326, -0.006637025158852339, 0.00930600706487894, 0.0021670714486390352, -8.002270624274388e-05, -0.007884912192821503, 0.0075345588847994804, -0.008534442633390427, -0.013541735708713531, 0.0030823196284472942, -0.001230172230862081, -0.03341344743967056, -0.010486972518265247, -0.02965010330080986, 0.03716104477643967, -0.03243718296289444, 0.00913279876112938, -0.01813962683081627, -0.009117052890360355, 0.041003115475177765, -0.01977723278105259, -0.0035980078391730785, 0.009109179489314556, 0.025288404896855354, -0.0011898225639015436, 0.029051747173070908, -0.011998607777059078, 0.0005225771456025541, -0.02393423020839691, -0.021005436778068542, 0.019541040062904358, -0.000627879926469177, -0.0029465085826814175, -0.0056528872810304165, -0.003536991309374571, 0.002296977676451206, 0.0234303530305624, 0.029492640867829323, 0.002674886491149664, 0.008699778467416763, -0.0036787071730941534, -0.021241629496216774, -0.0007046426762826741, -0.0133134163916111, 0.02799675241112709, 0.014321173541247845, 0.003098065732046962, 0.015053371898829937, 0.008904478512704372, 0.00955794658511877, -0.003798771882429719, 0.012313531711697578, 0.0014899845700711012, -0.015195087529718876, -0.004420747049152851, 0.006593723315745592, 0.031224723905324936, -0.0015332866460084915, -0.025697806850075722, 0.034925080835819244, -0.027445634827017784, 0.011636445298790932, 0.011557714082300663, -0.02054879628121853, -0.00204307003878057, 0.022217893972992897, 0.02332012914121151, -0.0027693638112396, 0.0046175746247172356, -0.031020022928714752, 0.013998376205563545, 0.014407777227461338, 0.009077686816453934, 0.022973712533712387, -0.010943612083792686, -0.007664464879781008, -0.009164291433990002, -4.846878437092528e-05, 0.007455827668309212, -0.0006869281642138958, 0.01432904601097107, 0.020060664042830467, -0.021855732426047325, 0.0015844618901610374, -0.018060896545648575, -0.013431512750685215, -0.01400624867528677, 0.024753034114837646, 0.0297760721296072, 0.011014469899237156, 0.030311444774270058, -0.005841841921210289, -0.020816482603549957, 0.01999768055975437, -0.018344327807426453, -0.004515224136412144, 0.010959358885884285, 0.0158406812697649, 0.027193695306777954, -0.006845662370324135, 0.0027634589932858944, 0.02394997701048851, -0.005326153710484505, -0.021729761734604836, -0.023005204275250435, -0.027036232873797417, 0.027776304632425308, 0.0065897866152226925, 0.009361119009554386, 0.0018747824942693114, -0.006554357707500458, 0.005621395073831081, -0.008290376514196396, 0.005684379953891039, 0.0316498726606369, 0.003436609171330929, -0.0009708519210107625, 0.006310291588306427, -0.0024249155540019274, -0.0061646392568945885, -0.03234270587563515, 0.027335410937666893, -0.01597452536225319, 0.005345836281776428, -0.005499362014234066, 0.0007016902673058212, 0.02698899433016777, -0.009400484152138233, 0.0036019443068653345, -0.025020718574523926, 0.010794023051857948, -0.005495425313711166, -0.013392146676778793, 0.02875256910920143, 0.012274166569113731, -0.009581565856933594, -0.031744349747896194, 0.03133494779467583, -0.010518464259803295, 0.00706217298284173, -0.010471225716173649, 0.0024741224478930235, 0.020942451432347298, 0.003137431340292096, -0.011392379179596901, 0.011061708442866802, -0.001651383237913251, -0.04204236716032028, 0.007829800248146057, 0.025571836158633232, -0.012195435352623463, -0.009927982464432716, -0.012589090503752232, 0.030090996995568275, 0.005802476312965155, 0.010250778868794441, -8.752675785217434e-05, -0.02736690454185009, 0.011085327714681625, -0.02357206866145134, 0.008817874826490879, 0.0007420398760586977, 0.036688655614852905, 0.011069581843912601, -0.020060664042830467, 0.009613057598471642, 0.028059735894203186, -0.026910264045000076, -0.00012154101568739861, -0.007440081797540188, -0.02015514113008976, -0.013856659643352032, -0.0014112535864114761, -0.020706258714199066, 0.017068885266780853, -0.02583952248096466, 0.004385318141430616, -0.0008222471224144101, -0.02256431058049202, -0.014132218435406685, -0.008896606042981148, -0.01823410578072071, -0.011683683842420578, -0.02459557168185711, 0.004153061658143997, 0.019367830827832222, 0.0009191847057081759, 0.0038125498685985804, -0.0019771328661590815, -0.02650086209177971, -0.012604836374521255, 0.026658324524760246, -0.006601596251130104, -0.0183915663510561, 0.0034936892334371805, -0.011683683842420578, -0.006310291588306427, 0.008857239969074726, 0.0037318505346775055, -0.008439965546131134, -0.021477822214365005, 0.004558526445180178, 0.0027851099148392677, -0.008132915012538433, -0.004597891587764025, 0.02080073580145836, 0.0021375473588705063, 0.0033933070953935385, 0.019037161022424698, -0.017021646723151207, 0.008644666522741318, 0.025918252766132355, 0.02127312310039997, -0.013242557644844055, 0.026768548414111137, 0.011360886506736279, 0.03514552861452103, 0.0064244517125189304, -0.020233873277902603, -0.044404298067092896, 0.01570683903992176, -0.0032102575059980154, -0.0056961895897984505, 0.013959010131657124, 0.012510359287261963, 0.04727010801434517, -0.004853767808526754, -0.021777000278234482, -0.025902505964040756, 0.0012291880557313561, 0.014951021410524845, -0.011967115104198456, -0.012659948319196701, -0.01573833078145981, 0.004700242076069117, -0.003635405097156763, 0.03385433927178383, -0.0016415418358519673, -0.012124577537178993, -0.010864880867302418, 0.02089521288871765, -0.007896721363067627, -0.031208977103233337, -0.01900566928088665, -0.025335643440485, 0.001469317707233131, 0.010518464259803295, -0.03284658119082451, 0.011069581843912601, -0.0107625313103199, -0.007255063857883215, -0.014880163595080376, -0.020092157647013664, -0.027823543176054955, -0.010723165236413479, -0.0022359611466526985, -0.011478982865810394, 0.0152108334004879, 0.02939816378057003, 0.01008544396609068, -0.0005265137297101319, -0.02483176440000534, 0.018926937133073807, -0.00408614007756114, -0.005589902866631746, -0.0316341258585453, -0.01248674001544714, 0.003739723702892661, 0.006955885794013739, -0.002747712656855583, 0.0028402216266840696, 0.0034425139892846346, -0.0022418659646064043, -0.03432672470808029, 0.01146323699504137, -0.037696413695812225, 0.012045846320688725, -0.00018329566228203475, 0.024705795571208, 0.013896025717258453, -0.0037220090162009, 0.021777000278234482, 0.0004303142486605793, 0.022280879318714142, 0.0005304502556100488, -0.035177022218704224, -0.013447258621454239, -0.0032063208054751158, 0.01177816092967987, -0.005818222649395466, 0.0005151961231604218, 0.006365403067320585, -0.00481440220028162, -0.0018964335322380066, -7.448693213518709e-05, -0.014029867947101593, -0.01160495262593031, 0.009014702402055264, 0.001914147986099124, -0.009644550271332264, 0.030185474082827568, -0.004389254376292229, -0.008140787482261658, -0.01606900244951248, 0.0010451542912051082, -0.001415190170519054, 0.015069117769598961, -0.01008544396609068, -0.033161506056785583, -0.00288155535236001, -0.004145188257098198, 0.026422131806612015, 0.019320592284202576, 0.03464164957404137, -0.014045614749193192, -0.007503066677600145, -0.010998724028468132, -0.01965126395225525, 0.02067476697266102, 0.015273818746209145, -0.004184553865343332, -0.010282271541655064, 0.01824985072016716, -0.00976264663040638, -0.0031236533541232347, -0.005711935926228762, 0.004235729109495878, 0.008203772827982903, -0.00251939264126122, 0.006983441766351461, 0.006310291588306427, -0.03128770738840103, 0.014376284554600716, 0.020596034824848175, -0.018281344324350357, -0.018045149743556976, -0.001103218412026763, 0.00027039184351451695, -0.0030705099925398827, -0.01573045924305916, -0.014226695522665977, 0.005959938280284405, -0.013108715415000916, -0.008778508752584457, 0.023005204275250435, 0.04273520037531853, -0.010534211061894894, 0.002596155507490039, -0.01645478419959545, -0.00388340768404305, -0.026815786957740784, 0.002192659070715308, -0.010408241301774979, -0.00943984929472208, 0.0158485546708107, -0.003322449279949069, -0.009274514392018318, 0.011912004090845585, -0.01539191510528326, -0.0152108334004879, 0.012211182154715061, 0.02583952248096466, 0.017415301874279976, -0.00987287051975727, -0.01773022674024105, -0.0038164863362908363, 0.0037377553526312113, -0.011982861906290054, -0.0012262356467545033, 0.013888152316212654, 0.010298017412424088, -0.009148544631898403, -0.004672686103731394, 0.0009678995120339096, -0.0013167763827368617, 0.0054875523783266544, 0.007085792254656553, 0.017399556934833527, 0.009069813415408134, -0.02294222079217434, 0.0028166023548692465, 0.007022807374596596, -0.013636212795972824, 0.024170424789190292, -0.009644550271332264, -0.01242375560104847, 0.029996519908308983, -0.0058969538658857346, -0.00048198149306699634, 0.03204352781176567, -0.0003114796127192676, 0.00913279876112938, -0.02952413447201252, 0.01051059179008007, 0.0005535774980671704, 0.005223803222179413, 0.002968159504234791, -0.005731618497520685, -0.008857239969074726, 0.0024544396437704563, -0.011274282820522785, 0.011408125050365925, -0.007259000558406115, 0.005920573137700558, -0.012242673896253109, 0.0009324705461040139, 0.009298133663833141, 0.014958894811570644, 0.04736458510160446, 0.004483731929212809, 0.008408472873270512, 0.019336339086294174, -0.005810349714010954, -0.009990966878831387, 0.023335875943303108, 0.012494613416492939, -0.0035507690627127886, 0.007581797428429127, -0.018407313153147697, -0.0018147501396015286, 0.0008438981603831053, -0.01736806333065033, -0.005711935926228762, -0.00697163213044405, -0.017462540417909622, -0.0033657513558864594, 0.04015282168984413, -0.014565239660441875, 0.008928097784519196, 0.011447491124272346, 0.0017084631836041808, 0.003300798125565052, -0.0023638990242034197, 0.0012656012549996376, 0.01280953735113144, -0.011227044276893139, 0.015510011464357376, 0.018454551696777344, 0.009502834640443325, -0.02295796573162079, -0.015265945345163345, 0.01475419383496046, -0.006668517831712961, 0.00016607325233053416, 0.00810929574072361, 0.020202379673719406, 0.014242442324757576, 0.00576704740524292, 0.0067984238266944885, -0.008935971185564995, 0.0009368991595692933, 0.016911424696445465, 0.022485580295324326, -0.029051747173070908, 0.00031295581720769405, 0.005530854221433401, -0.0017980197444558144, 0.00026399496709927917, -0.005263168830424547, 0.013329162262380123, 0.013069350272417068, -0.004963991232216358, 0.0017350349808111787, -0.003409053198993206, 0.014840797521173954, -0.009400484152138233, 0.00937686488032341, 0.006133146584033966, 0.00032427339465357363, -0.00721963495016098, 0.001130774267949164, -0.002411137567833066, -0.023776769638061523, -0.0042081731371581554, -0.015250199474394321, 0.004227856174111366, 0.010526337660849094, -0.0035488009452819824, 0.0008935971418395638, 0.03144517168402672, 0.000392670975998044, 0.023886991664767265, 0.0027693638112396, -0.02621743083000183, -0.01861201412975788, 0.0404992401599884, -0.011990734376013279, -0.006853535771369934, 0.008416346274316311, 0.012431629002094269, -0.010282271541655064, -0.013848787173628807, -0.011447491124272346, 0.0008148660999722779, 0.009345372207462788, 0.012502486817538738, -0.023509083315730095, 0.0019200528040528297, 0.0058969538658857346, 0.0018550996901467443, 0.002113928087055683, -0.0032279719598591328, -0.012360770255327225, -0.0016996059566736221, -0.015801316127181053, -0.013423639349639416, 0.007243254221975803, 0.0026315844152122736, 0.02776055969297886, -0.0014801432844251394, 0.012053719721734524, -0.011053835973143578, -0.015935158357024193, -0.011415998451411724, 0.019367830827832222, -0.008010881952941418, -0.009904362261295319, 0.0171161238104105, 0.006416578311473131, 0.006546484772115946, -0.014392031356692314, -0.014848670922219753, 0.0027181885670870543, 0.002127705840393901, -0.007436145097017288, 0.00035945631680078804, 0.003690516809001565, -0.004397127777338028, -0.004944308195263147, -0.0017911307513713837, 0.017903434112668037, -0.02941391058266163, -0.012589090503752232, -0.006219750735908747, 0.006522865500301123, 0.004464048892259598, 0.0034523552749305964, 0.0034425139892846346, 0.0025508850812911987, 0.00983350444585085, -0.000918200530577451, -0.0076605286449193954, 0.028043990954756737, 0.005566283129155636, -0.0026847277767956257, 0.02267453446984291, 0.012904014438390732, -0.030374428257346153, -0.0008872002363204956, 0.00424360204488039, 0.02051730453968048, -0.023036697879433632, 0.016627991572022438, -0.011486856266856194, -0.015761950984597206, -0.021099913865327835, -0.022280879318714142, -0.008282504044473171, -0.0004652511270251125, -0.015628108754754066, -0.014998259954154491, -0.004940371494740248, 0.006625215522944927, -0.013179573230445385, 0.0018560838652774692, 0.004700242076069117, 0.0023717719595879316, -0.024674301967024803, -0.0031098753679543734, -0.022107671946287155, -0.007932150736451149, 0.008298249915242195, -0.01861201412975788, -0.01355748251080513, -0.0142660615965724, -0.00160119216889143, -0.00032205908792093396, 0.0019200528040528297, -0.012022227048873901, -0.012360770255327225, -0.0006455943803302944, 0.017320824787020683, 0.0009792171185836196, 0.004353825468569994, -0.02368229255080223, 0.022658787667751312, 0.011762415058910847, 0.02431214042007923, 0.013770055957138538, 0.006436261348426342, 0.008518696762621403, 0.027729066088795662, 0.022737519815564156, 0.02051730453968048, -0.0285321231931448, -0.02292647399008274, 0.005735555198043585, 0.0010067729745060205, 0.0049679274670779705, 0.036184776574373245, 0.0014584922464564443, 0.003905058838427067, 0.025918252766132355, -0.0202496200799942, -0.011667937971651554, 0.01991894841194153, -0.010423987172544003, -0.0022398976143449545, -0.007936087436974049, 0.007507002912461758, -0.013911771588027477, 0.01572258584201336, 0.020123649388551712, -0.0017606224864721298, -0.014021995477378368, 0.003580293385311961, 0.022391103208065033, 0.008912351913750172, -0.01645478419959545, 0.00440106401219964, -0.004188490565866232, 0.0023422478698194027, -0.00888085924088955, 0.023272890597581863, 0.0017143680015578866, 0.014872290194034576, 0.00799513515084982, 0.014140091836452484, 0.01762000285089016, 0.003962138667702675, -0.011203425005078316, -0.005503298714756966, 0.014565239660441875, 0.001233124639838934, -0.0023796451278030872, -0.006148892920464277, 0.003847978776320815, -0.027319664135575294, -0.02089521288871765, -0.01153409481048584, 0.031350694596767426, 0.0020863721147179604, 0.003328354097902775, 0.0152108334004879, 0.0058615244925022125, 0.006259116344153881, 0.002174944616854191, -0.007329858373850584, -0.007873102091252804, -0.016816945746541023, -0.008195899426937103, 0.0026866961270570755, 4.560863453662023e-05, 0.006129210349172354, 0.003879471216350794, -0.023367367684841156, -0.02544586732983589, -3.60748017556034e-05, -0.014880163595080376, -0.016627991572022438, -0.001232140464708209, 0.010313764214515686, 0.016753962263464928, -0.010038205422461033, -0.02105267532169819, -0.019352085888385773, -0.0011593142990022898, 0.015903666615486145, 0.02785503678023815, -0.009187910705804825, -0.00535764591768384, 0.005782793741673231, 0.015297438018023968, 0.02609146200120449, -0.038704171776771545, 0.009927982464432716, 0.007203888613730669, 0.03536597639322281, -0.01064443401992321, 0.013927518390119076, 0.02155655436217785, -0.01636030711233616, -0.006700010038912296, 0.03700358048081398, -0.0012744584819301963, 0.022391103208065033, -0.016139859333634377, 0.00043646511039696634, -0.002877618884667754, -0.001989926677197218, 0.011132566258311272, -0.01121917087584734, 0.012124577537178993, 0.0023678354918956757, 0.02801249735057354, -0.005755237769335508, 0.021887224167585373, -0.01007757056504488, -0.011297902092337608, -0.014486508443951607, -0.007455827668309212, -0.011935623362660408, -0.00976264663040638, -0.02332012914121151, -0.018297089263796806, -0.00288352370262146, -0.003544864244759083, -0.011164058931171894, -0.0142581881955266, 0.02394997701048851, 0.001074678497388959, 0.00697163213044405, -0.007333794608712196, 0.011187678202986717, -0.001207537017762661, 0.014203076250851154, 0.00497580086812377, -0.0025548217818140984, -0.02927219495177269, 0.011069581843912601, -0.006613405887037516, 0.007105474825948477, -0.01007757056504488, -0.002544980263337493, -0.005881207529455423, -0.004613637924194336, -0.007542431820183992, 0.00816440675407648, -0.007770752068608999, -0.011242790147662163, -0.026280416175723076, 0.011242790147662163, 0.026170192286372185, 0.007034617010504007, 0.00624337000772357, -0.0071290940977633, -0.0008114216034300625, -0.028721077367663383, -0.010786150582134724, -0.010353129357099533, -0.0008596443803980947, -0.008975336328148842, -0.034673143178224564, -0.008518696762621403, -0.01634456031024456, 0.004582145716995001, 0.008313995786011219, 0.015218706801533699, 0.012935507111251354, 0.0002050697075901553, 0.026784293353557587, -0.006314228288829327, -0.0025331706274300814, -0.003727913834154606, 7.030434062471613e-05, 0.011376633308827877, 0.02621743083000183, 0.0043656351044774055, 0.0002908127207774669, 0.016029635444283485, 0.01876947656273842, 0.004586081951856613, 0.00449554156512022, 0.01621859148144722, -0.0025981238577514887, 0.015620235353708267, -0.003826327621936798, 0.021603792905807495, -0.00401725061237812, -0.021336106583476067, -0.006700010038912296, -0.010179921053349972, 0.011132566258311272, -0.015092737041413784, 0.010557830333709717, -0.02812272123992443, -0.04623085632920265, 0.018674999475479126, -0.028327422216534615, 0.005790666677057743, -0.033507924526929855, -0.020344097167253494, 0.004767163656651974, 0.016565008088946342, 0.014722701162099838, 0.003176796715706587, 0.015769824385643005, 0.014053487218916416, -0.019792979583144188, -0.013738563284277916, -0.005089960526674986, 0.018848206847906113, 0.010384622029960155, 0.016021763905882835, 0.00017529954493511468, 0.011006597429513931, -0.0028146340046077967, -0.0060701617039740086, 0.004448303021490574, -0.014951021410524845, 0.01710037887096405, -0.007101538125425577, -0.012392262928187847, -0.012408008798956871, -0.015092737041413784, 0.024611318483948708, -0.004279030952602625, 0.014234568923711777, 0.009085560217499733, 0.011801780201494694, 0.013431512750685215, 0.00608197133988142, 0.03662567213177681, -0.025146689265966415, -0.007121221162378788, 0.0036767388228327036, 0.00737709691748023, -0.017194855958223343, 0.00045122718438506126, 0.010502718389034271, -0.0014968735631555319, -0.006408705376088619, 0.020470065996050835, -0.001258712261915207, -0.00471992464736104, -0.0011967115569859743, 0.013045731000602245, 0.024044454097747803, 0.0005452123587019742, -0.012880395166575909, 0.011880511417984962, -0.029996519908308983, 0.0067157563753426075, 0.0015323025872930884, 0.006290608551353216, 0.007495193276554346, -0.029445402324199677, 0.0069322665221989155, 0.03391732648015022, -0.009431976824998856, -0.019714247435331345, 0.02229662612080574, -0.008266757242381573, -0.006278798915445805, 0.012045846320688725, -0.00236193067394197, 0.002426883904263377, 0.00955794658511877, 0.0036826436407864094, 0.006892900913953781, -0.01210095826536417, 0.004901006352156401, 0.00020408557611517608, -0.003981821704655886, -0.0027713319286704063, -0.02114715240895748, -0.012951252982020378, -0.005735555198043585, 0.006078035105019808, -0.016250083222985268, -0.0001238168333657086, 0.011250663548707962, -0.010951485484838486, -0.0070070610381662846, 6.34153766441159e-05, 0.014738447964191437, 0.020186634734272957, -0.01000671274960041, -0.013415765948593616, 0.0016307163750752807, -0.003613753942772746, 0.007573924493044615, -0.009101306088268757, 0.0016927169635891914, 0.00874701701104641, 0.00037101993802934885, 0.007428272161632776, 0.006601596251130104, 0.009707535617053509, -0.012565471231937408, 0.011770287528634071, -0.00037913909181952477, 0.003224035492166877, 0.0013531894655898213, 0.005940255708992481, 0.018785221502184868, 0.009266640990972519, 0.013588974252343178, -0.007510939612984657, -0.0005147040355950594, -0.0139353908598423, -0.020092157647013664, -0.013337035663425922, -0.03684611991047859, 0.014706955291330814, -0.009487087838351727, 0.008707650937139988, 6.821304850745946e-05, 0.006207941100001335, 0.018533281981945038, -0.003033112734556198, 0.010361002758145332, 0.011030216701328754, -0.009888616390526295, -0.00535764591768384, 0.016753962263464928, -0.015084863640367985, 0.009156418032944202, -0.010046078823506832, 0.009392610751092434, 0.008644666522741318, -0.027729066088795662, -0.005593839101493359, -0.01273867953568697, -0.020312603563070297, -0.017210600897669792, 0.014919528737664223, -0.009219402447342873, -0.011675810441374779, -0.0021946271881461143, 0.010982978157699108, -0.01572258584201336, -0.011935623362660408, 0.014210949651896954, -0.006416578311473131, -0.0183915663510561, 0.0018491948721930385, -0.005806413013488054, 0.014470761641860008, -0.01337640080600977, 0.0007833736599422991, -0.010298017412424088, -0.014478635042905807, 0.012699314393103123, -0.021084168925881386, 0.002639457583427429, -0.010935738682746887, 0.024642810225486755, 0.002143452176824212, 0.007869165390729904, 0.0048419577069580555, 0.007636909373104572, -0.011195551604032516, 0.01606900244951248, 0.011305774562060833, 0.003475974779576063, 0.010486972518265247, -0.004227856174111366, 0.004621510859578848, 0.01191987656056881, -0.015407660976052284, 0.0018167183734476566, -0.007329858373850584, -0.010951485484838486, 0.012573344632983208, 0.0005240533500909805, -0.01837582141160965, -0.02141483873128891, 0.026800040155649185, -0.010242906399071217, -0.008022691123187542, 0.01773022674024105, -0.0049679274670779705, 0.0006849599303677678, 0.0015618266770616174, 0.0004130918241571635, 0.025335643440485, 0.013833040371537209, 0.009715408086776733, 0.008392727002501488, 0.024879002943634987, 0.002192659070715308, 0.0029720962047576904, -0.015549377538263798, -0.010211413726210594, 0.006727566011250019, -0.019304847344756126, 0.0023205969482660294, -0.0015815094811841846, 0.02042282745242119, -0.003586198203265667, -0.003515340154990554, -0.005680443253368139, 0.010526337660849094, -0.01606900244951248, 0.016423290595412254, -0.004117632284760475, -0.010794023051857948, 0.016753962263464928, 0.010368876159191132, 0.005664696916937828, -0.0013315384276211262, -0.01464396994560957, -0.004302650224417448, -0.0017744004726409912, 0.0007735323160886765, -0.013006364926695824, 0.0177617184817791, 0.015998143702745438, 0.02114715240895748, 0.016690976917743683, -0.010841261595487595, 0.019210370257496834, 0.0036373732145875692, -0.0006273878389038146, -0.012762298807501793, 0.001337443245574832, 0.006133146584033966, -0.0024386935401707888, 0.0048025925643742085, -0.005959938280284405, 0.00791640393435955, -0.002619774779304862, 0.024249155074357986, -0.017667241394519806, 0.006865345407277346, 0.016250083222985268, 0.013470877893269062, -0.007821926847100258, 0.001833448652178049, 0.007625099737197161, 0.0008655491983518004, -0.0074007161892950535, 0.004025123547762632, 0.011290028691291809, 0.0012409978080540895, -0.0009590422851033509, -0.007404652889817953, 0.006282735615968704, 0.0011130598140880466, 0.017525525763630867, 0.0075345588847994804, 0.019541040062904358, -0.002749681007117033, -0.016502022743225098, -0.011597080156207085, 0.001962370704859495, -0.0011475046630948782, -0.0016464624786749482, 0.007262936793267727, -0.002913047792389989, 0.009975221008062363, 0.012573344632983208, 0.009014702402055264, 0.006148892920464277, 0.00033337666536681354, 0.021997448056936264, 0.027335410937666893, -0.003720040898770094, 0.0056961895897984505, -0.01064443401992321, -0.010919992811977863, -0.040247298777103424, -0.0056135221384465694, -0.0120301004499197, 0.011345140635967255, -0.008376981131732464, -0.02267453446984291, -0.009754774160683155, 0.0164862759411335, -0.04194789007306099, 0.010038205422461033, 0.010612942278385162, 0.022107671946287155, -0.0074440180324018, 0.003639341564849019, -0.014273934066295624, -0.0003132018609903753, 0.012691440992057323, -0.028799807652831078, -0.006829916033893824, -8.531244384357706e-05, 0.003216162323951721, 0.02042282745242119, -0.003962138667702675, 0.027303919196128845, -0.002586314221844077, 0.00240720110014081, 0.01160495262593031, 0.030059505254030228, -0.0032102575059980154, 0.013218938373029232, -0.002176912734284997, -0.018218358978629112, -0.0019357990240678191, -0.029461149126291275, -0.006644898559898138, 0.006125273648649454, -0.020706258714199066, -0.013092969544231892, 0.010880627669394016, -0.010778277181088924, -7.942299816932064e-06, -0.026044221594929695, -0.010935738682746887, -0.0068102334626019, -0.005869397893548012, 0.02053305134177208, 0.004168807528913021, 0.0003776628873310983, 0.012447374872863293, 0.0026827596593648195, 0.00021269677381496876, -0.012329278513789177, -0.030327189713716507, 0.009219402447342873, -0.0034976257011294365, 0.010620814748108387, -0.005503298714756966, -0.017147617414593697, -0.026059968397021294, -0.01184901874512434, -0.012872522696852684, -0.013116588816046715, -0.010738911107182503, -0.009786265902221203, 0.004897069651633501, 0.011187678202986717, 0.004621510859578848, 0.003826327621936798, 0.012321405112743378, -0.007388906553387642, -0.014392031356692314, 0.02240685001015663, -0.02520967274904251, 0.003460228443145752, 0.008526570163667202, 0.00393064646050334, -0.0018797031370922923, 0.0059560020454227924, -0.02650086209177971, -3.210749491699971e-05, -0.013470877893269062, -0.0025528534315526485, -0.01938357762992382, 0.028280183672904968, -0.0026276479475200176, 0.019446562975645065, 0.010628688149154186, 0.005314344074577093, 0.015746204182505608, 0.00976264663040638, -0.011951369233429432, -0.007636909373104572, 0.005530854221433401, -0.02028111182153225, -0.005030912347137928, 0.005298597738146782, -0.021210137754678726, 0.01210095826536417, 0.012297785840928555, 0.015927286818623543, 0.020989689975976944, -0.019588278606534004, -0.0066724540665745735, -0.022343864664435387, -0.0016464624786749482, 0.004361698869615793, 0.011455363593995571, 0.004070393741130829, 0.0008817874477244914, 0.0013138239737600088, -0.004448303021490574, 0.022123416885733604, 0.00440500071272254, -0.0014968735631555319, 0.006452007219195366, -0.0030449223704636097, 0.006554357707500458, 0.0031059389002621174, -0.013683452270925045, 0.0005565299070440233, -0.006353593431413174, 0.013864533044397831, -0.0034779428970068693, -0.023650798946619034, 0.01596665196120739, 0.010471225716173649, 0.010841261595487595, 0.0025981238577514887, 0.0003894725232385099, 0.0020588161423802376, 0.0035291181411594152, 0.0073495409451425076, -0.01058144960552454, 0.019352085888385773, -0.007424335461109877, 0.0011721081100404263, 0.016816945746541023, 0.009274514392018318, -0.0031827015336602926, 0.007018870674073696, 0.0006490388768725097, -0.004310523625463247, 0.01861201412975788, 0.008432092145085335, 0.002704410580918193, 0.036058809608221054, 0.005582029465585947, -0.0014014121843501925, 0.0028756505344063044, 0.0029150161426514387, 0.012368643656373024, 0.0014329046243801713, 0.009487087838351727, 0.011140439659357071, 0.006522865500301123, 0.0012862681178376079, 0.013179573230445385, 0.016171352937817574, -0.014116472564637661, -0.009258768521249294, -0.0024012962821871042, 0.008581681177020073, -0.004735670983791351, 0.008258884772658348, -2.0021052478114143e-05, -0.01813962683081627, 0.004397127777338028, 0.009920109063386917, -0.007943959906697273, -0.007676274981349707, -0.011486856266856194, -0.005574156530201435, -0.015887919813394547, 0.01152622140944004, 0.0021414838265627623, 0.014226695522665977, -0.0026315844152122736, -0.023146919906139374, 0.019415071234107018, -0.00664883479475975, 0.0028185707051306963, -0.00803450122475624, 0.017399556934833527, -0.004204236436635256, -0.008054183796048164, -0.0164705291390419, -0.013667705468833447, 0.015628108754754066, -0.004042838234454393, -0.02042282745242119, 0.003989694640040398, -0.0029189526103436947, 0.017194855958223343, -0.0018678935011848807, -0.00983350444585085, 0.0003562578931450844, 0.021210137754678726, -0.0272566806524992, -0.023351620882749557, -0.018438804894685745, 0.010998724028468132, -0.010486972518265247, -0.0038637248799204826, -0.008085676468908787, 0.00880212802439928, 0.017147617414593697, -0.004948244895786047, 0.004294777289032936, 0.007471574004739523, 0.007959706708788872, 0.0133055429905653, -0.0028185707051306963, -0.0013905867235735059, 0.009400484152138233, -0.011408125050365925, -0.007739259395748377, 0.005204120650887489, 0.0007090712897479534, -0.00471992464736104, -0.0008822795352898538, -0.003905058838427067, -0.00931388046592474, -0.0253513902425766, 0.007821926847100258, -0.03347643092274666, -0.012447374872863293, -0.0028402216266840696, 0.007093665190041065, 0.02801249735057354, 0.0015401756390929222, 0.002277294872328639, -0.00029548737802542746, 0.008125041611492634, 0.008282504044473171, -0.007892784662544727, 0.02420191653072834, 0.013604721054434776, -0.0025252974592149258, -0.0070661092177033424, 0.005818222649395466, 0.028847046196460724, 0.0002920428814832121, 0.015431280247867107, -0.006078035105019808, -0.002102118218317628, 0.00535764591768384, -0.01121917087584734, -0.00912492536008358, 0.004897069651633501, 0.009510708041489124, -0.005054531618952751, -0.02017088793218136, 0.013014238327741623, -0.011447491124272346, -0.0009236133191734552, 0.002621743129566312, -0.0020607844926416874, -0.017840450629591942, -0.01599027030169964, -0.014840797521173954, 0.007668401580303907, -0.005743428133428097, 0.019336339086294174, -0.02812272123992443, 0.003115780185908079, -0.003513371804729104, -0.026579594239592552, 0.006766931619495153, 0.021084168925881386, -0.01950954832136631, -0.011124693788588047, 0.013344908133149147, -0.008321869187057018, 0.0001590612664585933, -0.012360770255327225, -0.01990320347249508, -0.017966419458389282, -0.0005516092060133815, 0.005999303888529539, 0.0031571141444146633, -0.016407545655965805, 0.0037613746244460344, -0.0005063388962298632, -0.018958430737257004, 0.011549840681254864, -0.0034917208831757307, 0.006644898559898138, -0.005365519318729639, 0.004641193896532059, 0.009676042944192886, 0.0003653611638583243, 0.004042838234454393, -0.0007774688419885933, 0.018155373632907867, 0.001312839798629284, 0.0029740643221884966, -0.00017726782243698835, 0.0133134163916111, 0.022627295926213264, -0.014951021410524845, 0.008699778467416763, -0.004507351201027632, -0.026926010847091675, 0.004479795228689909, -0.0010569640435278416, -0.006577976979315281, 0.005306471139192581, -0.02862660028040409, -0.016549261286854744, -0.016171352937817574, 0.0148959094658494, -0.027209442108869553, -0.013463005423545837, 0.005593839101493359, -0.0027969195507466793, 0.011415998451411724, -0.010140555910766125, 0.013754310086369514, 0.014281807467341423, -0.005385201890021563, -0.019210370257496834, -0.00345038715749979, -0.005105706863105297, -0.009723281487822533, -0.015376169234514236, -0.009117052890360355, -0.010148429311811924, 0.01636030711233616, -0.018659252673387527, 0.005459996405988932, -0.015289564616978168, -0.006822043098509312, -0.03253166005015373, 0.013659832067787647, -0.023225652053952217, 0.006141019985079765, 0.001732082455419004, -0.011431744322180748, 0.009518580511212349, -0.0005845778505317867, 0.002171007916331291, 0.005546600557863712, -0.003430704353377223, 0.011707303114235401, 0.013100842013955116, 0.00440500071272254, 0.012722933664917946, 0.0026827596593648195, -0.0007922309450805187, -0.0068062967620790005, -0.009266640990972519, -0.016769707202911377, -0.003844042308628559, 0.011171932332217693, 0.01661224663257599, 0.006274862680584192, -0.03621627017855644, 0.023603560402989388, -0.0031256217043846846, 0.011801780201494694, -0.027666080743074417, -0.0025036465376615524, 0.0006913567776791751, -0.03180733323097229, 0.009542199783027172, 0.006089844740927219, 0.020958198234438896, 0.022202149033546448, -0.026406385004520416, 0.012565471231937408, -0.007664464879781008, 0.003198447870090604, 0.004916752222925425, -0.013037857599556446, -0.0023698038421571255, -0.009408357553184032, 0.01407710649073124, 0.0129906190559268, 0.004597891587764025, -0.019966186955571175, -0.027146456763148308, -0.004397127777338028, 0.011376633308827877, 0.006668517831712961, 0.018060896545648575, 0.026453623548150063, 0.0033362270332872868, 0.015494265593588352, 0.0063811494037508965, -0.017194855958223343, 0.00024111375387292355, -0.0002543996088206768, -0.014864416792988777, 0.01057357620447874, -0.01684843935072422, 0.011376633308827877, -0.02269028127193451, -0.029476895928382874, 0.013588974252343178, -0.0018039245624095201, 0.009888616390526295, 0.007203888613730669, -0.007688084617257118, -0.00576311070472002, 0.0031827015336602926, 0.0013699198607355356, -0.02179274708032608, -0.0054442500695586205, -0.027540111914277077, -0.026800040155649185, -0.0023481526877731085, -0.0011189646320417523, 0.0037101993802934885, 0.007975452579557896, 0.0053025344386696815, -0.003753501456230879, -0.009164291433990002, -0.026910264045000076, 0.00936899147927761, 0.013415765948593616, 0.016879931092262268, -0.005263168830424547, 0.02483176440000534, 0.026437876746058464, -0.00497186416760087, -0.012581217102706432, -0.0008970415801741183, 0.004731734283268452, -0.006436261348426342, -0.0046766228042542934, -0.021194390952587128, 0.0008581681759096682, 0.012636329047381878, -0.02623317763209343, -0.002853999612852931, 0.016391798853874207, -0.0012272198218852282, -0.009636676870286465, -0.02925644814968109, 0.0072747464291751385, 0.003113812068477273, -0.012589090503752232, 0.01798216626048088, 0.01750977896153927, -0.011927749961614609, -0.005747364833950996, 0.017714479938149452, 0.0031236533541232347, -0.003505498869344592, 0.006459880620241165, 0.003844042308628559, 0.009164291433990002, -0.009266640990972519, -0.004786846227943897, -0.02114715240895748, -0.01128215529024601, 0.022233640775084496, 0.017431048676371574, -0.0014023963594809175, 0.0018462424632161856, 0.021588046103715897, -0.020485812798142433, -0.007546368520706892, -0.005416694562882185, 0.013392146676778793, 0.0024741224478930235, -0.020501557737588882, -0.00018526393978390843, 0.01146323699504137, -0.0008822795352898538, 0.018297089263796806, -0.011085327714681625, 0.007841610349714756, 0.018470298498868942, -0.008644666522741318, 0.01991894841194153, -0.0073495409451425076, -0.003745628520846367, -0.003430704353377223, -0.005566283129155636, 0.01032951008528471, -0.014990386553108692, -0.023855499923229218, -0.005743428133428097, 0.0004792750987689942, 0.026406385004520416, 0.012211182154715061, -0.0018472266383469105, 0.015328929759562016, 0.02143058367073536, 0.0008926129667088389, 0.0126756951212883, -0.00969966221600771, -0.003688548458740115, -0.0064638168551027775, -0.01621859148144722, -0.011447491124272346, -0.0013276018435135484, -0.019100146368145943, 0.0018747824942693114, 0.01686418429017067, 0.0026119016110897064, 0.016313068568706512, 0.01798216626048088, 0.008872986771166325, 0.006105591077357531, 0.015439153648912907, -0.0076605286449193954, 0.018706491217017174, -0.015998143702745438, 0.002387518296018243, -0.010731038637459278, -0.011266409419476986, 0.0139353908598423, -0.006613405887037516, -0.018076643347740173, 0.03382284939289093, -0.002485932083800435, 0.005208057351410389, 0.0013423638883978128, 0.01621859148144722, 0.013636212795972824, -0.026658324524760246, -0.01418733038008213, 0.005499362014234066, -0.0107625313103199, 0.03220098838210106, 0.0062394337728619576, -0.0042081731371581554, -0.0029563498683273792, -0.01597452536225319, -0.015336803160607815, 0.005235612858086824, -0.012612709775567055, -0.014021995477378368, -0.010872754268348217, 0.005853651557117701, 0.012746552936732769, -0.012360770255327225, -0.015021879225969315, 0.0012459184508770704, -0.013722817413508892, -0.021131407469511032, -0.024658557027578354, 0.008479331620037556, 0.020470065996050835, 0.010022459551692009, -0.003324417397379875, -0.04541205242276192, 0.011486856266856194, -0.009022574871778488, -0.0019505610689520836, -0.00874701701104641, 0.032626137137413025, 0.0013561418745666742, 0.003351973369717598, -0.025130942463874817, 0.0017409397987648845, 0.008723397739231586, 0.00267882295884192, 0.0018462424632161856, -0.0021257377229630947, -0.005707999225705862, 0.0005073230131529272, -0.0011602984741330147, -0.009746900759637356, 0.009707535617053509, 0.01724209450185299, -0.015163594856858253, 0.0022103735245764256, -0.006078035105019808, -0.034043293446302414, 0.004704178776592016, 0.004263285081833601, -0.017147617414593697, -0.02089521288871765, -0.001467349473387003, -0.02839040756225586, -0.013494497165083885, -0.007987262681126595, -0.0005826095584779978, -0.0228005051612854, -0.01388027984648943, 0.005648951046168804, -0.017305077984929085, 0.009739027358591557, 0.03265762701630592, 0.010794023051857948, 0.012935507111251354, 0.009077686816453934, 0.010534211061894894, 0.0009934870759025216, 0.005223803222179413, -0.006577976979315281, 0.011612826026976109, -0.014840797521173954, -0.013392146676778793, 0.016942916437983513, -0.018942683935165405, 0.013337035663425922, -0.004349889233708382, -0.010872754268348217, -0.00409007677808404, -0.006637025158852339, 0.010235032998025417, 0.012242673896253109, 0.020706258714199066, -0.02432788535952568, 0.0077668153680861, 0.01569896563887596, 0.011156185530126095, 0.003113812068477273, -0.007247190456837416, 0.004897069651633501, 0.0015116356080397964, 0.0038066450506448746, -0.0015047467313706875, -0.025256913155317307, 0.0030606684740632772, 0.00044384613283909857, -0.010534211061894894, 0.005641077645123005, 0.024028709158301353, -0.006617342587560415, 0.0011839177459478378, -0.012187561951577663, -0.015344676561653614, 0.011982861906290054, 0.0027359030209481716, -0.023855499923229218, 0.007522749248892069, -0.036814626306295395, -0.015289564616978168, -0.01670672371983528, 0.01873798295855522, 0.009904362261295319, 0.00994372833520174, -0.004275094717741013, -0.01887969858944416, 0.003540927777066827, -0.0023934231139719486, 0.00471992464736104, 0.05882782116532326, -0.01001458615064621, 0.0009196767932735384, -0.021761255338788033, 0.008652538992464542, 0.0008680095197632909, 0.0019564658869057894, -0.024296393617987633, -0.0054875523783266544, -0.00045836216304451227, 0.001520492834970355, -0.0001845258375396952, -0.008298249915242195, -0.005641077645123005, -0.004385318141430616, 0.011297902092337608, -0.006282735615968704, 0.004523097071796656, -0.00930600706487894, -0.0171161238104105, -0.009746900759637356, -0.004590018652379513, 0.009006829001009464, 0.001047122641466558, 0.024422364309430122, -0.0053025344386696815, -0.012510359287261963, 0.006050479132682085, -0.008518696762621403, -0.03079957701265812, 0.021635284647345543, -0.024154677987098694, 0.002143452176824212, -6.864361057523638e-05, -0.01064443401992321, 0.003464164910838008, -0.03435821831226349, -0.0048773870803415775, 0.016391798853874207, -0.009613057598471642, 0.0142581881955266, 0.003554705763235688, 0.011959242634475231, 0.010864880867302418, -0.014368412084877491, -0.006829916033893824, 0.005830032285302877, -0.015132103115320206, -0.0016100493958219886, -0.023335875943303108, 0.000774024345446378, 0.005168691743165255, -0.005369455553591251, 0.03240568935871124, -0.021950209513306618, -0.004530970472842455, -0.0025882823392748833, 0.021603792905807495, -0.0055387276224792, 0.014053487218916416, 0.005908763501793146, -0.0026611085049808025, -0.00881000142544508, 0.0003259956429246813, 0.005841841921210289, 0.017588511109352112, -0.011297902092337608, -0.008518696762621403, 0.004818338435143232, -0.015494265593588352, 0.02484751120209694, -0.01000671274960041, 0.01242375560104847, 0.01089637354016304, 0.02064327336847782, -0.0016740183345973492, -0.020580289885401726, 0.0016405576607212424, 0.025697806850075722, -0.008770636282861233, 0.0164705291390419, -0.0020568480249494314, -0.000957073993049562, -0.00943984929472208, -0.018690744414925575, -0.02950838766992092, -0.006731502711772919, -0.0016622086986899376, 0.0310515146702528, -0.006483499892055988, 0.01952529326081276, 0.009794139303267002, -0.003668865654617548, -0.003046890487894416, 0.004901006352156401, -0.0035763566847890615, -0.011691557243466377, -0.002745744539424777, 0.00855806190520525, 0.0048773870803415775, -0.0005811333539895713, 0.011549840681254864, -0.01887969858944416, 0.0007700878195464611, 0.03131920099258423, -0.00640083197504282, 0.008888732641935349, 0.0071251573972404, 0.005971747916191816, -0.009101306088268757, -0.006680327467620373, -0.011723048985004425, -0.006558294408023357, -0.014478635042905807, 0.0017724321223795414, 0.001913163810968399, 0.002068657660856843, 0.003753501456230879, -0.002586314221844077, 0.007566051557660103, -0.02711496502161026, 0.008896606042981148, 0.0164705291390419, -0.0009664233075454831, -0.018060896545648575, -0.015801316127181053, -0.0016877963207662106, 0.004830148071050644, 0.0060386694967746735, -0.010620814748108387, 0.002643394051119685, 0.01450225431472063, 0.02938241697847843, 0.028453391045331955, 0.025036465376615524, 0.00873914361000061, 0.006066225469112396, -0.012219054624438286, 0.009203656576573849, 0.002048974856734276, -0.023398859426379204, 0.0060386694967746735, -0.005424567498266697, -0.010872754268348217, 0.015683220699429512, 0.0011061708210036159, -0.0019239893881604075, -0.009715408086776733, 0.006322101224213839, -0.0145809855312109, -0.0046687498688697815, 0.011990734376013279, 0.03867267817258835, -0.0028146340046077967, -0.005853651557117701, -0.01762000285089016, -0.01147111039608717, -0.020044919103384018, 0.01419520378112793, 0.013274050317704678, -0.010723165236413479, 0.017210600897669792, 0.007168459706008434, 0.0046254475601017475, 0.0142660615965724, -0.010518464259803295, -0.012951252982020378, -0.00671969261020422, 0.00034986098762601614, 0.013966883532702923, 0.0016070969868451357, 0.014203076250851154, -0.001782273524440825, 0.0068810912780463696, 0.01412434596568346, -0.015478518791496754, 0.02128886803984642, -0.015903666615486145, 0.008251011371612549, -0.021225884556770325, 0.005334026645869017, -4.161057586316019e-05, 0.03602731600403786, -0.013762182556092739, 0.00440500071272254, -0.0038401056081056595, -0.003954265732318163, 0.009014702402055264, -0.0002566139155533165, 0.014691208489239216, -0.0002895825309678912, -0.028185706585645676, -0.002828411990776658, 0.005818222649395466, -0.015171468257904053, 0.008006945252418518, -0.020627528429031372, 0.016407545655965805, -0.018029404804110527, -0.024170424789190292, 0.014533746987581253, 0.0011229012161493301, -0.02028111182153225, 0.0004876402672380209
                ],
                "page_number": 105
            }
        ]
    }

创建知识来源

知识来源是指可重复使用的源数据参考资料。 使用知识来源 - 创建 (REST API)定义一个名为 earth-knowledge-source 的知识来源,并将其与 earth-at-night 索引关联起来。

searchIndexParameters.sourceDataSelect 指定检索和引文可访问的索引字段。 为了避免响应结果中出现冗长且难以理解的嵌入式数据,我们的示例仅包含人类可读的字段。

### Create a knowledge source
POST {{search-url}}/knowledgesources?api-version={{api-version}}  HTTP/1.1
    Content-Type: application/json
    Authorization: Bearer {{token}}

    {
        "name": "{{knowledge-source-name}}",
        "description": "This knowledge source pulls from a search index that contains pages from the Earth at Night e-book.",
        "kind": "searchIndex",
        "searchIndexParameters": {
            "searchIndexName": "{{index-name}}",
            "sourceDataSelect": "id, page_chunk, page_number"
        }
    }

创建知识代理

为在查询时将 earth-knowledge-sourcegpt-5-mini 部署作为目标,需要一个知识智能体。 使用知识智能体 - 创建 (REST API) 定义一个名为 earth-knowledge-agent 的智能体,之前使用 @knowledge-agent-name 变量指定该智能体。

knowledgeSources.rerankerThreshold 通过排除重排序得分不高于 2.5 的响应来确保语义相关性。 同时,将 outputConfiguration.modality 设置为 answerSynthesis,从而启用能够引用检索文档的自然语言回答。

### Create a knowledge agent
PUT {{search-url}}/agents/{{knowledge-agent-name}}?api-version={{api-version}}  HTTP/1.1
    Content-Type: application/json
    Authorization: Bearer {{token}}

    {
        "name": "{{knowledge-agent-name}}",
        "knowledgeSources": [
            {
            "name": "{{knowledge-source-name}}",
            "rerankerThreshold": 2.5
            }
        ],
        "models": [
            {
                "kind": "azureOpenAI",
                "azureOpenAIParameters": {
                    "resourceUri": "{{aoai-url}}",
                    "deploymentId": "{{aoai-gpt-deployment}}",
                    "modelName": "{{aoai-gpt-model}}"
                }
            }
        ],
        "outputConfiguration": {
            "modality": "answerSynthesis"
        }
    }

运行检索管道

你已准备好运行智能体检索。 使用知识检索 - 检索 (REST API) 将由两部分构成的用户查询发送到 earth-knowledge-agent,该查询将查询解构为子查询,针对 earth-at-night 索引中的文本和向量字段运行子查询,并对结果进行排名和合并。

### Run agentic retrieval
POST {{search-url}}/agents('{{knowledge-agent-name}}')/retrieve?api-version={{api-version}}  HTTP/1.1
    Content-Type: application/json
    Authorization: Bearer {{token}}

    {
        "messages": [
            {
                "role": "user",
                "content": [
                    {
                        "type": "text",
                        "text": "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?"
                    }
                ]
            }
        ],
        "knowledgeSourceParams": [
            {
                "knowledgeSourceName": "{{knowledge-source-name}}",
                "kind": "searchIndex"
            }
        ]
    }

输出应类似于以下 JSON,其中:

  • response 会根据检索到的文档,生成一个由大型语言模型 (LLM) 合成的答案。 如果未启用答案合成功能,则此部分将直接显示从文档中提取的内容。

  • activity 会追踪检索过程中的所有步骤,包括 gpt-5-mini 部署在检索过程中生成的子查询,以及用于语义排序、查询规划和答案合成所使用的标记。

  • references 列出构成该响应的文档,每个文档都由其 docKey标识。

{
  "response": [
    {
      "content": [
        {
          "type": "text",
          "text": "Suburban belts display larger December brightening than urban cores despite higher absolute light levels downtown because the urban grid encourages outward growth along city borders, fueled by widespread personal automobile use, leading to extensive suburban and residential municipalities linked by surface streets and freeways. This expansion results in increased lighting in suburban areas during December. The Phoenix nighttime street grid is sharply visible from space due to its regular grid layout of city blocks and streets, with major transportation corridors like Grand Avenue and brightly lit commercial properties at intersections, which create distinct lighting patterns. In contrast, large stretches of interstate highways between Midwestern cities remain comparatively dim because they lack the dense, grid-like urban development and associated lighting found in metropolitan areas like Phoenix [ref_id:0][ref_id:1]."
        }
      ]
    }
  ],
  "activity": [
    {
      "type": "modelQueryPlanning",
      "id": 0,
      "inputTokens": 2079,
      "outputTokens": 121,
      "elapsedMs": 2887
    },
    {
      "type": "searchIndex",
      "id": 1,
      "knowledgeSourceName": "earth-knowledge-source",
      "queryTime": "2025-08-25T16:23:17.832Z",
      "count": 0,
      "elapsedMs": 1065,
      "searchIndexArguments": {
        "search": "Reasons for larger December brightening in suburban belts compared to urban cores despite higher downtown light levels",
        "filter": null
      }
    },
    {
      "type": "searchIndex",
      "id": 2,
      "knowledgeSourceName": "earth-knowledge-source",
      "queryTime": "2025-08-25T16:23:18.139Z",
      "count": 2,
      "elapsedMs": 298,
      "searchIndexArguments": {
        "search": "Factors making Phoenix nighttime street grid sharply visible from space",
        "filter": null
      }
    },
    {
      "type": "searchIndex",
      "id": 3,
      "knowledgeSourceName": "earth-knowledge-source",
      "queryTime": "2025-08-25T16:23:18.332Z",
      "count": 0,
      "elapsedMs": 189,
      "searchIndexArguments": {
        "search": "Reasons why large stretches of interstate between Midwestern cities are comparatively dim at night from space",
        "filter": null
      }
    },
    {
      "type": "semanticReranker",
      "id": 4,
      "inputTokens": 2349
    },
    {
      "type": "modelAnswerSynthesis",
      "id": 5,
      "inputTokens": 3216,
      "outputTokens": 155,
      "elapsedMs": 2274
    }
  ],
  "references": [
    {
      "type": "searchIndex",
      "id": "0",
      "activitySource": 2,
      "sourceData": null,
      "rerankerScore": 2.6642752,
      "docKey": "earth_at_night_508_page_104_verbalized"
    },
    {
      "type": "searchIndex",
      "id": "1",
      "activitySource": 2,
      "sourceData": null,
      "rerankerScore": 2.5905457,
      "docKey": "earth_at_night_508_page_105_verbalized"
    }
  ]
}

清理资源

当你使用自己的订阅服务时,最好在完成一个项目后,先评估一下是否还需要你所创建的那些资源。 持续运行的资源可能会产生费用。

Azure 门户中,可以通过在左侧窗格中选择“所有资源”或“资源组”来管理 Azure AI 搜索和 Azure AI Foundry 资源

否则,请运行以下代码以删除在本快速入门中创建的对象。

删除知识代理

### Delete the knowledge agent
DELETE {{search-url}}/agents/{{knowledge-agent-name}}?api-version={{api-version}}  HTTP/1.1
    Content-Type: application/json
    Authorization: Bearer {{token}}

删除知识来源

### Delete the knowledge source
DELETE {{search-url}}/knowledgesources('{{knowledge-source-name}}')?api-version={{api-version}}  HTTP/1.1
    Content-Type: application/json
    Authorization: Bearer {{token}}

删除搜索索引

### Delete the index
DELETE {{search-url}}//indexes/{{index-name}}?api-version={{api-version}}  HTTP/1.1
    Content-Type: application/json
    Authorization: Bearer {{token}}