Notatka
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Kontekst środowiska uruchomieniowego zapewnia oprogramowanie pośredniczące z dostępem do informacji o bieżącym środowisku wykonywania i żądaniu. Umożliwia to wzorce, takie jak konfiguracja poszczególnych sesji, zachowanie specyficzne dla użytkownika i dynamiczne zachowanie oprogramowania pośredniczącego na podstawie warunków środowiska uruchomieniowego.
W języku C# kontekst środowiska uruchomieniowego przepływa przez trzy główne powierzchnie:
-
AgentRunOptions.AdditionalPropertiesw przypadku metadanych wartości klucza uruchamianych, które mogą odczytywać oprogramowanie pośredniczące i narzędzia. -
FunctionInvocationContextdo sprawdzania i modyfikowania argumentów wywołania narzędzia wewnątrz oprogramowania pośredniczącego wywołania funkcji. -
AgentSession.StateBagw przypadku stanu współużytkowanego, który będzie się powtarzać w ramach konwersacji.
Użyj najwęższej powierzchni, która pasuje. Metadane poszczególnych przebiegów AdditionalPropertiesnależą do , trwały stan konwersacji należy do sesji StateBag, a manipulowanie argumentami narzędzi należy do oprogramowania pośredniczącego wywołania funkcji.
Tip
Zobacz stronę Agent a Zakres uruchamiania , aby uzyskać informacje na temat wpływu zakresu oprogramowania pośredniczącego na dostęp do kontekstu środowiska uruchomieniowego.
Wybieranie właściwej powierzchni środowiska uruchomieniowego
| Przypadek użycia | Powierzchnia interfejsu API | Dostęp z |
|---|---|---|
| Udostępnianie stanu konwersacji lub danych między przebiegami | AgentSession.StateBag |
session.StateBag w przypadku uruchamiania oprogramowania pośredniczącego w AIAgent.CurrentRunContext?.Session narzędziach |
| Przekazywanie metadanych na przebieg do oprogramowania pośredniczącego lub narzędzi | AgentRunOptions.AdditionalProperties |
options.AdditionalProperties w przypadku uruchamiania oprogramowania pośredniczącego w AIAgent.CurrentRunContext?.RunOptions narzędziach |
| Sprawdzanie lub modyfikowanie argumentów wywołania narzędzia w programie pośredniczącym | FunctionInvocationContext |
Wywołanie zwrotne wywołania oprogramowania pośredniczącego funkcji |
Przekazywanie wartości na przebieg za pośrednictwem polecenia AgentRunOptions
Użyj polecenia AdditionalProperties , AgentRunOptions aby dołączyć dane typu klucz-wartość na przebieg. Oprogramowanie pośredniczące wywołania funkcji może przekazywać te wartości do argumentów narzędzi.
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);
Ostrzeżenie
DefaultAzureCredential jest wygodne do programowania, ale wymaga starannego rozważenia w środowisku produkcyjnym. W środowisku produkcyjnym rozważ użycie określonego poświadczenia (np. ManagedIdentityCredential), aby uniknąć problemów z opóźnieniami, niezamierzonego sondowania poświadczeń i potencjalnych zagrożeń bezpieczeństwa wynikających z mechanizmów awaryjnych.
Oprogramowanie pośredniczące odczytuje wartości AgentRunOptions.AdditionalProperties poszczególnych przebiegów z otoczenia AIAgent.CurrentRunContext i wprowadza je do narzędzia FunctionInvocationContext.Arguments przed wykonaniem narzędzia.
Oprogramowanie pośredniczące wywołania funkcji odbiera kontekst
Oprogramowanie pośredniczące wywołania funkcji służy FunctionInvocationContext do sprawdzania lub modyfikowania argumentów narzędzi, przechwytywania wyników lub całkowitego pomijania wykonywania narzędzia.
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();
Oprogramowanie pośredniczące odbiera kontekst wywołania funkcji i wywołuje je next , aby kontynuować potok. Zmutuj context.Arguments przed wywołaniem metody next, a narzędzie zobaczy zaktualizowane wartości.
Użyj AgentSession.StateBag dla stanu współużytkowanego środowiska uruchomieniowego
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"));
Przekaż sesję jawnie session: i uzyskaj do niej dostęp z narzędzi za pośrednictwem programu AIAgent.CurrentRunContext?.Session. Zapewnia StateBag bezpieczny dla typów, bezpieczny wątkowo magazyn, który jest utrwalany w różnych przebiegach w ramach tej samej sesji.
Udostępnianie stanu sesji między oprogramowaniem pośredniczącym i narzędziami
Uruchamianie oprogramowania pośredniczącego może odczytywać i zapisywać sesję StateBag, a wszelkie zmiany są widoczne dla oprogramowania pośredniczącego wywołania funkcji i narzędzi wykonywanych w tym samym żądaniu.
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"));
Uruchamianie oprogramowania pośredniczącego odbiera sesję bezpośrednio jako parametr. Użyj funkcji StateBag.SetValue i GetValue w celu uzyskania bezpiecznego dostępu. Wszystkie wartości przechowywane w fazie uruchamiania oprogramowania pośredniczącego są dostępne dla narzędzi i oprogramowania pośredniczącego wywołania funkcji za pośrednictwem programu AIAgent.CurrentRunContext?.Session.
Kontekst środowiska uruchomieniowego języka Python jest podzielony na trzy publiczne powierzchnie:
-
session=dla stanu konwersacji i historii. -
function_invocation_kwargs=w przypadku wartości, które powinny być widoczne tylko dla narzędzi lub oprogramowania pośredniczącego funkcji. -
client_kwargs=w przypadku danych specyficznych dla klienta czatu lub konfiguracji oprogramowania pośredniczącego klienta.
Użyj najmniejszej powierzchni, która pasuje do danych. Dzięki temu dane wejściowe narzędzia są jawne i zapobiegają wyciekom metadanych tylko przez klienta do wykonywania narzędzi.
Tip
Traktuj function_invocation_kwargs jako zamiennik starego wzorca przekazywania dowolnych publicznych **kwargs do agent.run() lub get_response().
Wybieranie odpowiedniego zasobnika środowiska uruchomieniowego
| Przypadek użycia | Powierzchnia interfejsu API | Dostęp z |
|---|---|---|
| Udostępnianie stanu konwersacji, identyfikatorów sesji usługi lub historii | session= |
ctx.session, AgentContext.session |
| Przekazywanie wartości środowiska uruchomieniowego wymaga tylko narzędzi lub oprogramowania pośredniczącego funkcji | function_invocation_kwargs= |
FunctionInvocationContext.kwargs |
| Przekazywanie wartości środowiska uruchomieniowego specyficznego dla klienta lub konfiguracji oprogramowania pośredniczącego klienta | client_kwargs= |
implementacje niestandardowe get_response(..., client_kwargs=...) |
Przekazywanie wartości środowiska uruchomieniowego tylko dla narzędzi
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)
Użyj ctx.kwargs wewnątrz narzędzia zamiast deklarowania koca **kwargs na wywoływaniu narzędzia. Starsze **kwargs narzędzia nadal działają pod kątem zgodności, ale zostaną usunięte przed dostępnością.
Każdy parametr z adnotacjami FunctionInvocationContext jest traktowany jako parametr kontekstu wstrzykniętego środowiska uruchomieniowego, niezależnie od jego nazwy, i nie jest uwidoczniony w schemacie JSON pokazanym w modelu. Jeśli podasz jawny model schematu/danych wejściowych, zwykły nieoznakowany parametr o nazwie ctx jest również rozpoznawany jako wstrzykiwany parametr kontekstu.
Jeśli wartość jest długotrwałym stanem narzędzia lub zależności, a nie danymi wywołania, zachowaj ją w wystąpieniu klasy narzędzi, zamiast przekazywać je za pomocą function_invocation_kwargsmetody . Aby uzyskać ten wzorzec, zobacz Tworzenie klasy z wieloma narzędziami funkcji.
Oprogramowanie pośredniczące funkcji odbiera ten sam kontekst
Oprogramowanie pośredniczące funkcji używa tego samego FunctionInvocationContext obiektu, który otrzymuje narzędzia. Oznacza to, że oprogramowanie pośredniczące może sprawdzać context.arguments, , context.kwargscontext.sessioni 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 oprogramowania pośredniczącego używa call_next() bez argumentów. Zmutuj context.kwargs przed wywołaniem metody , a wybrane narzędzie zobaczy te wartości za pomocą wprowadzonego FunctionInvocationContextelementu .
Użyj session= dla stanu współużytkowanego środowiska uruchomieniowego
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"])
Przekaż sesję jawnie session= i odczytaj ją z pliku ctx.session. Dostęp do sesji nie musi już podróżować za pośrednictwem środowiska uruchomieniowego kwargs.
Udostępnianie stanu sesji agentom delegowanym
Gdy agent jest uwidoczniony jako narzędzie za pomocą as_tool()polecenia , funkcja środowiska uruchomieniowego kwargs już przepływa przez ctx.kwargselement . Dodaj propagate_session=True tylko wtedy, gdy agent podrzędny powinien udostępnić obiekt wywołujący 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,
)
W przypadku propagate_session=Truepolecenia agent delegowany widzi ten sam ctx.session stan co obiekt wywołujący. Pozostaw go, False aby odizolować agenta podrzędnego we własnej sesji.
Niestandardowi klienci czatu i agenci
W przypadku implementowania niestandardowych metod lub run() publicznych get_response() dodaj do podpisu jawne zasobniki środowiska uruchomieniowego.
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,
):
...
Służy function_invocation_kwargs do obsługi przepływów wywołania narzędzi i client_kwargs zachowania specyficznego dla klienta. Przekazywanie wartości specyficznych dla klienta bezpośrednio za pośrednictwem publicznej **kwargs jest tylko ścieżką zgodności i powinno być traktowane jako przestarzałe. Podobnie definiowanie nowych narzędzi ze zgodnością tylko do **kwargs migracji — zamiast tego zużywaj dane środowiska uruchomieniowego za pośrednictwem wprowadzonego obiektu kontekstu.