你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
在本教程中,你将使用 .NET Blazor、Azure OpenAI 和 Azure AI 搜索创建 .NET 检索扩充生成(RAG)应用程序,并将其部署到 Azure 应用服务。 此应用程序演示如何实现聊天界面,该界面从自己的文档检索信息,并利用 Azure AI 服务提供准确的上下文感知答案,并提供适当的引文。 解决方案使用托管标识在服务之间进行无密码身份验证。
本教程中,您将学习如何:
- 部署将 RAG 模式与 Azure AI 服务配合使用的 Blazor 应用程序。
- 为混合搜索配置 Azure OpenAI 和 Azure AI 搜索。
- 上传文档并编制索引,以便在 AI 驱动的应用程序中使用。
- 使用托管标识进行安全的服务到服务通信。
- 使用生产服务在本地测试 RAG 实现。
体系结构概述
在开始部署之前,了解要生成的应用程序的体系结构会很有帮助。 下图来自 Azure AI 搜索的自定义 RAG 模式:
在本教程中,应用服务中的 Blazer 应用程序负责应用 UX 和应用服务器。 但是,它不会对 Azure AI 搜索进行单独的知识查询。 相反,它指示 Azure OpenAI 使用 Azure AI 搜索作为数据源来进行知识查询。 此体系结构提供几个关键优势:
- 集成矢量化:Azure AI 搜索的集成向量化功能可让你轻松快速地引入所有文档进行搜索,而无需更多代码来生成嵌入内容。
- 简化的 API 访问:通过将 Azure OpenAI On Your Data 模式与 Azure AI 搜索结合使用作为 Azure OpenAI 完成的数据源,无需实现复杂的矢量搜索或嵌入生成。 这只是一个 API 调用,Azure OpenAI 处理所有内容,包括提示工程和查询优化。
- 高级搜索功能:集成矢量化提供高级混合搜索所需的一切,并结合关键字匹配、矢量相似性和 AI 支持的排名的优势。
- 完整的引文支持:响应自动包括对源文档的引文,使信息可验证和可跟踪。
先决条件
- 具有活动订阅的 Azure 帐户 - 免费创建帐户。
- GitHub 帐户用于使用 GitHub Codespaces - 详细了解 GitHub Codespaces。
1.使用 Codespaces 打开示例
最简单的入门方法是使用 GitHub Codespaces,它提供一个完整的开发环境,并预装了所有必需的工具。
请导航至位于https://github.com/Azure-Samples/app-service-rag-openai-ai-search-dotnet的 GitHub 存储库。
选择 “代码 ”按钮,选择 “Codespaces ”选项卡,然后单击 main 上的“创建代码空间”。
请稍等片刻,让 Codespace 初始化。 准备就绪后,浏览器中会显示完全配置的 VS Code 环境。
2.部署示例体系结构
在终端中,使用 Azure 开发人员 CLI 登录到 Azure:
azd auth login
按照说明完成身份验证过程。
使用 AZD 模板预配 Azure 资源:
azd provision
出现提示时,请提供以下答案:
问题 答案 输入新的环境名称: 键入唯一名称。 选择要使用的 Azure 订阅: 选择订阅。 选择要使用的资源组: 选择“新建资源组”。 选择要在其中创建资源组的位置: 选择任何区域。 实际上,资源将在 美国东部 2 中生成。 输入新资源组的名称: 键入 Enter。 等待部署完成。 此过程将:
- 创建所有必需的 Azure 资源。
- 将 Blazor 应用程序部署到 Azure 应用服务。
- 使用托管标识配置安全的服务到服务身份验证。
- 设置必要的角色分配,以确保服务之间的安全访问。
注释
若要详细了解托管标识的工作原理,请参阅什么是 Azure 资源的托管标识?以及如何对应用服务使用托管标识。
成功部署后,会看到已部署应用程序的 URL。 记下此 URL,但尚未访问它,因为仍需要设置搜索索引。
3.上传文档并创建搜索索引
部署基础结构后,需要上传文档并创建应用程序将使用的搜索索引:
在 Azure 门户中,导航到部署创建的存储帐户。 该名称以前面提供的环境名称开头。
从左侧导航菜单中选择 “容器 ”,然后打开 文档 容器。
单击“ 上传”上传示例文档。 可以使用存储库中文件夹中的示例文档
sample-docs
,或者你自己的 PDF、Word 或文本文件。在 Azure 门户中导航到 Azure AI 搜索服务。
选择 “导入”并向量化数据 以开始创建搜索索引的过程。
在“连接到数据”步骤中:
- 选择 Azure Blob 存储 作为数据源。
- 选择 RAG。
- 选择存储帐户和 文档 容器。
- 确保已选择 使用托管标识进行身份验证 。
- 选择“下一步”。
在 向量化文本 步骤中:
- 选择 Azure OpenAI 服务。
- 选择 文本嵌入-ada-002 作为嵌入模型。 AZD 模板已为你部署了此模型。
- 选择 系统分配的标识 进行身份验证。
- 请勾选用于确认额外费用的复选框。
- 选择“下一步”。
小窍门
详细了解 Azure AI 搜索中的矢量搜索 和 Azure OpenAI 中的文本嵌入。
在 矢量化和扩充图像 步骤中:
- 保留默认设置。
- 选择“下一步”。
在 “高级设置” 步骤中:
- 确保已选择 “启用语义排名器 ”。
- (可选)选择索引计划。 如果要使用最新文件更改定期刷新索引,这非常有用。
- 选择“下一步”。
在 “审阅”和“创建 ”步骤中:
- 复制 对象名称前缀 值。 这是您的搜索索引名称。
- 选择 “创建 ”以启动索引过程。
等待索引进程完成。 这可能需要几分钟时间,具体取决于文档的大小和数量。
若要测试数据导入,请选择 “开始搜索 ”并尝试搜索查询,例如 “告诉我你的公司”。
返回 Codespace 终端,将搜索索引名称设置为 AZD 环境变量:
azd env set SEARCH_INDEX_NAME <your-search-index-name>
将
<your-search-index-name>
替换为之前复制的索引名称。 AZD 在后续部署中使用此变量来设置应用服务应用设置。
4.测试应用程序并部署
如果想要在部署前后在本地测试应用程序,可以直接从 Codespace 运行它:
在 Codespace 终端中,获取 AZD 环境值:
azd env get-values
打开 appsettings.Development.json。 使用终端输出,更新值
OpenAIEndpoint
,SearchServiceUrl
以及SearchIndexName
。使用 Azure CLI 登录到 Azure:
az login
这允许示例代码中的 Azure 标识客户端库接收已登录用户的身份验证令牌。
在本地运行应用程序:
dotnet run
当看到 端口 5017 上运行的应用程序可用时,请选择 “在浏览器中打开”。
请尝试在聊天界面中提出几个问题。 如果收到响应,应用程序将成功连接到 Azure OpenAI 资源。
在 Azure 中应用新
SEARCH_INDEX_NAME
配置并部署示例应用程序代码:azd up
5.测试已部署的 RAG 应用程序
在完全部署和配置应用程序后,现在可以测试 RAG 功能:
打开部署结束时提供的应用程序 URL。
你会看到一个聊天界面,你可以在其中输入有关已上传文档内容的问题。
请尝试询问特定于文档内容的问题。 例如,如果在 sample-docs 文件夹中上传了文档,可以尝试这些问题:
- Contoso 如何使用我的个人数据?
- 如何提出保修索赔?
请注意响应如何包含引用源文档的引文。 这些引文可帮助用户验证信息的准确性,并在源材料中查找更多详细信息。
通过提出可能受益于不同搜索方法的问题来测试混合搜索功能:
- 具有特定术语的问题(适用于关键字搜索)。
- 有关使用不同术语(适合矢量搜索)描述的概念的问题。
- 需要理解上下文的复杂问题(适用于语义排名)。
清理资源
完成应用程序后,可以删除所有资源,以避免产生进一步的成本:
azd down --purge
此命令将删除与应用程序关联的所有资源。
常见问题
- 示例代码如何从 Azure OpenAI 聊天完成中检索引文?
- 在此解决方案中使用托管标识有什么优势?
- 此体系结构和示例应用程序中如何使用系统分配的托管标识?
- 如何在示例应用程序中实现语义排名器混合搜索?
- 为什么在美国东部 2 中创建所有资源?
- 是否可以使用自己的 OpenAI 模型而不是 Azure 提供的模型?
- 如何提高响应质量?
示例代码如何从 Azure OpenAI 聊天生成的完成结果中检索引文?
该示例使用 AzureSearchChatDataSource()
作为聊天客户端的数据源,从中检索引文。 请求聊天完成时,响应将包含 Citations
消息上下文中的对象。 代码提取这些引文,如下所示:
var result = await _chatClient.CompleteChatAsync(messages, options);
var ctx = result.Value.GetMessageContext();
var response = new ChatResponse
{
Content = result.Value.Content,
Citations = ctx?.Citations
};
return response;
在聊天响应中,内容使用 [doc#]
表示法引用列表中的相应引文,允许用户跟踪信息回原始源文档。 有关详细信息,请参见:
在此解决方案中使用托管标识有什么优势?
托管标识无需在代码或配置中存储凭据。 通过使用托管标识,应用程序可以在不管理机密的情况下安全地访问 Azure 服务,例如 Azure OpenAI 和 Azure AI 搜索。 此方法遵循零信任安全原则,并降低凭据泄露的风险。
此体系结构和示例应用程序中如何使用系统分配的托管标识?
AZD 部署为 Azure 应用服务、Azure OpenAI 和 Azure AI 搜索创建系统分配的托管标识。 它还为他们中的每一个进行角色分配(请参阅 main.bicep 文件)。 有关所需角色分配的信息,请参阅 Azure OpenAI On Your Data 的网络和访问配置。
在示例应用程序中,Azure SDK 使用此托管标识安全地对请求进行身份验证,而无需在任何地方存储凭据或机密。 例如,AzureOpenAIClient
使用 DefaultAzureCredential
初始化,它在 Azure 中运行时使用托管标识:
_openAIClient = new AzureOpenAIClient(
new Uri(_settings.OpenAIEndpoint),
new DefaultAzureCredential()
);
同样,在为 Azure AI 搜索配置数据源时,为身份验证指定托管标识:
options.AddDataSource(new AzureSearchChatDataSource()
{
Endpoint = new Uri(_settings.SearchServiceUrl ?? throw new ArgumentNullException(nameof(_settings.SearchServiceUrl))),
IndexName = _settings.SearchIndexName,
Authentication = DataSourceAuthentication.FromSystemManagedIdentity(), // Use system-assigned managed identity
// ...
});
这可实现 Blazor 应用与 Azure 服务之间的安全无密码通信,遵循零信任安全性的最佳做法。 详细了解 DefaultAzureCredential 和适用于 .NET 的 Azure Identity 客户端库。
如何在示例应用程序中实现语义排名器混合搜索?
示例应用程序使用 Azure.AI.Search.Documents SDK 配置具有语义排名的混合搜索。 在后端中,数据源按如下所示进行设置:
options.AddDataSource(new AzureSearchChatDataSource()
{
// ...
QueryType = DataSourceQueryType.VectorSemanticHybrid, // Combines vector search with keyword matching and semantic ranking
VectorizationSource = DataSourceVectorizer.FromDeploymentName(_settings.OpenAIEmbeddingDeployment),
SemanticConfiguration = _settings.SearchIndexName + "-semantic-configuration", // Build semantic configuration name from index name
});
此配置使应用程序能够在单个查询中合并矢量搜索(语义相似性)、关键字匹配和语义排名。 语义排名器对结果进行重新排序,以返回最相关的上下文适当的答案,然后由 Azure OpenAI 用于生成响应。
语义配置名称由集成向量化过程自动定义。 它使用搜索索引名称作为前缀,并追加 -semantic-configuration
为后缀。 这可确保语义配置与相应的索引唯一关联,并遵循一致的命名约定。
为什么在美国东部 2 中创建所有资源?
此示例使用 gpt-4o-mini 和 text-embedding-ada-002 模型,这两种模型都可用于美国东部 2 的标准部署类型。 此外,还会选择这些模型,因为它们不会很快停用,从而为示例部署提供稳定性。 模型可用性和部署类型可能因区域而异,因此选择美国东部 2 以确保示例开箱即用。 如果要使用不同的区域或模型,请确保选择可用于同一区域中相同部署类型的模型。 选择自己的模型时,请检查其可用性和停用日期以避免中断。
- 模型可用性: Azure OpenAI 服务模型
- 模型停用日期:Azure OpenAI 服务模型弃用和停用。
是否可以使用自己的 OpenAI 模型而不是 Azure 提供的模型?
此解决方案旨在与 Azure OpenAI 服务配合使用。 虽然可以修改代码以使用其他 OpenAI 模型,但会丢失集成安全功能、托管标识支持以及此解决方案提供的与 Azure AI 搜索的无缝集成。
如何提高响应质量?
可以通过以下方法提高响应质量:
- 上传质量更高、更相关的文档。
- 在 Azure AI 搜索索引管道中调整分块策略。 但是,不能使用本教程中显示的集成矢量化自定义分块。
- 在应用程序代码中试验不同的提示模板。
- 使用 AzureSearchChatDataSource 类中的其他属性微调搜索。
- 为特定域使用更专用的 Azure OpenAI 模型。