通过


代理后台响应

Microsoft Agent Framework 支持后台响应来处理长时间运行的作,这些作可能需要一段时间才能完成。 此功能使代理能够开始处理请求并返回一个延续令牌,该标记可用于轮询结果或恢复中断的流。

小窍门

有关完整的工作示例,请参阅 后台响应示例

何时使用后台响应

后台响应特别适用于:

  • 需要大量处理时间的复杂推理任务
  • 网络问题或客户端超时可能会中断的作
  • 想要启动长时间运行的任务并稍后查看结果的方案

后台响应的工作原理

后台响应使用 延续令牌 机制来处理长时间运行的作。 向启用了后台响应的代理发送请求时,会发生以下两种情况之一:

  1. 立即完成:代理快速完成任务并返回最终响应,无需继续标记
  2. 后台处理:代理开始在后台进行处理,并返回延续标记而不是最终结果

延续令牌包含使用非流式处理代理 API 轮询完成的所有必要信息,或者使用流式处理代理 API 恢复中断的流。 当继续标记是 null时,作已完成 - 当后台响应已完成、失败或无法继续时(例如,需要用户输入时),将发生这种情况。

启用后台响应

若要启用后台响应,请将AllowBackgroundResponses属性设置为 trueAgentRunOptions

AgentRunOptions options = new()
{
    AllowBackgroundResponses = true
};

注释

目前,只有使用 OpenAI 响应 API 的代理支持后台响应: OpenAI 响应代理Azure OpenAI 响应代理

某些代理可能不允许显式控制后台响应。 无论设置如何, AllowBackgroundResponses 这些代理都可以根据作的复杂性自主决定是否启动后台响应。

非流式处理后台响应

对于非流式处理方案,当你最初运行代理时,它可能会或可能不会返回延续令牌。 如果未返回延续标记,则表示作已完成。 如果返回延续令牌,则表示代理已启动仍在处理的后台响应,并且需要轮询才能检索最终结果:

AIAgent agent = new AzureOpenAIClient(
    new Uri("https://<myresource>.openai.azure.com"),
    new DefaultAzureCredential())
    .GetOpenAIResponseClient("<deployment-name>")
    .AsAIAgent();

AgentRunOptions options = new()
{
    AllowBackgroundResponses = true
};

AgentSession session = await agent.CreateSessionAsync();

// Get initial response - may return with or without a continuation token
AgentResponse response = await agent.RunAsync("Write a very long novel about otters in space.", session, options);

// Continue to poll until the final response is received
while (response.ContinuationToken is not null)
{
    // Wait before polling again.
    await Task.Delay(TimeSpan.FromSeconds(2));

    options.ContinuationToken = response.ContinuationToken;
    response = await agent.RunAsync(session, options);
}

Console.WriteLine(response.Text);

警告

DefaultAzureCredential 对于开发来说很方便,但在生产中需要仔细考虑。 在生产环境中,请考虑使用特定凭据(例如), ManagedIdentityCredential以避免延迟问题、意外凭据探测以及回退机制的潜在安全风险。

要点:

  • 初始调用可能立即完成(无继续标记)或启动后台作(带有继续标记)
  • 如果未返回延续标记,则作已完成,响应包含最终结果
  • 如果返回延续令牌,代理已启动需要轮询的后台进程
  • 在后续轮询调用中使用上一响应中的延续标记
  • ContinuationToken何时null完成作

流式处理后台响应

在流式处理方案中,后台响应的工作方式非常类似于常规流式处理响应 - 代理实时将所有更新流式传输到使用者。 但是,主要区别在于,如果原始流中断,代理支持通过延续令牌恢复流。 每个更新都包含一个延续令牌,该标记捕获当前状态,允许通过将此令牌传递给后续流 API 调用,从其离开的位置完全恢复流式处理:

AIAgent agent = new AzureOpenAIClient(
    new Uri("https://<myresource>.openai.azure.com"),
    new DefaultAzureCredential())
    .GetOpenAIResponseClient("<deployment-name>")
    .AsAIAgent();

AgentRunOptions options = new()
{
    AllowBackgroundResponses = true
};

AgentSession session = await agent.CreateSessionAsync();

AgentResponseUpdate? latestReceivedUpdate = null;

await foreach (var update in agent.RunStreamingAsync("Write a very long novel about otters in space.", session, options))
{
    Console.Write(update.Text);

    latestReceivedUpdate = update;

    // Simulate an interruption
    break;
}

// Resume from interruption point captured by the continuation token
options.ContinuationToken = latestReceivedUpdate?.ContinuationToken;
await foreach (var update in agent.RunStreamingAsync(session, options))
{
    Console.Write(update.Text);
}

要点:

  • 每个 AgentResponseUpdate 标记都包含可用于恢复的延续标记
  • 在中断之前存储上次收到的更新中的延续令牌
  • 使用存储的继续标记从中断点恢复流

小窍门

有关完整的可运行示例,请参阅 .NET 示例

小窍门

有关完整的工作示例,请参阅 后台响应示例

启用后台响应

若要启用后台响应,请 background 传递调用 agent.run()时的选项:

session = agent.create_session()
response = await agent.run(
    messages="Your prompt here",
    session=session,
    options={"background": True},
)

注释

目前,只有使用 OpenAI 响应 API 的代理支持后台响应: OpenAI 响应代理Azure OpenAI 响应代理

非流式处理后台响应

对于非流式处理方案,当你最初运行 background=True代理时,它可能会立即使用 a continuation_token. None如果是continuation_token,该作已完成。 否则,通过在后续调用中传递令牌来轮询:

import asyncio
from agent_framework import Agent
from agent_framework.openai import OpenAIResponsesClient

agent = Agent(
    name="researcher",
    instructions="You are a helpful research assistant.",
    client=OpenAIResponsesClient(model_id="o3"),
)

session = await agent.create_session()

# Start a background run — returns immediately
response = await agent.run(
    messages="Briefly explain the theory of relativity in two sentences.",
    session=session,
    options={"background": True},
)

# Poll until the operation completes
while response.continuation_token is not None:
    await asyncio.sleep(2)
    response = await agent.run(
        session=session,
        options={"continuation_token": response.continuation_token},
    )

# Done — response.text contains the final result
print(response.text)

要点

  • 初始调用可能立即完成(无继续标记)或启动后台作(带有继续标记)
  • continuation_token在后续轮询调用中使用上一个响应中的响应
  • continuation_token何时None完成作

流式处理后台响应

在流式处理方案中,后台响应的工作方式类似于常规流式处理 , 代理流会实时更新。 主要区别在于,每个更新都包含一个 continuation_token,如果连接中断,则启用流恢复:

session = await agent.create_session()

# Start a streaming background run
last_token = None
stream = agent.run(
    messages="Briefly list three benefits of exercise.",
    stream=True,
    session=session,
    options={"background": True},
)

# Read chunks — each update carries a continuation_token
async for update in stream:
    last_token = update.continuation_token
    if update.text:
        print(update.text, end="", flush=True)
    # If interrupted (e.g., network issue), break and resume later

恢复中断的流

如果流中断,请使用最后 continuation_token 一个从中断位置恢复:

if last_token is not None:
    stream = agent.run(
        stream=True,
        session=session,
        options={"continuation_token": last_token},
    )
    async for update in stream:
        if update.text:
            print(update.text, end="", flush=True)

要点

  • 每个AgentResponseUpdate项都包含一个用于恢复的continuation_token
  • 在中断之前存储上次收到的更新中的令牌
  • 传递存储的令牌 options={"continuation_token": token} 以恢复

最佳做法

使用后台响应时,请考虑以下最佳做法:

  • 实现适当的轮询间隔 以避免服务压倒性
  • 如果作花费的时间超过预期,则对轮询间隔使用指数回退
  • 始终检查 null 继续标记 以确定处理何时完成
  • 考虑将延续令牌持久存储 为可能跨越用户会话的作

限制和注意事项

  • 后台响应依赖于支持长时间运行的作的基础 AI 服务
  • 并非所有代理类型都支持后台响应
  • 网络中断或客户端重启可能需要特殊处理才能保留延续令牌

后续步骤