4. Adım: Bellek ve Kalıcılık

Kullanıcı tercihlerini, geçmiş etkileşimleri veya dış bilgileri anımsayabilmesi için aracınıza bağlam ekleyin.

Varsayılan olarak aracılar, temel alınan hizmetin gereğine bağlı olarak sohbet geçmişini ya InMemoryChatHistoryProvider içinde ya da temel yapay zeka hizmetinde depolar.

Aşağıdaki temsilci, hizmet içi sohbet geçmişi depolama işlevini desteklemeyen veya gerektirmeyen OpenAI Sohbet Tamamlama Özelliği'ni kullanır, bu nedenle otomatik olarak bir InMemoryChatHistoryProvider oluşturur ve kullanır.

using System;
using Azure.AI.Projects;
using Azure.Identity;
using Microsoft.Agents.AI;

var endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT")
    ?? throw new InvalidOperationException("Set AZURE_OPENAI_ENDPOINT");
var deploymentName = Environment.GetEnvironmentVariable("AZURE_OPENAI_DEPLOYMENT_NAME") ?? "gpt-4o-mini";

AIAgent agent = new AIProjectClient(new Uri(endpoint), new DefaultAzureCredential())
    .AsAIAgent(
        model: deploymentName,
        instructions: "You are a friendly assistant. Keep your answers brief.",
        name: "MemoryAgent");

Warning

DefaultAzureCredential geliştirme için uygundur ancak üretimde dikkatli bir şekilde dikkate alınması gerekir. Üretimde gecikme sorunları, istenmeyen kimlik bilgisi yoklama ve geri dönüş mekanizmalarından kaynaklanan olası güvenlik risklerini önlemek için belirli bir kimlik bilgisi (ör ManagedIdentityCredential. ) kullanmayı göz önünde bulundurun.

Özel ChatHistoryProvider kullanmak için aracı seçeneklerine bir tane geçirebilirsiniz:

using System;
using Azure.AI.Projects;
using Azure.Identity;
using Microsoft.Agents.AI;

var endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT")
    ?? throw new InvalidOperationException("Set AZURE_OPENAI_ENDPOINT");
var deploymentName = Environment.GetEnvironmentVariable("AZURE_OPENAI_DEPLOYMENT_NAME") ?? "gpt-4o-mini";

AIAgent agent = new AIProjectClient(new Uri(endpoint), new DefaultAzureCredential())
    .AsAIAgent(model: deploymentName, options: new ChatClientAgentOptions()
    {
        ChatOptions = new() { Instructions = "You are a helpful assistant." },
        ChatHistoryProvider = new CustomChatHistoryProvider()
    });

Çalıştırmalar arasında bağlamı paylaşmak için oturum kullanın:

AgentSession session = await agent.CreateSessionAsync();

Console.WriteLine(await agent.RunAsync("Hello! What's the square root of 9?", session));
Console.WriteLine(await agent.RunAsync("My name is Alice", session));
Console.WriteLine(await agent.RunAsync("What is my name?", session));

Tip

Tam çalıştırılabilir örnek uygulama için buraya bakın.

Tam örnek bir bağlam sağlayıcısı tanımlar, bir aracıya ekler ve kişiselleştirme durumunu korumak için bir oturum kullanır:

import asyncio
from typing import Any

from agent_framework import Agent, AgentSession, ContextProvider, SessionContext
from agent_framework.foundry import FoundryChatClient
from azure.identity import AzureCliCredential


class UserMemoryProvider(ContextProvider):
    def __init__(self) -> None:
        super().__init__("user_memory")

    async def before_run(
        self,
        *,
        agent: Any,
        session: AgentSession | None,
        context: SessionContext,
        state: dict[str, Any],
    ) -> None:
        user_name = state.get("user_name")
        instructions = (
            f"The user's name is {user_name}. Address them by name." if user_name else "Ask for the user's name."
        )
        context.extend_instructions(self.source_id, instructions)

    async def after_run(
        self,
        *,
        agent: Any,
        session: AgentSession | None,
        context: SessionContext,
        state: dict[str, Any],
    ) -> None:
        for message in context.input_messages:
            text = message.text
            if not isinstance(text, str):
                continue
            _, marker, name = text.lower().partition("my name is")
            if marker and name.strip():
                state["user_name"] = name.split()[0].capitalize()


async def main() -> None:
    agent = Agent(
        client=FoundryChatClient(
            project_endpoint="https://your-account.services.ai.azure.com/api/projects/your-project",
            model="gpt-6-luna",
            credential=AzureCliCredential(),
        ),
        instructions="You are a friendly assistant.",
        context_providers=[UserMemoryProvider()],
    )
    session = agent.create_session()

    print(await agent.run("Hello! What's the square root of 9?", session=session))
    print(await agent.run("My name is Alice", session=session))
    print(await agent.run("What is 2 + 2?", session=session))


if __name__ == "__main__":
    asyncio.run(main())

Tip

Çalıştırılabilir dosyanın tamamı için tam örneğe bakın.

Uyarı

Python'da kalıcılık/bellek, ContextProvider ve HistoryProvider uygulamaları tarafından yönetilir. InMemoryHistoryProvider yerleşik yerel, bellek içi geçmiş sağlayıcısıdır. RawAgent belirli durumlarda (örneğin, yapılandırılmış bağlam sağlayıcıları ve hizmet tarafı depolama göstergeleri olmayan bir oturum kullanırken) otomatik olarak eklenebilir InMemoryHistoryProvider() , ancak bu tüm senaryolarda garanti edilmez. Her zaman yerel kalıcılık istiyorsanız, açıkça bir InMemoryHistoryProvider ekleyin. Ayrıca, yalnızca bir tane geçmiş sağlayıcısının load_messages=True içerdiğinden emin olun, böylece birden fazla depoyu aynı çağrıya aktarmazsınız.

Microsoft Foundry yönetilen semantik belleği izleyerek bir proje istemcisi ve bellek deposu oluşturun. Ardından yerel transkript geçmişini, yönetilen belleği ve bir denetim deposunu birleştirin:

from agent_framework import InMemoryHistoryProvider
from agent_framework.foundry import FoundryMemoryProvider

history = InMemoryHistoryProvider(load_messages=True)
memory = FoundryMemoryProvider(
    project_client=project_client,
    memory_store_name="user-memory",
    scope="user-123",
)
audit_store = InMemoryHistoryProvider(
    "audit",
    load_messages=False,
    store_context_messages=True,  # include context added by other providers
)

agent = client.as_agent(
    name="MemoryAgent",
    instructions="You are a friendly assistant.",
    context_providers=[history, memory, audit_store],  # audit store last
)

Varsayılan olarak, aracılar sağlayıcıya ve oturuma bağlı olarak yerel bellek içi geçmişi veya hizmet tarafından yönetilen geçmişi kullanır.

Aşağıdaki Foundry aracısı proje destekli model dağıtımı kullanır. Uygulamaya özgü bellek veya kişiselleştirme durumunun konuşma geçmişinin ötesinde olmasını istediğinizde bir bağlam sağlayıcısı ekleyin.

a := foundryprovider.NewAgent(
    endpoint,
    token,
    foundryprovider.ModelDeployment(model),
    foundryprovider.AgentConfig{
        Instructions: "You are a friendly assistant. Keep your answers brief.",
        Config: agent.Config{
            Name: "MemoryAgent",
        },
    },
)

Kullanıcı bilgilerini oturum durumunda depolayan ve kişiselleştirme yönergelerini ekleyen bir bağlam sağlayıcısı tanımlayın:

import (
    "context"
    "fmt"
    "strings"

    "github.com/microsoft/agent-framework-go/agent"
    "github.com/microsoft/agent-framework-go/message"
)

const userMemorySourceID = "user_memory"

type providerState struct {
    UserName string `json:"user_name,omitempty"`
}

func newUserMemoryProvider() agent.ContextProvider {
    return agent.NewContextProvider(agent.ContextProviderConfig{
        SourceID: userMemorySourceID,
        Provide:  provideUserMemory,
        Store:    storeUserMemory,
    })
}

func provideUserMemory(ctx context.Context, invoking agent.InvokingContext) ([]*message.Message, []agent.Option, error) {
    session, _ := agent.GetOption(invoking.Options, agent.WithSession)
    var state providerState
    _, _ = session.Get(userMemorySourceID, &state)

    instructions := "You don't know the user's name yet. Ask for it politely."
    if state.UserName != "" {
        instructions = fmt.Sprintf("The user's name is %s. Always address them by name.", state.UserName)
    }
    return nil, []agent.Option{agent.WithInstructions(instructions)}, nil
}

func storeUserMemory(ctx context.Context, invoked agent.InvokedContext) error {
    session, _ := agent.GetOption(invoked.Options, agent.WithSession)
    var state providerState
    _, _ = session.Get(userMemorySourceID, &state)
    for _, msg := range invoked.RequestMessages {
        text := strings.TrimSpace(msg.Contents.Text())
        lower := strings.ToLower(text)
        if idx := strings.Index(lower, "my name is"); idx >= 0 {
            parts := strings.Fields(text[idx+len("my name is"):])
            if len(parts) == 0 {
                continue
            }
            state.UserName = strings.Trim(parts[0], ".,!?")
            session.Set(userMemorySourceID, state)
            break
        }
    }
    return nil
}

Bağlam sağlayıcısı ile bir aracı oluşturun:

a := foundryprovider.NewAgent(
    endpoint,
    token,
    foundryprovider.ModelDeployment(model),
    foundryprovider.AgentConfig{
        Instructions: "You are a friendly assistant.",
        Config: agent.Config{
            Name:             "MemoryAgent",
            ContextProviders: []agent.ContextProvider{newUserMemoryProvider()},
        },
    },
)

Bunu çalıştırın — ajan artık bağlama erişimi var.

ctx := context.Background()
session, err := a.CreateSession(ctx)
if err != nil {
    panic(err)
}

// The provider doesn't know the user yet.
resp, err := a.RunText(ctx, "Hello, what is the square root of 9?", agent.WithSession(session)).Collect()
fmt.Println(resp, err)

// Teach the provider the user's name.
resp, err = a.RunText(ctx, "My name is Alice", agent.WithSession(session)).Collect()
fmt.Println(resp, err)

// Subsequent calls are personalized using session state.
resp, err = a.RunText(ctx, "What is 2 + 2?", agent.WithSession(session)).Collect()
fmt.Println(resp, err)

Tip

Çalıştırılabilir dosyanın tamamı için tam örneğe bakın.

Sonraki Adımlar

Daha derine gidin: