Futtatókörnyezet környezete

A futtatókörnyezet hozzáférést biztosít a köztes szoftvernek az aktuális végrehajtási környezettel és kéréssel kapcsolatos információkhoz. Ez olyan mintákat tesz lehetővé, mint a munkamenetenkénti konfiguráció, a felhasználóspecifikus viselkedés és a futásidejű feltételek alapján a köztes szoftver dinamikus viselkedése.

A C#-ban a futtatókörnyezet három fő felületen halad át:

  • AgentRunOptions.AdditionalProperties futtatásonkénti kulcs-érték metaadatokhoz, amelyeket a köztes szoftver és az eszközök képesek olvasni.
  • FunctionInvocationContext az eszközhívási argumentumok vizsgálatához és módosításához a függvényhívás köztes szoftverében.
  • AgentSession.StateBag olyan megosztott állapot esetén, amely egy beszélgetésen belül több futtatáson is megmarad.

Használja a legszűkebb felületet, amely illeszkedik. A futtatásonkénti metaadatok a munkamenetben StateBagaz állandó beszélgetési állapothoz tartoznakAdditionalProperties, az eszközargumentum-kezelés pedig a függvényhívás köztes szoftveréhez tartozik.

Jótanács

Az Ügynök és a Futtatási hatókör lapon tájékozódhat arról, hogy a köztes szoftver hatóköre hogyan befolyásolja a futtatókörnyezethez való hozzáférést.

A megfelelő futtatókörnyezeti felület kiválasztása

Felhasználási eset API-felület Elérhető innen:
Beszélgetési állapot vagy adatok megosztása futtatások között AgentSession.StateBag session.StateBag köztes szoftverben, AIAgent.CurrentRunContext?.Session eszközökben
Futtatásonkénti metaadatok átadása köztes szoftvernek vagy eszközöknek AgentRunOptions.AdditionalProperties options.AdditionalProperties köztes szoftverben, AIAgent.CurrentRunContext?.RunOptions eszközökben
Eszközhívási argumentumok vizsgálata vagy módosítása köztes szoftverben FunctionInvocationContext Függvényhívás köztes szoftver visszahívása

Futtatásonkénti értékek átadása AgentRunOptions

AgentRunOptions Futtatásonkénti kulcs-érték adatok csatolására használhatóAdditionalProperties. A függvényhívás közbenső szoftvere továbbíthatja ezeket az értékeket eszközargumentumokba.

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);

Figyelmeztetés

DefaultAzureCredential a fejlesztéshez kényelmes, de a termelési környezetben gondos megfontolást igényel. Éles környezetben fontolja meg egy adott hitelesítő adat (pl. ManagedIdentityCredential) használatát a késési problémák elkerülése, a hitelesítő adatok nem szándékos próbálgatásának és a tartalék mechanizmusokból eredő esetleges biztonsági kockázatok elkerülése érdekében.

A köztes szoftver futtatásonkénti értékeket AgentRunOptions.AdditionalProperties olvas be a környezeti AIAgent.CurrentRunContext adatokból, és a szerszám végrehajtása előtt beszúrja FunctionInvocationContext.Arguments azokat az eszközbe.

A függvényhívás közbenső szoftvere kontextust fogad

A függvényhívás közbenső szoftvere az eszközargumentumok vizsgálatára vagy módosítására, az eredmények elfogására vagy az eszköz végrehajtásának teljes kihagyására használható FunctionInvocationContext .

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();

A köztes szoftver fogadja a függvényhívási környezetet, és meghívja next a folyamat folytatására. context.Arguments A hívás nextelőtt mutálhat, és az eszköz a frissített értékeket látja.

Használat AgentSession.StateBag megosztott futtatókörnyezeti állapothoz

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"));

Adja át a munkamenetet explicit módon, session: és az eszközökről érheti el a következőn keresztül AIAgent.CurrentRunContext?.Session: . Ez StateBag típusbiztos, szálbiztos tárolást biztosít, amely ugyanazon munkameneten belül több futtatáson is megmarad.

Munkamenet-állapot megosztása köztes szoftver és eszközök között

A köztes szoftver futtatása képes olvasni és írni a munkamenetet StateBag, és minden módosítás látható az invocation köztes szoftver és az ugyanabban a kérésben végrehajtó eszközök számára.

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"));

A köztes szoftver futtatása közvetlenül paraméterként fogadja a munkamenetet. Típusbiztos hozzáférés használata StateBag.SetValue és GetValue használata. A köztes szoftver futtatása során tárolt értékek az eszközök és a függvények köztes szoftverei számára érhetők el a következőn keresztül AIAgent.CurrentRunContext?.Session: .

A Python-futtatókörnyezet három nyilvános felületre van felosztva:

  • session= a beszélgetések állapotához és előzményeihez.
  • function_invocation_kwargs= olyan értékek esetén, amelyeket csak az eszközöknek vagy a függvényközvetmezőknek kell látniuk.
  • client_kwargs= csevegőügyfél-specifikus adatokhoz vagy ügyfél köztes szoftver konfiguráláshoz.

Használja az adatoknak leginkább megfelelő legkisebb felületet. Ez explicit módon tartja az eszközbemeneteket, és elkerüli, hogy csak ügyféloldali metaadatokat szivárogtassunk az eszközök végrehajtásába.

Jótanács

Kezelje function_invocation_kwargs a régi minta helyettesítését, amely tetszőleges nyilvános **kwargsagent.run()get_response()vagy .

Válassza ki a megfelelő futtatókörnyezeti gyűjtőt

Felhasználási eset API-felület Elérhető innen:
Beszélgetési állapot, szolgáltatás-munkamenet azonosítóinak vagy előzményeinek megosztása session= ctx.session, AgentContext.session
Futásidejű értékek átadása csak olyan eszközöknek vagy függvényközvetítenivalóknak, amelyekre szükség van function_invocation_kwargs= FunctionInvocationContext.kwargs
Ügyfélspecifikus futtatókörnyezeti értékek vagy ügyfél köztes szoftver konfigurációjának átadása client_kwargs= egyéni get_response(..., client_kwargs=...) implementációk

Csak eszközalapú futásidejű értékek átadása

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)

Használja ctx.kwargs az eszközben ahelyett, hogy a hívható eszközre vonatkozó takarót **kwargs deklarál. **kwargs Az örökölt eszközök továbbra is kompatibilisek, de a ga előtt el lesznek távolítva.

Az injektált futásidejű környezeti paraméterként jegyzett FunctionInvocationContext paraméterek neveiktől függetlenül nem jelennek meg a modell számára megjelenített JSON-sémában. Ha explicit sémát/bemeneti modellt ad meg, a rendszer ctx egy egyszerű, névvel nem ellátott paramétert is felismer az injektált környezeti paraméterként.

Ha az érték hosszú élettartamú eszközállapot vagy függőség a per-invocation adatok helyett, ahelyett, hogy átengedi azt function_invocation_kwargsegy eszközosztálypéldányon. Ehhez a mintához tekintse meg az Osztály létrehozása több függvényeszközzel című témakört.

A függvény köztes szoftver ugyanazt a környezetet kapja

A függvény köztes szoftver ugyanazt FunctionInvocationContext az objektumot használja, amelyet az eszközök kapnak. Ez azt jelenti, hogy a köztes szoftver megvizsgálhatja context.arguments, context.kwargsés context.sessioncontext.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],
)

A köztes szoftverszerződés argumentumok nélkül használ call_next() . context.kwargs A hívás előtt mutáció, és a kijelölt eszköz ezeket az értékeket az injektált FunctionInvocationContextértéken keresztül látja.

Használat session= megosztott futtatókörnyezeti állapothoz

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"])

Adja át a munkamenetet explicit módon, session= és olvassa el a következőből ctx.session: . A munkamenet-hozzáférésnek már nem kell futásidejű kwargokon keresztül haladnia.

Munkamenet-állapot megosztása delegált ügynökökkel

Ha egy ügynök eszközként as_tool()jelenik meg, a futtatókörnyezeti függvények már áthaladnak.ctx.kwargs Csak akkor adja hozzá propagate_session=True , ha az alügynöknek meg kell osztania a hívó adatait 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,
)

Ezzel propagate_session=Trueegyütt a delegált ügynök ugyanazt ctx.session az állapotot látja, mint a hívó. Hagyja elkülöníteni False a gyermekügynököt a saját munkamenetében.

Egyéni csevegési ügyfelek és ügynökök

Ha egyéni nyilvános run() vagy get_response() metódusokat implementál, adja hozzá az explicit futtatókörnyezeti gyűjtőket az aláíráshoz.

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,
):
    ...

Eszköz-meghívási folyamatokhoz és function_invocation_kwargs ügyfélspecifikus viselkedéshez használhatóclient_kwargs. Az ügyfélspecifikus értékek közvetlen átadása nyilvánosan **kwargs csak kompatibilitási útvonal, ezért elavultként kell kezelni. Hasonlóképpen, az új eszközök csak migrálási kompatibilitással való **kwargs definiálása – a futtatókörnyezeti adatokat inkább az injektált környezeti objektumon keresztül használja fel.

Következő lépések