Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Historie chatu agenta a paměť jsou klíčové funkce, které umožňují agentům udržovat kontext napříč konverzacemi, pamatovat si uživatelské předvolby a poskytovat přizpůsobené prostředí. Agent Framework poskytuje několik funkcí, které vyhovují různým případům použití, od jednoduchého úložiště zpráv v paměti až po trvalé databáze a specializované paměťové služby.
Historie chatu
Rozhraní Agent Framework podporuje různé možnosti úložiště historie chatu. Dostupné možnosti se liší podle typu agenta a podkladových služeb použitých k sestavení agenta.
Mezi dva hlavní podporované scénáře patří:
-
Úložiště v paměti: Agent je založený na službě, která nepodporuje ukládání historie chatu v rámci služby (například Dokončení chatu OpenAI). Ve výchozím nastavení agent Framework ukládá úplnou historii chatu do
AgentThreadpaměti objektu, ale vývojáři mohou poskytnout vlastníChatMessageStoreimplementaci pro ukládání historie chatu do úložiště třetí strany v případě potřeby. -
Úložiště v rámci služby: Agent je založený na službě, která vyžaduje ukládání historie chatu v rámci služby (například trvalé agenty Azure AI Foundry). Agent Framework ukládá ID historie vzdáleného chatu v objektu
AgentThreada nepodporuje žádné další možnosti úložiště historie chatu.
Úložiště historie chatu v paměti
Pokud používáte službu, která nepodporuje ukládání historie chatu v rámci služby, rozhraní Agent Framework ve výchozím nastavení ukládá historii chatu do objektu AgentThread . V tomto případě se základní službě na každém spuštění agenta poskytne úplná historie chatu uložená v objektu vlákna a všechny nové zprávy. Tento návrh umožňuje přirozené konverzační prostředí s agentem. Volající zobrazí jenom novou zprávu uživatele a agent vrátí jenom nové odpovědi. Agent má ale přístup k celé historii konverzací a použije ho při generování odpovědi.
Pokud jako podkladovou službu pro agenty používáte dokončování chatu OpenAI, výsledkem následujícího kódu je objekt vlákna obsahující historii chatu ze spuštění agenta.
AIAgent agent = new OpenAIClient("<your_api_key>")
.GetChatClient(modelName)
.AsAIAgent(JokerInstructions, JokerName);
AgentThread thread = await agent.GetNewThreadAsync();
Console.WriteLine(await agent.RunAsync("Tell me a joke about a pirate.", thread));
Pokud jsou zprávy uložené v paměti, je možné načíst seznam zpráv z vlákna a manipulovat se zprávami přímo v případě potřeby.
IList<ChatMessage>? messages = thread.GetService<IList<ChatMessage>>();
Poznámka:
Načítání zpráv z objektu AgentThread tímto způsobem funguje pouze v případě, že se používá úložiště v paměti.
Snížení historie chatu s úložištěm v paměti
Integrovaná služba InMemoryChatMessageStore , která se ve výchozím nastavení používá, když podkladová služba nepodporuje úložiště v rámci služby, je možné nakonfigurovat s redukčním nástrojem pro správu velikosti historie chatu.
To je užitečné, abyste se vyhnuli překročení limitů velikosti kontextu základní služby.
Volitelná InMemoryChatMessageStoreMicrosoft.Extensions.AI.IChatReducer implementace může snížit velikost historie chatu.
Umožňuje také nakonfigurovat událost, během které se reduktor vyvolá, a to buď po přidání zprávy do historie chatu, nebo před vrácením historie chatu pro další vyvolání.
Pokud chcete nakonfigurovat InMemoryChatMessageStore redukční nástroj, můžete poskytnout továrnu pro vytvoření nového pro každý nový InMemoryChatMessageStoreAgentThread a předat ho redukčnímu nástroji podle vašeho výběru. Lze InMemoryChatMessageStore také předat volitelnou aktivační událost, která může být nastavena na buď InMemoryChatMessageStore.ChatReducerTriggerEvent.AfterMessageAdded nebo InMemoryChatMessageStore.ChatReducerTriggerEvent.BeforeMessagesRetrieval.
Objekt pro vytváření je asynchronní funkce, která přijímá kontextový objekt a token zrušení.
AIAgent agent = new OpenAIClient("<your_api_key>")
.GetChatClient(modelName)
.AsAIAgent(new ChatClientAgentOptions
{
Name = JokerName,
ChatOptions = new() { Instructions = JokerInstructions },
ChatMessageStoreFactory = (ctx, ct) => new ValueTask<ChatMessageStore>(
new InMemoryChatMessageStore(
new MessageCountingChatReducer(2),
ctx.SerializedState,
ctx.JsonSerializerOptions,
InMemoryChatMessageStore.ChatReducerTriggerEvent.AfterMessageAdded))
});
Poznámka:
Tato funkce je podporována pouze při použití funkce InMemoryChatMessageStore. Pokud má služba úložiště historie chatu v rámci služby, je na samotné službě, aby spravovala velikost historie chatu. Podobně platí, že pokud používáte úložiště třetích stran (viz níže), je to řešení úložiště třetí strany, které spravuje velikost historie chatu. Pokud zadáte ChatMessageStoreFactory úložiště zpráv, ale použijete službu s integrovaným úložištěm historie chatu, továrna se nepoužije.
Úložiště historie chatu služby odvození
Při použití služby, která vyžaduje ukládání historie chatu v rámci služby, agent Framework ukládá ID historie vzdáleného chatu v objektu AgentThread .
Pokud například použijete odpovědi OpenAI s úložištěm =true jako podkladovou službu pro agenty, následující kód způsobí, že objekt vlákna obsahující poslední ID odpovědi vrácené službou.
AIAgent agent = new OpenAIClient("<your_api_key>")
.GetOpenAIResponseClient(modelName)
.AsAIAgent(JokerInstructions, JokerName);
AgentThread thread = await agent.GetNewThreadAsync();
Console.WriteLine(await agent.RunAsync("Tell me a joke about a pirate.", thread));
Poznámka:
Některé služby, například odpovědi OpenAI, podporují buď úložiště historie chatu ve službě (store=true), nebo poskytují úplnou historii chatu při každém vyvolání (store=false). Proto v závislosti na režimu, ve které se služba používá, agent Framework buď ve výchozím nastavení uloží úplnou historii chatu do paměti, nebo uloží ID odkaz na uloženou historii chatu služby.
Úložiště historie chatu třetích stran
Při použití služby, která nepodporuje ukládání historie chatu v rámci služby, umožňuje rozhraní Agent Framework vývojářům nahradit výchozí úložiště historie chatu v paměti úložištěm historie chatu třetích stran. Vývojář musí poskytnout podtřídu základní abstraktní ChatMessageStore třídy.
Třída ChatMessageStore definuje rozhraní pro ukládání a načítání chatových zpráv. Vývojáři musí implementovat a InvokedAsyncInvokingAsync metody pro přidání zpráv do vzdáleného úložiště při jejich generování a načtení zpráv ze vzdáleného úložiště před vyvoláním základní služby.
Agent použije všechny zprávy vrácené InvokingAsync při zpracování uživatelského dotazu. Je na implementátoru ChatMessageStore zajistit, aby velikost historie chatu nepřekračovala kontextové okno podkladové služby.
Při implementaci vlastního ChatMessageStore úložiště, který ukládá historii chatu ve vzdáleném úložišti, by se historie chatu pro toto vlákno měla uložit pod klíčem, který je pro toto vlákno jedinečný. Implementace ChatMessageStore by měla tento klíč generovat a udržovat ho ve svém stavu.
ChatMessageStore má metodu Serialize , která lze přepsat k serializaci jeho stavu při serializaci vlákna. Měl ChatMessageStore by také poskytnout konstruktor, který jako vstup podporuje JsonElement deserializaci jeho stavu.
Chcete-li zadat vlastní ChatMessageStoreChatClientAgentobjekt , můžete použít ChatMessageStoreFactory možnost při vytváření agenta.
Tady je příklad ukazující, jak předat vlastní implementaci do ChatMessageStore chatu založeného na dokončení chatu ChatClientAgent Azure OpenAI.
Objekt pro vytváření je asynchronní funkce, která přijímá kontextový objekt a token zrušení.
AIAgent agent = new AzureOpenAIClient(
new Uri(endpoint),
new AzureCliCredential())
.GetChatClient(deploymentName)
.AsAIAgent(new ChatClientAgentOptions
{
Name = JokerName,
ChatOptions = new() { Instructions = JokerInstructions },
ChatMessageStoreFactory = (ctx, ct) => new ValueTask<ChatMessageStore>(
// 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.
new CustomMessageStore(
vectorStore,
ctx.SerializedState,
ctx.JsonSerializerOptions))
});
Návod
Podrobný příklad vytvoření vlastního úložiště zpráv najdete v kurzu Ukládání historie chatu v úložišti třetích stran .
Dlouhodobá paměť
Agent Framework umožňuje vývojářům poskytovat vlastní komponenty, které můžou extrahovat vzpomínky nebo poskytovat paměti agentům.
Aby vývojář takovou součást paměti implementoval, musí podtřídu abstraktní základní třídy podtřídy AIContextProvider . Tato třída má dvě základní metody a InvokingAsyncInvokedAsync. Při přepsání InvokedAsync umožňuje vývojářům kontrolovat všechny zprávy poskytované uživateli nebo generované agentem.
InvokingAsync umožňuje vývojářům vložit další kontext pro konkrétní spuštění agenta. Můžete zadat systémové pokyny, další zprávy a další funkce.
Návod
Podrobný příklad vytvoření vlastní součásti paměti najdete v kurzu Přidání paměti do agenta .
Serializace AgentThread
Je důležité mít možnost zachovat AgentThread objekt mezi vyvoláním agenta. To umožňuje situace, kdy se uživatel může zeptat agenta, a trvat dlouhou dobu, než se zeptá na další otázky. To umožňuje AgentThread , aby stav přežil služby nebo restartování aplikace.
I když je historie chatu uložená ve vzdáleném úložišti, AgentThread objekt stále obsahuje ID odkazující na historii vzdáleného chatu.
AgentThread Ztráta stavu proto způsobí ztrátu ID historie vzdáleného chatu.
Stejně AgentThread jako všechny objekty, které jsou k němu připojeny, proto poskytují metodu Serialize serializace jejich stavu. Poskytuje AIAgent také metodu DeserializeThreadAsync , která znovu vytvoří vlákno ze serializovaného stavu. Metoda DeserializeThreadAsync znovu vytvoří vlákno s ChatMessageStore a AIContextProvider nakonfigurovaným v agentu.
// 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 = await agent.DeserializeThreadAsync(serializedThreadState);
Poznámka:
AgentThread objekty mohou obsahovat více než jen historii chatu, například zprostředkovatelé kontextu mohou také ukládat stav v objektu vlákna. Proto je důležité vždy serializovat, ukládat a deserializovat celý AgentThread objekt, aby se zajistilo, že je zachován veškerý stav.
Důležité
Objekty vždy považují za AgentThread neprůžné, pokud si nejste jisti vnitřními objekty. Obsah se může lišit nejen podle typu agenta, ale také podle typu služby a konfigurace.
Výstraha
Deserializace vlákna s jiným agentem, než který ho původně vytvořil, nebo s agentem, který má jinou konfiguraci než původní agent, může vést k chybám nebo neočekávanému chování.
Typy paměti
Agent Framework podporuje několik typů paměti pro různé případy použití, včetně správy historie chatu v rámci krátkodobé paměti a poskytování rozšiřujících bodů pro extrakci, ukládání a vkládání dlouhodobých pamětí do agentů.
In-Memory Storage (výchozí)
Nejjednodušší forma paměti, ve které je historie konverzací uložena v paměti během modulu runtime aplikace. Toto je výchozí chování a nevyžaduje žádnou další konfiguraci.
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)
Trvalé úložiště zpráv
Pro aplikace, které potřebují zachovat historii konverzací napříč relacemi, poskytuje ChatMessageStore architektura implementace:
Integrovaný ChatMessageStore
Výchozí implementace v paměti, kterou lze serializovat:
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
)
Úložiště zpráv Redis
Pro produkční aplikace vyžadující trvalé úložiště:
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
)
Vlastní úložiště zpráv
Vlastní back-end úložiště můžete implementovat implementací :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"]
Návod
Podrobný příklad vytvoření vlastního úložiště zpráv najdete v kurzu Ukládání historie chatu v úložišti třetích stran .
Zprostředkovatelé kontextu (dynamická paměť)
Poskytovatelé kontextu umožňují sofistikované vzory paměti vložením relevantního kontextu před vyvolání každého agenta:
Základní zprostředkovatel kontextu
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
Návod
Podrobný příklad vytvoření vlastní součásti paměti najdete v kurzu Přidání paměti do agenta .
Externí paměťové služby
Architektura podporuje integraci se specializovanými paměťovými službami, jako je Mem0:
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
)
Serializace vláken a trvalost
Architektura podporuje serializaci celých stavů vlákna pro trvalost napříč restartováními aplikace:
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)