Aracılığıyla paylaş


Aracı Sohbet Geçmişi ve Belleği

Aracı sohbet geçmişi ve belleği, aracıların konuşmalar arasında bağlamı korumasına, kullanıcı tercihlerini hatırlamasına ve kişiselleştirilmiş deneyimler sağlamasına olanak sağlayan önemli özelliklerdir. Agent Framework, basit bellek içi sohbet iletisi depolamadan kalıcı veritabanlarına ve özel bellek hizmetlerine kadar farklı kullanım örneklerine uygun birden çok özellik sağlar.

Sohbet Geçmişi

Agent Framework tarafından çeşitli sohbet geçmişi depolama seçenekleri desteklenir. Kullanılabilir seçenekler aracı türüne ve aracıyı derlemek için kullanılan temel hizmetlere göre farklılık gösterir.

Desteklenen iki ana senaryo şunlardır:

  1. Bellek içi depolama: Aracı, sohbet geçmişinin hizmet içi depolamasını desteklemeyen bir hizmet üzerine kurulmuştur (ör. OpenAI Sohbet Tamamlama). Agent Framework varsayılan olarak tam sohbet geçmişini bellek içinde nesnede AgentThread depolar, ancak geliştiriciler gerekirse sohbet geçmişini 3. taraf bir mağazada depolamak için özel ChatMessageStore bir uygulama sağlayabilir.
  2. Hizmet içi depolama: Aracı, sohbet geçmişinin (örneğin Azure AI Foundry Kalıcı Aracıları) hizmet içi depolanmasını gerektiren bir hizmet üzerine kurulmuştur. Agent Framework, uzak sohbet geçmişinin kimliğini nesnede AgentThread depolar ve başka hiçbir sohbet geçmişi depolama seçeneği desteklenmez.

Bellek içi sohbet geçmişi depolama

Sohbet geçmişinin hizmet içi depolamasını desteklemeyen bir hizmet kullanırken, Agent Framework varsayılan olarak nesnede sohbet geçmişini bellek içinde AgentThread depolar. Bu durumda, iş parçacığı nesnesinde depolanan tam sohbet geçmişi ve tüm yeni iletiler, her aracı çalıştırmasında temel alınan hizmete sağlanacaktır. Bu, arayanın yalnızca yeni kullanıcı iletisini sağladığı ve aracının yalnızca yeni yanıtlar döndürdüğü, ancak aracının konuşma geçmişinin tamamına eriştiği ve yanıtını oluştururken bunu kullanacağı aracıyla doğal bir konuşma deneyimi sağlar.

Aracılar için temel hizmet olarak OpenAI Sohbet Tamamlama kullanılırken, aşağıdaki kod aracı çalıştırmasından sohbet geçmişini içeren iş parçacığı nesnesine neden olur.

AIAgent agent = new OpenAIClient("<your_api_key>")
     .GetChatClient(modelName)
     .CreateAIAgent(JokerInstructions, JokerName);
AgentThread thread = agent.GetNewThread();
Console.WriteLine(await agent.RunAsync("Tell me a joke about a pirate.", thread));

İletilerin bellekte depolandığı durumlarda, iş parçacığından ileti listesini almak ve gerekirse iletileri doğrudan işlemek mümkündür.

IList<ChatMessage>? messages = thread.GetService<IList<ChatMessage>>();

Uyarı

Nesneden AgentThread iletileri bu şekilde almak yalnızca bellek içi depolama kullanılıyorsa çalışır.

In-Memory depolama alanıyla Sohbet Geçmişi azaltma

Temel alınan hizmet hizmet içi depolamayı desteklemediğinde varsayılan olarak kullanılan yerleşik InMemoryChatMessageStore , sohbet geçmişinin boyutunu yönetmek için bir azaltıcı ile yapılandırılabilir. Bu, temel alınan hizmetin bağlam boyutu sınırlarını aşmamak için yararlıdır.

, InMemoryChatMessageStore sohbet geçmişinin boyutunu küçültmek için isteğe bağlı Microsoft.Extensions.AI.IChatReducer bir uygulama alabilir. Ayrıca, sohbet geçmişine bir ileti eklendikten sonra veya bir sonraki çağrı için sohbet geçmişi döndürülmeden önce azaltıcının çağrıldığı olayı yapılandırmanıza da olanak tanır.

bir azaltıcı ile yapılandırmak InMemoryChatMessageStore için, her yeni InMemoryChatMessageStore için yeni AgentThread bir fabrika oluşturup istediğiniz azaltıcıyı geçirebilirsiniz. veya InMemoryChatMessageStore olarak ayarlanabilen InMemoryChatMessageStore.ChatReducerTriggerEvent.AfterMessageAddedInMemoryChatMessageStore.ChatReducerTriggerEvent.BeforeMessagesRetrievalisteğe bağlı bir tetikleyici olayı da geçirilebilir.

AIAgent agent = new OpenAIClient("<your_api_key>")
    .GetChatClient(modelName)
    .CreateAIAgent(new ChatClientAgentOptions
    {
        Name = JokerName,
        Instructions = JokerInstructions,
        ChatMessageStoreFactory = ctx => new InMemoryChatMessageStore(
            new MessageCountingChatReducer(2),
            ctx.SerializedState,
            ctx.JsonSerializerOptions,
            InMemoryChatMessageStore.ChatReducerTriggerEvent.AfterMessageAdded)
    });

Uyarı

Bu özellik yalnızca kullanılırken InMemoryChatMessageStoredesteklenir. Bir hizmetin hizmet içi sohbet geçmişi depolama alanı olduğunda, sohbet geçmişinin boyutunu yönetmek hizmetin kendisine aittir. Benzer şekilde, 3. taraf depolamayı kullanırken (aşağıya bakın), sohbet geçmişi boyutunu yönetmek 3. taraf depolama çözümüne kadardır. İleti deposu için bir ChatMessageStoreFactory sağlarsanız ancak yerleşik sohbet geçmişi depolaması olan bir hizmet kullanıyorsanız fabrika kullanılmaz.

Çıkarım hizmeti sohbet geçmişi depolama

Sohbet geçmişinin hizmet içi depolanmasını gerektiren bir hizmeti kullanırken, Agent Framework uzak sohbet geçmişinin kimliğini nesnesinde AgentThread depolar.

Örneğin, aracılar için temel alınan hizmet olarak Store=true ile OpenAI Yanıtları kullanılırken aşağıdaki kod, hizmet tarafından döndürülen son yanıt kimliğini içeren iş parçacığı nesnesine neden olur.

AIAgent agent = new OpenAIClient("<your_api_key>")
     .GetOpenAIResponseClient(modelName)
     .CreateAIAgent(JokerInstructions, JokerName);
AgentThread thread = agent.GetNewThread();
Console.WriteLine(await agent.RunAsync("Tell me a joke about a pirate.", thread));

Uyarı

Örneğin OpenAI Yanıtları, sohbet geçmişinin hizmet içi depolanmasını (store=true) veya her çağrıda (store=false) tam sohbet geçmişini sağlamayı destekler. Bu nedenle, hizmetin kullanıldığı moda bağlı olarak, Agent Framework varsayılan olarak tüm sohbet geçmişini bellekte depolar veya hizmet tarafından depolanan sohbet geçmişine bir kimlik başvurusu depolar.

Üçüncü taraf sohbet geçmişi depolama

Agent Framework, sohbet geçmişinin hizmet içi depolamasını desteklemeyen bir hizmet kullanırken, geliştiricilerin sohbet geçmişinin varsayılan bellek içi depolama alanını 3. taraf sohbet geçmişi depolama alanıyla değiştirmesine olanak tanır. Geliştiricinin temel soyut ChatMessageStore sınıfın bir alt sınıfını sağlaması gerekir.

sınıfı, ChatMessageStore sohbet iletilerini depolamak ve almak için arabirimi tanımlar. Geliştiricilerin AddMessagesAsync , oluşturulan iletileri uzak depoya eklemek ve temel hizmeti çağırmadan önce uzak depodan iletileri almak için ve GetMessagesAsync yöntemlerini uygulaması gerekir.

Aracı, kullanıcı sorgusunu işlerken tarafından GetMessagesAsync döndürülen tüm iletileri kullanır. Sohbet geçmişinin boyutunun temel alınan hizmetin bağlam penceresini aşmadığından emin olmak için uygulayıcısına ChatMessageStore bağlıdır.

Sohbet geçmişini uzak bir mağazada depolayan bir özel ChatMessageStore uygulama sırasında, bu yazışmanın sohbet geçmişi bu yazışmaya özgü bir anahtar altında depolanmalıdır. Uygulamanın ChatMessageStore bu anahtarı oluşturması ve durumunda tutması gerekir. ChatMessageStore , iş parçacığı seri hale getirildiğinde durumunu serileştirmek için geçersiz kılınabilecek bir Serialize yönteme sahiptir. ayrıca ChatMessageStore , durumunun seri durumdan çıkarıldığını desteklemek için giriş olarak alan bir JsonElement oluşturucu da sağlamalıdır.

öğesine özel ChatMessageStore sağlamak için ChatClientAgentaracını oluştururken seçeneğini kullanabilirsiniz ChatMessageStoreFactory . Özel uygulamasının ChatMessageStore Azure OpenAI Sohbet Tamamlamayı temel alan bir ChatClientAgent uygulamasına nasıl geçirildiğini gösteren bir örnek aşağıda verilmiştir.

AIAgent agent = new AzureOpenAIClient(
    new Uri(endpoint),
    new AzureCliCredential())
     .GetChatClient(deploymentName)
     .CreateAIAgent(new ChatClientAgentOptions
     {
         Name = JokerName,
         Instructions = JokerInstructions,
         ChatMessageStoreFactory = ctx =>
         {
             // Create a new chat message store for this agent that stores the messages in a custom store.
             // Each thread must get its own copy of the CustomMessageStore, since the store
             // also contains the id that the thread is stored under.
             return new CustomMessageStore(vectorStore, ctx.SerializedState, ctx.JsonSerializerOptions);
         }
     });

Tip

Özel ileti deposu oluşturma hakkında ayrıntılı bir örnek için Sohbet Geçmişini 3. Taraf Depolamada Depolama öğreticisine bakın.

Uzun süreli bellek

Agent Framework, geliştiricilerin bellek ayıklayabilecek veya bir aracıya bellek sağlayabilecek özel bileşenler sağlamasına olanak tanır.

Böyle bir bellek bileşenini uygulamak için geliştiricinin soyut temel sınıfını alt sınıfına alması AIContextProvider gerekir. Bu sınıfın iki temel yöntemi vardır InvokingAsync ve InvokedAsync. Geçersiz kılındığında, InvokedAsync geliştiricilerin kullanıcılar tarafından sağlanan veya aracı tarafından oluşturulan tüm iletileri incelemesine olanak tanır. InvokingAsync geliştiricilerin belirli bir aracı çalıştırması için ek bağlam eklemesine olanak tanır. Sistem yönergeleri, ek iletiler ve ek işlevler sağlanabilir.

Tip

Özel bellek bileşeni oluşturma hakkında ayrıntılı bir örnek için Bkz. Aracıya Bellek Ekleme öğreticisi.

AgentThread Serileştirme

Aracı çağrıları arasında bir AgentThread nesneyi kalıcı hale getirmek önemlidir. Bu, kullanıcının aracıyla ilgili bir soru sorabileceği ve takip soruları sorması uzun sürebileceği durumlar için olanak sağlar. Bu, durumun hizmette veya uygulama yeniden başlatmalarında hayatta kalmasına olanak tanır AgentThread .

Sohbet geçmişi uzak bir depoda depolansa bile, AgentThread nesne yine de uzak sohbet geçmişine başvuran bir kimlik içerir. AgentThread Bu nedenle durumu kaybetmek, uzak sohbet geçmişinin kimliğinin de kaybolmasına neden olur.

AgentThread ve buna bağlı tüm nesneler, bu nedenle durumlarını seri hale getirmek için yöntemini sağlarSerializeAsync. ayrıca AIAgent serileştirilmiş durumdan bir iş parçacığını yeniden oluşturan bir yöntem sağlar DeserializeThread . DeserializeThread yöntemi, aracıda ve ChatMessageStore ile iş parçacığını AIContextProvider yeniden oluşturur.

// Serialize the thread state to a JsonElement, so it can be stored for later use.
JsonElement serializedThreadState = thread.Serialize();

// Re-create the thread from the JsonElement.
AgentThread resumedThread = AIAgent.DeserializeThread(serializedThreadState);

Uyarı

AgentThread nesneler yalnızca sohbet geçmişinden fazlasını içerebilir; örneğin bağlam sağlayıcıları da durumu iş parçacığı nesnesinde depolar. Bu nedenle, tüm durumun korunmasını sağlamak için nesnenin tamamını AgentThread her zaman seri hale getirmek, depolamak ve seri durumdan çıkarmak önemlidir.

Önemli

İç öğelerden çok emin değilseniz nesneleri her zaman opak nesneler olarak değerlendirin AgentThread . İçerikler yalnızca aracı türüne göre değil, hizmet türüne ve yapılandırmasına göre de farklılık gösterebilir.

Uyarı

bir iş parçacığını başlangıçta oluşturandan farklı bir aracıyla veya özgün aracıdan farklı bir yapılandırmaya sahip bir aracıyla seri durumdan çıkarma, hatalara veya beklenmeyen davranışlara neden olabilir.

Bellek Türleri

Agent Framework, kısa süreli belleğin bir parçası olarak sohbet geçmişini yönetme ve aracılara uzun süreli bellek ayıklama, depolama ve ekleme için uzantı noktaları sağlama dahil olmak üzere farklı kullanım durumlarına uyum sağlamak için çeşitli bellek türlerini destekler.

In-Memory Depolama (Varsayılan)

Konuşma geçmişinin uygulama çalışma zamanı sırasında bellekte depolandığı en basit bellek biçimi. Bu varsayılan davranıştır ve ek yapılandırma gerektirmez.

from agent_framework import ChatAgent
from agent_framework.openai import OpenAIChatClient

# Default behavior - uses in-memory storage
agent = ChatAgent(
    chat_client=OpenAIChatClient(),
    instructions="You are a helpful assistant."
)

# Conversation history is maintained in memory for this thread
thread = agent.get_new_thread()

response = await agent.run("Hello, my name is Alice", thread=thread)

Kalıcı İleti Depoları

Konuşma geçmişini oturumlar arasında kalıcı hale getirmek gereken uygulamalar için çerçeve aşağıdaki uygulamaları sağlar ChatMessageStore :

Yerleşik ChatMessageStore

Serileştirilebilen varsayılan bellek içi uygulama:

from agent_framework import ChatMessageStore

# Create a custom message store
def create_message_store():
    return ChatMessageStore()

agent = ChatAgent(
    chat_client=OpenAIChatClient(),
    instructions="You are a helpful assistant.",
    chat_message_store_factory=create_message_store
)

Redis İleti Deposu

Kalıcı depolama gerektiren üretim uygulamaları için:

from agent_framework.redis import RedisChatMessageStore

def create_redis_store():
    return RedisChatMessageStore(
        redis_url="redis://localhost:6379",
        thread_id="user_session_123",
        max_messages=100  # Keep last 100 messages
    )

agent = ChatAgent(
    chat_client=OpenAIChatClient(),
    instructions="You are a helpful assistant.",
    chat_message_store_factory=create_redis_store
)

Özel İleti Deposu

uygulamasını uygulayarak kendi depolama arka ucunuzu uygulayabilirsiniz ChatMessageStoreProtocol:

from agent_framework import ChatMessage, ChatMessageStoreProtocol
from typing import Any
from collections.abc import Sequence

class DatabaseMessageStore(ChatMessageStoreProtocol):
    def __init__(self, connection_string: str):
        self.connection_string = connection_string
        self._messages: list[ChatMessage] = []

    async def add_messages(self, messages: Sequence[ChatMessage]) -> None:
        """Add messages to database."""
        # Implement database insertion logic
        self._messages.extend(messages)

    async def list_messages(self) -> list[ChatMessage]:
        """Retrieve messages from database."""
        # Implement database query logic
        return self._messages

    async def serialize(self, **kwargs: Any) -> Any:
        """Serialize store state for persistence."""
        return {"connection_string": self.connection_string}

    async def update_from_state(self, serialized_store_state: Any, **kwargs: Any) -> None:
        """Update store from serialized state."""
        if serialized_store_state:
            self.connection_string = serialized_store_state["connection_string"]

Tip

Özel ileti deposu oluşturma hakkında ayrıntılı bir örnek için Sohbet Geçmişini 3. Taraf Depolamada Depolama öğreticisine bakın.

Bağlam Sağlayıcıları (Dinamik Bellek)

Bağlam sağlayıcıları, her aracı çağırmadan önce ilgili bağlamı ekleyerek gelişmiş bellek desenleri sağlar:

Temel Bağlam Sağlayıcısı

from agent_framework import ContextProvider, Context, ChatMessage
from collections.abc import MutableSequence
from typing import Any

class UserPreferencesMemory(ContextProvider):
    def __init__(self):
        self.preferences = {}

    async def invoking(self, messages: ChatMessage | MutableSequence[ChatMessage], **kwargs: Any) -> Context:
        """Provide user preferences before each invocation."""
        if self.preferences:
            preferences_text = ", ".join([f"{k}: {v}" for k, v in self.preferences.items()])
            instructions = f"User preferences: {preferences_text}"
            return Context(instructions=instructions)
        return Context()

    async def invoked(
        self,
        request_messages: ChatMessage | Sequence[ChatMessage],
        response_messages: ChatMessage | Sequence[ChatMessage] | None = None,
        invoke_exception: Exception | None = None,
        **kwargs: Any,
    ) -> None:
        """Extract and store user preferences from the conversation."""
        # Implement preference extraction logic
        pass

Tip

Özel bellek bileşeni oluşturma hakkında ayrıntılı bir örnek için Bkz. Aracıya Bellek Ekleme öğreticisi.

Dış Bellek Hizmetleri

Çerçeve, Mem0 gibi özel bellek hizmetleriyle tümleştirmeyi destekler:

from agent_framework.mem0 import Mem0Provider

# Using Mem0 for advanced memory capabilities
memory_provider = Mem0Provider(
    api_key="your-mem0-api-key",
    user_id="user_123",
    application_id="my_app"
)

agent = ChatAgent(
    chat_client=OpenAIChatClient(),
    instructions="You are a helpful assistant with memory.",
    context_providers=memory_provider
)

İş Parçacığı Serileştirme ve Kalıcılık

Çerçeve, uygulama yeniden başlatmalarında kalıcılık için tüm iş parçacığı durumlarının serileştirilmesini destekler:

import json

# Create agent and thread
agent = ChatAgent(chat_client=OpenAIChatClient())
thread = agent.get_new_thread()

# Have conversation
await agent.run("Hello, my name is Alice", thread=thread)

# Serialize thread state
serialized_thread = await thread.serialize()
# Save to file/database
with open("thread_state.json", "w") as f:
    json.dump(serialized_thread, f)

# Later, restore the thread
with open("thread_state.json", "r") as f:
    thread_data = json.load(f)

restored_thread = await agent.deserialize_thread(thread_data)
# Continue conversation with full context
await agent.run("What's my name?", thread=restored_thread)

Sonraki Adımlar