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.
Kontext modulu runtime poskytuje middleware s přístupem k informacím o aktuálním spouštěcím prostředí a požadavku. To umožňuje vzory, jako je konfigurace relace, chování specifické pro uživatele a dynamické chování middlewaru na základě podmínek za běhu.
V jazyce C# kontext modulu runtime prochází třemi hlavními plochami:
-
AgentRunOptions.AdditionalPropertiespro metadata klíč-hodnota pro spuštění, která middleware a nástroje mohou číst. -
FunctionInvocationContextpro kontrolu a úpravu argumentů volání nástroje uvnitř middlewaru vyvolání funkce. -
AgentSession.StateBagpro sdílený stav, který přetrvává napříč běhy v rámci konverzace.
Použijte nejužší povrch, který se vejde. Metadata pro jednotlivé spuštění patří do AdditionalProperties, trvalý stav konverzace patří do relace StateBaga manipulace s argumenty nástroje patří do middlewaru vyvolání funkce.
Návod
Informace o tom, jak rozsah middlewaru ovlivňuje přístup k kontextu modulu runtime, najdete na stránce Agent vs. Spustit obor .
Volba vhodné plochy modulu runtime
| Případ použití | Plocha rozhraní API | Přístup z |
|---|---|---|
| Sdílení stavu konverzace nebo dat napříč spuštěními | AgentSession.StateBag |
session.StateBag ve spuštění middlewaru AIAgent.CurrentRunContext?.Session v nástrojích |
| Předání metadat pro jednotlivé spuštění middlewaru nebo nástrojům | AgentRunOptions.AdditionalProperties |
options.AdditionalProperties ve spuštění middlewaru AIAgent.CurrentRunContext?.RunOptions v nástrojích |
| Kontrola nebo úprava argumentů volání nástroje v middlewaru | FunctionInvocationContext |
Zpětné volání middlewaru funkce |
Předání hodnot pro jednotlivé spuštění prostřednictvím AgentRunOptions
AgentRunOptions Používá AdditionalProperties se k připojení dat klíč-hodnota pro jednotlivé spuštění. Middleware vyvolání funkce může tyto hodnoty předat do argumentů nástroje.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Threading;
using System.Threading.Tasks;
using Azure.AI.Projects;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
[Description("Send an email to the specified address.")]
static string SendEmail(
[Description("Recipient email address.")] string address,
[Description("User ID of the sender.")] string userId,
[Description("Tenant name.")] string tenant = "default")
{
return $"Queued email for {address} from {userId} ({tenant})";
}
// Function invocation middleware that injects per-run values into tool arguments
async ValueTask<object?> InjectRunContext(
AIAgent agent,
FunctionInvocationContext context,
Func<FunctionInvocationContext, CancellationToken, ValueTask<object?>> next,
CancellationToken cancellationToken)
{
var runOptions = AIAgent.CurrentRunContext?.RunOptions;
if (runOptions?.AdditionalProperties is { } props)
{
if (props.TryGetValue("user_id", out var userId))
{
context.Arguments["userId"] = userId;
}
if (props.TryGetValue("tenant", out var tenant))
{
context.Arguments["tenant"] = tenant;
}
}
return await next(context, cancellationToken);
}
AIAgent baseAgent = new AIProjectClient(
new Uri("<your-foundry-project-endpoint>"),
new DefaultAzureCredential())
.AsAIAgent(
model: "gpt-4o-mini",
instructions: "Send email updates.",
tools: [AIFunctionFactory.Create(SendEmail)]);
var agent = baseAgent
.AsBuilder()
.Use(InjectRunContext)
.Build();
var response = await agent.RunAsync(
"Email the launch update to finance@example.com",
options: new AgentRunOptions
{
AdditionalProperties = new AdditionalPropertiesDictionary
{
["user_id"] = "user-123",
["tenant"] = "contoso",
}
});
Console.WriteLine(response);
Výstraha
DefaultAzureCredential je vhodný pro vývoj, ale vyžaduje pečlivé zvážení v produkčním prostředí. V produkčním prostředí zvažte použití konkrétních přihlašovacích údajů (např ManagedIdentityCredential. ) k zabránění problémům s latencí, neúmyslnému testování přihlašovacích údajů a potenciálním bezpečnostním rizikům z náhradních mechanismů.
Middleware čte hodnoty AgentRunOptions.AdditionalProperties pro jednotlivé spuštění z okolí AIAgent.CurrentRunContext a vloží je do nástroje FunctionInvocationContext.Arguments před spuštěním nástroje.
Middleware vyvolání funkce přijímá kontext.
Middleware vyvolání funkce používá FunctionInvocationContext ke kontrole nebo úpravě argumentů nástroje, zachycení výsledků nebo přeskočení provádění nástrojů úplně.
using System;
using System.Threading;
using System.Threading.Tasks;
using Azure.AI.Projects;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
async ValueTask<object?> EnrichToolContext(
AIAgent agent,
FunctionInvocationContext context,
Func<FunctionInvocationContext, CancellationToken, ValueTask<object?>> next,
CancellationToken cancellationToken)
{
if (!context.Arguments.ContainsKey("tenant"))
{
context.Arguments["tenant"] = "contoso";
}
if (!context.Arguments.ContainsKey("requestSource"))
{
context.Arguments["requestSource"] = "middleware";
}
return await next(context, cancellationToken);
}
AIAgent baseAgent = new AIProjectClient(
new Uri("<your-foundry-project-endpoint>"),
new DefaultAzureCredential())
.AsAIAgent(
model: "gpt-4o-mini",
instructions: "Send email updates.",
tools: [AIFunctionFactory.Create(SendEmail)]);
var agent = baseAgent
.AsBuilder()
.Use(EnrichToolContext)
.Build();
Middleware obdrží kontext vyvolání funkce a volání next pro pokračování kanálu. Před voláním nextztlumte context.Arguments a nástroj zobrazí aktualizované hodnoty.
Použití AgentSession.StateBag pro sdílený stav modulu runtime
using System;
using System.ComponentModel;
using System.Threading;
using System.Threading.Tasks;
using Azure.AI.Projects;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
[Description("Store the specified topic in session state.")]
static string RememberTopic(
[Description("Topic to remember.")] string topic)
{
var session = AIAgent.CurrentRunContext?.Session;
if (session is null)
{
return "No session available.";
}
session.StateBag.SetValue("topic", topic);
return $"Stored '{topic}' in session state.";
}
AIAgent agent = new AIProjectClient(
new Uri("<your-foundry-project-endpoint>"),
new DefaultAzureCredential())
.AsAIAgent(
model: "gpt-4o-mini",
instructions: "Remember important topics.",
tools: [AIFunctionFactory.Create(RememberTopic)]);
var session = await agent.CreateSessionAsync();
await agent.RunAsync("Remember that the budget review is on Friday.", session: session);
Console.WriteLine(session.StateBag.GetValue<string>("topic"));
Předat relaci explicitně session: a přistupovat k ní z nástrojů prostřednictvím AIAgent.CurrentRunContext?.Session. Poskytuje StateBag typově bezpečné úložiště bezpečné pro přístup z více vláken, které se udržuje napříč běhy ve stejné relaci.
Sdílení stavu relace napříč middlewarem a nástroji
Spuštění middlewaru může číst a zapisovat relace StateBaga všechny změny jsou viditelné pro vyvolání middlewaru a nástrojů spuštěných ve stejném požadavku.
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Azure.AI.Projects;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
// Run middleware that stamps the session with request metadata
async Task<AgentResponse> StampRequestMetadata(
IEnumerable<ChatMessage> messages,
AgentSession? session,
AgentRunOptions? options,
AIAgent innerAgent,
CancellationToken cancellationToken)
{
if (session is not null && options?.AdditionalProperties is { } props)
{
if (props.TryGetValue("request_id", out var requestId))
{
session.StateBag.SetValue("requestId", requestId?.ToString());
}
}
return await innerAgent.RunAsync(messages, session, options, cancellationToken);
}
AIAgent baseAgent = new AIProjectClient(
new Uri("<your-foundry-project-endpoint>"),
new DefaultAzureCredential())
.AsAIAgent(
model: "gpt-4o-mini",
instructions: "You are a helpful assistant.");
var agent = baseAgent
.AsBuilder()
.Use(runFunc: StampRequestMetadata, runStreamingFunc: null)
.Build();
var session = await agent.CreateSessionAsync();
await agent.RunAsync(
"Hello!",
session: session,
options: new AgentRunOptions
{
AdditionalProperties = new AdditionalPropertiesDictionary
{
["request_id"] = "req-abc-123",
}
});
Console.WriteLine(session.StateBag.GetValue<string>("requestId"));
Spuštění middlewaru přijme relaci přímo jako parametr. Používejte StateBag.SetValue a GetValue pro typově bezpečný přístup. Všechny hodnoty uložené během fáze middlewaru spuštění jsou k dispozici nástrojům a funkci vyvolání middlewaru prostřednictvím AIAgent.CurrentRunContext?.Session.
Kontext modulu runtime Pythonu je rozdělený mezi tři veřejné plochy:
-
session=pro stav konverzace a historii. -
function_invocation_kwargs=pro hodnoty, které by měly vidět pouze nástroje nebo middleware funkcí. -
client_kwargs=pro konfiguraci middlewaru specifického pro chat klienta nebo klienta.
Použijte nejmenší povrch, který odpovídá datům. Díky tomu jsou vstupy nástrojů explicitní a zabraňuje úniku metadat pouze klienta do provádění nástrojů.
Návod
Považovat function_invocation_kwargs za náhradu za starý vzor předávání libovolných veřejných **kwargs nebo agent.run()get_response().
Volba správného kontejneru modulu runtime
| Případ použití | Plocha rozhraní API | Přístup z |
|---|---|---|
| Sdílení stavu konverzace, ID relací služby nebo historie | session= |
ctx.session, AgentContext.session |
| Předání hodnot modulu runtime pouze nástrojům nebo middlewaru funkcí | function_invocation_kwargs= |
FunctionInvocationContext.kwargs |
| Předání hodnot modulu runtime specifických pro klienta nebo konfigurace middlewaru klienta | client_kwargs= |
vlastní get_response(..., client_kwargs=...) implementace |
Předání hodnot modulu runtime jen pro nástroj
from typing import Annotated
from agent_framework import FunctionInvocationContext, tool
from agent_framework.openai import OpenAIChatClient
@tool(approval_mode="never_require")
def send_email(
address: Annotated[str, "Recipient email address."],
ctx: FunctionInvocationContext,
) -> str:
user_id = ctx.kwargs["user_id"]
tenant = ctx.kwargs.get("tenant", "default")
return f"Queued email for {address} from {user_id} ({tenant})"
agent = OpenAIChatClient().as_agent(
name="Notifier",
instructions="Send email updates.",
tools=[send_email],
)
response = await agent.run(
"Email the launch update to finance@example.com",
function_invocation_kwargs={
"user_id": "user-123",
"tenant": "contoso",
},
)
print(response.text)
Používejte ctx.kwargs uvnitř nástroje místo deklarování deky **kwargs na volatelném nástroji. Starší **kwargs nástroje stále fungují kvůli kompatibilitě, ale před ga se odeberou.
Jakýkoli parametr, který FunctionInvocationContext je označený jako vložený kontextový parametr modulu runtime bez ohledu na jeho název, a není vystavený ve schématu JSON zobrazeném modelu. Pokud zadáte explicitní model schématu nebo vstupu, je jako vložený kontextový parametr rozpoznán také prostý neoznačený ctx parametr.
Pokud je hodnota dlouhodobý stav nástroje nebo závislost místo dat pro vyvolání, nechejte ji na instanci function_invocation_kwargstřídy nástroje místo předávání . Tento vzor najdete v tématu Vytvoření třídy s více nástroji funkcí.
Middleware funkce přijímá stejný kontext.
Middleware funkce používá stejný FunctionInvocationContext objekt, který nástroje přijímají. To znamená, že middleware může kontrolovat context.arguments, context.kwargs, context.sessiona context.result.
from collections.abc import Awaitable, Callable
from agent_framework import FunctionInvocationContext
from agent_framework.openai import OpenAIChatClient
async def enrich_tool_runtime_context(
context: FunctionInvocationContext,
call_next: Callable[[], Awaitable[None]],
) -> None:
context.kwargs.setdefault("tenant", "contoso")
context.kwargs.setdefault("request_source", "middleware")
await call_next()
agent = OpenAIChatClient().as_agent(
name="Notifier",
instructions="Send email updates.",
tools=[send_email],
middleware=[enrich_tool_runtime_context],
)
Kontrakt middlewaru používá call_next() bez argumentů. Před voláním ztlumte context.kwargs a vybraný nástroj tyto hodnoty zobrazí prostřednictvím injektáže FunctionInvocationContext.
Použití session= pro sdílený stav modulu runtime
from typing import Annotated
from agent_framework import FunctionInvocationContext, tool
from agent_framework.openai import OpenAIChatClient
@tool(approval_mode="never_require")
def remember_topic(
topic: Annotated[str, "Topic to remember."],
ctx: FunctionInvocationContext,
) -> str:
if ctx.session is None:
return "No session available."
ctx.session.state["topic"] = topic
return f"Stored {topic!r} in session state."
agent = OpenAIChatClient().as_agent(
name="MemoryAgent",
instructions="Remember important topics.",
tools=[remember_topic],
)
session = agent.create_session()
await agent.run("Remember that the budget review is on Friday.", session=session)
print(session.state["topic"])
Předat relaci explicitně session= a číst z ctx.session. Přístup k relacím už nemusí procházet moduly runtime kwargs.
Sdílení stavu relace s delegovanými agenty
Když je agent vystaven jako nástroj prostřednictvím as_tool(), funkce runtime kwargs již prochází ctx.kwargs. Přidat propagate_session=True pouze tehdy, když má sub-agent sdílet volajícího AgentSession.
from agent_framework import FunctionInvocationContext, tool
from agent_framework.openai import OpenAIChatClient
@tool(description="Store findings for later steps.")
def store_findings(findings: str, ctx: FunctionInvocationContext) -> None:
if ctx.session is not None:
ctx.session.state["findings"] = findings
client = OpenAIChatClient()
research_agent = client.as_agent(
name="ResearchAgent",
instructions="Research the topic and store findings.",
tools=[store_findings],
)
research_tool = research_agent.as_tool(
name="research",
description="Research a topic and store findings.",
arg_name="query",
propagate_session=True,
)
U propagate_session=Truedelegovaného agenta se zobrazí stejný ctx.session stav jako volající.
False Ponechte ho tak, aby izoloval podřízeného agenta ve vlastní relaci.
Vlastní chatovací klienti a agenti
Pokud implementujete vlastní veřejné run() nebo get_response() metody, přidejte do podpisu explicitní kontejnery modulu runtime.
from collections.abc import Mapping, Sequence
from typing import Any
from agent_framework import ChatOptions, Message
async def get_response(
self,
messages: Sequence[Message],
*,
options: ChatOptions[Any] | None = None,
function_invocation_kwargs: Mapping[str, Any] | None = None,
client_kwargs: Mapping[str, Any] | None = None,
**kwargs: Any,
):
...
Používá se function_invocation_kwargs pro toky volání nástrojů a client_kwargs pro chování specifické pro klienta. Předávání hodnot specifických pro klienta přímo prostřednictvím veřejného **kwargs je pouze cesta kompatibility a měla by se považovat za zastaralá. Stejně tak definování nových nástrojů s kompatibilitou pouze s **kwargs migrací – místo toho spotřebovávají data modulu runtime prostřednictvím vloženého objektu kontextu.