Ескертпе
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Жүйеге кіруді немесе каталогтарды өзгертуді байқап көруге болады.
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Каталогтарды өзгертуді байқап көруге болады.
Контекст среды выполнения предоставляет по промежуточному слоям доступ к сведениям о текущей среде выполнения и запросе. Это позволяет использовать такие шаблоны, как конфигурация сеанса, поведение конкретного пользователя и динамическое поведение по промежуточному слоям на основе условий выполнения.
В C#контекст среды выполнения проходит через три основных поверхности:
-
AgentRunOptions.AdditionalPropertiesдля метаданных типа "ключ-значение" для каждого запуска, которые могут читать по промежуточному по промежуточному слоям и средствам. -
FunctionInvocationContextдля проверки и изменения аргументов вызова средства внутри по промежуточного слоя вызова функции. -
AgentSession.StateBagдля общего состояния, которое сохраняется во время выполнения беседы.
Используйте самую узкую поверхность, которая подходит. Метаданные для каждого запуска относятся к AdditionalPropertiesсостоянию сохраняемого диалога в сеансе StateBag, а манипуляция с аргументами инструментов относится к по промежуточному слоям вызова функции.
Подсказка
Сведения о том, как область по промежуточного слоя влияет на доступ к контексту среды выполнения, см. на странице агента и области выполнения .
Выбор правой области выполнения
| Сценарий использования | Поверхность API | Доступ из |
|---|---|---|
| Совместное использование состояния беседы или данных между запусками | AgentSession.StateBag |
session.StateBag в по промежуточном слоях AIAgent.CurrentRunContext?.Session запуска в средствах |
| Передача метаданных для каждого запуска в ПО промежуточного слоя или средства | AgentRunOptions.AdditionalProperties |
options.AdditionalProperties в по промежуточном слоях AIAgent.CurrentRunContext?.RunOptions запуска в средствах |
| Проверка или изменение аргументов вызова средства в ПО промежуточного слоя | FunctionInvocationContext |
Обратный вызов ПО промежуточного слоя функции |
Передача значений для каждого запуска с помощью AgentRunOptions
AgentRunOptions Используйте AdditionalProperties для подключения данных ключа-значения для каждого запуска. ПО промежуточного слоя вызова функции может перенаправить эти значения в аргументы инструментов.
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);
Предупреждение
DefaultAzureCredential удобно для разработки, но требует тщательного рассмотрения в рабочей среде. В рабочей среде рекомендуется использовать определенные учетные данные (например, ManagedIdentityCredential), чтобы избежать проблем с задержкой, непреднамеренной проверки данных аутентификации и потенциальных рисков безопасности из-за резервных механизмов.
ПО промежуточного слоя считывает значения AgentRunOptions.AdditionalProperties для каждого запуска через внешний объект AIAgent.CurrentRunContext и внедряет их в средство FunctionInvocationContext.Arguments перед выполнением средства.
ПО промежуточного слоя вызова функции получает контекст
ПО промежуточного слоя вызова функций используется 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();
ПО промежуточного слоя получает контекст вызова функции и вызовы next для продолжения конвейера. Мутировать context.Arguments перед вызовом next, а средство видит обновленные значения.
Использование AgentSession.StateBag для состояния общей среды выполнения
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"));
Передайте сеанс явным образом и session: получите доступ к нему с помощью AIAgent.CurrentRunContext?.Sessionинструментов. Предоставляет StateBag типобезопасный, потокобезопасный хранилище, которое сохраняется во время выполнения в одном сеансе.
Предоставление общего доступа к состоянию сеанса между ПО промежуточного слоя и инструментами
Запуск ПО промежуточного слоя может считывать и записывать сеанс StateBag, и любые изменения видны функции по промежуточному слоям и средствам вызова функции, выполняемым в том же запросе.
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"));
Запуск ПО промежуточного слоя получает сеанс непосредственно в качестве параметра. Используйте StateBag.SetValue и GetValue для доступа к типу. Все значения, хранящиеся на этапе промежуточного слоя запуска, доступны для средств и по промежуточному слоям вызова функций через AIAgent.CurrentRunContext?.Session.
Контекст среды выполнения Python разделен на три общедоступных поверхности:
-
session=для состояния беседы и журнала. -
function_invocation_kwargs=для значений, которые должны видеть только средства или ПО промежуточного слоя функций. -
client_kwargs=для данных, относящихся к клиенту чата или конфигурации ПО промежуточного слоя клиента.
Используйте наименьшую поверхность, которая соответствует данным. Это обеспечивает явные входные данные средства и позволяет избежать утечки метаданных только для клиента в выполнение средства.
Подсказка
Рассматривать function_invocation_kwargs как замену старого шаблона передачи произвольной общественности **kwargsagent.run() или get_response().
Выбор подходящего контейнера среды выполнения
| Сценарий использования | Поверхность API | Доступ из |
|---|---|---|
| Предоставление общего доступа к состоянию беседы, идентификаторам сеансов службы или журналу | session= |
ctx.session, AgentContext.session |
| Передача значений среды выполнения требуется только для средств или ПО промежуточного слоя функций | function_invocation_kwargs= |
FunctionInvocationContext.kwargs |
| Передача значений среды выполнения для конкретного клиента или конфигурации ПО промежуточного слоя клиента | client_kwargs= |
пользовательские get_response(..., client_kwargs=...) реализации |
Передача значений среды выполнения только для инструментов
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)
Используйте ctx.kwargs внутри средства вместо объявления одеяла **kwargs на вызываемом инструменте.
**kwargs Устаревшие средства по-прежнему работают для совместимости, но будут удалены до общедоступной версии.
Любой параметр, помеченный как FunctionInvocationContext внедренный параметр контекста среды выполнения, независимо от его имени, и он не предоставляется в схеме JSON, показанной модели. Если вы предоставляете явную модель схемы и ввода, простой ctx ненатированный параметр также распознается как внедренный параметр контекста.
Если значение является длительным состоянием средства или зависимостью, а не данными для каждого вызова, сохраните его в экземпляре класса инструментов вместо передачи function_invocation_kwargsчерез него. Для этого шаблона см. раздел "Создание класса с несколькими инструментами функций".
ПО промежуточного слоя функций получает тот же контекст
ПО промежуточного слоя функций использует тот же FunctionInvocationContext объект, который получает средства. Это означает, что ПО промежуточного слоя может проверять context.arguments, context.kwargscontext.sessionи 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],
)
Контракт ПО промежуточного слоя используется call_next() без аргументов. Переключитесь context.kwargs перед вызовом, а выбранное средство видит эти значения через его внедренные FunctionInvocationContext.
Использование session= для состояния общей среды выполнения
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"])
Передайте сеанс явным образом и session= считывает его из ctx.session. Доступ к сеансам больше не должен проходить через kwargs среды выполнения.
Совместное использование состояния сеанса с делегированными агентами
Когда агент предоставляется в качестве средства через as_tool(), функция выполнения kwargs уже проходит через ctx.kwargs. Добавьте propagate_session=True только в том случае, если дочерний агент должен совместно использовать вызывающий объект 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,
)
С propagate_session=Trueпомощью делегированного агента отображается то же ctx.session состояние, что и вызывающий объект. Оставьте его False , чтобы изолировать дочерний агент в собственном сеансе.
Пользовательские клиенты и агенты чата
При реализации пользовательских общедоступных run() или get_response() методов добавьте явные контейнеры среды выполнения в сигнатуру.
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,
):
...
Используется function_invocation_kwargs для потоков вызова инструментов и client_kwargs для поведения, зависяющего от клиента. Передача значений для конкретного клиента непосредственно через общедоступную **kwargs версию — это только путь совместимости, и его следует рассматривать как нерекомендуемые. Аналогичным образом, определение новых средств с **kwargs совместимостью только для миграции — использование данных среды выполнения с помощью внедренного объекта контекста.