Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Contextproviders worden rond elke aanroep uitgevoerd om context toe te voegen vóór uitvoering en gegevens te verwerken na uitvoering.
Opmerking
Zie Contextproviderintegraties voor een lijst met vooraf gebouwde contextproviders die u met uw agent kunt gebruiken.
Ingebouwd patroon
Configureer providers via constructoropties bij het maken van een agent.
AIContextProvider is het ingebouwde extensiepunt voor geheugen-/contextverrijking.
AIAgent agent = new OpenAIClient("<your_api_key>")
.GetChatClient(modelName)
.AsAIAgent(new ChatClientAgentOptions()
{
ChatOptions = new() { Instructions = "You are a helpful assistant." },
AIContextProviders = [
new MyCustomMemoryProvider()
],
});
AgentSession session = await agent.CreateSessionAsync();
Console.WriteLine(await agent.RunAsync("Remember my name is Alice.", session));
Tip
Zie Contextproviderintegraties voor een lijst met vooraf gebouwde AIContextProvider implementaties.
Het normale patroon is het configureren van providers bij het maken van een agent via context_providers=[...].
InMemoryHistoryProvider is de ingebouwde geschiedenisprovider die wordt gebruikt voor lokaal gespreksgeheugen.
from agent_framework import Agent, InMemoryHistoryProvider
from agent_framework.openai import OpenAIChatClient
agent = Agent(
client=OpenAIChatClient(),
name="MemoryBot",
instructions="You are a helpful assistant.",
context_providers=[InMemoryHistoryProvider("memory", load_messages=True)],
)
session = agent.create_session()
await agent.run("Remember that I prefer vegetarian food.", session=session)
RawAgent kan automatisch toevoegen InMemoryHistoryProvider() met de standaardbron-id "in_memory" in specifieke gevallen, maar voeg deze expliciet toe wanneer u deterministisch lokaal geheugengedrag wilt.
Door bestanden ondersteund geheugen in sessies
Gebruik FileMemoryProvider wanneer het model moet bepalen wat u wilt opslaan en intrekken via file_memory_* hulpprogramma's. In Python wordt de werkmap weggelaten scope uit de huidige sessie-id, zodat afzonderlijke sessies geen geheugenbestanden delen. Geef een stabiele scope, zoals een gebruikers-id, door om dezelfde geheugenbestanden te delen in sessies en kies een AgentFileStore implementatie voor de back-upopslag.
# 1. Create the file store the provider will use to persist memory files.
# Here we use a file-system backed store rooted at a local
# ``agent-file-memory`` folder, but any AgentFileStore implementation can
# be used, e.g. InMemoryAgentFileStore or a custom blob-backed store.
memory_root = Path(__file__).parent / "agent-file-memory"
store = FileSystemAgentFileStore(memory_root)
# 2. Create the FileMemoryProvider over that store.
# The ``scope`` determines the scope and lifetime of the memories:
# - A stable scope, like the per-user one below, gives durable memories
# shared by every session for that user. That is what allows the second
# conversation further down to recall what the user said in the first.
# - Omitting ``scope`` (the default) isolates memories to a single session
# (the working folder is derived from the session id).
file_memory_provider = FileMemoryProvider(store, scope=f"users/{USER_ID}")
# 3. Attach the provider to the agent so it gets the file_memory_* tools.
agent = Agent(
client=client,
name="TravelAssistant",
instructions=(
"You are a helpful travel assistant. Remember what the user tells you about "
"themselves so that you can give better recommendations later."
),
context_providers=[file_memory_provider],
)
Configureer providers via agent.Config.ContextProviders tijdens het maken van een agent. Contextproviders injecteren extra context voordat elke agent wordt uitgevoerd en kan de status behouden na elke uitvoering.
a := foundryprovider.NewAgent(endpoint, token, foundryprovider.ModelDeployment(model), foundryprovider.AgentConfig{
Config: agent.Config{
ContextProviders: []agent.ContextProvider{provider},
},
})
Contextproviders gebruiken met Harness Agent
De bovenstaande handmatige patronen koppelen alleen de providers die u kiest. Harness Agent stelt een geordende providerset samen wanneer deze wordt gemaakt. Gebruik de bouwopties van elke SDK om standaardinstellingen uit te schakelen of te vervangen en extra providers toe te voegen.
HarnessAgent
TodoProviderschakelt , AgentModeProvideren FileMemoryProviderAgentSkillsProvider standaard in. Het voegt providers toe van HarnessAgentOptions.AIContextProviders na die ingebouwde.
HarnessAgent agent = chatClient.AsHarnessAgent(new HarnessAgentOptions
{
AIContextProviders = [new MyCustomMemoryProvider()],
DisableAgentSkillsProvider = true,
});
DisableAgentModeProviderStandaardwaarden gebruikenDisableTodoProvider, en DisableAgentSkillsProviderDisableFileMemoryverwijderen. Configureer de modus en vaardigheden met AgentModeProviderOptions en AgentSkillsSource; vervang bestandsgeheugenopslag door FileMemoryStore. Bestandstoegang is opt-in en FileAccessStoreFileAccessProviderOptions, en achtergronddelegering is opt-in through BackgroundAgents en BackgroundAgentsProviderOptions.
AsHarnessAgent(options) en new HarnessAgent(chatClient, options) accepteer hetzelfde HarnessAgentOptions.
create_harness_agent bestelt eerst de geschiedenisprovider en vervolgens compressie na uitvoering wanneer deze is ingeschakeld, gevolgd door todo-, modus- en bestandsgeheugenproviders. Bestandsgeheugen is standaard ingeschakeld; vaardigheden, bestandstoegang, achtergrondagenten en shell-context zijn opt-in. Providers die worden doorgegeven context_providers= , worden als laatste toegevoegd.
agent = create_harness_agent(
client,
context_providers=[UserPreferenceProvider()],
disable_mode=True,
skills_paths=["./skills"],
)
Gebruik history_provider, todo_provideren mode_provider vervang deze standaardwaarden door disable_todo, disable_modeen disable_file_memory als opt-outs. Gebruik file_memory_store dit om de standaardopslag {cwd}/agent-file-memory te vervangen. Schakel optionele providers in met file_access_store, skills_provider of , background_agentsen skills_pathsshell_executor; hun gerelateerde installatieparameters configureren machtigingen, instructies en gedrag van de omgeving.
Harness Agent is momenteel niet beschikbaar in de Go SDK. Voeg contextproviders expliciet toe via agent.Config.ContextProviders.
Aangepaste context-provider
Gebruik aangepaste contextproviders wanneer u dynamische instructies/berichten/hulpprogramma's moet injecteren of de status na uitvoeringen moet extraheren.
De basisklasse voor contextproviders is Microsoft.Agents.AI.AIContextProvider.
Contextproviders nemen deel aan de agentpijplijn, kunnen bijdragen aan agent-invoerberichten of deze overschrijven en kunnen informatie extraheren uit nieuwe berichten.
AIContextProvider heeft verschillende virtuele methoden die kunnen worden overschreven om uw eigen aangepaste contextprovider te implementeren.
Zie de verschillende implementatieopties hieronder voor meer informatie over wat u wilt overschrijven.
AIContextProvider Status
Een AIContextProvider exemplaar is gekoppeld aan een agent en hetzelfde exemplaar wordt gebruikt voor alle sessies.
Dit betekent dat de AIContextProvider geen sessiespecifieke status mag opslaan in het providerexemplaar.
Het AIContextProvider kan een verwijzing hebben naar een geheugenserviceclient in een veld, maar mag geen id hebben voor de specifieke set geheugens in een veld.
In plaats daarvan kan de AIContextProvider sessiespecifieke waarden opslaan, zoals geheugen-id's, berichten of iets anders dat relevant is in het AgentSession zelf. De virtuele methoden op AIContextProvider krijgen allemaal een referentie naar de huidige AIAgent en AgentSession.
Er is een hulpprogrammaklasse beschikbaar om eenvoudig de getypte status op te slaan in de AgentSessionklasse:
// First define a type containing the properties to store in state
internal class MyCustomState
{
public string? MemoryId { get; set; }
}
// Create the helper
var sessionStateHelper = new ProviderSessionState<MyCustomState>(
// stateInitializer is called when there is no state in the session for this AIContextProvider yet
stateInitializer: currentSession => new MyCustomState() { MemoryId = Guid.NewGuid().ToString() },
// The key under which to store state in the session for this provider. Make sure it does not clash with the keys of other providers.
stateKey: this.GetType().Name,
// An optional jsonSerializerOptions to control the serialization/deserialization of the custom state object
jsonSerializerOptions: myJsonSerializerOptions);
// Using the helper you can read state:
MyCustomState state = sessionStateHelper.GetOrInitializeState(session);
Console.WriteLine(state.MemoryId);
// And write state:
sessionStateHelper.SaveState(session, state);
Eenvoudige AIContextProvider implementatie
De eenvoudigste AIContextProvider implementatie overschrijft doorgaans twee methoden:
- AIContextProvider.ProvideAIContextAsync : laad relevante gegevens en retourneer aanvullende instructies, berichten of hulpprogramma's.
- AIContextProvider.StoreAIContextAsync : pak alle relevante gegevens uit nieuwe berichten en sla ze op.
Hier volgt een voorbeeld van een eenvoudige AIContextProvider integratie met een geheugenservice.
internal sealed class SimpleServiceMemoryProvider : AIContextProvider
{
private readonly ProviderSessionState<State> _sessionState;
private readonly ServiceClient _client;
public SimpleServiceMemoryProvider(ServiceClient client, Func<AgentSession?, State>? stateInitializer = null)
: base(null, null)
{
this._sessionState = new ProviderSessionState<State>(
stateInitializer ?? (_ => new State()),
this.GetType().Name);
this._client = client;
}
public override string StateKey => this._sessionState.StateKey;
protected override ValueTask<AIContext> ProvideAIContextAsync(InvokingContext context, CancellationToken cancellationToken = default)
{
var state = this._sessionState.GetOrInitializeState(context.Session);
if (state.MemoriesId == null)
{
// No stored memories yet.
return new ValueTask<AIContext>(new AIContext());
}
// Find memories that match the current user input.
var memories = this._client.LoadMemories(state.MemoriesId, string.Join("\n", context.AIContext.Messages?.Select(x => x.Text) ?? []));
// Return a new message that contains the text from any memories that were found.
return new ValueTask<AIContext>(new AIContext
{
Messages = [new ChatMessage(ChatRole.User, "Here are some memories to help answer the user question: " + string.Join("\n", memories.Select(x => x.Text)))]
});
}
protected override async ValueTask StoreAIContextAsync(InvokedContext context, CancellationToken cancellationToken = default)
{
var state = this._sessionState.GetOrInitializeState(context.Session);
// Create a memory container in the service for this session
// and save the returned id in the session.
state.MemoriesId ??= this._client.CreateMemoryContainer();
this._sessionState.SaveState(context.Session, state);
// Use the service to extract memories from the user input and agent response.
await this._client.StoreMemoriesAsync(state.MemoriesId, context.RequestMessages.Concat(context.ResponseMessages ?? []), cancellationToken);
}
public class State
{
public string? MemoriesId { get; set; }
}
}
Geavanceerde AIContextProvider implementatie
Een geavanceerdere implementatie kan ervoor kiezen om de volgende methoden te overschrijven:
- AIContextProvider.InvokingCoreAsync - Wordt opgeroepen voordat de agent de LLM aanroept en hiermee kan de lijst met aanvraagberichten, hulpprogramma's en instructies worden gewijzigd.
- AIContextProvider.InvokedCoreAsync : aangeroepen nadat de agent de LLM heeft aangeroepen en toegang heeft tot alle aanvraag- en antwoordberichten.
AIContextProvider biedt basis-implementaties van InvokingCoreAsync en InvokedCoreAsync.
De InvokingCoreAsync basis-implementatie doet het volgende:
- filtert de lijst met invoerberichten op alleen berichten die door de beller zijn doorgegeven aan de agent. Houd er rekening mee dat dit filter kan worden overschreven via de
provideInputMessageFilterparameter in deAIContextProviderconstructor. - Roept
ProvideAIContextAsyncop met de gefilterde aanvraagberichten, bestaande hulpprogramma's en instructies. - stempelt alle berichten die door
ProvideAIContextAsyncworden geretourneerd met broninformatie, waarmee wordt aangegeven dat deze berichten afkomstig zijn van deze contextprovider. - voegt de berichten, hulpprogramma's en instructies die door
ProvideAIContextAsyncworden geretourneerd samen met de bestaande om de invoer te creëren die door de agent wordt gebruikt. Berichten, hulpprogramma's en instructies worden toegevoegd aan bestaande berichten.
De InvokedCoreAsync basis doet het volgende:
- controleert of de uitvoering is mislukt en als dat het geval is, retourneert zonder verdere verwerking.
- filtert de lijst met invoerberichten op alleen berichten die door de beller zijn doorgegeven aan de agent. Houd er rekening mee dat dit filter kan worden overschreven via de
storeInputMessageFilterparameter in deAIContextProviderconstructor. - geeft de gefilterde aanvraagberichten en alle antwoordberichten door aan
StoreAIContextAsyncvoor opslag.
Het is mogelijk om deze methoden te overschrijven om een AIContextProvider te implementeren, maar hiervoor moet de implementator de basisfunctionaliteit zelf implementeren waar nodig.
Hier volgt een voorbeeld van een dergelijke implementatie.
internal sealed class AdvancedServiceMemoryProvider : AIContextProvider
{
private readonly ProviderSessionState<State> _sessionState;
private readonly ServiceClient _client;
public AdvancedServiceMemoryProvider(ServiceClient client, Func<AgentSession?, State>? stateInitializer = null)
: base(null, null)
{
this._sessionState = new ProviderSessionState<State>(
stateInitializer ?? (_ => new State()),
this.GetType().Name);
this._client = client;
}
public override string StateKey => this._sessionState.StateKey;
protected override async ValueTask<AIContext> InvokingCoreAsync(InvokingContext context, CancellationToken cancellationToken = default)
{
var state = this._sessionState.GetOrInitializeState(context.Session);
if (state.MemoriesId == null)
{
// No stored memories yet.
return new AIContext();
}
// We only want to search for memories based on user input, and exclude chat history or other AI context provider messages.
var filteredInputMessages = context.AIContext.Messages?.Where(m => m.GetAgentRequestMessageSourceType() == AgentRequestMessageSourceType.External);
// Find memories that match the current user input.
var memories = this._client.LoadMemories(state.MemoriesId, string.Join("\n", filteredInputMessages?.Select(x => x.Text) ?? []));
// Create a message for the memories, and stamp it to indicate where it came from.
var memoryMessages =
[new ChatMessage(ChatRole.User, "Here are some memories to help answer the user question: " + string.Join("\n", memories.Select(x => x.Text)))]
.Select(m => m.WithAgentRequestMessageSource(AgentRequestMessageSourceType.AIContextProvider, this.GetType().FullName!));
// Return a new merged AIContext.
return new AIContext
{
Instructions = context.AIContext.Instructions,
Messages = context.AIContext.Messages.Concat(memoryMessages),
Tools = context.AIContext.Tools
};
}
protected override async ValueTask InvokedCoreAsync(InvokedContext context, CancellationToken cancellationToken = default)
{
if (context.InvokeException is not null)
{
return;
}
var state = this._sessionState.GetOrInitializeState(context.Session);
// Create a memory container in the service for this session
// and save the returned id in the session.
state.MemoriesId ??= this._client.CreateMemoryContainer();
this._sessionState.SaveState(context.Session, state);
// We only want to store memories based on user input and agent output, and exclude messages from chat history or other AI context providers to avoid feedback loops.
var filteredRequestMessages = context.RequestMessages.Where(m => m.GetAgentRequestMessageSourceType() == AgentRequestMessageSourceType.External);
// Use the service to extract memories from the user input and agent response.
await this._client.StoreMemoriesAsync(state.MemoriesId, filteredRequestMessages.Concat(context.ResponseMessages ?? []), cancellationToken);
}
public class State
{
public string? MemoriesId { get; set; }
}
}
from typing import Any
from agent_framework import AgentSession, ContextProvider, SessionContext
class UserPreferenceProvider(ContextProvider):
def __init__(self) -> None:
super().__init__("user-preferences")
async def before_run(
self,
*,
agent: Any,
session: AgentSession,
context: SessionContext,
state: dict[str, Any],
) -> None:
if favorite := state.get("favorite_food"):
context.extend_instructions(self.source_id, f"User's favorite food is {favorite}.")
async def after_run(
self,
*,
agent: Any,
session: AgentSession,
context: SessionContext,
state: dict[str, Any],
) -> None:
for message in context.input_messages:
text = (message.text or "") if hasattr(message, "text") else ""
if isinstance(text, str) and "favorite food is" in text.lower():
state["favorite_food"] = text.split("favorite food is", 1)[1].strip().rstrip(".")
Opmerking
ContextProvider en HistoryProvider zijn de canonieke Python-basisklassen.
Contextproviders kunnen ook chat- of functie-middleware toevoegen voor de huidige aanroep door aan te roepen context.extend_middleware(self.source_id, middleware). De agent platt deze toevoegingen met context.get_middleware() en past deze toe in providervolgorde voordat de chatclient wordt aanroepen.
Dynamische selectie van hulpprogramma's
Contextproviders kunnen hulpprogramma's toevoegen voor de huidige aanroep met context.extend_tools(self.source_id, tools). Zie het voorbeeld dynamic_tool_exposure voor het geleidelijk laden van hulpprogramma's tijdens een lus met functieaanroepen. Zie Microsoft Foundry Toolbox voor bundels met beheerde hulpprogramma's.
Aangepaste geschiedenisprovider
Geschiedenisproviders zijn contextproviders die gespecialiseerd zijn voor het laden/opslaan van berichten.
from collections.abc import Sequence
from typing import Any
from agent_framework import HistoryProvider, Message
class DatabaseHistoryProvider(HistoryProvider):
def __init__(self, db: Any) -> None:
super().__init__("db-history", load_messages=True)
self._db = db
async def get_messages(
self,
session_id: str | None,
*,
state: dict[str, Any] | None = None,
**kwargs: Any,
) -> list[Message]:
key = (state or {}).get("history_key", session_id or "default")
rows = await self._db.load_messages(key)
return [Message.from_dict(row) for row in rows]
async def save_messages(
self,
session_id: str | None,
messages: Sequence[Message],
*,
state: dict[str, Any] | None = None,
**kwargs: Any,
) -> None:
if not messages:
return
if state is not None:
key = state.setdefault("history_key", session_id or "default")
else:
key = session_id or "default"
await self._db.save_messages(key, [m.to_dict() for m in messages])
Important
In Python kunt u meerdere geschiedenisproviders configureren, maar slechts één zou load_messages=True moeten gebruiken.
Gebruik extra providers voor diagnostische evaluaties met load_messages=False en store_context_messages=True, zodat ze naast invoer/uitvoer ook de context van andere providers vastleggen.
Als u lokale geschiedenis nodig hebt om elke modeloproep in een tool-lus te behouden, raadpleegt u Storage.
Voorbeeldpatroon:
primary = DatabaseHistoryProvider(db)
audit = InMemoryHistoryProvider("audit", load_messages=False, store_context_messages=True)
agent = Agent(client=OpenAIChatClient(), context_providers=[primary, audit])
Definieer een aangepaste contextprovider met een Provide callback:
import (
"context"
"github.com/microsoft/agent-framework-go/agent"
"github.com/microsoft/agent-framework-go/message"
)
provider := agent.NewContextProvider(agent.ContextProviderConfig{
SourceID: "user_memory",
Provide: func(ctx context.Context, invoking agent.InvokingContext) ([]*message.Message, []agent.Option, error) {
return nil, []agent.Option{agent.WithInstructions("User prefers short answers.")}, nil
},
})
Contextproviders kunnen de sessiestatus lezen en schrijven:
Provide: func(ctx context.Context, invoking agent.InvokingContext) ([]*message.Message, []agent.Option, error) {
session, _ := agent.GetOption(invoking.Options, agent.WithSession)
var state MyState
_, _ = session.Get("my_key", &state)
return nil, nil, nil
},
Store: func(ctx context.Context, invoked agent.InvokedContext) error {
session, _ := agent.GetOption(invoked.Options, agent.WithSession)
session.Set("my_key", updatedState)
return nil
},