Condividi tramite


Contesto di runtime

Il contesto di runtime fornisce al middleware l'accesso alle informazioni sull'ambiente di esecuzione corrente e sulla richiesta. Ciò consente modelli come la configurazione per sessione, il comportamento specifico dell'utente e il comportamento del middleware dinamico in base alle condizioni di runtime.

In C# il contesto di runtime viene in genere passato attraverso AgentRunOptions o stato di sessione personalizzato. Il middleware può accedere alle proprietà della sessione ed eseguire le opzioni per prendere decisioni in fase di esecuzione.

Suggerimento

Per informazioni sul modo in cui l'ambito del middleware influisce sull'accesso al contesto di runtime, vedere la pagina Agent vs Run Scope .See the Agent vs Run Scope page for information on middleware scope affects access to runtime context.

Il contesto di runtime python è suddiviso in tre superfici pubbliche:

  • session= per lo stato e la cronologia della conversazione.
  • function_invocation_kwargs= per i valori che devono essere visualizzati solo gli strumenti o il middleware della funzione.
  • client_kwargs= per i dati specifici del client di chat o la configurazione del middleware client.

Usare la superficie più piccola adatta ai dati. In questo modo gli input degli strumenti vengono archiviati in modo esplicito ed evita la perdita di metadati solo client nell'esecuzione degli strumenti.

Suggerimento

Considerare function_invocation_kwargs come sostituzione del modello precedente di passare un pubblico **kwargs arbitrario a agent.run() o get_response().

Scegliere il bucket di runtime corretto

caso d'uso Superficie API Accesso da
Condividere lo stato della conversazione, gli ID sessione del servizio o la cronologia session= ctx.session, AgentContext.session
Passare i valori di runtime solo gli strumenti o il middleware di funzione necessari function_invocation_kwargs= FunctionInvocationContext.kwargs
Passare valori di runtime specifici del client o configurazione del middleware client client_kwargs= implementazioni personalizzate get_response(..., client_kwargs=...)

Passare valori di runtime solo strumenti

from typing import Annotated

from agent_framework import FunctionInvocationContext, tool
from agent_framework.openai import OpenAIResponsesClient


@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 = OpenAIResponsesClient().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)

Usare ctx.kwargs all'interno dello strumento invece di dichiarare coperta **kwargs sullo strumento chiamabile. Gli strumenti legacy **kwargs funzionano ancora per la compatibilità, ma verranno rimossi prima della disponibilità generale.

Qualsiasi parametro annotato come FunctionInvocationContext viene considerato come parametro di contesto di runtime inserito, indipendentemente dal nome e non viene esposto nello schema JSON mostrato al modello. Se si specifica un modello di schema/input esplicito, viene riconosciuto anche un parametro non annotato normale denominato ctx come parametro di contesto inserito.

Se il valore è uno stato dello strumento di lunga durata o una dipendenza anziché i dati per chiamata, mantenerlo in un'istanza della classe degli strumenti anziché passarlo attraverso function_invocation_kwargs. Per questo modello, vedere Creare una classe con più strumenti per le funzioni.

Il middleware della funzione riceve lo stesso contesto

Il middleware della funzione usa lo stesso FunctionInvocationContext oggetto ricevuto dagli strumenti. Ciò significa che il middleware può esaminare context.arguments, context.kwargscontext.session, e context.result.

from collections.abc import Awaitable, Callable

from agent_framework import FunctionInvocationContext
from agent_framework.openai import OpenAIResponsesClient


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 = OpenAIResponsesClient().as_agent(
    name="Notifier",
    instructions="Send email updates.",
    tools=[send_email],
    middleware=[enrich_tool_runtime_context],
)

Il contratto middleware usa call_next() senza argomenti. context.kwargs Modificare prima di chiamarla e lo strumento selezionato visualizza tali valori tramite l'oggetto inseritoFunctionInvocationContext.

Usare session= per lo stato di runtime condiviso

from typing import Annotated

from agent_framework import FunctionInvocationContext, tool
from agent_framework.openai import OpenAIResponsesClient


@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 = OpenAIResponsesClient().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"])

Passare la sessione in modo esplicito con session= e leggerla da ctx.session. L'accesso alla sessione non deve più spostarsi tra kwarg di runtime.

Condividere lo stato della sessione con agenti delegati

Quando un agente viene esposto come strumento tramite as_tool(), i kwarg della funzione di runtime passano già attraverso ctx.kwargs. Aggiungere propagate_session=True solo quando l'agente secondario deve condividere l'oggetto del AgentSessionchiamante.

from agent_framework import FunctionInvocationContext, tool
from agent_framework.openai import OpenAIResponsesClient


@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 = OpenAIResponsesClient()

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

Con propagate_session=True, l'agente delegato vede lo stesso ctx.session stato del chiamante. Lasciarlo False isolare l'agente figlio nella propria sessione.

Client e agenti di chat personalizzati

Se si implementano metodi o get_response() pubblici run() personalizzati, aggiungere i bucket di runtime espliciti alla firma.

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

Usare function_invocation_kwargs per i flussi di chiamata degli strumenti e client_kwargs per il comportamento specifico del client. Il passaggio di valori specifici del client direttamente tramite public **kwargs è solo un percorso di compatibilità e deve essere considerato deprecato. Analogamente, la definizione di nuovi strumenti con **kwargs è compatibilità solo migrazione: utilizzare i dati di runtime tramite l'oggetto contesto inserito.

Passaggi successivi