快速入門:使用來自 Azure AI 搜尋服務的基礎資料的生成式搜尋 (RAG)
本快速入門說明如何將基本和複雜的查詢傳送至大型語言模型 (LLM),以取得 Azure AI 搜尋上索引內容的對話式搜尋體驗。 您會使用 Azure 入口網站來設定資源,然後執行 Python 程式碼以呼叫 API。
必要條件
Azure 訂用帳戶。 免費建立一個。
Azure AI 搜尋服務 (基本層或更高層級),以便可以啟用語意排名工具。 區域必須與用於 Azure OpenAI 的區域相同。
在與 Azure AI 搜尋相同的區域中,部署
gpt-4o
、gpt-4o-mini
或對等 LLM 的 Azure OpenAI 資源。具有 Python 延伸模組和 Jupyter 套件的 Visual Studio Code。 如需詳細資訊,請參閱 Visual Studio Code 中的 Python。
下載檔案
從 GitHub 下載 Jupyter Notebook,以在本快速入門中傳送要求。 如需相關資訊,請參閱從 GitHub 下載檔案。
您也可以在本機系統上啟動新的檔案,並使用本文中的指示手動建立要求。
設定存取權
對搜尋端點發出的要求必須經過驗證和授權。 您可以針對這項工作使用 API 金鑰或角色。 金鑰較容易上手,但角色更安全。 本快速入門採用角色。
您正在設定兩個用戶端,因此您需要這兩個資源的權限。
Azure AI 搜尋服務會從本機系統接收查詢要求。 為自己指派該工作的搜尋索引資料讀者角色指派。 如果您也正在建立和載入旅館範例索引,則新增搜尋服務參與者和搜尋索引資料參與者角色。
Azure OpenAI 正在接收來自您本機系統的 (查詢)「您可以推薦幾個旅館嗎」,並從搜尋服務接收搜尋結果 (來源)。 為您自己和搜尋服務指派認知服務 OpenAI 使用者角色。
登入 Azure 入口網站。
將 Azure AI 搜尋服務設定為使用系統指派的受控識別,以便您可以為其指派角色:
在 Azure 入口網站上,尋找您的搜尋服務。
在左側功能表上,選取 [設定] > [身分識別]。
在 [系統指派] 索引標籤上,將狀態設定為 [開啟]。
針對角色型存取設定 Azure AI 搜尋服務:
在 Azure 入口網站中,尋找您的 Azure AI 搜尋服務。
在左側功能表上,選取 [設定]>[金鑰],然後選取 [角色型存取控制] 或 [兩者]。
指派角色:
在左側功能表中,選取 [存取控制 (IAM)]。
在 Azure AI 搜尋服務上,確定您有建立、載入和查詢搜尋索引的權限:
- 搜尋索引資料參與者
- 搜尋服務參與者
在 Azure OpenAI 上,選取 [存取控制 (IAM)],以便為您自己和搜尋服務指派 Azure OpenAI 上的身分識別權限。 本快速入門的程式碼會在本機執行。 對 Azure OpenAI 的要求源自您的系統。 此外,來自搜尋引擎的搜尋結果也會傳遞至 Azure OpenAI。 基於這些原因,您和搜尋服務都需要 Azure OpenAI 的權限。
- 認知服務 OpenAI 使用者
權限可能需要幾分鐘的時間才會生效。
建立索引
我們的建議是使用 hotels-sample-index,可在幾分鐘內就建立好,並在任何搜尋服務層級上執行。 此索引是使用內建的範例資料所建立的。
在 Azure 入口網站上,尋找您的搜尋服務。
在 [連線到您的資料] 頁面上,從下拉式清單中選取 [範例]。
選擇 [hotels-sample]。
剩餘頁面皆選取 [下一步],並接受預設值。
建立索引之後,從左側功能表中選取 [搜尋管理]>[索引] 以開啟索引。
選取 [編輯 JSON]。
搜尋「語意」,以在索引中尋找語意設定的區段。 將空白的
"semantic": {}
行取代為下列語意設定。 此範例會指定"defaultConfiguration"
,這對執行本快速入門很重要。"semantic":{ "defaultConfiguration":"semantic-config", "configurations":[ { "name":"semantic-config", "prioritizedFields":{ "titleField":{ "fieldName":"HotelName" }, "prioritizedContentFields":[ { "fieldName":"Description" } ], "prioritizedKeywordsFields":[ { "fieldName":"Category" }, { "fieldName":"Tags" } ] } } ] },
儲存您的變更。
在搜尋總管中執行下列查詢來測試您的索引:
complimentary breakfast
。輸出應看起來應類似下列範例。 直接從搜尋引擎傳回的結果包含欄位及其逐字字串值,以及搜尋分數和語意排名分數和標題等中繼資料 (若您有使用語意排名工具)。 我們使用 select 語句只傳回 HotelName、Description 和 Tags 字段。
{ "@odata.count": 18, "@search.answers": [], "value": [ { "@search.score": 2.2896252, "@search.rerankerScore": 2.506816864013672, "@search.captions": [ { "text": "Head Wind Resort. Suite. coffee in lobby\r\nfree wifi\r\nview. The best of old town hospitality combined with views of the river and cool breezes off the prairie. Our penthouse suites offer views for miles and the rooftop plaza is open to all guests from sunset to 10 p.m. Enjoy a **complimentary continental breakfast** in the lobby, and free Wi-Fi throughout the hotel..", "highlights": "" } ], "HotelName": "Head Wind Resort", "Description": "The best of old town hospitality combined with views of the river and cool breezes off the prairie. Our penthouse suites offer views for miles and the rooftop plaza is open to all guests from sunset to 10 p.m. Enjoy a complimentary continental breakfast in the lobby, and free Wi-Fi throughout the hotel.", "Tags": [ "coffee in lobby", "free wifi", "view" ] }, { "@search.score": 2.2158256, "@search.rerankerScore": 2.288334846496582, "@search.captions": [ { "text": "Swan Bird Lake Inn. Budget. continental breakfast\r\nfree wifi\r\n24-hour front desk service. We serve a continental-style breakfast each morning, featuring a variety of food and drinks. Our locally made, oh-so-soft, caramel cinnamon rolls are a favorite with our guests. Other breakfast items include coffee, orange juice, milk, cereal, instant oatmeal, bagels, and muffins..", "highlights": "" } ], "HotelName": "Swan Bird Lake Inn", "Description": "We serve a continental-style breakfast each morning, featuring a variety of food and drinks. Our locally made, oh-so-soft, caramel cinnamon rolls are a favorite with our guests. Other breakfast items include coffee, orange juice, milk, cereal, instant oatmeal, bagels, and muffins.", "Tags": [ "continental breakfast", "free wifi", "24-hour front desk service" ] }, { "@search.score": 0.92481667, "@search.rerankerScore": 2.221315860748291, "@search.captions": [ { "text": "White Mountain Lodge & Suites. Resort and Spa. continental breakfast\r\npool\r\nrestaurant. Live amongst the trees in the heart of the forest. Hike along our extensive trail system. Visit the Natural Hot Springs, or enjoy our signature hot stone massage in the Cathedral of Firs. Relax in the meditation gardens, or join new friends around the communal firepit. Weekend evening entertainment on the patio features special guest musicians or poetry readings..", "highlights": "" } ], "HotelName": "White Mountain Lodge & Suites", "Description": "Live amongst the trees in the heart of the forest. Hike along our extensive trail system. Visit the Natural Hot Springs, or enjoy our signature hot stone massage in the Cathedral of Firs. Relax in the meditation gardens, or join new friends around the communal firepit. Weekend evening entertainment on the patio features special guest musicians or poetry readings.", "Tags": [ "continental breakfast", "pool", "restaurant" ] }, . . . ]}
取得服務端點
在其餘各節中,您會設定對 Azure OpenAI 和 Azure AI 搜尋的 API 呼叫。 取得服務端點,讓您可以在程式碼中作為變數提供。
登入 Azure 入口網站。
在 [概觀] 首頁上,複製 URL。 範例端點看起來會像是
https://example.search.windows.net
。在 [概觀] 首頁上,選取連結以檢視端點。 複製 URL。 範例端點看起來會像是
https://example.openai.azure.com/
。
設定查詢和聊天對話
本節使用 Visual Studio Code 和 Python 在 Azure OpenAI 上呼叫聊天完成 API。
啟動 Visual Studio Code 並 開啟 .ipynb 檔案 或建立新的 Python 檔案。
安裝下列 Python 套件。
! pip install azure-search-documents==11.6.0b5 --quiet ! pip install azure-identity==1.16.1 --quiet ! pip install openai --quiet ! pip install aiohttp --quiet ! pip install ipykernel --quiet
設定下列變數,並將預留位置替換為您在上一個步驟中收集的端點。
AZURE_SEARCH_SERVICE: str = "PUT YOUR SEARCH SERVICE ENDPOINT HERE" AZURE_OPENAI_ACCOUNT: str = "PUT YOUR AZURE OPENAI ENDPOINT HERE" AZURE_DEPLOYMENT_MODEL: str = "gpt-4o"
設定用戶端、提示、查詢和回應。
針對 Azure Government 雲端,將令牌提供者上的 API 端點修改為
"https://cognitiveservices.azure.us/.default"
。# Set up the query for generating responses from azure.identity import DefaultAzureCredential from azure.identity import get_bearer_token_provider from azure.search.documents import SearchClient from openai import AzureOpenAI credential = DefaultAzureCredential() token_provider = get_bearer_token_provider(credential, "https://cognitiveservices.azure.com/.default") openai_client = AzureOpenAI( api_version="2024-06-01", azure_endpoint=AZURE_OPENAI_ACCOUNT, azure_ad_token_provider=token_provider ) search_client = SearchClient( endpoint=AZURE_SEARCH_SERVICE, index_name="hotels-sample-index", credential=credential ) # This prompt provides instructions to the model GROUNDED_PROMPT=""" You are a friendly assistant that recommends hotels based on activities and amenities. Answer the query using only the sources provided below in a friendly and concise bulleted manner. Answer ONLY with the facts listed in the list of sources below. If there isn't enough information below, say you don't know. Do not generate answers that don't use the sources below. Query: {query} Sources:\n{sources} """ # Query is the question being asked. It's sent to the search engine and the LLM. query="Can you recommend a few hotels with complimentary breakfast?" # Set up the search results and the chat thread. # Retrieve the selected fields from the search index related to the question. search_results = search_client.search( search_text=query, top=5, select="Description,HotelName,Tags" ) sources_formatted = "\n".join([f'{document["HotelName"]}:{document["Description"]}:{document["Tags"]}' for document in search_results]) response = openai_client.chat.completions.create( messages=[ { "role": "user", "content": GROUNDED_PROMPT.format(query=query, sources=sources_formatted) } ], model=AZURE_DEPLOYMENT_MODEL ) print(response.choices[0].message.content)
輸出來自 Azure OpenAI,其中包含數家飯店的建議。 此輸出可能看起來會像以下的範例:
Sure! Here are a few hotels that offer complimentary breakfast: - **Head Wind Resort** - Complimentary continental breakfast in the lobby - Free Wi-Fi throughout the hotel - **Double Sanctuary Resort** - Continental breakfast included - **White Mountain Lodge & Suites** - Continental breakfast available - **Swan Bird Lake Inn** - Continental-style breakfast each morning with a variety of food and drinks such as caramel cinnamon rolls, coffee, orange juice, milk, cereal, instant oatmeal, bagels, and muffins
若看到 [禁止] 錯誤訊息,請檢查 Azure AI 搜尋服務設定以確定已啟用角色型存取。
若看到 [授權失敗] 錯誤訊息,請稍候幾分鐘再試一次。 角色指派可能需要幾分鐘的時間才能運作。
否則,若要進一步實驗,請變更查詢並重新執行最後一個步驟,以進一步了解模型如何搭配基礎資料運作。
您也可以修改提示以變更輸出的音調或結構。
您也可以在查詢參數步驟中設定
use_semantic_reranker=False
,以嘗試沒有語意排名的查詢。 語意排名無法明顯改善查詢結果的相關性,以及 LLM 傳回實用資訊的能力。 實驗可協助您決定它是否對您的內容有所影響。
傳送複雜的RAG查詢
Azure AI 搜尋支援 巢狀 JSON 結構的複雜類型 。 在hotels-sample-index 中,Address
是複雜類型的範例,由Address.StreetAddress
、、Address.City
、 Address.StateProvince
Address.PostalCode
和Address.Country
組成。 索引也有每個旅館的複雜集合 Rooms
。
如果您的索引具有複雜類型,則查詢可以在您先將搜尋結果輸出轉換成 JSON 時提供這些欄位,然後將 JSON 傳遞至 LLM。 下列範例會將複雜型別新增至要求。 格式化指示包含 JSON 規格。
import json
# Query is the question being asked. It's sent to the search engine and the LLM.
query="Can you recommend a few hotels that offer complimentary breakfast?
Tell me their description, address, tags, and the rate for one room that sleeps 4 people."
# Set up the search results and the chat thread.
# Retrieve the selected fields from the search index related to the question.
selected_fields = ["HotelName","Description","Address","Rooms","Tags"]
search_results = search_client.search(
search_text=query,
top=5,
select=selected_fields,
query_type="semantic"
)
sources_filtered = [{field: result[field] for field in selected_fields} for result in search_results]
sources_formatted = "\n".join([json.dumps(source) for source in sources_filtered])
response = openai_client.chat.completions.create(
messages=[
{
"role": "user",
"content": GROUNDED_PROMPT.format(query=query, sources=sources_formatted)
}
],
model=AZURE_DEPLOYMENT_MODEL
)
print(response.choices[0].message.content)
輸出來自 Azure OpenAI,而且會新增來自複雜類型的內容。
Here are a few hotels that offer complimentary breakfast and have rooms that sleep 4 people:
1. **Head Wind Resort**
- **Description:** The best of old town hospitality combined with views of the river and
cool breezes off the prairie. Enjoy a complimentary continental breakfast in the lobby,
and free Wi-Fi throughout the hotel.
- **Address:** 7633 E 63rd Pl, Tulsa, OK 74133, USA
- **Tags:** Coffee in lobby, free Wi-Fi, view
- **Room for 4:** Suite, 2 Queen Beds (Amenities) - $254.99
2. **Double Sanctuary Resort**
- **Description:** 5-star Luxury Hotel - Biggest Rooms in the city. #1 Hotel in the area
listed by Traveler magazine. Free WiFi, Flexible check in/out, Fitness Center & espresso
in room. Offers continental breakfast.
- **Address:** 2211 Elliott Ave, Seattle, WA 98121, USA
- **Tags:** View, pool, restaurant, bar, continental breakfast
- **Room for 4:** Suite, 2 Queen Beds (Amenities) - $254.99
3. **Swan Bird Lake Inn**
- **Description:** Continental-style breakfast featuring a variety of food and drinks.
Locally made caramel cinnamon rolls are a favorite.
- **Address:** 1 Memorial Dr, Cambridge, MA 02142, USA
- **Tags:** Continental breakfast, free Wi-Fi, 24-hour front desk service
- **Room for 4:** Budget Room, 2 Queen Beds (City View) - $85.99
4. **Gastronomic Landscape Hotel**
- **Description:** Known for its culinary excellence under the management of William Dough,
offers continental breakfast.
- **Address:** 3393 Peachtree Rd, Atlanta, GA 30326, USA
- **Tags:** Restaurant, bar, continental breakfast
- **Room for 4:** Budget Room, 2 Queen Beds (Amenities) - $66.99
...
- **Tags:** Pool, continental breakfast, free parking
- **Room for 4:** Budget Room, 2 Queen Beds (Amenities) - $60.99
Enjoy your stay! Let me know if you need any more information.
疑難排解錯誤
若要針對驗證錯誤進行偵錯,請在呼叫搜尋引擎和 LLM 的步驟之前插入下列程式代碼。
import sys
import logging # Set the logging level for all azure-storage-* libraries
logger = logging.getLogger('azure.identity')
logger.setLevel(logging.DEBUG)
handler = logging.StreamHandler(stream=sys.stdout)
formatter = logging.Formatter('[%(levelname)s %(name)s] %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)
請重新執行查詢指令碼。 您現在應該會在輸出中看到「資訊」和「偵錯」陳述,其提供有關問題的詳細資料。
若您看到與 ManagedIdentityCredential 和權杖擷取失敗相關的輸出訊息,可能是您有多個租用戶,而且您的 Azure 登入是使用沒有搜尋服務的租用戶。 若要取得您的租用戶識別碼,請在 Azure 入口網站中搜尋「租用戶屬性」或執行 az login tenant list
。
擁有租用戶識別碼後,請在命令提示字元執行 az login --tenant <YOUR-TENANT-ID>
,然後重新執行指令碼。
清理
如果您是在自己的訂用帳戶中進行,建議您在專案結束時判斷自己是否仍需要先前所建立的資源。 資源若繼續執行,將需付費。 您可以個別刪除資源,或刪除資源群組以刪除整組資源。
您可以使用最左邊窗格中的 [所有資源] 或 [資源群組] 連結,在 Azure 入口網站 中找到和管理資源。