Microsoft Agent Framework용 지속성 작업 확장

Microsoft 에이전트 프레임워크용 지속 가능한 작업 확장은 지속 실행을 Microsoft 에이전트 프레임워크 내에서 직접 제공합니다. 에이전트 논리를 변경하지 않고도 확장에 에이전트를 등록하여 영구 세션, 기본 제공 API 엔드포인트 및 분산 크기 조정을 통해 자동으로 내구성을 유지하도록 할 수 있습니다.

지속성 에이전트를 사용하는 경우

필요한 경우 지속성 작업 확장을 선택합니다.

  • 영구 대화 상태 - 에이전트 세션은 컨텍스트를 잃지 않고 프로세스 충돌, 다시 시작 및 크기 조정 이벤트를 유지합니다.
  • 다중 에이전트 오케스트레이션 - 자동 검사점 및 실패 복구를 사용하여 결정적 워크플로에서 특수 에이전트를 조정합니다.
  • 장기 실행 워크플로 - 컴퓨팅 리소스를 사용하지 않고 몇 시간, 며칠 또는 몇 주 동안 지속될 수 있는 휴먼 인 더 루프 승인 또는 시간 제한 대기를 지원합니다.
  • 확장 가능한, 서버리스 호스팅 — Azure Functions Flex Consumption 계획에서 에이전트 세션의 동시 실행 수를 수천 개(또는 0)까지 유연하게 조절할 수 있습니다.

지속성 상태 또는 다중 에이전트 조정이 필요하지 않은 경우 확장 없이 표준 Microsoft 에이전트 프레임워크 에이전트로 충분할 수 있습니다.

Tip

로컬 설정, 필수 구성 요소 및 배포를 포함한 단계별 연습은 Microsoft Learn tutorial을 참조하세요.

아키텍처

확장은 내부적으로 엔터티 기반 에이전트 루프를 구현합니다. 여기서 각 에이전트 세션은 대화 상태 및 검사점을 자동으로 관리하는 지속성 엔터티입니다.

확장은 다음 두 가지 호스팅 방법을 지원합니다.

  • Azure Functions 통합 패키지를 사용하는 Azure Functions.
  • 기본 패키지를 사용하여 고유한 컴퓨팅을 가져옵니다.

에이전트 호스팅

표준 Microsoft 에이전트 프레임워크 패턴을 사용하여 에이전트를 정의한 다음 지속성 작업 확장으로 에이전트를 향상시킵니다. 확장은 세션 지속성, 엔드포인트 만들기 및 상태 관리를 자동으로 처리합니다.

var endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT")
    ?? throw new InvalidOperationException("AZURE_OPENAI_ENDPOINT is not set.");
var deploymentName = Environment.GetEnvironmentVariable("AZURE_OPENAI_DEPLOYMENT")
    ?? "gpt-4o-mini";

// Create an AI agent using the Microsoft Agent Framework pattern
AIAgent agent = new AIProjectClient(new Uri(endpoint), new DefaultAzureCredential())
    .AsAIAgent(
        model: deploymentName,
        instructions: "You are a professional content writer who creates engaging, "
                    + "well-structured documents for any given topic.",
        name: "DocumentPublisher");

// One line to make the agent durable with serverless hosting
using IHost app = FunctionsApplication
    .CreateBuilder(args)
    .ConfigureFunctionsWebApplication()
    .ConfigureDurableAgents(options => options.AddAIAgent(agent))
    .Build();
app.Run();
var endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT")
    ?? throw new InvalidOperationException("AZURE_OPENAI_ENDPOINT is not set.");
var deploymentName = Environment.GetEnvironmentVariable("AZURE_OPENAI_DEPLOYMENT")
    ?? "gpt-4o-mini";

// Create an AI agent using the Microsoft Agent Framework pattern
AIAgent agent = new AIProjectClient(new Uri(endpoint), new DefaultAzureCredential())
    .AsAIAgent(
        model: deploymentName,
        instructions: "You are a professional content writer who creates engaging, "
                    + "well-structured documents for any given topic.",
        name: "DocumentPublisher");

// Host the agent with Durable Task Scheduler
string connectionString = "Endpoint=http://localhost:8080;TaskHub=default;Authentication=None";

IHost host = Host.CreateDefaultBuilder(args)
    .ConfigureServices(services =>
    {
        services.ConfigureDurableAgents(
            options => options.AddAIAgent(agent),
            workerBuilder: builder => builder.UseDurableTaskScheduler(connectionString),
            clientBuilder: builder => builder.UseDurableTaskScheduler(connectionString));
    })
    .Build();

await host.StartAsync();

메모

C# 예제에서는 새 프로젝트에 권장되는 패턴인 AIProjectClient 패키지의 Azure.AI.Projects 사용합니다. Python 예제에서는 FoundryChatClientagent_framework.azure 사용합니다. 두 클라이언트 모두 지속 작업 확장과 통합되는 .AsAIAgent() / .as_agent() 확장을 지원합니다. 최신 패키지 참조는 GitHub 샘플을 참조하세요.

지속 가능한 체크포인트를 사용하는 다중 에이전트 오케스트레이션

지속성 오케스트레이션의 단계로 여러 특수 에이전트를 조정할 수 있습니다. 각 에이전트 호출은 검사점이 지정되며 단계가 실패하면 오케스트레이션이 자동으로 복구됩니다. 완료된 에이전트 호출은 복구할 때 다시 실행되지 않습니다.

context.GetAgent()(C#) 또는 app.get_agent()(Python)를 사용하여 오케스트레이션 내에서 등록된 에이전트를 검색합니다. 반환된 DurableAIAgent 래퍼는 호출이 프레임워크에 의해 추적 및 검사점이 되도록 합니다.

다음 예제에서는 연구 에이전트가 정보를 수집하고 기록기 에이전트가 문서를 생성하는 순차적인 다중 에이전트 워크플로를 보여 줍니다.

[Function(nameof(DocumentPublishingOrchestration))]
public async Task<string> DocumentPublishingOrchestration(
    [OrchestrationTrigger] TaskOrchestrationContext context)
{
    var docRequest = context.GetInput<DocumentRequest>();

    DurableAIAgent researchAgent = context.GetAgent("ResearchAgent");
    DurableAIAgent writerAgent = context.GetAgent("DocumentPublisherAgent");

    // Step 1: Research the topic
    AgentResponse<ResearchResult> researchResult = await researchAgent
        .RunAsync<ResearchResult>(
            $"Research the following topic: {docRequest.Topic}");

    // Step 2: Write the document using the research findings
    AgentResponse<DocumentResponse> document = await writerAgent
        .RunAsync<DocumentResponse>(
            $"""Create a document about {docRequest.Topic}.
            Research findings: {researchResult.Result.Findings}""");

    // Step 3: Publish
    return await context.CallActivityAsync<string>(
        nameof(PublishDocument),
        new { docRequest.Topic, document.Result.Text });
}
static async Task<string> DocumentPublishingOrchestration(
    TaskOrchestrationContext context, DocumentRequest docRequest)
{
    DurableAIAgent researchAgent = context.GetAgent("ResearchAgent");
    DurableAIAgent writerAgent = context.GetAgent("DocumentPublisherAgent");

    // Step 1: Research the topic
    AgentResponse<ResearchResult> researchResult = await researchAgent
        .RunAsync<ResearchResult>(
            $"Research the following topic: {docRequest.Topic}");

    // Step 2: Write the document using the research findings
    AgentResponse<DocumentResponse> document = await writerAgent
        .RunAsync<DocumentResponse>(
            $"""Create a document about {docRequest.Topic}.
            Research findings: {researchResult.Result.Findings}""");

    // Step 3: Publish
    return await context.CallActivityAsync<string>(
        nameof(PublishDocument),
        new { docRequest.Topic, document.Result.Text });
}

Microsoft Agent Framework를 사용하는 그래프 기반 워크플로

지속성 작업 확장은 선언적 그래프 기반 프로그래밍 모델()을 사용하여 실행기와 에이전트의 다단계 파이프라인을 정의하는 WorkflowBuilder도 지원합니다. 확장은 그래프의 각 단계를 자동으로 검사하고 워크플로 정의를 변경하지 않고 실패에서 복구합니다.

워크플로는 오케스트레이션을 보완합니다. 조건부 논리를 사용하여 명령적 에이전트 조정을 위해 오케스트레이션을 사용하고, 형식 유효성이 검사된 메시지 라우팅을 사용하는 고정 그래프 토폴로지의 워크플로를 사용합니다.

순차 워크플로

다음 예제에서는 주문 취소 워크플로에 세 개의 실행기를 연결합니다. 주문을 조회하고 취소한 다음 확인 전자 메일을 보냅니다.

OrderLookup orderLookup = new();
OrderCancel orderCancel = new();
SendEmail sendEmail = new();

Workflow cancelOrder = new WorkflowBuilder(orderLookup)
    .WithName("CancelOrder")
    .WithDescription("Cancel an order and notify the customer")
    .AddEdge(orderLookup, orderCancel)
    .AddEdge(orderCancel, sendEmail)
    .Build();

using IHost app = FunctionsApplication
    .CreateBuilder(args)
    .ConfigureFunctionsWebApplication()
    .ConfigureDurableWorkflows(workflows => workflows.AddWorkflows(cancelOrder))
    .Build();
app.Run();

OrderLookup, OrderCancelSendEmail 실행기는 지속성 관련 코드가 없는 표준 Microsoft 에이전트 프레임워크 실행기입니다. 전체 구현은 GitHub 샘플을 참조하세요.

string dtsConnectionString = Environment.GetEnvironmentVariable("DURABLE_TASK_SCHEDULER_CONNECTION_STRING")
    ?? "Endpoint=http://localhost:8080;TaskHub=default;Authentication=None";

OrderLookup orderLookup = new();
OrderCancel orderCancel = new();
SendEmail sendEmail = new();

Workflow cancelOrder = new WorkflowBuilder(orderLookup)
    .WithName("CancelOrder")
    .WithDescription("Cancel an order and notify the customer")
    .AddEdge(orderLookup, orderCancel)
    .AddEdge(orderCancel, sendEmail)
    .Build();

IHost host = Host.CreateDefaultBuilder(args)
    .ConfigureServices(services =>
    {
        services.ConfigureDurableWorkflows(
            workflowOptions => workflowOptions.AddWorkflow(cancelOrder),
            workerBuilder: builder => builder.UseDurableTaskScheduler(dtsConnectionString),
            clientBuilder: builder => builder.UseDurableTaskScheduler(dtsConnectionString));
    })
    .Build();

await host.StartAsync();

IWorkflowClient workflowClient = host.Services.GetRequiredService<IWorkflowClient>();
IAwaitableWorkflowRun run = (IAwaitableWorkflowRun)await workflowClient.RunAsync(cancelOrder, "ORD-12345");
string? result = await run.WaitForCompletionAsync<string>();

OrderLookup, OrderCancelSendEmail 실행기는 지속성 관련 코드가 없는 표준 Microsoft 에이전트 프레임워크 실행기입니다. 전체 구현은 GitHub 샘플을 참조하세요.

팬아웃/팬인(동시 실행) 워크플로

여러 실행기 또는 병렬로 실행되는 에이전트로 팬 아웃 한 후 다음 결과를 집계하기 위해 팬 인 할 수 있습니다. 다음 예제에서는 과학 질문을 물리학자 및 화학자 에이전트에 병렬로 보낸 다음 응답을 집계합니다.

ChatClient chatClient = new AzureOpenAIClient(
    new Uri(endpoint), new DefaultAzureCredential()).GetChatClient(deploymentName);

AIAgent physicist = chatClient.AsAIAgent(
    "You are a physics expert. Be concise (2-3 sentences).", "Physicist");
AIAgent chemist = chatClient.AsAIAgent(
    "You are a chemistry expert. Be concise (2-3 sentences).", "Chemist");

ParseQuestionExecutor parseQuestion = new();
AggregatorExecutor aggregator = new();

Workflow workflow = new WorkflowBuilder(parseQuestion)
    .WithName("ExpertReview")
    .AddFanOutEdge(parseQuestion, [physicist, chemist])
    .AddFanInBarrierEdge([physicist, chemist], aggregator)
    .Build();

using IHost app = FunctionsApplication
    .CreateBuilder(args)
    .ConfigureFunctionsWebApplication()
    .ConfigureDurableWorkflows(workflows => workflows.AddWorkflows(workflow))
    .Build();
app.Run();

ParseQuestionExecutorAggregatorExecutor 지속성 관련 코드가 없는 표준 Microsoft 에이전트 프레임워크 실행기입니다. 전체 구현은 GitHub 샘플을 참조하세요.

string dtsConnectionString = Environment.GetEnvironmentVariable("DURABLE_TASK_SCHEDULER_CONNECTION_STRING")
    ?? "Endpoint=http://localhost:8080;TaskHub=default;Authentication=None";

ChatClient chatClient = new AzureOpenAIClient(
    new Uri(endpoint), new DefaultAzureCredential()).GetChatClient(deploymentName);

ParseQuestionExecutor parseQuestion = new();
AIAgent physicist = chatClient.AsAIAgent(
    "You are a physics expert. Be concise (2-3 sentences).", "Physicist");
AIAgent chemist = chatClient.AsAIAgent(
    "You are a chemistry expert. Be concise (2-3 sentences).", "Chemist");
AggregatorExecutor aggregator = new();

Workflow workflow = new WorkflowBuilder(parseQuestion)
    .WithName("ExpertReview")
    .AddFanOutEdge(parseQuestion, [physicist, chemist])
    .AddFanInBarrierEdge([physicist, chemist], aggregator)
    .Build();

IHost host = Host.CreateDefaultBuilder(args)
    .ConfigureServices(services =>
    {
        services.ConfigureDurableOptions(
            options => options.Workflows.AddWorkflow(workflow),
            workerBuilder: builder => builder.UseDurableTaskScheduler(dtsConnectionString),
            clientBuilder: builder => builder.UseDurableTaskScheduler(dtsConnectionString));
    })
    .Build();

await host.StartAsync();

IWorkflowClient workflowClient = host.Services.GetRequiredService<IWorkflowClient>();
IWorkflowRun run = await workflowClient.RunAsync(workflow, "Why is the sky blue?");

if (run is IAwaitableWorkflowRun awaitableRun)
{
    string? result = await awaitableRun.WaitForCompletionAsync<string>();
    Console.WriteLine(result);
}

ParseQuestionExecutorAggregatorExecutor 지속성 관련 코드가 없는 표준 Microsoft 에이전트 프레임워크 실행기입니다. 전체 구현은 GitHub 샘플을 참조하세요.

조건부 라우팅 워크플로

런타임 결과에 따라 실행을 다른 분기로 라우팅할 수 있습니다. 다음 예제에서는 스팸 검색 에이전트를 사용하여 들어오는 전자 메일을 분류한 다음 스팸 처리기 또는 전자 메일 도우미 에이전트로 라우팅합니다.

AIAgent spamDetector = chatClient.AsAIAgent(
    "You are a spam detection assistant. Return JSON with is_spam (bool) and reason (string).",
    "SpamDetectionAgent");
AIAgent emailAssistant = chatClient.AsAIAgent(
    "You are an email assistant. Draft a professional response.",
    "EmailAssistantAgent");

SpamHandlerExecutor spamHandler = new();
EmailSenderExecutor emailSender = new();

Workflow workflow = new WorkflowBuilder(spamDetector)
    .WithName("EmailClassification")
    .AddSwitchCaseEdgeGroup(spamDetector, [
        new Case(condition: IsSpamDetected, target: spamHandler),
        new Default(target: emailAssistant),
    ])
    .AddEdge(emailAssistant, emailSender)
    .Build();

using IHost app = FunctionsApplication
    .CreateBuilder(args)
    .ConfigureFunctionsWebApplication()
    .ConfigureDurableWorkflows(workflows => workflows.AddWorkflows(workflow))
    .Build();
app.Run();

SpamHandlerExecutorEmailSenderExecutor 지속성 관련 코드가 없는 표준 Microsoft 에이전트 프레임워크 실행기입니다. 전체 구현은 GitHub 샘플을 참조하세요.

string dtsConnectionString = Environment.GetEnvironmentVariable("DURABLE_TASK_SCHEDULER_CONNECTION_STRING")
    ?? "Endpoint=http://localhost:8080;TaskHub=default;Authentication=None";

ChatClient chatClient = new AzureOpenAIClient(
    new Uri(endpoint), new DefaultAzureCredential()).GetChatClient(deploymentName);

AIAgent spamDetector = chatClient.AsAIAgent(
    "You are a spam detection assistant. Return JSON with is_spam (bool) and reason (string).",
    "SpamDetectionAgent");
AIAgent emailAssistant = chatClient.AsAIAgent(
    "You are an email assistant. Draft a professional response.",
    "EmailAssistantAgent");

SpamHandlerExecutor spamHandler = new();
EmailSenderExecutor emailSender = new();

Workflow workflow = new WorkflowBuilder(spamDetector)
    .WithName("EmailClassification")
    .AddSwitchCaseEdgeGroup(spamDetector, [
        new Case(condition: IsSpamDetected, target: spamHandler),
        new Default(target: emailAssistant),
    ])
    .AddEdge(emailAssistant, emailSender)
    .Build();

IHost host = Host.CreateDefaultBuilder(args)
    .ConfigureServices(services =>
    {
        services.ConfigureDurableWorkflows(
            workflowOptions => workflowOptions.AddWorkflow(workflow),
            workerBuilder: builder => builder.UseDurableTaskScheduler(dtsConnectionString),
            clientBuilder: builder => builder.UseDurableTaskScheduler(dtsConnectionString));
    })
    .Build();

await host.StartAsync();

IWorkflowClient workflowClient = host.Services.GetRequiredService<IWorkflowClient>();
IAwaitableWorkflowRun run = (IAwaitableWorkflowRun)await workflowClient.RunAsync(workflow, "Check this email for spam");
string? result = await run.WaitForCompletionAsync<string>();

SpamHandlerExecutorEmailSenderExecutor 지속성 관련 코드가 없는 표준 Microsoft 에이전트 프레임워크 실행기입니다. 전체 구현은 GitHub 샘플을 참조하세요.

HITL(휴먼 인 더 루프) 워크플로

지정된 지점에서 워크플로 실행을 일시 중지하여 계속하기 전에 외부 입력을 기다릴 수 있습니다. Microsoft Agent Framework 워크플로 모델은 RequestPort 노드(.NET) 또는 ctx.request_info()(Python)을 사용하여 일시 중지 지점을 정의합니다. 다음 예제에서는 관리자 승인과 병렬 예산 및 규정 준수 승인을 사용하여 비용 상환 워크플로를 구현합니다.

CreateApprovalRequest createRequest = new();
RequestPort<ApprovalRequest, ApprovalResponse> managerApproval =
    RequestPort.Create<ApprovalRequest, ApprovalResponse>("ManagerApproval");
PrepareFinanceReview prepareFinanceReview = new();
RequestPort<ApprovalRequest, ApprovalResponse> budgetApproval =
    RequestPort.Create<ApprovalRequest, ApprovalResponse>("BudgetApproval");
RequestPort<ApprovalRequest, ApprovalResponse> complianceApproval =
    RequestPort.Create<ApprovalRequest, ApprovalResponse>("ComplianceApproval");
ExpenseReimburse reimburse = new();

Workflow expenseApproval = new WorkflowBuilder(createRequest)
    .WithName("ExpenseReimbursement")
    .WithDescription("Expense reimbursement with manager and parallel finance approvals")
    .AddEdge(createRequest, managerApproval)
    .AddEdge(managerApproval, prepareFinanceReview)
    .AddFanOutEdge(prepareFinanceReview, [budgetApproval, complianceApproval])
    .AddFanInBarrierEdge([budgetApproval, complianceApproval], reimburse)
    .Build();

using IHost app = FunctionsApplication
    .CreateBuilder(args)
    .ConfigureFunctionsWebApplication()
    .ConfigureDurableWorkflows(workflows =>
        workflows.AddWorkflow(expenseApproval, exposeStatusEndpoint: true))
    .Build();
app.Run();

프레임워크는 HITL 상호 작용을 위해 3개의 HTTP 엔드포인트를 자동으로 생성합니다.

  • POST /api/workflows/{name}/run : 워크플로 시작
  • GET /api/workflows/{name}/status/{id} : 상태 및 보류 중인 승인 확인
  • POST /api/workflows/{name}/respond/{id} : 다시 시작하려면 승인 응답 보내기

다음 레코드 형식은 워크플로를 통해 흐르는 데이터를 정의합니다.

public record ApprovalRequest(string ExpenseId, decimal Amount, string EmployeeName);
public record ApprovalResponse(bool Approved, string? Comments);

CreateApprovalRequest, PrepareFinanceReviewExpenseReimburse 실행기는 지속성 관련 코드가 없는 표준 Microsoft 에이전트 프레임워크 실행기입니다. 전체 구현은 GitHub 샘플을 참조하세요.

string dtsConnectionString = Environment.GetEnvironmentVariable("DURABLE_TASK_SCHEDULER_CONNECTION_STRING")
    ?? "Endpoint=http://localhost:8080;TaskHub=default;Authentication=None";

CreateApprovalRequest createRequest = new();
RequestPort<ApprovalRequest, ApprovalResponse> managerApproval =
    RequestPort.Create<ApprovalRequest, ApprovalResponse>("ManagerApproval");
PrepareFinanceReview prepareFinanceReview = new();
RequestPort<ApprovalRequest, ApprovalResponse> budgetApproval =
    RequestPort.Create<ApprovalRequest, ApprovalResponse>("BudgetApproval");
RequestPort<ApprovalRequest, ApprovalResponse> complianceApproval =
    RequestPort.Create<ApprovalRequest, ApprovalResponse>("ComplianceApproval");
ExpenseReimburse reimburse = new();

Workflow expenseApproval = new WorkflowBuilder(createRequest)
    .WithName("ExpenseReimbursement")
    .AddEdge(createRequest, managerApproval)
    .AddEdge(managerApproval, prepareFinanceReview)
    .AddFanOutEdge(prepareFinanceReview, [budgetApproval, complianceApproval])
    .AddFanInBarrierEdge([budgetApproval, complianceApproval], reimburse)
    .Build();

IHost host = Host.CreateDefaultBuilder(args)
    .ConfigureServices(services =>
    {
        services.ConfigureDurableWorkflows(
            options => options.AddWorkflow(expenseApproval),
            workerBuilder: builder => builder.UseDurableTaskScheduler(dtsConnectionString),
            clientBuilder: builder => builder.UseDurableTaskScheduler(dtsConnectionString));
    })
    .Build();

await host.StartAsync();

IWorkflowClient workflowClient = host.Services.GetRequiredService<IWorkflowClient>();
IStreamingWorkflowRun run = await workflowClient.StreamAsync(expenseApproval, "EXP-2025-001");

await foreach (WorkflowEvent evt in run.WatchStreamAsync())
{
    switch (evt)
    {
        case DurableWorkflowWaitingForInputEvent requestEvent:
            Console.WriteLine($"Workflow paused at: {requestEvent.RequestPort.Id}");
            ApprovalResponse approval = new(Approved: true, Comments: "Approved.");
            await run.SendResponseAsync(requestEvent, approval);
            break;

        case DurableWorkflowCompletedEvent completedEvent:
            Console.WriteLine($"Workflow completed: {completedEvent.Result}");
            break;
    }
}

다음 레코드 형식은 워크플로를 통해 흐르는 데이터를 정의합니다.

public record ApprovalRequest(string ExpenseId, decimal Amount, string EmployeeName);
public record ApprovalResponse(bool Approved, string? Comments);

CreateApprovalRequest, PrepareFinanceReviewExpenseReimburse 실행기는 지속성 관련 코드가 없는 표준 Microsoft 에이전트 프레임워크 실행기입니다. 전체 구현은 GitHub 샘플을 참조하세요.

지속성 작업 스케줄러 대시보드

지속성 작업 스케줄러 대시보드를 사용하여 지속성 에이전트, 오케스트레이션 및 그래프 기반 워크플로를 완전히 볼 수 있습니다.

  • 각 에이전트 세션에 대한 대화 기록 보기
  • 도구 호출 및 구조적 출력 검사
  • 오케스트레이션 및 워크플로우 실행 흐름 추적
  • 성능 메트릭 모니터링

로컬 개발(에뮬레이터를 통해) 및 프로덕션 배포 모두 동일한 대시보드 환경을 표시합니다.

다음 스크린샷은 대화 기록 및 세션 세부 정보가 있는 에이전트 세션을 보여 줍니다.

에이전트 대화 기록 및 세션 세부 정보를 보여 주는 지속성 작업 스케줄러 대시보드의 스크린샷.

다음 스크린샷은 활동 실행 세부 정보가 포함된 결정적 오케스트레이션을 보여 줍니다.

결정적 에이전트 오케스트레이션 보기를 보여 주는 지속성 작업 스케줄러 대시보드의 스크린샷.

지속형 에이전트의 세션 유지 시간(TTL)

지속성 에이전트 세션은 대화 기록 및 상태를 자동으로 유지 관리하므로 무기한 누적할 수 있습니다. TTL(Time to Live) 기능은 유휴 세션의 자동 정리를 제공하여 스토리지 리소스 소비 및 비용 증가를 방지합니다.

에이전트 세션이 구성된 TTL 기간보다 오랫동안 유휴 상태이면 세션 상태가 자동으로 삭제됩니다. 각각의 새로운 상호 작용은 TTL 타이머를 다시 설정하여 세션의 수명을 연장합니다.

기본값

  • 기본 TTL: 14일
  • 최소 TTL 삭제 지연: 5분

Configuration

TTL은 전역적으로 또는 에이전트별로 구성할 수 있습니다. 에이전트 세션이 만료되면 대화 기록 및 사용자 지정 상태 데이터를 포함하여 전체 상태가 삭제됩니다. 삭제 후 메시지가 동일한 세션으로 전송되면 새 대화 기록을 사용하여 새 세션이 만들어집니다.

메모

TTL 구성은 현재 .NET만 사용할 수 있습니다.

services.ConfigureDurableAgents(
    options =>
    {
        // Set global default TTL to 7 days
        options.DefaultTimeToLive = TimeSpan.FromDays(7);

        // Agent with custom TTL of 1 day
        options.AddAIAgent(shortLivedAgent, timeToLive: TimeSpan.FromDays(1));

        // Agent with custom TTL of 90 days
        options.AddAIAgent(longLivedAgent, timeToLive: TimeSpan.FromDays(90));

        // Agent using global default (7 days)
        options.AddAIAgent(defaultAgent);

        // Agent with no TTL (never expires)
        options.AddAIAgent(permanentAgent, timeToLive: null);
    });

알려진 제한 사항

  • 최대 대화 크기입니다.
    전체 대화 기록을 포함한 에이전트 세션 상태는 지속성 백 엔드의 상태 크기 제한이 적용됩니다. 지속성 작업 스케줄러를 사용하는 경우 최대 엔터티 상태 크기는 1MB입니다. 대규모 도구 호출 응답이 있는 장기 실행 대화는 이 제한에 도달할 수 있습니다. 예를 들어 새 에이전트 세션을 시작하고 이전 컨텍스트를 요약하여 대화 기록을 수동으로 압축해야 합니다.

  • 대기 시간이.
    모든 에이전트 상호 작용은 메모리 내 에이전트 실행에 비해 대기 시간을 추가하는 지속성 작업 스케줄러를 통해 라우팅됩니다. 이러한 절충은 내구성과 분산 크기 조정을 제공합니다.

  • 스트리밍.
    지속성 에이전트는 지속성 엔터티를 기반으로 구현되므로 기본 통신 모델은 요청/응답입니다. 스트리밍은 응답 콜백(예: 클라이언트 사용을 위해 Redis Stream에 토큰 푸시)을 통해 지원되며, 엔터티는 스트림이 완료된 후 전체 응답을 반환합니다.

  • TTL 만료.
    TTL 타이머는 누적 작업 시간이 아니라 마지막 메시지 이후의 벽시계 시간을 기반으로 합니다. 세션이 삭제되면(TTL 만료 또는 수동 삭제를 통해) 대화 기록을 복구할 수 없습니다.

추가 기능

다음 고급 패턴은 GitHub샘플에서 사용할 수 있지만> 이 문서에서는 자세히 다루지 않습니다.

패턴 설명
지속 실행 도구 에이전트는 도구 호출에서 지속성 오케스트레이션을 시작하여 진행률 추적을 통해 장기간 실행되는 도구를 사용할 수 있습니다.
MCP 도구로서의 에이전트 지속성 에이전트를 MCP(모델 컨텍스트 프로토콜) 도구로 노출하여 다른 에이전트 또는 클라이언트가 표준 인터페이스를 통해 호출할 수 있도록 합니다.
신뢰할 수 있는 스트리밍 클라이언트의 연결 해제 및 재연결 시에도 유지되는 재개 가능한 토큰 스트리밍을 위해 Redis Streams(또는 유사한 전송 수단)를 사용합니다.

다음 단계