Udostępnij za pośrednictwem


Dostawca pamięci historii rozmów

Jest ChatHistoryMemoryProvider dostawcą kontekstu sztucznej inteligencji, który przechowuje całą historię czatów w składnicy wektorów i pobiera powiązane wiadomości w celu wzbogacenia bieżącej konwersacji. Dzięki temu agenci mogą odwołać odpowiedni kontekst z poprzednich interakcji przy użyciu wyszukiwania semantycznego podobieństwa.

Jak to działa

Dostawca działa w dwóch fazach:

  1. Przechowywanie: Po wywołaniu każdego agenta nowe komunikaty żądań i odpowiedzi są przechowywane w pamięci wektorów jako osadzenia wygenerowane na podstawie ich zawartości.

  2. Pobieranie: przed każdym wywołaniem (lub na żądanie za pośrednictwem wywołania funkcji) dostawca przeszukuje magazyn wektorów dla komunikatów semantycznie podobnych do bieżących danych wejściowych użytkownika i wprowadza je jako kontekst.

Zakres przechowywanych komunikatów jest definiowany przy użyciu konfigurowalnych identyfikatorów (aplikacji, agenta, użytkownika, sesji), umożliwiają szczegółową kontrolę nad tym, jaka historia jest przechowywana i które można wyszukiwać.

Wymagania wstępne

Wskazówka

Aby uzyskać więcej informacji na temat abstrakcji VectorData i dostępnych implementacji, zobacz dokumentację dotyczącą integracji Sklepów Wektorowych.

Użycie

W poniższym przykładzie pokazano tworzenie agenta z ChatHistoryMemoryProvider, wykorzystując wewnętrzny magazyn wektorów.

Zwróć uwagę na użycie tylko identyfikatora userid dla zakresu wyszukiwania. Dzięki temu agent może odwołać informacje z poprzednich rozmów z tym samym użytkownikiem, aby poinformować o nowych odpowiedziach.

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));

Wskazówka

Użyj różnych konfiguracji storageScope i searchScope do kontrolowania izolacji pamięci. Na przykład przechowuj dane dla każdej sesji, ale wyszukuj we wszystkich sesjach użytkownika.

Opcje konfiguracji

Klasa ChatHistoryMemoryProviderOptions zapewnia konfigurację zachowania dostawcy.

Zachowania podczas wyszukiwania

Option Typ Wartość domyślna Opis
SearchTime SearchBehavior BeforeAIInvoke Określa, kiedy jest wykonywane wyszukiwanie pamięci.

Wyliczenie SearchBehavior ma dwie wartości:

  • BeforeAIInvoke: Automatycznie wyszukuje odpowiednie wspomnienia przed każdym wywołaniem sztucznej inteligencji i wprowadza je jako komunikaty kontekstowe. Jest to zachowanie domyślne.
  • OnDemandFunctionCalling: uwidacznia narzędzie funkcji, które model AI może wywołać w celu wyszukiwania wspomnień na żądanie. Użyj tej opcji, jeśli chcesz, aby model zdecydował, kiedy odwołać wspomnienia.

Opcje wyników wyszukiwania

Option Typ Wartość domyślna Opis
MaxResults int? 3 Maksymalna liczba wyników historii czatu do pobrania podczas jednego wyszukiwania.
ContextPrompt string? "## Memories\nConsider the following memories..." Tekst monitu, który jest prefiksem wyników wyszukiwania przed ich wstrzyknięciem.

Opcje narzędzi funkcji na żądanie

Te opcje mają zastosowanie tylko wtedy, gdy SearchTime jest ustawiona na OnDemandFunctionCallingwartość :

Option Typ Wartość domyślna Opis
FunctionToolName string? "Search" Nazwa narzędzia funkcji wyszukiwania udostępnionego modelowi.
FunctionToolDescription string? "Allows searching for related previous chat history..." Opis narzędzia funkcji wyszukiwania.

Filtrowanie komunikatów

Option Typ Wartość domyślna Opis
SearchInputMessageFilter Func<IEnumerable<ChatMessage>, IEnumerable<ChatMessage>>? Tylko komunikaty zewnętrzne Filtr zastosowany do wiadomości żądania podczas konstruowania zapytań wyszukiwania.
StorageInputRequestMessageFilter Func<IEnumerable<ChatMessage>, IEnumerable<ChatMessage>>? Tylko komunikaty zewnętrzne Filtr zastosowany do komunikatów żądania przed ich zapisywaniem.
StorageInputResponseMessageFilter Func<IEnumerable<ChatMessage>, IEnumerable<ChatMessage>>? Brak filtru Filtr zastosowany do komunikatów odpowiedzi przed przechowywaniem.

Rejestrowanie i telemetria

Option Typ Wartość domyślna Opis
EnableSensitiveTelemetryData bool false Gdy true dane poufne (identyfikatory użytkowników, zawartość komunikatu) są wyświetlane w logach bez zmian.
Redactor Redactor? Redaktor zastępujący tekst za pomocą "<redacted>" Niestandardowy edytor dla wartości poufnych przy logowaniu. Ignorowane, jeśli EnableSensitiveTelemetryData ma wartość true.

Zarządzanie stanem

Option Typ Wartość domyślna Opis
StateKey string? Nazwa typu dostawcy Klucz używany do przechowywania stanu dostawcy w konstrukcji AgentSession.StateBag. Zastąp w przypadku używania wielu wystąpień ChatHistoryMemoryProvider w tej samej sesji.

Konfiguracja zakresu

Klasa ChatHistoryMemoryProviderScope określa sposób organizowania i filtrowania komunikatów w magazynie wektorów.

Majątek Typ Opis
ApplicationId string? Określanie zakresu komunikatów do określonej aplikacji. Jeśli nie zostanie ustawiona, obejmuje wszystkie aplikacje.
AgentId string? Określanie zakresu komunikatów do określonego agenta. Jeśli nie jest ustawione, obejmuje wszystkich agentów.
UserId string? Określanie zakresu komunikatów dla określonego użytkownika. Jeśli nie jest ustawiona, obejmuje wszystkich użytkowników.
SessionId string? Ograniczenie komunikatów do konkretnej sesji.

Zakres magazynowania i wyszukiwania

Klasa ChatHistoryMemoryProvider.State akceptuje dwa zakresy:

  • storageScope: definiuje sposób oznaczania nowych komunikatów podczas przechowywania. Wszystkie właściwości zakresu są zapisywane jako metadane.
  • searchScope: definiuje kryteria filtrowania podczas wyszukiwania. Ustaw ten zakres szerszy niż zakres magazynu, aby wyszukiwać w wielu sesjach lub agentach.

Przykład: Przechowywanie poszczególnych sesji, wyszukiwanie wszystkich sesji dla użytkownika:

new ChatHistoryMemoryProvider.State(
    storageScope: new() { UserId = "user-123", SessionId = "session-456" },
    searchScope: new() { UserId = "user-123" })

Zagadnienia dotyczące zabezpieczeń

Ostrzeżenie

Zapoznaj się z tymi kwestiami dotyczącymi zabezpieczeń przed wdrożeniem ChatHistoryMemoryProvider w środowisku produkcyjnym.

  • Iniekcja monitu pośredniego: komunikaty pobierane z magazynu wektorów są wstrzykiwane do kontekstu LLM. Jeśli magazyn wektorów zostanie naruszony, treść atakująca może wpłynąć na zachowanie LLM. Dane z magazynu są akceptowane takie, jakie są, bez walidacji.

  • Dane osobowe i dane poufne: komunikaty konwersacji (w tym dane wejściowe użytkownika i odpowiedzi LLM) są przechowywane jako wektory. Te komunikaty mogą zawierać dane osobowe lub poufne informacje. Upewnij się, że magazyn wektorów ma odpowiednie mechanizmy kontroli dostępu i szyfrowanie danych w spoczynku.

  • Narzędzie wyszukiwania na żądanie: w przypadku używania OnDemandFunctionCallingmodelu AI kontroluje, kiedy i czego szukać. Zapytanie wyszukiwania jest generowane przez sztuczną inteligencję i powinno być traktowane jako niezaufane dane wejściowe w implementacji magazynu wektorów.

  • Rejestrowanie śledzenia: Po LogLevel.Trace włączeniu mogą być rejestrowane pełne zapytania wyszukiwania i ich wyniki. Te dane mogą zawierać dane osobowe. Użyj opcji Redactor lub wyłącz poufne dane telemetryczne w środowisku produkcyjnym.

Ten dostawca nie jest jeszcze dostępny dla Python. Zobacz kartę C#, aby zapoznać się z przykładami użycia.

Następne kroki