Compartilhar via


Contexto de runtime

O contexto de runtime fornece ao middleware acesso a informações sobre o ambiente de execução e a solicitação atuais. Isso permite padrões como configuração por sessão, comportamento específico do usuário e comportamento de middleware dinâmico com base em condições de runtime.

Em C#, o contexto de runtime normalmente é passado pelo AgentRunOptions estado da sessão ou personalizado. O Middleware pode acessar propriedades de sessão e executar opções para tomar decisões de runtime.

Dica

Consulte a página Agente vs Executar Escopo para obter informações sobre como o escopo do middleware afeta o acesso ao contexto de runtime.

O contexto de runtime do Python é dividido entre três superfícies públicas:

  • session= para o estado e o histórico da conversa.
  • function_invocation_kwargs= para valores que somente ferramentas ou middleware de função devem ver.
  • client_kwargs= para dados específicos do cliente de chat ou configuração de middleware do cliente.

Use a menor superfície que se ajusta aos dados. Isso mantém as entradas da ferramenta explícitas e evita o vazamento de metadados somente do cliente na execução da ferramenta.

Dica

Trate function_invocation_kwargs como a substituição do antigo padrão de passar público **kwargs arbitrário para agent.run() ou get_response().

Escolher o bucket de runtime certo

Caso de uso Superfície da API Acessado a partir de
Compartilhar estado da conversa, IDs de sessão de serviço ou histórico session= ctx.session, AgentContext.session
Passar valores de runtime somente ferramentas ou middleware de função precisa function_invocation_kwargs= FunctionInvocationContext.kwargs
Passar valores de runtime específicos do cliente ou configuração de middleware do cliente client_kwargs= implementações personalizadas get_response(..., client_kwargs=...)

Passar valores de runtime somente para ferramentas

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)

Use ctx.kwargs dentro da ferramenta em vez de declarar o cobertor **kwargs na ferramenta que pode ser chamada. As ferramentas herdadas **kwargs ainda funcionam para compatibilidade, mas serão removidas antes da GA.

Qualquer parâmetro anotado como FunctionInvocationContext é tratado como o parâmetro de contexto de runtime injetado, independentemente de seu nome, e não é exposto no esquema JSON mostrado ao modelo. Se você fornecer um modelo de esquema/entrada explícito, um parâmetro sem anotação simples nomeado ctx também será reconhecido como o parâmetro de contexto injetado.

Se o valor for um estado de ferramenta de longa duração ou uma dependência em vez de dados por invocação, mantenha-o em uma instância de classe de ferramenta em vez de passá-lo.function_invocation_kwargs Para esse padrão, consulte Criar uma classe com várias ferramentas de função.

O middleware de função recebe o mesmo contexto

O middleware de função usa o mesmo FunctionInvocationContext objeto que as ferramentas recebem. Isso significa que o middleware pode inspecionarcontext.arguments, context.kwargse 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],
)

O contrato de middleware usa call_next() sem argumentos. Mutar context.kwargs antes de chamá-lo, e a ferramenta selecionada vê esses valores por meio de sua injeção FunctionInvocationContext.

Usar session= para o estado de runtime compartilhado

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

Passe a sessão explicitamente com session= e leia-a de ctx.session. O acesso à sessão não precisa mais percorrer kwargs de runtime.

Compartilhar o estado da sessão com agentes delegados

Quando um agente é exposto como uma ferramenta por meio as_tool()de kwargs de função de runtime que já fluem por ctx.kwargs. Adicione propagate_session=True somente quando o subagente deve compartilhar o chamador 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,
)

Com propagate_session=True, o agente delegado vê o mesmo ctx.session estado que o chamador. Deixe-o False isolar o agente filho em sua própria sessão.

Clientes e agentes de chat personalizados

Se você implementar métodos públicos run() ou get_response() personalizados, adicione os buckets de runtime explícitos à assinatura.

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

Use function_invocation_kwargs para fluxos de invocação de ferramentas e client_kwargs para comportamento específico do cliente. Passar valores específicos do cliente diretamente pelo público **kwargs é apenas um caminho de compatibilidade e deve ser tratado como preterido. Da mesma forma, definir novas ferramentas com **kwargs a compatibilidade somente migração é consumir dados de runtime por meio do objeto de contexto injetado.

Próximas etapas