참고
Azure AI 검색 Azure 포털, REST API 및 Azure SDK 통해 사용할 수 있습니다. 또한 엔터프라이즈 콘텐츠를 Microsoft Foundry 포털의 에이전트에 대해 재사용 가능한 사용 권한 인식 기술 자료로 변환하는 관리되는 기술 계층인 Foundry IQ를 뒷받침합니다.
중요
기능, 기능 또는 표시된 속성(미리 보기)은 서비스 수준 계약에 포함되지 않으며 프로덕션 워크로드에는 권장되지 않으며 일반적으로 사용 가능해지기 전에 변경되거나 제한될 수 있습니다. Azure AI 검색 미리 보기 용어는 독립 실행형 기능이든 일반 공급 기능의 일부이든 관계없이 모든 미리 보기 기능에 적용됩니다.
에이전트 검색 파이프라인에서 검색 작업은 기술 자료에서 병렬 쿼리 처리를 호출합니다. Search Service REST API 또는 Azure SDK 사용하여 검색 작업을 직접 호출할 수 있습니다. 각 기술 자료는 MCP 호환 에이전트에서 사용할 MCP(모델 컨텍스트 프로토콜) 엔드포인트도 노출합니다.
이 문서에서는 선택적 권한 적용을 사용하여 두 검색 메서드를 호출하는 방법을 설명합니다. MCP 도구 결과가 현재 REST 및 SDK 응답 셰이프와 다르기 때문에 먼저 검색 작업과 나중에 MCP 엔드포인트를 다룹니다.
MCP를 통해 Azure AI 검색 Foundry 에이전트 서비스에 연결하는 파이프라인을 설정하려면 Tutorial: 엔드투엔드 에이전트 검색 솔루션 빌드 참조하세요.
사용량 지원
| Azure Portal | Microsoft Foundry 포털 | .NET SDK | Python SDK | Java SDK | JavaScript SDK | REST API |
|---|---|---|---|---|---|---|
| ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
필수 구성 요소
Azure AI 검색 서비스는 지식 베이스를 포함합니다.
공유 모델 액세스 및 클라이언트 설정은 기술 자료를 만들기 위한 필수 구성 요소를 참조하세요.
기술 자료를 쿼리할 수 있는 권한입니다. 사용자 계정에 할당된 검색 인덱스 데이터 판독기 역할을 사용하여 키 없는 인증을 구성하거나 쿼리 API 키를 사용합니다.
Azure OpenAI 응답 API를 통해 MCP 엔드포인트를 호출하는 경우 다음이 필요합니다.
Foundry 리소스에 배포된 LLM 및 Cognitive Services OpenAI 사용자 역할(또는 API 키)입니다. 해당하는 경우 기술 자료에 지정된 LLM 및 리소스를 다시 사용할 수 있습니다.
패키지:
Azure.AI.OpenAIdotnet add package Azure.AI.OpenAI
필수
Azure.Search.Documents패키지:2026-08-01-preview기능의 경우, 최신 미리 보기 패키지:dotnet add package Azure.Search.Documents --prerelease2026-04-01기능의 경우, 최신 안정화 패키지:dotnet add package Azure.Search.Documents
키 없는 인증의 경우 패키지:
Azure.Identitydotnet add package Azure.Identity
Azure OpenAI 응답 API를 통해 MCP 엔드포인트를 호출하는 경우 다음이 필요합니다.
Foundry 리소스에 배포된 LLM 및 Cognitive Services OpenAI 사용자 역할(또는 API 키)입니다. 해당하는 경우 기술 자료에 지정된 LLM 및 리소스를 다시 사용할 수 있습니다.
패키지:
openaipip install openai
필수
azure-search-documents패키지:2026-08-01-preview기능의 경우, 최신 미리 보기 패키지:pip install --pre azure-search-documents2026-04-01기능의 경우, 최신 안정화 패키지:pip install azure-search-documents
키 없는 인증의 경우 패키지:
azure-identitypip install azure-identity
필수 Search Service REST API 버전:
미리 보기 기능: 2026-08-01-preview
정식 출시된 기능: 2026-04-01
키 없는 인증의 경우 각 HTTP 요청의 헤더에 Microsoft Entra ID 토큰을
Authorization포함합니다.
Limitations
검색 인덱스 지식 원본의 경우, 재순위 지정을 사용하도록 설정하면 검색은 해당 지식 원본의 시맨틱 구성을 사용합니다. 기본 인덱스의 defaultScoringProfile( 포함)은 적용되지 않습니다. 검색 응답도 @search.rerankerBoostedScore표시되지 않습니다.
검색 작업 호출
기술 자료에서 검색 작업을 지정합니다. 요청 본문에는 쿼리 입력과 대상으로 지정할 기술 자료의 선택적 목록이 포함됩니다.
2026-04-01 API 버전은 intents 입력과 최소한의 추출형 검색만 지원합니다. 입력, 쿼리 계획, 응답 합성 및 구성 가능한 추론 노력을 포함한 messages 미리 보기 전용 기능은 지원되지 않습니다. 전체 기능을 사용하려면 2026-08-01-preview을 사용하세요.
using Azure.Identity;
using Azure;
using Azure.Search.Documents.KnowledgeBases;
using Azure.Search.Documents.KnowledgeBases.Models;
// Create knowledge base retrieval client
var kbClient = new KnowledgeBaseRetrievalClient(
endpoint: new Uri("<search-endpoint>"),
knowledgeBaseName: "<knowledge-base-name>",
credential: new DefaultAzureCredential()
);
var retrievalRequest = new KnowledgeBaseRetrievalRequest();
retrievalRequest.Messages.Add(
new KnowledgeBaseMessage(
content: new[] {
new KnowledgeBaseMessageTextContent(
"You 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 do not know'."
)
}
) { Role = "assistant" }
);
retrievalRequest.Messages.Add(
new KnowledgeBaseMessage(
content: new[] {
new KnowledgeBaseMessageTextContent(
"Why is the Phoenix nighttime street grid so sharply visible from space, "
+ "whereas large stretches of the interstate between midwestern cities remain comparatively dim?"
)
}
) { Role = "user" }
);
var result = await kbClient.RetrieveAsync(retrievalRequest);
Console.WriteLine(
(result.Value.Response[0].Content[0] as KnowledgeBaseMessageTextContent)!.Text
);
참조:KnowledgeBaseRetrievalClient, KnowledgeBaseRetrievalRequest
from azure.identity import DefaultAzureCredential
from azure.search.documents.knowledgebases import KnowledgeBaseRetrievalClient
from azure.search.documents.knowledgebases.models import (
KnowledgeBaseMessage,
KnowledgeBaseMessageTextContent,
KnowledgeBaseRetrievalRequest,
SearchIndexKnowledgeSourceParams,
)
# Create knowledge base retrieval client
kb_client = KnowledgeBaseRetrievalClient(
endpoint="<search-endpoint>",
knowledge_base_name="<knowledge-base-name>",
credential=DefaultAzureCredential(),
)
request = KnowledgeBaseRetrievalRequest(
messages=[
KnowledgeBaseMessage(
role="assistant",
content=[
KnowledgeBaseMessageTextContent(
text="You 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 do not know'."
)
],
),
KnowledgeBaseMessage(
role="user",
content=[
KnowledgeBaseMessageTextContent(
text="Why is the Phoenix nighttime street grid so sharply visible from space, "
"whereas large stretches of the interstate between midwestern cities remain comparatively dim?"
)
],
),
],
knowledge_source_params=[
SearchIndexKnowledgeSourceParams(
knowledge_source_name="earth-at-night-blob-ks",
)
],
)
result = kb_client.retrieve(request)
print(result.response[0].content[0].text)
참조:KnowledgeBaseRetrievalClient, KnowledgeBaseRetrievalRequest
@search-endpoint = <search-endpoint> // Example: https://my-service.search.windows.net
@search-access-token = <search-access-token> // Run: az account get-access-token --scope https://search.azure.com/.default --query accessToken -o tsv
POST {{search-endpoint}}/knowledgebases/{{knowledge-base-name}}/retrieve?api-version=2026-08-01-preview
Content-Type: application/json
Authorization: Bearer {{search-access-token}}
{
"messages": [
{
"role": "assistant",
"content": [
{
"type": "text",
"text": "You 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 do not know'."
}
]
},
{
"role": "user",
"content": [
{
"type": "text",
"text": "Why is the Phoenix nighttime street grid so sharply visible from space, whereas large stretches of the interstate between midwestern cities remain comparatively dim?"
}
]
}
],
"knowledgeSourceParams": [
{
"knowledgeSourceName": "earth-at-night-blob-ks",
"kind": "searchIndex"
}
]
}
참조:지식 검색 - 검색
합성에 응답할 이미지 제공(미리 보기)
자산 저장소를 사용하여 구성하는 Blob, 인덱싱된 OneLake 및 인덱싱된 SharePoint 기술 원본의 경우 텍스트와 함께 다운스트림 응답 합성 모델에 문서 포함 이미지를 제공할 수 있습니다.
enableImageServing의 일치하는 항목에서 knowledgeSourceParams을 설정하여 기술 자료 정의에 설정된 기본값을 재정의합니다. 검색 응답에는 모델에 제공된 개별 이미지 경로 또는 이미지 바이트에 대한 전용 필드가 포함되지 않습니다.
이미지 제공은 ingestionPermissionOptions가 outputMode인 경우에만 실행되며, answerSynthesis를 구성하는 지식 소스에서는 지원되지 않습니다. 설정 단계, 우선 순위 테이블 및 이미지 제공 통계를 검사하는 방법은 에이전트형 검색(미리 보기)에서 문서에 포함된 이미지 표시를 참조하세요.
지식 소스에 대한 재순위 지정 사용 안 함(미리 보기)
2026-08-01-preview API 버전부터는 특정 지식 소스에 대한 재순위 지정을 우회하고 원래 결과 순서를 유지하려면 "resultsProcessing": "none" 항목에 knowledgeSourceParams를 설정하세요.
resultsProcessing를 지식 소스에 기본값으로 저장할 수도 있습니다. 모든 지식 원본 종류는 이 속성을 지원합니다.
다음 예제에서는 하나의 검색 요청에 대해 product-catalog-ks의 재순위 지정을 건너뜁니다.
using System;
using System.Linq;
using Azure.Identity;
using Azure.Search.Documents.Indexes.Models;
using Azure.Search.Documents.KnowledgeBases;
using Azure.Search.Documents.KnowledgeBases.Models;
var client = new KnowledgeBaseRetrievalClient(
new Uri("<search-endpoint>"),
"product-catalog-kb",
new DefaultAzureCredential());
var request = new KnowledgeBaseRetrievalRequest
{
IncludeActivity = true
};
request.Intents.Add(
new KnowledgeRetrievalSemanticIntent(
"Find the power adapter for SKU 88421."));
request.KnowledgeSourceParams.Add(
new SearchIndexKnowledgeSourceParams("product-catalog-ks")
{
AlwaysQuerySource = true,
IncludeReferences = true,
ResultsProcessing = KnowledgeSourceResultsProcessing.None
});
var result = await client.RetrieveAsync(request);
Console.WriteLine(
$"References with a reranker score: "
+ $"{result.Value.References.Count(x => x.RerankerScore.HasValue)}");
참조:KnowledgeBaseRetrievalClient, SearchIndexKnowledgeSourceParams
from azure.identity import DefaultAzureCredential
from azure.search.documents.knowledgebases import (
KnowledgeBaseRetrievalClient,
)
from azure.search.documents.knowledgebases.models import (
KnowledgeBaseRetrievalRequest,
KnowledgeRetrievalSemanticIntent,
SearchIndexKnowledgeSourceParams,
)
client = KnowledgeBaseRetrievalClient(
endpoint="<search-endpoint>",
knowledge_base_name="product-catalog-kb",
credential=DefaultAzureCredential(),
)
request = KnowledgeBaseRetrievalRequest(
intents=[
KnowledgeRetrievalSemanticIntent(
search="Find the power adapter for SKU 88421."
)
],
include_activity=True,
knowledge_source_params=[
SearchIndexKnowledgeSourceParams(
knowledge_source_name="product-catalog-ks",
always_query_source=True,
include_references=True,
results_processing="none",
)
],
)
result = client.retrieve(request)
reranked_count = sum(
reference.reranker_score is not None
for reference in result.references
)
print("References with a reranker score:", reranked_count)
참조:KnowledgeBaseRetrievalClient, SearchIndexKnowledgeSourceParams
@search-endpoint = <search-endpoint>
@search-access-token = <search-access-token> // Run: az account get-access-token --scope https://search.azure.com/.default --query accessToken -o tsv
@knowledge-base-name = product-catalog-kb
POST {{search-endpoint}}/knowledgebases/{{knowledge-base-name}}/retrieve?api-version=2026-08-01-preview
Content-Type: application/json
Authorization: Bearer {{search-access-token}}
{
"intents": [
{
"type": "semantic",
"search": "Find the power adapter for SKU 88421."
}
],
"includeActivity": true,
"knowledgeSourceParams": [
{
"knowledgeSourceName": "product-catalog-ks",
"kind": "searchIndex",
"alwaysQuerySource": true,
"includeReferences": true,
"resultsProcessing": "none"
}
]
}
참조:지식 검색 - 검색
리랭킹 파이프라인을 사용하려면 "resultsProcessing": "rerank"로 설정하거나, 저장된 기본값이 없으면 이를 생략합니다. Azure AI 검색 각 원본의 유효 값을 다음 순서대로 확인합니다.
- retrieve 요청의
knowledgeSourceParams에 있는resultsProcessing -
resultsProcessing지식 원본에 저장됩니다. -
rerank두 속성이 모두 없는 경우
MCP 서버 지식 원본resultsProcessing의 경우 개별 도구에 설정된 값이 요청 및 저장된 값보다 우선합니다.
Tip
resultsProcessing 는 쿼리되는 원본이 아니라 결과 처리 방법을 변경합니다. 지식 소스를 쿼리해야 하는 경우 true을(를) alwaysQuerySource(으)로 설정합니다.
유효 값이 다음과 같은 경우:none
- 지식 소스의 참조에는
rerankerScore가 제외되며, 결과는 소스의 검색 활동 내에서 원래 순서를 유지합니다. - 어떤 소스든 재순위 지정을 우회하면 Azure AI 검색는 지식 원본 선언 순서에 따라 라운드 로빈 방식으로 활동 전반에 걸쳐 최종 결과를 분산합니다. 재순위가 매겨진 활동은 점수순으로 유지됩니다.
- 중복 제거 및 원본별, 문서 및 토큰 제한이 계속 적용되므로 검색된 모든 결과가 응답에 나타나지는 않습니다.
Azure AI 검색 다음 순서로 유효성을 검사합니다.rerankerThreshold
- 검색은 가져오기 요청과 저장된 지식 소스 값을 바탕으로
resultsProcessing를 확인합니다. - 확정된 값이
none이고 요청에rerankerThreshold이 포함된 경우 Search는400 Bad Request를 반환합니다. - MCP 서버 도구의 경우 검색은 요청의 유효성을 검사한 후 도구 수준
resultsProcessing값을 적용합니다.
따라서 MCP 도구 설정은 요청이 유효성 검사를 통과하는지 여부를 변경하지 않습니다. 도구 수준 none 값은 임계값 오류를 일으키지 않으며, 도구 수준 rerank 값은 요청 또는 저장된 값이 확인 none될 때 오류를 방지하지 않습니다.
어떤 모드가 실행되었는지 확인하려면 지식 원본의 참조에 rerankerScore가 포함되어 있는지 확인하세요. 생략되는 대신 semanticConfigurationName될 수 있는 null에 의존하지 마십시오.
인덱스 검색 동작
검색 인덱스를 대상으로 하는 지식 원본의 경우 암시적 쿼리 유형은 semantic검색 모드가 없습니다. 재순위 지정이 실행될 때 쿼리 실행은 semanticConfigurationName를 사용합니다. 다른 소스 설정(포함 searchFields 및 sourceDataFields포함)은 두 모드에서 모두 적용됩니다.
에이전트형 검색은 scoringProfile 또는 scoringParameters 입력을 허용하지 않습니다. 인덱싱된 지식 소스에 대해 최신성 편향이 필요한 경우 인덱스 채점 프로필 대신 최신성 인식 검색(미리 보기)을 사용하세요.
인덱스에 벡터 필드가 포함된 경우 에이전트 검색 엔진이 쿼리 입력을 벡터화할 수 있도록 유효한 벡터라이저 정의가 필요합니다. 그렇지 않으면 벡터 필드가 무시됩니다.
자세한 내용은 에이전트 검색을 위한 인덱스 만들기를 참조하세요.
스트림 검색 결과(미리 보기)
2026-08-01-preview API 버전부터 단일 JSON 응답을 기다리는 대신 검색 결과를 SSE(서버 전송 이벤트) 스트림으로 받을 수 있습니다. 스트리밍을 사용하면 각 부분을 사용할 수 있게 되면 클라이언트에서 쿼리 계획, 원본 활동 및 합성된 응답 또는 추출된 응답을 해당 순서대로 표시할 수 있습니다.
using Azure.Identity;
using Azure.Search.Documents.Indexes.Models;
using Azure.Search.Documents.KnowledgeBases;
using Azure.Search.Documents.KnowledgeBases.Models;
var client = new KnowledgeBaseRetrievalClient(
new Uri("<search-endpoint>"),
"<knowledge-base-name>",
new DefaultAzureCredential());
var request = new KnowledgeBaseRetrievalRequest
{
OutputMode = KnowledgeRetrievalOutputMode.ExtractiveData,
RetrievalReasoningEffort =
new KnowledgeRetrievalMinimalReasoningEffort(),
IncludeActivity = true,
};
request.Intents.Add(
new KnowledgeRetrievalSemanticIntent("What is the return policy?"));
request.KnowledgeSourceParams.Add(
new SearchIndexKnowledgeSourceParams(
"<knowledge-source-name>")
{
ResultsProcessing = KnowledgeSourceResultsProcessing.None,
IncludeReferences = true,
});
var eventCounts = new Dictionary<string, int>();
await foreach (var item in client.RetrieveStreamAsync(request))
{
eventCounts.TryGetValue(item.EventType, out var count);
eventCounts[item.EventType] = count + 1;
}
foreach (var (eventType, count) in eventCounts)
{
Console.WriteLine($"{eventType}: {count}");
}
from collections import Counter
from azure.identity import DefaultAzureCredential
from azure.search.documents.indexes.models import (
KnowledgeSourceResultsProcessing,
)
from azure.search.documents.knowledgebases import (
KnowledgeBaseRetrievalClient,
)
from azure.search.documents.knowledgebases.models import (
KnowledgeBaseRetrievalRequest,
KnowledgeRetrievalMinimalReasoningEffort,
KnowledgeRetrievalOutputMode,
KnowledgeRetrievalSemanticIntent,
SearchIndexKnowledgeSourceParams,
)
client = KnowledgeBaseRetrievalClient(
endpoint="<search-endpoint>",
knowledge_base_name="<knowledge-base-name>",
credential=DefaultAzureCredential(),
)
request = KnowledgeBaseRetrievalRequest(
intents=[
KnowledgeRetrievalSemanticIntent(
search="What is the return policy?"
)
],
output_mode=KnowledgeRetrievalOutputMode.EXTRACTIVE_DATA,
retrieval_reasoning_effort=KnowledgeRetrievalMinimalReasoningEffort(),
include_activity=True,
knowledge_source_params=[
SearchIndexKnowledgeSourceParams(
knowledge_source_name="<knowledge-source-name>",
results_processing=KnowledgeSourceResultsProcessing.NONE,
include_references=True,
)
],
)
event_counts = Counter()
with client.retrieve_stream(request) as stream:
for event in stream:
event_counts[event.event_type] += 1
for event_type, count in event_counts.items():
print(f"{event_type}: {count}")
스트리밍을 옵트인하려면 검색 요청에 헤더를 포함합니다 Accept: text/event-stream . 이 헤더가 없으면 검색 작업은 표준 JSON 응답을 반환합니다.
POST {{search-endpoint}}/knowledgebases/{{knowledge-base-name}}/retrieve?api-version=2026-08-01-preview
Content-Type: application/json
Accept: text/event-stream
Authorization: Bearer {{search-access-token}}
{
"intents": [
{
"type": "semantic",
"search": "What is the return policy?"
}
],
"outputMode": "extractiveData",
"retrievalReasoningEffort": {
"kind": "minimal"
},
"includeActivity": true,
"knowledgeSourceParams": [
{
"knowledgeSourceName": "{{knowledge-source-name}}",
"kind": "searchIndex",
"resultsProcessing": "none",
"includeReferences": true
}
]
}
참조:지식 검색 - 검색
이벤트 수명 주기
단일 응답을 반환하는 대신, 서비스는 하나의 HTTP 연결(콘텐츠 형식 text/event-stream; charset=utf-8)을 열어 두고 데이터를 사용할 수 있게 되면 일련의 이벤트를 보냅니다. 각 이벤트에는 event: 이벤트 형식의 이름을 지정하는 줄, data: JSON 값이 있는 줄 및 이벤트의 끝을 표시하는 빈 줄이 있습니다.
성공적인 스트림은 다음 수명 주기를 사용합니다.
| Event | 전송되는 경우 | 포함된 내용 |
|---|---|---|
retrieval.started |
모든 스트리밍 요청에서 발생하는 첫 번째 이벤트입니다. | 서비스가 요청 및 지식 베이스의 기본값을 적용한 후의 요청 ID, 지식 베이스 이름, 출력 모드 및 최종 추론 노력 수준 유효한 kind이(가) auto인 경우, 이벤트는 auto를 보고하며 이후의 에스컬레이션은 예측하지 않습니다. |
activity.started |
서비스가 쿼리 계획, 원본 또는 모델 작업을 시작하는 경우 이전 작업이 완료되기 전에 여러 활동을 시작할 수 있습니다. | 활동 id, type시작 시간 및 선택적 지식 원본 이름입니다. |
activity.completed |
해당 작업이 완료되면
activity.started을 일치시켜 해당 id 이벤트와 연관시킵니다. |
완료된 활동 레코드입니다. |
answer.completed |
outputMode가 answerSynthesis일 때만 한 번 가능합니다. |
messageIndex 는 최종 응답 배열 message 에서 메시지의 위치를 식별하고 전체 합성된 대답을 포함합니다. 토큰별 토큰 델타 이벤트는 없습니다. |
references.completed |
모든 참조가 해결된 후. | 이벤트 데이터는 개체 래퍼가 없는 전체 참조 배열입니다. |
response.completed |
성공하거나 부분적으로 성공한 스트림에 대한 터미널 이벤트입니다. |
200 또는 206 상태 코드와 비 스트리밍 JSON 호출과 같은 셰이프를 가진 전체 검색 응답 본문입니다. 각 상태 코드의 의미에 대한 자세한 내용은 검색 작업 문제 해결을 참조하세요. |
error |
스트림이 열린 후 검색에 실패하는 경우에는 references.completed 및 response.completed 대신 |
오류 및 실패 전에 완료된 모든 활동 기록. |
이벤트가 순서대로 도착합니다. 각 activity.started 이벤트는 동일한 activity.completed를 가진 id 이벤트보다 먼저 발생하지만, 활동은 서로 뒤섞여 실행될 수 있습니다. 완료된 활동 기록에는 completedAt 및 startedAt 타임스탬프도 포함됩니다. 스트림이 유휴 상태인 동안 서버는 약 15초마다 주석을 보내 : heartbeat 연결을 열어 둡니다. SSE 클라이언트는 이러한 주석을 무시할 수 있습니다.
다음 예제에서는 가독성을 위해 페이로드가 단축된 스트리밍 응답을 보여 줍니다.
event: retrieval.started
data: {"requestId":"<request-id>","outputMode":"answerSynthesis"}
event: activity.started
data: {"id":0,"type":"searchIndex","startedAt":"<timestamp>"}
: heartbeat
event: activity.completed
data: {"id":0,"startedAt":"<start>","completedAt":"<end>"}
event: answer.completed
data: {"messageIndex":0,"message":{"content":[{"type":"text","text":"..."}]}}
event: references.completed
data: [{"type":"searchIndex","id":"0","activitySource":0}]
event: response.completed
data: {"statusCode":200,"response":{}}
오류, 취소 및 대체 처리
실행 전 오류: 잘못된 형식의 요청 본문과 같이 스트림이 열리기 전에 요청 유효성 검사가 실패하는 경우 검색 작업은 표준 JSON 오류 응답을 반환하고 스트림을 열지 않습니다.
중간 스트림 오류: 스트림이 열린 후 검색에 실패하면 터미널 이벤트가
error대신references.completed및response.completed. 이벤트에는 실패하기 전에 완료된 모든 활동 레코드가 포함될 수 있습니다. 스트림이 시작되면 HTTP 상태 코드가 유지200되므로 HTTP 상태 코드가 아닌 터미널 이벤트를 확인하여 성공을 확인합니다.취소 또는 연결 끊기: 스트림이 완료되기 전에 클라이언트가 요청을 취소하거나 연결을 끊으면 서비스는 검색을 취소하고 터미널 이벤트 없이 스트림을 종료합니다. 취소 또는 연결 끊기 전에 받은 이벤트를 불완전한 것으로 처리합니다.
JSON 대체 응답: 사용 시 헤더가 없거나 값이 , , 또는 인 경우, 응답 검토에 설명된 표준 JSON 응답이 반환됩니다. 이전 API 버전에서 요청하면
text/event-stream반환됩니다406 Not Acceptable.
쿼리 시점에 검색 인덱스의 지식 원본 필터링
검색 인덱스 지식 원본에서 검색할 때 쿼리 시간에 OData 필터 를 적용하여 결과를 특정 문서 또는 필드로 좁힐 수 있습니다. 필터 식은 OData 구문을 사용하며 매개 변수를 filterAddOn 통해 전달됩니다.
필터 구문 및 예제
매개 변수는 filterAddOn OData 필터 식을 허용합니다. 예제 패턴은 다음과 같습니다.
-
메타데이터 필드:
city eq 'Phoenix'status eq 'active' -
날짜 범위:
publishDate ge 2024-01-01 and publishDate le 2024-12-31 -
숫자 범위:
price ge 100 and price le 5000 -
텍스트 일치:
substringof('climate', description),indexof(title, 'urgent') ge 0 -
논리 연산자:
(category eq 'News' or category eq 'Analysis') and status eq 'published'
using Azure;
using Azure.Search.Documents.KnowledgeBases;
using Azure.Search.Documents.KnowledgeBases.Models;
var kbClient = new KnowledgeBaseRetrievalClient(
endpoint: new Uri("<search-endpoint>"),
knowledgeBaseName: "<knowledge-base-name>",
credential: new DefaultAzureCredential()
);
var retrievalRequest = new KnowledgeBaseRetrievalRequest();
retrievalRequest.Messages.Add(
new KnowledgeBaseMessage(
content: new[] {
new KnowledgeBaseMessageTextContent(
"You are a support agent. Answer questions based on published documentation. "
+ "If you don't know the answer, say so."
)
}
) { Role = "assistant" }
);
retrievalRequest.Messages.Add(
new KnowledgeBaseMessage(
content: new[] {
new KnowledgeBaseMessageTextContent(
"What is the process for submitting an expense report?"
)
}
) { Role = "user" }
);
// Apply a filter to search only published documents
var searchIndexParams = new SearchIndexKnowledgeSourceParams(
knowledgeSourceName: "internal-documentation-ks"
);
searchIndexParams.FilterAddOn = "status eq 'published'";
retrievalRequest.KnowledgeSourceParams.Add(searchIndexParams);
var result = await kbClient.RetrieveAsync(retrievalRequest);
Console.WriteLine(
(result.Value.Response[0].Content[0] as KnowledgeBaseMessageTextContent)!.Text
);
from azure.identity import DefaultAzureCredential
from azure.search.documents.knowledgebases import KnowledgeBaseRetrievalClient
from azure.search.documents.knowledgebases.models import (
KnowledgeBaseMessage,
KnowledgeBaseMessageTextContent,
KnowledgeBaseRetrievalRequest,
SearchIndexKnowledgeSourceParams,
)
kb_client = KnowledgeBaseRetrievalClient(
endpoint="<search-endpoint>",
knowledge_base_name="<knowledge-base-name>",
credential=DefaultAzureCredential(),
)
request = KnowledgeBaseRetrievalRequest(
messages=[
KnowledgeBaseMessage(
role="assistant",
content=[
KnowledgeBaseMessageTextContent(
text="You are a support agent. Answer questions based on published documentation. "
"If you don't know the answer, say so."
)
],
),
KnowledgeBaseMessage(
role="user",
content=[
KnowledgeBaseMessageTextContent(
text="What is the process for submitting an expense report?"
)
],
),
],
knowledge_source_params=[
SearchIndexKnowledgeSourceParams(
knowledge_source_name="internal-documentation-ks",
# Apply a filter to search only published documents
filter_add_on="status eq 'published'",
)
],
)
result = kb_client.retrieve(request)
print(result.response[0].content[0].text)
POST {{search-endpoint}}/knowledgebases/{{knowledge-base-name}}/retrieve?api-version=2026-08-01-preview
Content-Type: application/json
Authorization: Bearer {{search-access-token}}
{
"messages": [
{
"role": "assistant",
"content": [
{
"type": "text",
"text": "You are a support agent. Answer questions based on published documentation. If you don't know the answer, say so."
}
]
},
{
"role": "user",
"content": [
{
"type": "text",
"text": "What is the process for submitting an expense report?"
}
]
}
],
"knowledgeSourceParams": [
{
"knowledgeSourceName": "internal-documentation-ks",
"kind": "searchIndex",
"filterAddOn": "status eq 'published'"
}
]
}
다중 필터 예제
여러 필터를 결합하여 결과를 더 구체화할 수 있습니다.
searchIndexParams.FilterAddOn = "(status eq 'published' or status eq 'internal') and created ge 2025-01-01";
filter_add_on="(status eq 'published' or status eq 'internal') and created ge 2025-01-01"
{
"knowledgeSourceName": "internal-documentation-ks",
"kind": "searchIndex",
"filterAddOn": "(status eq 'published' or status eq 'internal') and created ge 2025-01-01"
}
쿼리 시간에 저장된 쿼리 힌트 재정의(미리 보기)
2026-08-01-preview API 버전부터는 검색 인덱스 지식 소스에 저장된 쿼리 힌트를 단일 retrieve 요청에 대해 해당 knowledgeSourceParams 항목에서 queryHintOverrides을(를) 설정하여 재정의할 수 있습니다.
재정의는 항목을 항목별로 병합하는 대신 저장된 queryHints 전체 개체를 대체하므로 적용하려는 모든 힌트를 포함합니다. 저장된 힌트를 사용하려면 queryHintOverrides을 생략하십시오.
검색 추론 수준이 minimal이(가) 아닌 경우, HTTP 400 응답은 재정의 내용이나 부스트 종류가 아니라 저장된 필터 힌트에 따라 달라집니다. 서비스는 적용하기 전에 기술 자료 모델에 대해 저장된 필터 힌트의 유효성을 검사합니다 queryHintOverrides. 따라서 GPT-4o 또는 GPT-4.1 계열 모델은 재정의가 비어 있거나 부스트만 포함하는 경우에도 해당 요청을 거부합니다. 저장된 부스트만으로는 이 유효성 검사가 트리거되지 않습니다. 호환되는 모델을 사용하거나 저장된 필터 힌트를 먼저 제거합니다.
다음 예제에서는 저장된 모든 힌트를 일본어 콘텐츠에 대한 하나의 fieldValue 부스트로 바꿉니다. 이 서비스는 저장된 필터 또는 기타 저장된 부스트를 이 요청에 적용하지 않습니다.
using System;
using Azure.Identity;
using Azure.Search.Documents.Indexes.Models;
using Azure.Search.Documents.KnowledgeBases;
using Azure.Search.Documents.KnowledgeBases.Models;
var endpoint = new Uri("<search-endpoint>");
var retrievalClient = new KnowledgeBaseRetrievalClient(
endpoint,
"product-kb",
new DefaultAzureCredential());
var languageBoost =
new SearchIndexKnowledgeSourceFieldValueBoost(
"language",
2.0);
languageBoost.FieldValues.Add("ja-JP");
var queryHintOverrides =
new SearchIndexKnowledgeSourceQueryHints();
queryHintOverrides.Boosts.Add(languageBoost);
var request = new KnowledgeBaseRetrievalRequest
{
RetrievalReasoningEffort =
new KnowledgeRetrievalLowReasoningEffort(),
IncludeActivity = true
};
request.Messages.Add(
new KnowledgeBaseMessage([
new KnowledgeBaseMessageTextContent(
"Find Japanese service guidance for Model-X200.")
])
{
Role = "user"
});
request.KnowledgeSourceParams.Add(
new SearchIndexKnowledgeSourceParams(
"product-docs-ks")
{
QueryHintOverrides = queryHintOverrides
});
var result = await retrievalClient.RetrieveAsync(request);
참조:KnowledgeBaseRetrievalClient, SearchIndexKnowledgeSourceParams
from azure.identity import DefaultAzureCredential
from azure.search.documents.indexes.models import (
SearchIndexKnowledgeSourceFieldValueBoost,
SearchIndexKnowledgeSourceQueryHints,
)
from azure.search.documents.knowledgebases import (
KnowledgeBaseRetrievalClient,
)
from azure.search.documents.knowledgebases.models import (
KnowledgeBaseMessage,
KnowledgeBaseMessageTextContent,
KnowledgeBaseRetrievalRequest,
KnowledgeRetrievalLowReasoningEffort,
SearchIndexKnowledgeSourceParams,
)
retrieval_client = KnowledgeBaseRetrievalClient(
endpoint="<search-endpoint>",
credential=DefaultAzureCredential(),
knowledge_base_name="product-kb",
)
query_hint_overrides = SearchIndexKnowledgeSourceQueryHints(
boosts=[
SearchIndexKnowledgeSourceFieldValueBoost(
field="language",
field_values=["ja-JP"],
boost=2.0,
)
]
)
request = KnowledgeBaseRetrievalRequest(
messages=[
KnowledgeBaseMessage(
role="user",
content=[
KnowledgeBaseMessageTextContent(
text="Find Japanese service guidance for Model-X200."
)
],
)
],
knowledge_source_params=[
SearchIndexKnowledgeSourceParams(
knowledge_source_name="product-docs-ks",
query_hint_overrides=query_hint_overrides,
)
],
retrieval_reasoning_effort=(
KnowledgeRetrievalLowReasoningEffort()
),
include_activity=True,
)
result = retrieval_client.retrieve(request)
참조:KnowledgeBaseRetrievalClient, SearchIndexKnowledgeSourceParams
POST {{search-endpoint}}/knowledgebases('product-kb')/retrieve?api-version=2026-08-01-preview
Content-Type: application/json
Authorization: Bearer {{search-access-token}}
{
"messages": [{
"role": "user",
"content": [{
"type": "text",
"text": "Find Japanese service guidance for Model-X200."
}]
}],
"knowledgeSourceParams": [{
"knowledgeSourceName": "product-docs-ks",
"kind": "searchIndex",
"queryHintOverrides": {
"boosts": [{
"kind": "fieldValue",
"field": "language",
"fieldValues": ["ja-JP"],
"boost": 2.0
}]
}
}],
"retrievalReasoningEffort": {"kind": "low"},
"includeActivity": true
}
참조:지식 검색 - 검색
서비스가 재정의를 적용했는지 확인하려면 요청에 includeActivity를 설정하고 반환된 searchIndex 활동을 검사합니다. 해당 개체는 queryHintProcessing 모델이 생성한 내용을 보고합니다. 이 예제에는 언어 부스트용 generatedBoost는 포함되어 있지만, 재정의가 저장된 필터 힌트를 대체했기 때문에 generatedFilter는 없습니다. 쿼리 힌트가 가장 적합하기 때문에 정확한 식을 확인하는 대신 이 작업을 확인으로 처리합니다.
{
"type": "searchIndex",
"queryHintProcessing": {
"generatedBoost": "language:(ja\\-JP)^2"
},
"searchIndexArguments": {
"queryType": "full"
}
}
저장된 정의, 지원되는 힌트 형식 및 결정적 필터가 있는 컴퍼지션은 쿼리 힌트 구성(미리 보기)을 참조하세요.
쿼리 시 사용 권한 적용(미리 보기)
2026-08-01-preview 외부에서 설정한 액세스 권한의 변경 사항이 2026-08-01-preview 검색 결과에 반영되기까지 시간이 걸릴 수 있습니다.
지식 원본에 권한으로 보호된 콘텐츠가 포함된 경우 각 사용자가 액세스 권한이 부여된 콘텐츠만 볼 수 있도록 검색 요청에 최종 사용자의 ID를 전달합니다. 인덱싱된 원본의 경우 검색 엔진은 이 ID를 사용하여 결과를 필터링하고 필터링되지 않은 결과를 생략하면 반환합니다. 또한 원격 원본은 검색 요청의 권한 부여를 사용하지만 원본에서 권한을 적용하며 원본별 토큰 및 헤더가 필요할 수 있습니다.
권한 적용에는 다음 두 부분으로 구성됩니다.
수집 시간: 인덱싱된 기술 원본의 경우에만 콘텐츠와 함께 사용 권한 메타데이터를 수집하도록 설정합니다
ingestionPermissionOptions.쿼리 시간: 기술 소스에 필요한 헤더에 사용자의 권한 부여를 전달합니다. 대부분의 원본은 .를 사용합니다
x-ms-query-source-authorization. 예외는x-ms-query-work-iq-source-authorization를 사용하는 Work IQ입니다.
수집 시간 구성
다음 표에서는 수집 시간 구성이 필요한 지식 원본과 각 원본이 사용 권한을 적용하는 방법을 보여 줍니다.
| 기술 자료 | 필요 ingestionPermissionOptions |
사용 권한 적용 방법 |
|---|---|---|
| Blob 또는 ADLS Gen2 | ✅ | 사용자 ID와 일치하는 RBAC 범위, ACL 또는 Microsoft Purview를 수집합니다. |
| OneLake | ✅ | 수집된 문서의 Microsoft Purview 민감도 레이블을 사용자 ID를 기준으로 대조합니다. |
| 인덱스된 SharePoint | ✅ | 사용자 ID와 일치하는 SharePoint ACL 또는 Microsoft Purview 민감도 레이블을 수집합니다. |
| 원격 SharePoint | ❌ | Copilot 검색 API는 사용자의 토큰을 사용하여 SharePoint API를 직접 쿼리합니다. |
| Fabric 데이터 에이전트 | ❌ | 검색 엔진은 사용자의 토큰을 Microsoft Fabric 범위가 지정된 토큰으로 교환하고 데이터 에이전트를 대신하여 쿼리합니다. |
| Fabric 온톨로지 | ❌ | 검색 엔진은 사용자의 토큰을 Microsoft Fabric 범위가 지정된 토큰으로 교환하고 대신 온톨로지 항목을 쿼리합니다. |
| 업무 지능 | ❌ | 검색 엔진은 x-ms-query-work-iq-source-authorization에서 앱 대상 사용자 어설션을 Work IQ 범위의 토큰으로 교환합니다. |
인덱싱된 기술 자료를 만들 때 구성 ingestionPermissionOptions 하지 않으면 인덱스가 권한 메타데이터를 포함하지 않습니다. 시스템은 헤더에 관계없이 필터링되지 않은 결과를 반환합니다. 이 문제를 해결하려면 적절한 ingestionPermissionOptions 값을 사용하여 기술 원본을 다시 만듭니다.
쿼리 시간 권한 부여
Work IQ가 아닌 지식 소스의 경우 retrieve 요청에 https://search.azure.com/.default 범위로 지정된 액세스 토큰을 포함하여 최종 사용자의 신원을 전달합니다. 이 토큰은 검색 서비스에 액세스하는 데 사용되는 서비스 자격 증명과는 별개입니다. 검색 서비스 권한이 필요하지 않으며 콘텐츠 액세스가 평가되는 사용자만 나타냅니다. 자세한 내용은 쿼리 시간 ACL 및 RBAC 적용을 참조하세요.
Work IQ 기술 자료의 경우 이 섹션은 적용되지 않습니다. 쿼리 시 권한 적용에 설명된 작업 IQ 관련 사용자 어설션 흐름을 사용합니다.
.NET SDK에서 토큰을 querySourceAuthorizationRetrieveAsync 매개 변수로 전달합니다.
using Azure;
using Azure.Identity;
using Azure.Search.Documents.KnowledgeBases;
using Azure.Search.Documents.KnowledgeBases.Models;
// Service credential: Authenticates to the search service
var serviceCredential = new DefaultAzureCredential();
// User identity token: Represents the end user for document-level permissions filtering
var userTokenContext = new Azure.Core.TokenRequestContext(
new[] { "https://search.azure.com/.default" }
);
string userToken = (await serviceCredential.GetTokenAsync(userTokenContext)).Token;
// Create the retrieval client with the service credential
var kbClient = new KnowledgeBaseRetrievalClient(
endpoint: new Uri("<search-endpoint>"),
knowledgeBaseName: "<knowledge-base-name>",
credential: serviceCredential
);
var request = new KnowledgeBaseRetrievalRequest();
request.Messages.Add(
new KnowledgeBaseMessage(
content: new[] {
new KnowledgeBaseMessageTextContent(
"What companies are in the financial sector?")
}
) { Role = "user" }
);
// Pass the user identity token for permissions filtering
var result = await kbClient.RetrieveAsync(
request, querySourceAuthorization: userToken);
var text = (result.Value.Response[0].Content[0] as KnowledgeBaseMessageTextContent)!.Text;
Console.WriteLine(text);
참조:KnowledgeBaseRetrievalClient, KnowledgeBaseRetrievalRequest
Python SDK에서 토큰을 query_source_authorizationretrieve 매개 변수로 전달합니다.
from azure.identity import DefaultAzureCredential, get_bearer_token_provider
from azure.search.documents.knowledgebases import KnowledgeBaseRetrievalClient
from azure.search.documents.knowledgebases.models import (
KnowledgeBaseMessage, KnowledgeBaseMessageTextContent,
KnowledgeBaseRetrievalRequest,
)
# Service credential: Authenticates to the search service
service_credential = DefaultAzureCredential()
# User identity token: Represents the end user for document-level permissions filtering
user_token_provider = get_bearer_token_provider(
service_credential, "https://search.azure.com/.default")
user_token = user_token_provider()
# Create the retrieval client with the service credential
kb_client = KnowledgeBaseRetrievalClient(
endpoint="<search-endpoint>",
knowledge_base_name="<knowledge-base-name>",
credential=service_credential,
)
request = KnowledgeBaseRetrievalRequest(
messages=[
KnowledgeBaseMessage(
role="user",
content=[KnowledgeBaseMessageTextContent(
text="What companies are in the financial sector?")],
)
]
)
# Pass the user identity token for permissions filtering
result = kb_client.retrieve(
retrieval_request=request, query_source_authorization=user_token)
print(result.response[0].content[0].text)
참조:KnowledgeBaseRetrievalClient, KnowledgeBaseRetrievalRequest
REST API에 사용자의 액세스 토큰이 포함된 헤더를 포함합니다 x-ms-query-source-authorization .
@search-endpoint = <search-endpoint>
@search-access-token = <search-access-token> // Service credential
@user-access-token = <user-access-token> // User identity token
POST {{search-endpoint}}/knowledgebases/{{knowledge-base-name}}/retrieve?api-version=2026-08-01-preview
Authorization: Bearer {{search-access-token}}
Content-Type: application/json
x-ms-query-source-authorization: {{user-access-token}}
{
"messages": [
{
"role": "user",
"content": [
{
"type": "text",
"text": "What companies are in the financial sector?"
}
]
}
]
}
참조:지식 검색 - 검색
응답 검토
검색 작업은 세 가지 주요 구성 요소를 반환합니다.
- 추출된 응답 또는 합성된 응답(미리 보기)( 출력 모드에 따라 다름)
- 활동 배열
- 참조 배열
추출된 응답
추출된 응답은 일반적으로 LLM에 전달하는 단일 통합 문자열입니다. LLM은 문자열을 접지 데이터로 사용하고 이를 사용하여 응답을 작성합니다. LLM에 대한 API 호출에는 접지 전용 또는 추가 기능으로 사용할지 여부와 같은 모델에 대한 통합 문자열 및 지침이 포함됩니다.
응답 본문은 채팅 메시지 스타일 형식으로 구성되며 콘텐츠는 JSON으로 직렬화됩니다.
"response": [
{
"role": "assistant",
"content": [
{
"type": "text",
"text": "[{\"ref_id\":\"0\",\"title\":\"Urban Structure\",\"terms\":\"Location of Phoenix, Grid of City Blocks, Phoenix Metropolitan Area at Night\",\"content\":\"<content chunk redacted>\"}]"
}
]
}
]
핵심 사항:
content.type유효한 값이 하나 있습니다text.content.text는 쿼리 및 채팅 기록 입력을 고려할 때 검색 인덱스에 있는 가장 관련성이 큰 문서(또는 청크)를 포함하는 JSON으로 인코딩된 문자열입니다. 이 문자열은 LLM이 사용자의 질문에 대한 응답을 작성하는 데 사용하는 기반 데이터입니다.응답의 이 부분은 200개 이하의 청크로 구성되며, 2.5 재랜커 점수의 최소 임계값을 충족하지 못하는 결과는 제외됩니다.
문자열은 청크의 참조 ID(인용 용도로 사용됨) 및 대상 인덱스의 의미 체계 구성에 지정된 모든 필드로 시작합니다. 이 예제에서는 대상 인덱스의 의미 체계 구성에 "제목" 필드, "용어" 필드 및 "콘텐츠" 필드가 있다고 가정합니다.
검색 결과 응답에는
@search.rerankerBoostedScore포함되지 않습니다.maxOutputSizeInTokens검색 요청의 속성(maxOutputSize이상2026-05-01-preview)은 문자열의 길이를 결정합니다.- 출력 예산을 초과하는
maxOutputSizeInTokens문서는 응답에서 생략할 수 있습니다. 작업 배열에는 가장 관련성이 큰 문서가 최대 출력 크기를 초과하는 경우 경고가 포함됩니다. 더 많은 콘텐츠를 유지하려면maxOutputSizeInTokens를 늘리세요. 자세한 내용은 빈 응답을 참조하세요.
- 출력 예산을 초과하는
활동 어레이
작업 배열은 추적 작업, 청구 의미 및 리소스 호출에 대한 운영 투명성을 제공하는 쿼리 계획을 출력합니다. 또한 검색 파이프라인으로 전송된 하위 쿼리도 포함됩니다.
206 Partial Content 응답의 경우 배열에는 실패한 지식 소스에 대한 오류가 포함됩니다. 응답은 502 Bad Gateway 최상위 오류에서만 오류 세부 정보를 제공할 수 있습니다.
활동 배열에는 다음 구성 요소가 포함됩니다.
| 섹션 | 설명 |
|---|---|
| 소스별 활동 | 쿼리에 포함된 각 지식 원본에 대해 이 섹션에서는 경과된 시간과 의미 체계 순위자를 포함하여 쿼리에 사용된 인수를 보고합니다. 지식 원본 유형에는 searchIndex, azureBlob, 및 기타 지원되는 지식 원본이 포함됩니다. |
agenticReasoning |
이 섹션에서는 지정된 검색 추론 작업(미리 보기)에 따라 검색하는 동안 에이전트 추론에 대한 토큰 사용량을 보고합니다. |
modelQueryPlanning |
쿼리 계획에 LLM을 사용하는 기술 자료의 경우 이 섹션에서는 입력에 사용되는 토큰 수와 하위 쿼리에 대한 토큰 수를 보고합니다. 여기에는 활동을 실행한 모델의 배포 이름이 아니라 공용 모델 이름을 포함하는 model 필드가 있는 modelName 필드가 포함됩니다. |
modelAnswerSynthesis |
답변 합성(미리 보기)을 사용하는 기술 자료의 경우 이 섹션에서는 대답을 작성하기 위한 토큰 수와 응답 출력의 토큰 수를 보고합니다. 여기에는 활동을 실행한 모델의 배포 이름이 아니라 공용 모델 이름을 포함하는 model 필드가 있는 modelName 필드가 포함됩니다. |
modelWebSummarization |
웹 요약을 사용하는 기술 자료의 경우 이 섹션에서는 웹 결과를 요약하기 위한 토큰 사용량을 보고합니다. 여기에는 활동을 실행한 모델의 배포 이름이 아니라 공용 모델 이름을 포함하는 model 필드가 있는 modelName 필드가 포함됩니다. |
model |
모델 지원 활동 레코드의 경우 이 섹션에서는 활동을 수행하는 데 사용되는 모델을 식별합니다. 이 섹션은 includeActivity을(를) true로 설정한 경우에만 표시됩니다. |
imageServing |
이미지 제공(미리 보기)이 사용 설정된 지식 원본의 경우, 이 섹션에는 verbalizationUsed, imagesRetrieved, imagesSentToModel, 그리고 인덱싱 시점의 totalImageSizeBytes가 켜져 있었는지 여부가 보고됩니다.
imagesSentToModel 및 verbalizationUsed를 각각 검사합니다. 응답은 verbalizationUsed를 true로 보고하면서도 여전히 이미지를 다운스트림 모델로 보낼 수 있습니다. 삭제된 이미지 수를 확인하려면 imagesSentToModel에서 imagesRetrieved를 빼세요. |
다음 예제에서는 활동 배열을 보여줍니다.
"activity": [
{
"type": "modelQueryPlanning",
"id": 0,
"inputTokens": 2302,
"outputTokens": 109,
"elapsedMs": 2396
},
{
"type": "searchIndex",
"id": 1,
"knowledgeSourceName": "demo-financials-ks",
"queryTime": "2025-11-04T19:25:23.683Z",
"count": 26,
"elapsedMs": 1137,
"searchIndexArguments": {
"search": "List of companies in the financial sector according to SEC GICS classification",
"filter": null,
"sourceDataFields": [ ],
"searchFields": [ ],
"semanticConfigurationName": "en-semantic-config"
}
},
{
"type": "searchIndex",
"id": 2,
"knowledgeSourceName": "demo-healthcare-ks",
"queryTime": "2025-11-04T19:25:24.186Z",
"count": 17,
"elapsedMs": 494,
"searchIndexArguments": {
"search": "List of companies in the financial sector according to SEC GICS classification",
"filter": null,
"sourceDataFields": [ ],
"searchFields": [ ],
"semanticConfigurationName": "en-semantic-config"
}
},
{
"type": "agenticReasoning",
"id": 3,
"retrievalReasoningEffort": {
"kind": "low"
},
"reasoningTokens": 103368
},
{
"type": "modelAnswerSynthesis",
"id": 4,
"inputTokens": 5821,
"outputTokens": 344,
"elapsedMs": 3837
}
]
참조 배열
참조 배열은 기본 접지 데이터에서 직접 제공됩니다. 응답을 생성하는 데 사용되는 항목 sourceData이 포함되며 에이전트형 검색 엔진이 찾아 의미적으로 랭킹하는 모든 문서로 구성됩니다.
참조 배열에는 다음 구성 요소가 포함됩니다.
| Field | 설명 |
|---|---|
type |
참조를 생성한 기술 자료 형식입니다(예: searchIndex.). |
id |
응답 내의 항목에 대한 참조 ID입니다. 검색 인덱스의 문서 키가 아닙니다. 인용을 제공하는 데 사용합니다. |
activitySource |
참조를 생성한 활동 항목의 id을 상호 참조하며, 이는 인용 링크에 유용합니다. |
docKey |
인덱싱된 참조의 경우 백업 검색 인덱스 내의 문서 키입니다. |
sourceData |
응답을 생성하는 데 사용되는 접지 데이터입니다. 인덱싱된 참조의 경우 필드에는 title 및 terms, content, id와 같은 시맨틱 필드가 포함될 수 있습니다. 도형은 참조 형식에 따라 다릅니다. |
citationUrl (미리 보기) |
서비스에서 생성된 읽기 전용 URL로, 백엔드 인덱스에 있는 참조 문서를 가리킵니다. 인덱싱된 기술 원본에 대해서만 반환됩니다. URL을 따르려면 인용 URL(미리 보기)을 사용하여 문서 조회를 참조하세요. |
다음 예제에서는 참조 배열을 보여 줍니다.
"references": [
{
"type": "searchIndex",
"id": "0",
"activitySource": 2,
"docKey": "policy=aug-2026",
"citationUrl": "https://my-search-service.search.windows.net/indexes/my-index/docs/policy%3Daug-2026?$select=title%2Ccontent%2Ccategory%2Cid%2Clanguage&api-version=2026-08-01-preview",
"sourceData": null
},
{
"type": "searchIndex",
"id": "1",
"activitySource": 2,
"docKey": "2",
"citationUrl": "https://my-search-service.search.windows.net/indexes/my-index/docs/2?$select=title%2Ccontent%2Ccategory%2Cid%2Clanguage&api-version=2026-08-01-preview",
"sourceData": null
}
]
인용 URL이 있는 문서 조회(미리 보기)
2026-08-01-preview API 버전부터 인덱싱된 지식 소스의 참조는 retrieve 응답에 citationUrl를 포함할 수 있습니다. 이 URL을 사용하여 원본 원본 문서를 열지 않고 대답의 출처를 보여 주는 인용 미리 보기를 렌더링할 수 있도록 해당 참조 titlecontent에 대한 인덱싱된 필드를 가져옵니다.
citationUrl는 소스 docUrl 및 blobUrl와는 별개로, 기반 인덱스에 대해 인증된 조회입니다.
다음 예제에서는 정제된 인용 URL을 보여줍니다.
"citationUrl": "https://my-search-service.search.windows.net/indexes/my-index/docs/policy%3Daug-2026?$select=title%2Ccontent%2Ccategory%2Cid%2Clanguage&api-version=2026-08-01-preview"
선택한 필드와 해당 순서는 인덱싱된 원본 및 검색 구성에 따라 달라집니다.
중요
응답 축자의 전체 URL을 따르고 앱에서 반환된 JSON 필드를 렌더링합니다. URL을 생성, 구문 분석 또는 정규화하지 마세요.
인용 URL이 지정된 경우 다음 예제에서는 검색 서비스에 대한 액세스 토큰을 가져옵니다. 헤더에서 해당 토큰을 사용하여 URL을 호출합니다 Authorization . 로그인한 ID에는 검색 인덱스 데이터 판독기 역할이 필요합니다.
Azure AI 검색 SDK 문서 조회 메서드에는 엔드포인트, 인덱스 이름, 문서 키, 선택한 필드 및 API 버전이 별도의 입력으로 필요합니다. 절대 인용 URL은 허용하지 않습니다. 이러한 예제에서는 인증된 HTTP GET을 사용하여 전체 서비스 생성 URL을 유지합니다.
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using Azure.Core;
using Azure.Identity;
// citationUrl comes from a retrieve response
string citationUrl = "<citation-url>";
var credential = new DefaultAzureCredential();
AccessToken token = await credential.GetTokenAsync(
new TokenRequestContext(
new[] { "https://search.azure.com/.default" }));
using var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", token.Token);
string document = await httpClient.GetStringAsync(citationUrl);
Console.WriteLine(document);
import json
from urllib.request import Request, urlopen
from azure.identity import DefaultAzureCredential
# citation_url comes from a retrieve response
citation_url = "<citation-url>"
credential = DefaultAzureCredential()
token = credential.get_token("https://search.azure.com/.default")
document_request = Request(
citation_url,
headers={"Authorization": f"Bearer {token.token}"},
)
with urlopen(document_request) as response:
document = json.load(response)
print(json.dumps(document, indent=2))
GET {{citation-url}}
Authorization: Bearer {{search-access-token}}
참조:문서 - 가져오기
문서 조회는 선택한 인덱스 필드를 JSON으로 반환합니다.
{
"id": "policy=aug-2026",
"title": "Escaped citation key",
"content": "Citation interoperability uses an escaped document key for the August preview.",
"category": "release",
"language": "en-US"
}
인용 URL을 사용하는 경우 다음 사항에 유의하세요.
인용을 렌더링하기 전에
citationUrl가 있는지 확인하세요. 응답이 참조를 생략하거나 서비스에서 지원 인덱스 또는 문서 키를 확인할 수 없는 경우 이 속성이 없을 수 있습니다.검색 요청에 문서 수준 액세스 제어가 포함된
x-ms-query-source-authorization경우 URL을 따를 때 동일한 사용자 토큰을 사용합니다.URL은 지원 인덱스 및 문서 키가 변경되지 않은 상태로 유지되는 동안에만 유효합니다.
응답에서 민감도 레이블 메타데이터 검사(미리 보기)
쿼리 시 권한 적용에 설명된 것과 동일한 시점 관련 동작이 여기에도 적용됩니다. 2026-08-01-preview 외부에서 설정한 액세스 권한의 변경 사항이 2026-08-01-preview 검색 응답에 반영되기까지 시간이 걸릴 수 있습니다.
Microsoft Purview 민감도 레이블 수집하는 기술 자료를 쿼리할 때 검색 응답에는 다음 두 가지 수준의 레이블 메타데이터가 포함됩니다.
| 위치 | Field | 설명 |
|---|---|---|
| 참조별 | sensitivityLabelInfo |
배열에서 반환된 각 문서에 적용된 민감도 레이블입니다 references . |
| 응답 | metadata.responseSensitivityLabelInfo |
응답에서 참조된 모든 문서에서 우선 순위가 가장 높은 민감도 레이블을 나타내는 집계 레이블입니다. 클라이언트 쪽 표시 배너 및 정책 적용에 유용합니다. |
Microsoft Graph Microsoft Purview 레이블 상속 규칙 사용하여 참조별 레이블에서 응답 수준 레이블을 계산합니다. 일반적으로 가장 제한적인 레이블이 우선합니다.
다음 예에서는 두 개의 참조 문서(하나는 Confidential, 다른 하나는 Internal)가 포함된 검색 응답과 그에 따른 응답 수준 레이블을 보여 줍니다.
{
"response": [
{
"role": "assistant",
"content": [
{ "type": "text", "text": "[ ... grounding data ... ]" }
]
}
],
"references": [
{
"type": "azureBlob",
"id": "0",
"activitySource": 1,
"docKey": "contract-2026.pdf",
"sensitivityLabelInfo": {
"labelId": "<label-guid>",
"labelName": "Confidential",
"color": "#FF0000",
"tooltip": "Confidential — Recipients can read but not forward.",
"isEncrypted": true,
"priority": 3
},
"sourceData": null
},
{
"type": "azureBlob",
"id": "1",
"activitySource": 1,
"docKey": "policy-overview.pdf",
"sensitivityLabelInfo": {
"labelId": "<label-guid>",
"labelName": "Internal",
"color": "#FFA500",
"tooltip": "For internal use only.",
"isEncrypted": false,
"priority": 1
},
"sourceData": null
}
],
"metadata": {
"responseSensitivityLabelInfo": {
"labelId": "<label-guid>",
"labelName": "Confidential",
"color": "#FF0000",
"tooltip": "Confidential — Recipients can read but not forward.",
"isEncrypted": true,
"priority": 3
}
}
}
민감도 레이블이 표시되는 참조 유형
레이블 메타데이터의 필드 이름 및 가용성은 각 참조를 생성한 기술 자료 유형에 따라 달라집니다.
참조 type |
레이블 필드 | 다음 경우에 사용할 수 있습니다... |
|---|---|---|
azureBlob |
sensitivityLabelInfo |
Blob 지식 원본에는 sensitivityLabel의 ingestionPermissionOptions가 포함됩니다. |
indexedOneLake |
sensitivityLabelInfo |
OneLake 지식 원본에는 sensitivityLabel에 있는 ingestionPermissionOptions이 포함됩니다. |
indexedSharePoint |
sensitivityLabelInfo |
SharePoint 인덱싱된 기술 자료에는 sensitivityLabelingestionPermissionOptions 포함됩니다. |
searchIndex |
sensitivityLabelInfo |
기본 인덱스에는 purviewEnabled이(가) true로 설정되어 있고 sensitivityLabel: true로 표시된 필드가 있습니다. |
권장사항 표시 및 감사
정책 컨트롤 또는 사용 권한과 같은 추가 속성이 필요한 경우
sensitivityLabelInfo.labelId사용하여 Microsoft Graph 민감도 레이블 API 통해 전체 레이블 정의를 조회합니다.응답 수준 민감도 배너를 렌더링하거나 응답 전체에서 복사 및 공유를 사용하지 않도록 설정하는 것과 같은 정책 컨트롤을 적용하는 데 사용합니다
metadata.responseSensitivityLabelInfo.지식 원본이 통합 벡터화 또는 사용자 지정 텍스트 분할 기술을 통해 채워진 인덱스와 같은 청크 인덱스를 가리키는 경우 기술 세트가 각 청크 행에 민감도 레이블을 투영하는지 확인합니다. 이 매핑이 없으면 청크 수준 참조가 쿼리 시간에 올바르게 필터링되지 않습니다.
레이블이 지정된 콘텐츠에 대한 감사 가능한 관리자 액세스에 대해서는 관리 조사를 위한 상승된 읽기 권한을 참조하세요.
MCP 서버 동작
각 기술 자료에 의해 노출되는 MCP 엔드포인트는 REST API와 동일한 민감도 레이블 필드를 표시합니다. MCP 호환 클라이언트가 도구를 호출 knowledge_base_retrieve 할 때 도구 결과에는 이 섹션의 앞부분에서 설명한 것과 동일한 참조 sensitivityLabelInfo 및 응답 수준이 metadata.responseSensitivityLabelInfo 포함됩니다. MCP 클라이언트는 이러한 필드를 기반으로 레이블 인식 표시 및 정책 제어를 적용합니다.
작업 예제 검색(미리 보기)
다음 예제에서는 API 버전을 사용하여 검색 작업을 호출하는 2026-08-01-preview 다양한 방법을 보여 줍니다. 이 버전은 응답 합성 및 구성 가능한 추론 작업을 포함하여 전체 기능 집합을 지원합니다. 사용법은 2026-04-01 이전 섹션을 참조하세요.
- 활동 로그에서 모델 이름 검사
- 성공하려면 기술 자료 필요
- 요청에서 기술 원본 제외
- 기술 자료별 후보 문서 조정
- 최종 접지 문서 제한
- 지식 베이스 검색 기본값 확인
- 기본 추론 작업 재정의 및 요청 제한 설정
- 서비스에서 추론 작업을 선택하도록 허용
- 각 기술 원본에 대한 참조 설정
- 최소한의 추론 작업 사용
활동 로그에서 모델 이름 검사
모델 기반 활동 레코드에서 모델 식별 필드를 반환하려면 true를 includeActivity로 설정합니다. 이러한 필드를 사용하여 검색 요청 중에 쿼리 계획, 응답 합성 또는 웹 요약을 처리한 구성된 모델을 확인합니다. 다음 예제에서는 요청에서 선택한 원본에 대해 저장된 결과 처리를 재정의합니다.
using Azure.Identity;
using Azure.Search.Documents.Indexes.Models;
using Azure.Search.Documents.KnowledgeBases;
using Azure.Search.Documents.KnowledgeBases.Models;
var kbClient = new KnowledgeBaseRetrievalClient(
new Uri("<search-endpoint>"),
"<knowledge-base-name>",
new DefaultAzureCredential()
);
var retrievalRequest = new KnowledgeBaseRetrievalRequest();
retrievalRequest.Messages.Add(
new KnowledgeBaseMessage(
content: new[]
{
new KnowledgeBaseMessageTextContent(
"Which policy applies to returns?"
)
}
) { Role = "user" }
);
retrievalRequest.IncludeActivity = true;
retrievalRequest.KnowledgeSourceParams.Add(
new SearchIndexKnowledgeSourceParams(
"<knowledge-source-name>"
)
{
ResultsProcessing = KnowledgeSourceResultsProcessing.None
}
);
var result = await kbClient.RetrieveAsync(retrievalRequest);
foreach (var activity in result.Value.Activity)
{
KnowledgeBaseActivityRecordModel? model = activity switch
{
KnowledgeBaseModelQueryPlanningActivityRecord queryPlanning =>
queryPlanning.Model,
KnowledgeBaseModelAnswerSynthesisActivityRecord answerSynthesis =>
answerSynthesis.Model,
KnowledgeBaseModelWebSummarizationActivityRecord webSummarization =>
webSummarization.Model,
_ => null
};
if (model is not null)
{
Console.WriteLine(
$"modelName={model.ModelName}, deploymentId={model.DeploymentId}");
}
}
참조:KnowledgeBaseRetrievalClient, KnowledgeBaseRetrievalRequest
from azure.identity import DefaultAzureCredential
from azure.search.documents.knowledgebases import (
KnowledgeBaseRetrievalClient,
)
from azure.search.documents.knowledgebases.models import (
KnowledgeBaseMessage,
KnowledgeBaseMessageTextContent,
KnowledgeBaseModelAnswerSynthesisActivityRecord,
KnowledgeBaseModelQueryPlanningActivityRecord,
KnowledgeBaseModelWebSummarizationActivityRecord,
KnowledgeBaseRetrievalRequest,
SearchIndexKnowledgeSourceParams,
)
kb_client = KnowledgeBaseRetrievalClient(
"<search-endpoint>",
DefaultAzureCredential(),
knowledge_base_name="<knowledge-base-name>",
)
model_activity_types = (
KnowledgeBaseModelQueryPlanningActivityRecord,
KnowledgeBaseModelAnswerSynthesisActivityRecord,
KnowledgeBaseModelWebSummarizationActivityRecord,
)
request = KnowledgeBaseRetrievalRequest(
messages=[
KnowledgeBaseMessage(
role="user",
content=[
KnowledgeBaseMessageTextContent(
text="Which policy applies to returns?"
)
],
)
],
include_activity=True,
knowledge_source_params=[
SearchIndexKnowledgeSourceParams(
knowledge_source_name="<knowledge-source-name>",
results_processing="none",
)
],
)
result = kb_client.retrieve(request)
for entry in result.activity or []:
if isinstance(entry, model_activity_types) and entry.model:
print(
"modelName=", entry.model.model_name,
"deploymentId=", entry.model.deployment_id,
)
참조:KnowledgeBaseRetrievalClient, KnowledgeBaseRetrievalRequest
POST {{search-endpoint}}/knowledgebases/{{knowledge-base-name}}/retrieve?api-version=2026-08-01-preview
Authorization: Bearer {{search-access-token}}
Content-Type: application/json
{
"messages": [
{
"role": "user",
"content": [
{ "type": "text", "text": "Which policy applies to returns?" }
]
}
],
"includeActivity": true,
"knowledgeSourceParams": [
{
"knowledgeSourceName": "{{knowledge-source-name}}",
"kind": "searchIndex",
"resultsProcessing": "none"
}
]
}
참조:지식 검색 - 검색
다음 응답 발췌에서는 중첩된 모델 ID를 보여 있습니다.
{
"activity": [
{
"type": "modelQueryPlanning",
"id": 0,
"model": {
"modelName": "gpt-5-mini",
"deploymentId": "gpt-5-mini-deployment"
},
"inputTokens": 1842,
"outputTokens": 87,
"elapsedMs": 1923
},
{
"type": "searchIndex",
"id": 1,
"knowledgeSourceName": "operations-ks",
"count": 12,
"elapsedMs": 234
},
{
"type": "modelAnswerSynthesis",
"id": 2,
"model": {
"modelName": "gpt-5-mini",
"deploymentId": "gpt-5-mini-deployment"
},
"inputTokens": 2418,
"outputTokens": 179,
"elapsedMs": 931
}
]
}
성공하려면 기술 자료 필요
failOnError에서 knowledgeSourceParams을 필수로 설정하여 지식 소스를 필수 항목으로 표시합니다. 원본을 사용할 수 없는 경우 부분 답변이 오해의 소지가 있거나 비준수인 경우 이 매개 변수를 사용합니다. 요청은 다른 원본이 성공하더라도 필요한 원본이 실패하는 경우 반환 502 Bad Gateway 됩니다. 처리 지침은 검색 작업 문제 해결을 참조하세요.
var retrievalRequest = new KnowledgeBaseRetrievalRequest();
retrievalRequest.Messages.Add(
new KnowledgeBaseMessage(
content: new[] {
new KnowledgeBaseMessageTextContent("Which HR policy applies?")
}
) { Role = "user" }
);
retrievalRequest.KnowledgeSourceParams.Add(
new SearchIndexKnowledgeSourceParams("hr-policy-ks")
{
FailOnError = true,
AlwaysQuerySource = true
}
);
retrievalRequest.KnowledgeSourceParams.Add(
new SearchIndexKnowledgeSourceParams("hr-faq-ks")
);
var result = await kbClient.RetrieveAsync(retrievalRequest);
request = KnowledgeBaseRetrievalRequest(
messages=[
KnowledgeBaseMessage(
role="user",
content=[KnowledgeBaseMessageTextContent(text="Which HR policy applies?")],
)
],
knowledge_source_params=[
SearchIndexKnowledgeSourceParams(
knowledge_source_name="hr-policy-ks",
fail_on_error=True,
always_query_source=True,
),
SearchIndexKnowledgeSourceParams(
knowledge_source_name="hr-faq-ks",
),
],
)
result = kb_client.retrieve(request)
POST {{search-endpoint}}/knowledgebases/{{knowledge-base-name}}/retrieve?api-version=2026-08-01-preview
Authorization: Bearer {{search-access-token}}
Content-Type: application/json
{
"messages": [
{
"role": "user",
"content": [
{ "type": "text", "text": "Which HR policy applies?" }
]
}
],
"knowledgeSourceParams": [
{
"knowledgeSourceName": "hr-policy-ks",
"kind": "searchIndex",
"failOnError": true,
"alwaysQuerySource": true
},
{
"knowledgeSourceName": "hr-faq-ks",
"kind": "searchIndex"
}
]
}
참조:지식 검색 - 검색
요청에서 기술 원본 제외
2026-08-01-preview API 버전부터 retrieve 요청에서 제외하려는 각 지식 소스에 대해 neverQuerySource를 true로 설정합니다. 요청 시 neverQuerySource은(는) 저장된 alwaysQuerySource 값을 해당 요청에 대해서만 재정의하며, 저장된 값은 변경하지 않습니다.
다음 예에서는 troubleshooting-ks 및 troubleshooting-ks이(가) 포함된 지식 베이스를 쿼리하며, 요청에서는 product-docs-ks을(를) 제외합니다.
var retrievalRequest = new KnowledgeBaseRetrievalRequest();
retrievalRequest.Messages.Add(
new KnowledgeBaseMessage(
content: new[] {
new KnowledgeBaseMessageTextContent(
"Explain the official SSO provisioning steps.")
}
) { Role = "user" }
);
retrievalRequest.KnowledgeSourceParams.Add(
new SearchIndexKnowledgeSourceParams("product-docs-ks")
);
retrievalRequest.KnowledgeSourceParams.Add(
new SearchIndexKnowledgeSourceParams("troubleshooting-ks")
{
NeverQuerySource = true
}
);
var result = await kbClient.RetrieveAsync(retrievalRequest);
request = KnowledgeBaseRetrievalRequest(
messages=[
KnowledgeBaseMessage(
role="user",
content=[
KnowledgeBaseMessageTextContent(
text="Explain the official SSO provisioning steps."
)
],
)
],
knowledge_source_params=[
SearchIndexKnowledgeSourceParams(
knowledge_source_name="product-docs-ks",
),
SearchIndexKnowledgeSourceParams(
knowledge_source_name="troubleshooting-ks",
never_query_source=True,
),
],
)
result = kb_client.retrieve(request)
POST {{search-endpoint}}/knowledgebases/{{knowledge-base-name}}/retrieve?api-version=2026-08-01-preview
Authorization: Bearer {{search-access-token}}
Content-Type: application/json
{
"messages": [
{
"role": "user",
"content": [
{
"type": "text",
"text": "Explain the official SSO provisioning steps."
}
]
}
],
"knowledgeSourceParams": [
{
"knowledgeSourceName": "product-docs-ks",
"kind": "searchIndex"
},
{
"knowledgeSourceName": "troubleshooting-ks",
"kind": "searchIndex",
"neverQuerySource": true
}
]
}
참조:지식 검색 - 검색
지식 소스별 후보 문서 조정
특정 지식 원본이 최종 결과를 선택하기 전에 제공할 수 있는 후보 문서 수를 제한하려면 maxOutputDocuments에서 knowledgeSourceParams을(를) 설정합니다. 다른 원본의 입력을 파이프라인에 바인딩하려는 경우 다른 원본에 영향을 주지 않고 이 매개 변수를 사용합니다.
var retrievalRequest = new KnowledgeBaseRetrievalRequest();
retrievalRequest.Messages.Add(
new KnowledgeBaseMessage(
content: new[] {
new KnowledgeBaseMessageTextContent("What safety procedures apply?")
}
) { Role = "user" }
);
retrievalRequest.KnowledgeSourceParams.Add(
new SearchIndexKnowledgeSourceParams("operations-ks")
{
MaxOutputDocuments = 50
}
);
var result = await kbClient.RetrieveAsync(retrievalRequest);
request = KnowledgeBaseRetrievalRequest(
messages=[
KnowledgeBaseMessage(
role="user",
content=[KnowledgeBaseMessageTextContent(text="What safety procedures apply?")],
)
],
knowledge_source_params=[
SearchIndexKnowledgeSourceParams(
knowledge_source_name="operations-ks",
max_output_documents=50,
),
],
)
result = kb_client.retrieve(request)
POST {{search-endpoint}}/knowledgebases/operations-kb/retrieve?api-version=2026-08-01-preview
Authorization: Bearer {{search-access-token}}
Content-Type: application/json
{
"messages": [
{
"role": "user",
"content": [
{ "type": "text", "text": "What safety procedures apply?" }
]
}
],
"knowledgeSourceParams": [
{
"knowledgeSourceName": "operations-ks",
"kind": "searchIndex",
"maxOutputDocuments": 50
}
]
}
참조:지식 검색 - 검색
최종 근거 문서 제한
최상위 maxOutputDocuments 매개 변수는 최종 검색 응답에서 반환되는 접지 문서 수를 제한합니다. 애플리케이션에 예측 가능한 인용 또는 참조 수가 필요한 경우 이 매개 변수를 사용합니다.
var retrievalRequest = new KnowledgeBaseRetrievalRequest();
retrievalRequest.Messages.Add(
new KnowledgeBaseMessage(
content: new[] {
new KnowledgeBaseMessageTextContent("What is the return policy?")
}
) { Role = "user" }
);
retrievalRequest.OutputMode = "extractedData";
retrievalRequest.MaxOutputDocuments = 3;
retrievalRequest.MaxOutputSizeInTokens = 6000;
var result = await kbClient.RetrieveAsync(retrievalRequest);
request = KnowledgeBaseRetrievalRequest(
messages=[
KnowledgeBaseMessage(
role="user",
content=[KnowledgeBaseMessageTextContent(text="What is the return policy?")],
)
],
output_mode="extractedData",
max_output_documents=3,
max_output_size_in_tokens=6000,
)
result = kb_client.retrieve(request)
POST {{search-endpoint}}/knowledgebases/{{knowledge-base-name}}/retrieve?api-version=2026-08-01-preview
Authorization: Bearer {{search-access-token}}
Content-Type: application/json
{
"messages": [
{
"role": "user",
"content": [
{ "type": "text", "text": "What is the return policy?" }
]
}
],
"outputMode": "extractedData",
"maxOutputDocuments": 3,
"maxOutputSizeInTokens": 6000
}
참조:지식 검색 - 검색
다음 표에서는 네 가지 조합에서 어떻게 상호 작용하는지를 maxOutputDocumentsmaxOutputSizeInTokens 보여 줍니다.
maxOutputDocuments |
maxOutputSizeInTokens |
Behavior |
|---|---|---|
| 지정되지 않음 | 지정되지 않음 | 기본 maxOutputSizeInTokens 응답 제한 동작을 사용합니다. |
| 지정되지 않음 | 지정됨 | 페이로드 크기 제한에 도달하면 문서를 삭제합니다. |
| 지정됨 | 지정되지 않음 | 지정된 수의 접지 문서까지 반환하며 제한을 적용 maxOutputSizeInTokens 하지 않습니다. |
| 지정됨 | 지정됨 |
maxOutputDocuments개 이하의 문서를 반환하거나, maxOutputSizeInTokens에 들어갈 수 있는 최대 개수 중 먼저 도달하는 쪽을 반환합니다. |
지식 베이스 검색 기본 설정 확인
지식 베이스는 retrieveDefaults에 요청 전체에 적용되는 기본값을 저장할 수 있습니다. 상속 및 요청별 재정의를 확인하기 위해 조회 요청 두 개를 보냅니다.
시작하기 전에 기본 검색 제한 구성(미리 보기)을 완료합니다. 첫 번째 요청은 세 개의 요청 전체 제한을 모두 생략하므로 저장된 값 45초, 문서 8개 및 토큰 12,000개가 적용됩니다. 두 번째 요청은 해당 값들을 20초, 문서 1개, 토큰 5,000개로 재정의합니다.
using System;
using Azure.Identity;
using Azure.Search.Documents;
using Azure.Search.Documents.KnowledgeBases;
using Azure.Search.Documents.KnowledgeBases.Models;
string searchEndpoint = "<search-endpoint>";
var options = new SearchClientOptions(
SearchClientOptions.ServiceVersion.V2026_08_01_Preview);
var kbClient = new KnowledgeBaseRetrievalClient(
new Uri(searchEndpoint),
"your-knowledge-base",
new DefaultAzureCredential(),
options);
KnowledgeBaseRetrievalRequest CreateRequest()
{
var request = new KnowledgeBaseRetrievalRequest();
request.Intents.Add(new KnowledgeRetrievalSemanticIntent(
"Summarize the latest support guidance."));
return request;
}
var inherited = await kbClient.RetrieveAsync(CreateRequest());
Console.WriteLine(
$"Stored defaults: {inherited.Value.References.Count} references");
KnowledgeBaseRetrievalRequest overriddenRequest = CreateRequest();
overriddenRequest.MaxRuntimeInSeconds = 20;
overriddenRequest.MaxOutputDocuments = 1;
overriddenRequest.MaxOutputSize = 5000;
var overridden = await kbClient.RetrieveAsync(overriddenRequest);
Console.WriteLine(
$"Request overrides: {overridden.Value.References.Count} references");
참조:KnowledgeBaseRetrievalClient, KnowledgeBaseRetrievalRequest
from azure.identity import DefaultAzureCredential
from azure.search.documents.knowledgebases import KnowledgeBaseRetrievalClient
from azure.search.documents.knowledgebases.models import (
KnowledgeBaseRetrievalRequest,
KnowledgeRetrievalSemanticIntent,
)
kb_client = KnowledgeBaseRetrievalClient(
endpoint="<search-endpoint>",
knowledge_base_name="your-knowledge-base",
credential=DefaultAzureCredential(),
api_version="2026-08-01-preview",
)
def create_request(**limits):
return KnowledgeBaseRetrievalRequest(
intents=[
KnowledgeRetrievalSemanticIntent(
search="Summarize the latest support guidance.",
)
],
**limits,
)
inherited = kb_client.retrieve(create_request())
print(f"Stored defaults: {len(inherited.references or [])} references")
overridden = kb_client.retrieve(
create_request(
max_runtime_in_seconds=20,
max_output_documents=1,
max_output_size=5000,
)
)
print(f"Request overrides: {len(overridden.references or [])} references")
참조:KnowledgeBaseRetrievalClient, KnowledgeBaseRetrievalRequest
먼저 세 개의 요청 전체 제한 필드를 생략하는 요청을 보냅니다.
POST {{search-endpoint}}/knowledgebases/your-knowledge-base/retrieve?api-version=2026-08-01-preview
Content-Type: application/json
Authorization: Bearer {{search-access-token}}
{
"intents": [
{
"type": "semantic",
"search": "Summarize the latest support guidance."
}
]
}
다음으로, 하나의 요청에 대해 세 값 모두를 재정의합니다.
POST {{search-endpoint}}/knowledgebases/your-knowledge-base/retrieve?api-version=2026-08-01-preview
Content-Type: application/json
Authorization: Bearer {{search-access-token}}
{
"intents": [
{
"type": "semantic",
"search": "Summarize the latest support guidance."
}
],
"maxRuntimeInSeconds": 20,
"maxOutputDocuments": 1,
"maxOutputSize": 5000
}
참조:지식 검색 - 검색
참조 개수는 저장된 값 또는 요청 수준 maxOutputDocuments 값이 적용되는지 여부를 보여 줍니다. 첫 번째 응답에는 최대 8개의 참조가 포함되고 두 번째 응답에는 최대 1개의 참조가 포함됩니다. 일치하는 문서가 적을 경우 응답에 더 적은 참조가 포함될 수 있습니다. 응답은 유효 런타임 또는 출력 토큰 예산을 보고하지 않지만 이러한 값은 여전히 요청 처리를 제어합니다. 요청 재정의는 저장된 기본값을 변경하지 않습니다.
기본 추론 작업 재정의 및 요청 제한 설정
다음 예제에서는 응답 합성을 지정하므로 검색 추론 작업은 다음과 여야 lowmedium합니다. 또한 검색 런타임을 제한하고 maxOutputSizeInTokens 응답 페이로드 크기를 제한하도록 설정합니다maxRuntimeInSeconds.
maxRuntimeInSeconds 는 10초에서 600초까지의 값을 허용하며 기본값은 90초입니다. 600초(10분) 최대값은 Azure AI 검색 검색 요청에만 적용됩니다.
var retrievalRequest = new KnowledgeBaseRetrievalRequest();
retrievalRequest.Messages.Add(
new KnowledgeBaseMessage(
content: new[] {
new KnowledgeBaseMessageTextContent("What companies are in the financial sector?")
}
) { Role = "user" }
);
retrievalRequest.RetrievalReasoningEffort = new KnowledgeRetrievalLowReasoningEffort();
retrievalRequest.OutputMode = "answerSynthesis";
retrievalRequest.MaxRuntimeInSeconds = 30;
retrievalRequest.MaxOutputSizeInTokens = 6000;
var result = await kbClient.RetrieveAsync(retrievalRequest);
Console.WriteLine(
(result.Value.Response[0].Content[0] as KnowledgeBaseMessageTextContent)!.Text
);
참조:KnowledgeBaseRetrievalClient, KnowledgeBaseRetrievalRequest
from azure.search.documents.knowledgebases.models import (
KnowledgeRetrievalLowReasoningEffort,
KnowledgeRetrievalOutputMode,
)
request = KnowledgeBaseRetrievalRequest(
messages=[
KnowledgeBaseMessage(
role="user",
content=[KnowledgeBaseMessageTextContent(text="What companies are in the financial sector?")],
)
],
retrieval_reasoning_effort=KnowledgeRetrievalLowReasoningEffort(),
output_mode=KnowledgeRetrievalOutputMode.ANSWER_SYNTHESIS,
max_runtime_in_seconds=30,
max_output_size_in_tokens=6000,
)
result = kb_client.retrieve(request)
print(result.response[0].content[0].text)
참조:KnowledgeBaseRetrievalClient, KnowledgeBaseRetrievalRequest
POST {{search-endpoint}}/knowledgebases/kb-override/retrieve?api-version=2026-08-01-preview
Authorization: Bearer {{search-access-token}}
Content-Type: application/json
{
"messages": [
{
"role": "user",
"content": [
{ "type": "text", "text": "What companies are in the financial sector?" }
]
}
],
"retrievalReasoningEffort": { "kind": "low" },
"outputMode": "answerSynthesis",
"maxRuntimeInSeconds": 30,
"maxOutputSizeInTokens": 6000
}
참조:지식 검색 - 검색
서비스에서 추론 작업을 선택하도록 허용
기술 자료 기본값을 재정의하려면 검색 요청에서 auto를 retrievalReasoningEffort.kind로 설정합니다. 자동 추론에 대한 자세한 내용은 검색 추론 작업 설정(미리 보기)을 참조하세요.
{
"retrievalReasoningEffort": {
"kind": "auto"
}
}
참조:지식 검색 - 검색
각 기술 원본에 대한 참조 설정
includeReferences에서 includeReferenceSourceData 및 knowledgeSourceParams를 사용하여 references 배열에 표시할 소스와 각 항목에 포함할 소스 데이터의 양을 제어합니다. 다음 예제에서는 기술 자료의 기본 추론 작업을 사용합니다.
var retrievalRequest = new KnowledgeBaseRetrievalRequest();
retrievalRequest.Messages.Add(
new KnowledgeBaseMessage(
content: new[] {
new KnowledgeBaseMessageTextContent("What companies are in the financial sector?")
}
) { Role = "user" }
);
retrievalRequest.IncludeActivity = true;
retrievalRequest.KnowledgeSourceParams.Add(
new SearchIndexKnowledgeSourceParams("demo-financials-ks")
{
IncludeReferences = true,
IncludeReferenceSourceData = true
}
);
retrievalRequest.KnowledgeSourceParams.Add(
new SearchIndexKnowledgeSourceParams("demo-communicationservices-ks")
{
IncludeReferences = false,
IncludeReferenceSourceData = false
}
);
retrievalRequest.KnowledgeSourceParams.Add(
new SearchIndexKnowledgeSourceParams("demo-healthcare-ks")
{
IncludeReferences = true,
IncludeReferenceSourceData = false,
AlwaysQuerySource = true
}
);
var result = await kbClient.RetrieveAsync(retrievalRequest);
Console.WriteLine(
(result.Value.Response[0].Content[0] as KnowledgeBaseMessageTextContent)!.Text
);
참조:KnowledgeBaseRetrievalClient, KnowledgeBaseRetrievalRequest
from azure.search.documents.knowledgebases.models import SearchIndexKnowledgeSourceParams
request = KnowledgeBaseRetrievalRequest(
messages=[
KnowledgeBaseMessage(
role="user",
content=[KnowledgeBaseMessageTextContent(text="What companies are in the financial sector?")],
)
],
include_activity=True,
knowledge_source_params=[
SearchIndexKnowledgeSourceParams(
knowledge_source_name="demo-financials-ks",
include_references=True,
include_reference_source_data=True,
),
SearchIndexKnowledgeSourceParams(
knowledge_source_name="demo-communicationservices-ks",
include_references=False,
include_reference_source_data=False,
),
SearchIndexKnowledgeSourceParams(
knowledge_source_name="demo-healthcare-ks",
include_references=True,
include_reference_source_data=False,
always_query_source=True,
),
],
)
result = kb_client.retrieve(request)
print(result.response[0].content[0].text)
참조:KnowledgeBaseRetrievalClient, SearchIndexKnowledgeSourceParams
POST {{search-endpoint}}/knowledgebases/kb-medium-example/retrieve?api-version=2026-08-01-preview
Authorization: Bearer {{search-access-token}}
Content-Type: application/json
{
"messages": [
{
"role": "user",
"content": [
{ "type": "text", "text": "What companies are in the financial sector?" }
]
}
],
"includeActivity": true,
"knowledgeSourceParams": [
{
"knowledgeSourceName": "demo-financials-ks",
"kind": "searchIndex",
"includeReferences": true,
"includeReferenceSourceData": true
},
{
"knowledgeSourceName": "demo-communicationservices-ks",
"kind": "searchIndex",
"includeReferences": false,
"includeReferenceSourceData": false
},
{
"knowledgeSourceName": "demo-healthcare-ks",
"kind": "searchIndex",
"includeReferences": true,
"includeReferenceSourceData": false,
"alwaysQuerySource": true
}
]
}
참조:지식 검색 - 검색
최소한의 추론 작업 사용
다음 예제에서는 지능형 쿼리 계획 또는 응답 합성을 위한 LLM이 없습니다. 쿼리 문자열은 키워드 검색 또는 하이브리드 검색을 위해 에이전트 검색 엔진으로 이동합니다.
var retrievalRequest = new KnowledgeBaseRetrievalRequest();
retrievalRequest.Intents.Add(
new KnowledgeRetrievalSemanticIntent("what is a brokerage")
);
var result = await kbClient.RetrieveAsync(retrievalRequest);
Console.WriteLine(
(result.Value.Response[0].Content[0] as KnowledgeBaseMessageTextContent)!.Text
);
참조:KnowledgeBaseRetrievalClient, KnowledgeBaseRetrievalRequest
from azure.search.documents.knowledgebases.models import (
KnowledgeBaseRetrievalRequest,
KnowledgeRetrievalSemanticIntent,
)
request = KnowledgeBaseRetrievalRequest(
intents=[
KnowledgeRetrievalSemanticIntent(
search="what is a brokerage",
)
]
)
result = kb_client.retrieve(request)
print(result.response[0].content[0].text)
참조:KnowledgeBaseRetrievalClient, KnowledgeBaseRetrievalRequest
POST {{search-endpoint}}/knowledgebases/kb-minimal/retrieve?api-version=2026-08-01-preview
Authorization: Bearer {{search-access-token}}
Content-Type: application/json
{
"intents": [
{
"type": "semantic",
"search": "what is a brokerage"
}
]
}
참조:지식 검색 - 검색
가져오기 작업 문제 해결
응답 2026-08-01-preview상태는 검색 성공 여부, 부분적으로 성공 또는 실패 여부 및 다음에 수행할 작업을 나타냅니다. 다음 표를 사용하여 각 상태를 의미에 매핑한 다음 문제 해결 지침에 대한 해당 섹션을 참조하세요.
| 상태 | Meaning |
|---|---|
200 OK |
검색에 성공했습니다. 내용이 출력 예산을 초과하는 경우에도 문서를 생략할 수 있습니다. 자세한 내용은 빈 응답을 참조하세요. |
400 Bad Request |
검색 요청이 검색을 시작하기 전에 유효성 검사에 실패했습니다. |
206 Partial Content |
하나 이상의 원본이 성공했으며 실패한 원본이 표시되지 failOnError않습니다. 응답에는 성공한 원본의 결과가 포함됩니다. |
502 Bad Gateway |
선택한 모든 원본이 실패했거나 표시된 failOnError: true 원본이 실패했습니다. |
200가 아닌 모든 응답의 경우 API 버전, 타임스탬프, 민감한 정보가 제거된 요청 본문, 응답 헤더, 그리고 요청 ID 또는 상관관계 ID를 기록합니다. 이러한 세부 정보는 실패를 진단하고 필요한 경우 지원과 문제를 공유하는 데 도움이 됩니다.
400 Bad Request
최상위 오류를 사용하여 잘못된 요청 속성을 식별합니다. 주요 원인은 다음과 같습니다.
-
knowledgeSourceName의knowledgeSourceParams이(가) 기술 자료실에 연결되어 있지 않거나 해당kind이(가) 연결된 원본과 일치하지 않습니다. - 요청 값이 지원되는 범위를 벗어났거나, 한 옵션을 사용하려면 활성화되지 않은 다른 옵션이 필요합니다. 예를 들어
includeReferenceSourceData에는includeReferences이 필요합니다. -
retrievalReasoningEffort.kind은(는)auto이지만 요청은2026-08-01-preview보다 이전 API 버전을 사용합니다. - 요청은
auto,low또는medium를 사용하지만, 기술 자료에는 모델이 정의되어 있지 않습니다. -
요청 시 원본 제외(미리 보기)의 경우, 동일한 항목에서
alwaysQuerySource및true를 모두neverQuerySource로 설정하거나, 연결된 모든 지식 원본이 제외됩니다.
요청을 다시 시도하기 전에 최상위 오류로 식별된 속성을 수정합니다.
206 Partial Content
activity를 포함하는 각 error 항목을 검사합니다. 원본 검색 활동은 실패한 기술 자료를 식별하고 모델 활동은 실패한 처리 단계를 식별합니다. 응답 본문에는 성공한 결과가 계속 포함됩니다.
원본 검색 작업 오류의 경우 일반적인 원인은 다음과 같습니다.
- 잘못된 형식의
filterAddOn식과 같은 잘못된 쿼리 시 입력입니다. - 이름이 변경된 필드, 누락된 시맨틱 구성 또는 잘못된 벡터라이저와 같은 기술 자료 원본 또는 인덱스 구성의 드리프트.
- 종속성 권한 부여가 없거나 잘못되었거나 원본을 쿼리하는 데 사용되는 ID에 대한 권한이 부족합니다.
- 종속성 스로틀링, 시간 제한 또는 일시적인 가용성 오류입니다.
모델 활동 오류의 경우 활동 type를 사용하여 실패한 처리 단계를 식별합니다. 예를 들어 오류는 modelWebSummarization웹 결과 요약 이 실패했음을 나타냅니다.
애플리케이션에서 부분 결과를 허용하는 경우 성공적인 결과를 처리하고 실패한 각 원본 또는 모델 단계를 기록합니다. 다시 시도하기 전에 구성, 권한 부여 및 권한 오류를 수정합니다. 스로틀링, 시간 초과 또는 일시적인 가용성 장애가 발생하는 경우 백오프를 적용한 제한된 재시도를 사용합니다.
특정 원본 없이 결과가 안전하지 않고 원본 형식이 지원하는 alwaysQuerySource경우 둘 다 alwaysQuerySourcefailOnError설정합니다. 첫 번째 옵션은 원본이 선택되었는지 확인하고, 두 번째 옵션은 쿼리에 실패하면 하드 오류를 반환합니다.
MCP 서버 지식 원본(미리 보기) 은 지원하지 alwaysQuerySource않습니다. 이러한 원본의 failOnError 경우 원본이 선택된 경우에만 적용됩니다.
failOnError 는 모델 활동 실패에 적용되지 않습니다.
502 Bad Gateway
최상위 오류는 다음 두 가지 하드 오류 경로 중 하나를 설명합니다.
- 선택한 모든 원본이 실패했습니다. 선택한 각 원본에서 오류가 반환되었습니다. 일치하는 문서가 0개인 성공적으로 완료된 원본은 실패한 원본이 아닙니다. 공유 구성, 권한 부여, 종속성 또는 가용성 문제에 대한 모든 원본 오류를 검사합니다.
-
원본이
failOnError실패했습니다. 필요한 원본을 쿼리할 수 없습니다. 다른 원본이 성공했을 수 있지만 필요한 원본이 실패했기 때문에 서비스가 부분 결과를 반환하지 않습니다.
근본적인 원본 실패는 일반적으로 206 Partial Content에서 설명된 것과 같은 유형으로, 원본별로 유효하지 않은 입력, 원본 또는 인덱스 구성 불일치, 종속성 인증 또는 권한 문제, 스로틀링, 시간 초과 또는 종속성을 일시적으로 사용할 수 없는 상태 등이 있습니다.
하드 502 응답은 activity 배열을 생략하고 소스 이름과 근본 원인을 최상위 수준의 오류 메시지에만 제공할 수 있습니다. 다시 시도하기 전에 구성, 권한 부여 및 권한 오류를 수정합니다. 스로틀링, 시간 초과 또는 일시적인 가용성 오류에 대해서만 백오프와 함께 재시도 횟수를 제한하여 사용합니다. 근본 원인인 소스 실패를 검토하기 전에는 502 Bad Gateway 응답을 Azure AI 검색 서비스 중단으로 간주하지 마세요.
빈 응답
검색 단계에서 문서를 찾을 수는 있지만, 해당 문서의 근거 콘텐츠가 maxOutputSize 출력 예산(maxOutputSizeInTokens 및 그 이후 버전의 2026-05-01-preview)을 초과하면 서비스가 최종 응답에서 해당 문서를 제외할 수 있습니다. 이 조건이 발생하면 활동 배열에 일치하는 항목이 발견되었음을 표시하고, 활동 레코드에는 가장 관련성이 큰 문서가 최대 출력 크기를 초과했다는 경고가 포함됩니다. 참조 배열 및 접지된 응답 콘텐츠는 해당 문서에 대해 비어 있습니다. 더 많은 콘텐츠를 유지하려면 maxOutputSizeInTokens를 늘리세요.
이 동작을 방지하려면 큰 원본 문서를 안정적인 식별자 및 원본 메타데이터를 사용하여 더 작은 청크로 인덱싱합니다. 이는 특히 긴 설명서, 정책 또는 기술 자료 문서에 적용됩니다.
MCP 엔드포인트 호출
Warning
MCP 구현은 공격, 연속 실패 및 사용자 감독 손실과 같은 위험에 취약합니다. Microsoft 권장 사례 및 사용 모범 사례에 따라 보안 및 안정성에 대한 MCP 서버를 검사하고 승인 메커니즘을 구현하고 연속 동작을 모니터링하여 이러한 위험을 완화할 수 있습니다.
MCP 는 AI 애플리케이션이 외부 데이터 원본 및 도구에 연결하는 방법을 표준화하는 개방형 프로토콜입니다.
Azure AI 검색에서 각 지식 베이스는 knowledge_base_retrieve 도구를 노출하는 독립 실행형 MCP 서버입니다.
Foundry Agent Service, GitHub Copilot, Claude 및 Cursor 등의 MCP 호환 클라이언트는 이 도구를 호출하여 기술 자료를 쿼리할 수 있습니다.
MCP 엔드포인트에 인증
각 기술 자료에는 다음 URL에 MCP 엔드포인트가 있습니다.
https://<search-service-name>.search.windows.net/knowledgebases/<knowledge-base-name>/mcp?api-version=<api-version>
지정한 API 버전에 따라 연결이 반환되는 항목이 결정됩니다.
2026-08-01-preview을 사용하면 기본 지식 기반이 LLM 및 호환되는 추론 수준으로 구성된 경우 지식 기반은 합성된 답변을 반환합니다.
2026-04-01을 사용하면 검색은 항상 최소화되고 추출형으로 수행되며, 연결은 그라운딩 데이터만 반환합니다.
이 엔드포인트에 인증하는 방법은 MCP 클라이언트에 따라 달라집니다. MCP 도구에서 knowledge_base_retrieve Azure OpenAI 응답 API를 사용하는 경우 Azure OpenAI에 대한 응답 API 호출과 Azure AI 검색 MCP 요청을 모두 인증합니다. MCP 클라이언트가 이 엔드포인트를 직접 호출하는 경우 Azure AI 검색에만 인증하면 됩니다.
Azure AI 검색 인증의 경우 다음 방법 중 하나를 사용합니다.
- 헤더에 전달자 토큰
Authorization전달(권장) - 헤더에
api-key
참고
MCP 클라이언트는 사용자 지정 헤더를 다르게 구성합니다. 예를 들어 Foundry 에이전트 서비스는 프로젝트 연결을 통해 헤더를 삽입하고 GitHub Copilot 같은 클라이언트는 MCP 서버 JSON에서 헤더를 필요로 합니다.
MCP 인증에 전달자 토큰 사용
MCP 인증에 권장되는 방법은 중요한 키를 구성 파일에 저장하지 않는 전달자 토큰입니다. 토큰 뒤에 있는 ID에는 검색 서비스에 할당된 검색 인덱스 데이터 판독기 역할이 있어야 합니다. 자세한 내용은 ID를 사용하여 앱을 Azure AI 검색 연결 참조하세요.
#pragma warning disable OPENAI001
using Azure.AI.OpenAI;
using Azure.Core;
using Azure.Identity;
using OpenAI.Responses;
using System;
using System.Collections.Generic;
string openAiEndpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT")!; // Example: https://<resource-name>.openai.azure.com
string mcpServerUrl = Environment.GetEnvironmentVariable("AZURE_SEARCH_MCP_ENDPOINT")!; // Example: https://<search-service-name>.search.windows.net/knowledgebases/<knowledge-base-name>/mcp?api-version=<api-version>
DefaultAzureCredential credential = new();
// Create the Azure OpenAI Responses client
AzureOpenAIClient azureClient = new(new Uri(openAiEndpoint), credential);
ResponsesClient openAIClient = azureClient.GetResponsesClient();
// Get a bearer token for Azure AI Search
string searchToken = credential.GetToken(
new TokenRequestContext(new[] { "https://search.azure.com/.default" })
).Token;
// Configure the MCP tool for knowledge base retrieval
McpTool mcpTool = ResponseTool.CreateMcpTool(
serverLabel: "search_kb",
serverUri: new Uri(mcpServerUrl),
headers: new Dictionary<string, string>
{
["Authorization"] = $"Bearer {searchToken}",
},
allowedTools: new McpToolFilter { ToolNames = { "knowledge_base_retrieve" } },
toolCallApprovalPolicy: new McpToolCallApprovalPolicy(
GlobalMcpToolCallApprovalPolicy.NeverRequireApproval)
);
// Build the response request with the MCP tool attached
CreateResponseOptions options = new()
{
Model = "MODEL_NAME",
InputItems =
{
ResponseItem.CreateUserMessageItem(
"What causes the strongest nighttime brightness patterns in this dataset?")
},
Tools = { mcpTool }
};
ResponseResult response = await openAIClient.CreateResponseAsync(options);
Console.WriteLine(response.GetOutputText());
import os
from azure.identity import DefaultAzureCredential, get_bearer_token_provider
from openai import AzureOpenAI
openai_endpoint = os.environ["AZURE_OPENAI_ENDPOINT"] # Example: https://<resource-name>.openai.azure.com
mcp_server_url = os.environ["AZURE_SEARCH_MCP_ENDPOINT"] # Example: https://<search-service-name>.search.windows.net/knowledgebases/<knowledge-base-name>/mcp?api-version=<api-version>
credential = DefaultAzureCredential()
# Create token providers for Azure OpenAI and Azure AI Search
openai_token_provider = get_bearer_token_provider(
credential, "https://cognitiveservices.azure.com/.default"
)
search_token_provider = get_bearer_token_provider(
credential, "https://search.azure.com/.default"
)
# Create the Azure OpenAI client
client = AzureOpenAI(
azure_endpoint=openai_endpoint,
azure_ad_token_provider=openai_token_provider,
api_version=os.environ["OPENAI_API_VERSION"], # Example: 2025-04-01-preview
)
# Create a response using the MCP tool configuration
response = client.responses.create(
model="MODEL_NAME",
input="What causes the strongest nighttime brightness patterns in this dataset?",
tools=[
{
"type": "mcp",
"server_label": "search_kb",
"server_url": mcp_server_url,
"allowed_tools": ["knowledge_base_retrieve"],
"headers": {
"Authorization": f"Bearer {search_token_provider()}"
},
"require_approval": "never",
}
],
)
print(response.output_text)
// This code snippet is currently unavailable.
MCP 인증에 관리 키 사용
관리자 키는 검색 서비스에 대한 전체 읽기/쓰기 권한을 부여하므로 개발 환경이나 전달자 토큰을 사용할 수 없는 경우에만 사용합니다. 자세한 내용은 API 키를 사용하여 Azure AI 검색 연결 참조하세요.
Tip
다음 예제에서는 전달자 토큰 예제와 다른 헤더만 보여 줍니다. 전체 설정은 MCP 인증에 전달자 토큰 사용을 참조하세요.
#pragma warning disable OPENAI001
using OpenAI.Responses;
using System;
using System.Collections.Generic;
string mcpServerUrl = Environment.GetEnvironmentVariable("AZURE_SEARCH_MCP_ENDPOINT")!; // Example: https://<search-service-name>.search.windows.net/knowledgebases/<knowledge-base-name>/mcp?api-version=<api-version>
string searchAdminKey = Environment.GetEnvironmentVariable("AZURE_SEARCH_ADMIN_KEY")!; // Example: <search-api-key>
McpTool mcpTool = ResponseTool.CreateMcpTool(
serverLabel: "search_kb",
serverUri: new Uri(mcpServerUrl),
headers: new Dictionary<string, string> { ["api-key"] = searchAdminKey },
allowedTools: new McpToolFilter { ToolNames = { "knowledge_base_retrieve" } },
toolCallApprovalPolicy: new McpToolCallApprovalPolicy(
GlobalMcpToolCallApprovalPolicy.NeverRequireApproval)
);
import os
mcp_server_url = os.environ["AZURE_SEARCH_MCP_ENDPOINT"] # Example: https://<search-service-name>.search.windows.net/knowledgebases/<knowledge-base-name>/mcp?api-version=<api-version>
search_admin_key = os.environ["AZURE_SEARCH_ADMIN_KEY"] # Example: <search-api-key>
tools = [
{
"type": "mcp",
"server_label": "search_kb",
"server_url": mcp_server_url,
"allowed_tools": ["knowledge_base_retrieve"],
"headers": {"api-key": search_admin_key},
"require_approval": "never",
}
]
// This code snippet is currently unavailable.
MCP 응답 검토
MCP 클라이언트가 knowledge_base_retrieve를 호출하면 retrieve 작업의 response, activity, references 래퍼 대신 MCP 도구 결과를 받습니다. 대부분의 MCP 클라이언트는 해당 도구 결과를 최상위 result 개체 아래에 표시하므로 예상해야 하는 페이로드는 다음과 같습니다 result.content[].
{
"result": {
"content": [
{
"type": "text",
"text": "[{\"ref_id\":\"0\",\"title\":\"Urban Structure\",\"terms\":\"Location of Phoenix, Grid of City Blocks, Phoenix Metropolitan Area at Night\",\"content\":\"<content chunk redacted>\"}]"
}
]
}
}
핵심 사항:
result.content[]에는 기술 자료에서 반환하는 MCP 도구 출력이 포함되어 있습니다.result.content[].type은text입니다.result.content[].text에는 검색된 접지 데이터를 JSON 인코딩 문자열로 포함합니다.검색 작업과 달리 현재 MCP 응답은 별도의
activity또는references배열을 반환하지 않으며, 반환된 콘텐츠에 대해resource항목도 채우지 않습니다.