ChatHistoryMemoryProvider 벡터 저장소에 모든 채팅 기록을 저장하고 관련 메시지를 검색하여 현재 대화를 보강하는 AI 컨텍스트 공급자입니다. 이를 통해 에이전트는 의미 체계 유사성 검색을 사용하여 이전 상호 작용에서 관련 컨텍스트를 회수할 수 있습니다.
작동 방식
공급자는 다음 두 단계로 작동합니다.
스토리지: 각 에이전트 호출 후 새 요청 및 응답 메시지가 콘텐츠에서 생성된 포함 항목과 함께 벡터 저장소에 저장됩니다.
검색: 각 호출(또는 함수 호출을 통한 주문형)전에 공급자는 벡터 저장소에서 현재 사용자 입력과 의미상 유사한 메시지를 검색하고 컨텍스트로 삽입합니다.
저장된 메시지는 구성 가능한 식별자(애플리케이션, 에이전트, 사용자, 세션)를 사용하여 범위가 지정되므로 저장되고 검색 가능한 기록을 세밀하게 제어할 수 있습니다.
사전 요구 사항
-
📦
Microsoft.Extensions.VectorData.Abstractions의 벡터 저장소 구현(예: 📦
InMemoryVectorStore, 📦Azure AI 검색 또는 다른 지원 저장소) - 벡터 저장소에 구성된 임베딩 모델
- Azure OpenAI 또는 OpenAI의 채팅 모델 배포
- .NET 8.0 이상
팁 (조언)
VectorData 추상화 및 사용 가능한 구현에 대한 자세한 내용은 Vector Stores 통합 설명서를 참조하세요.
사용법
다음 예제에서는 메모리 내 벡터 저장소를 ChatHistoryMemoryProvider 사용하여 에이전트를 만드는 방법을 보여 줍니다.
"검색 범위에는 userid만 사용하십시오." 이렇게 하면 에이전트가 동일한 사용자와의 이전 대화에서 정보를 회수하여 새 응답을 알릴 수 있습니다.
using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
using Microsoft.Extensions.VectorData;
using Microsoft.SemanticKernel.Connectors.InMemory;
var endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT")
?? throw new InvalidOperationException("AZURE_OPENAI_ENDPOINT is not set.");
var deploymentName = Environment.GetEnvironmentVariable("AZURE_OPENAI_DEPLOYMENT_NAME") ?? "gpt-4o-mini";
var embeddingDeploymentName = Environment.GetEnvironmentVariable("AZURE_OPENAI_EMBEDDING_DEPLOYMENT_NAME")
?? "text-embedding-3-large";
// Create a vector store with an embedding generator.
// For production, replace InMemoryVectorStore with a persistent store.
VectorStore vectorStore = new InMemoryVectorStore(new InMemoryVectorStoreOptions()
{
EmbeddingGenerator = new AzureOpenAIClient(new Uri(endpoint), new DefaultAzureCredential())
.GetEmbeddingClient(embeddingDeploymentName)
.AsIEmbeddingGenerator()
});
// Create the agent with ChatHistoryMemoryProvider
AIAgent agent = new AzureOpenAIClient(
new Uri(endpoint),
new DefaultAzureCredential())
.GetChatClient(deploymentName)
.AsAIAgent(new ChatClientAgentOptions
{
ChatOptions = new() { Instructions = "You are a helpful assistant." },
Name = "MemoryAgent",
AIContextProviders = [new ChatHistoryMemoryProvider(
vectorStore,
collectionName: "chathistory",
vectorDimensions: 3072,
session => new ChatHistoryMemoryProvider.State(
// Configure where messages are stored
storageScope: new() { UserId = "user-123", SessionId = Guid.NewGuid().ToString() },
// Configure where to search (can be broader than storage scope)
searchScope: new() { UserId = "user-123" }))]
});
// Start a session and interact with the agent
AgentSession session = await agent.CreateSessionAsync();
Console.WriteLine(await agent.RunAsync("I prefer window seats on flights.", session));
// Start a new session - the agent can recall the user's preference
AgentSession session2 = await agent.CreateSessionAsync();
Console.WriteLine(await agent.RunAsync("Book me a flight to Seattle.", session2));
팁 (조언)
다른 storageScope 구성과 searchScope 구성을 사용하여 메모리 격리를 제어합니다. 예를 들어 세션당 저장하지만 모든 세션에서 사용자를 검색합니다.
구성 옵션
이 클래스는 ChatHistoryMemoryProviderOptions 공급자 동작에 대한 구성을 제공합니다.
검색 동작
| Option | 유형 | 기본값 | 설명 |
|---|---|---|---|
SearchTime |
SearchBehavior |
BeforeAIInvoke |
메모리 검색이 실행되는 시기를 제어합니다. |
열거형에는 SearchBehavior 다음 두 가지 값이 있습니다.
-
BeforeAIInvoke: 각 AI 호출 전에 관련 메모리를 자동으로 검색하고 컨텍스트 메시지로 삽입합니다. 이 옵션은 기본 동작입니다. -
OnDemandFunctionCalling: AI 모델이 요청 시 추억을 검색하기 위해 호출할 수 있는 함수 도구를 노출합니다. 모델에서 추억을 기억할 시기를 결정하려는 경우 이를 사용합니다.
검색 결과 옵션
| Option | 유형 | 기본값 | 설명 |
|---|---|---|---|
MaxResults |
int? |
3 |
검색당 검색할 최대 채팅 기록 결과 수입니다. |
ContextPrompt |
string? |
"## Memories\nConsider the following memories..." |
검색 결과에 삽입되기 전에 접두사로 추가되는 프롬프트 텍스트입니다. |
주문형 함수 도구 옵션
이러한 옵션은 SearchTime이(가) OnDemandFunctionCalling로 설정된 경우에만 적용됩니다.
| Option | 유형 | 기본값 | 설명 |
|---|---|---|---|
FunctionToolName |
string? |
"Search" |
모델에 노출되는 검색 함수 도구의 이름입니다. |
FunctionToolDescription |
string? |
"Allows searching for related previous chat history..." |
검색 함수 도구에 대한 설명입니다. |
메시지 필터링
| Option | 유형 | 기본값 | 설명 |
|---|---|---|---|
SearchInputMessageFilter |
Func<IEnumerable<ChatMessage>, IEnumerable<ChatMessage>>? |
외부 메시지만 | 검색 쿼리를 생성할 때 요청 메시지에 적용된 필터입니다. |
StorageInputRequestMessageFilter |
Func<IEnumerable<ChatMessage>, IEnumerable<ChatMessage>>? |
외부 메시지만 | 스토리지 전에 요청 메시지에 적용된 필터입니다. |
StorageInputResponseMessageFilter |
Func<IEnumerable<ChatMessage>, IEnumerable<ChatMessage>>? |
필터 없음 | 스토리지 전에 응답 메시지에 적용된 필터입니다. |
로깅 및 원격 분석
| Option | 유형 | 기본값 | 설명 |
|---|---|---|---|
EnableSensitiveTelemetryData |
bool |
false |
중요한 데이터(사용자 ID, 메시지 콘텐츠)가 변경되지 않은 로그에 표시되는 경우 true |
Redactor |
Redactor? |
텍스트를 "<redacted>"로 교체하는 편집기 |
로깅 시 민감한 값을 처리하기 위한 사용자 지정 필터입니다.
EnableSensitiveTelemetryData이 true이면 무시됩니다. |
상태 관리
| Option | 유형 | 기본값 | 설명 |
|---|---|---|---|
StateKey |
string? |
공급자 유형 이름 | 공급자 상태를 저장하는 데 사용되는 키입니다 AgentSession.StateBag. 동일 세션에서 여러 ChatHistoryMemoryProvider 인스턴스를 사용할 때, 대체합니다. |
범위 구성
클래스는 ChatHistoryMemoryProviderScope 벡터 저장소에서 메시지를 구성하고 필터링하는 방법을 제어합니다.
| 재산 | 유형 | 설명 |
|---|---|---|
ApplicationId |
string? |
메시지를 특정 애플리케이션으로 범위 지정합니다. 설정하지 않으면 모든 애플리케이션에 걸쳐 있습니다. |
AgentId |
string? |
메시지를 특정 에이전트로 범위 지정합니다. 설정하지 않으면 모든 에이전트에 적용됩니다. |
UserId |
string? |
특정 사용자에게 메시지 범위를 지정합니다. 설정하지 않으면 모든 사용자에게 적용됩니다. |
SessionId |
string? |
메시지를 특정 세션으로 범위 지정합니다. |
스토리지 및 검색 범위
클래스는 ChatHistoryMemoryProvider.State 다음 두 가지 범위를 허용합니다.
-
storageScope: 새 메시지를 저장할 때 태그를 지정하는 방법을 정의합니다. 모든 범위 속성은 메타데이터로 작성됩니다. -
searchScope: 검색할 때 필터 조건을 정의합니다. 여러 세션 또는 에이전트에서 검색하도록 스토리지 범위보다 더 넓은 범위를 설정합니다.
예: 세션당 저장, 사용자에 대한 모든 세션 검색:
new ChatHistoryMemoryProvider.State(
storageScope: new() { UserId = "user-123", SessionId = "session-456" },
searchScope: new() { UserId = "user-123" })
보안 고려 사항
경고
프로덕션 환경에서 배포 ChatHistoryMemoryProvider 하기 전에 이러한 보안 고려 사항을 검토합니다.
간접 프롬프트 삽입: 벡터 저장소에서 검색된 메시지는 LLM 컨텍스트에 삽입됩니다. 벡터 저장소가 손상된 경우 악의적인 콘텐츠가 LLM 동작에 영향을 줄 수 있습니다. 저장소의 데이터는 유효성 검사 없이 as-is 허용됩니다.
PII 및 중요한 데이터: 대화 메시지(사용자 입력 및 LLM 응답 포함)는 벡터로 저장됩니다. 이러한 메시지에는 PII 또는 중요한 정보가 포함될 수 있습니다. 벡터 저장소에 적절한 액세스 제어 및 미사용 암호화가 있는지 확인합니다.
주문형 검색 도구: 사용할
OnDemandFunctionCalling때 AI 모델은 검색 시기와 대상을 제어합니다. 검색 쿼리는 AI에서 생성되며 벡터 저장소 구현에서 신뢰할 수 없는 입력으로 처리되어야 합니다.추적 로깅: 사용하도록 설정되면
LogLevel.Trace전체 검색 쿼리 및 결과가 기록될 수 있습니다. 이 데이터에는 PII가 포함될 수 있습니다. 이Redactor옵션을 사용하거나 프로덕션 환경에서 중요한 원격 분석을 사용하지 않도록 설정합니다.
이 공급자는 아직 Python 사용할 수 없습니다. 사용 예제는 C# 탭을 참조하세요.