Deklaratív munkafolyamatok – Áttekintés

A deklaratív munkafolyamatok lehetővé teszik a munkafolyamat-logika definiálását YAML-konfigurációs fájlok használatával a programozott kód írása helyett. Ez a módszer megkönnyíti a munkafolyamatok olvasását, módosítását és megosztását a csapatok között.

Áttekintés

Deklaratív munkafolyamatok esetén azt kell leírnia, mit kell tennie, ahelyett, hogy hogyan valósítaná meg. A keretrendszer kezeli az alapul szolgáló végrehajtást, és a YAML-definíciókat végrehajtható munkafolyamat-grafikonokká alakítja.

Főbb előnyök:

  • Olvasható formátum: A YAML-szintaxis könnyen érthető, még nem fejlesztők számára is
  • Hordozható: A munkafolyamat-definíciók kódmódosítások nélkül megosztható, verziószámozott és módosíthatók
  • Gyors iteráció: A munkafolyamat viselkedésének módosítása konfigurációs fájlok szerkesztésével
  • Konzisztens struktúra: Előre definiált művelettípusok biztosítják, hogy a munkafolyamatok követik az ajánlott eljárásokat

Mikor érdemes deklaratív és programozott munkafolyamatokat használni?

Scenario Ajánlott megközelítés
Standard orchesztrációs minták Deklaratív
Gyakran változó munkafolyamatok Deklaratív
A nem fejlesztőknek módosítaniuk kell a munkafolyamatokat Deklaratív
Összetett egyéni logika Programmatic
Maximális rugalmasság és szabályozás Programmatic
Integráció meglévő Python-kóddal Programmatic

Alapszintű YAML-struktúra

A YAML-struktúra kissé eltér a C# és a Python implementációk között. A részletekért tekintse meg az alábbi nyelvspecifikus szakaszokat.

Művelettípusok

A deklaratív munkafolyamatok számos különféle művelettípust támogatnak, például a változókezelést, a vezérlési folyamatot, az ügynök- és eszközhívást, a HTTP- és MCP-integrációt, a humán-in-the-loopot és a beszélgetésvezérlést. A teljes nyelvspecifikus hivatkozás az alábbi zónákban jelenik meg; A két nyelvre kiterjedő rendelkezésre állási mátrixot a cikk alján található Műveletek rövid útmutatójában találja.

C# YAML-struktúra

A C# deklaratív munkafolyamatai triggeralapú struktúrát használnak:

#
# Workflow description as a comment
#
kind: Workflow
trigger:

  kind: OnConversationStart
  id: my_workflow
  actions:

    - kind: ActionType
      id: unique_action_id
      displayName: Human readable name
      # Action-specific properties

Szerkezeti elemek

Elem Kötelező Description
kind Igen Legyen Workflow
trigger.kind Igen Eseményindító típusa (általában OnConversationStart)
trigger.id Igen A munkafolyamat egyedi azonosítója
trigger.actions Igen Végrehajtandó műveletek listája

Python YAML-struktúra

A Python deklaratív munkafolyamatai névalapú struktúrát használnak opcionális bemenetekkel:

name: my-workflow
description: A brief description of what this workflow does

inputs:
  parameterName:
    type: string
    description: Description of the parameter

actions:
  - kind: ActionType
    id: unique_action_id
    displayName: Human readable name
    # Action-specific properties

Szerkezeti elemek

Elem Kötelező Description
name Igen A munkafolyamat egyedi azonosítója
description Nem Ember által olvasható leírás
inputs Nem A munkafolyamat által elfogadott bemeneti paraméterek
actions Igen Végrehajtandó műveletek listája

Előfeltételek

Mielőtt hozzákezdene, győződjön meg arról, hogy:

  • .NET 8.0 vagy újabb
  • Microsoft Foundry-projekt legalább egy üzembe helyezett ügynökkel
  • A következő NuGet-csomagok vannak telepítve:
dotnet add package Microsoft.Agents.AI.Workflows.Declarative --prerelease
dotnet add package Microsoft.Agents.AI.Workflows.Declarative.AzureAI --prerelease
  • Ha MCP-eszközhívási műveletet szeretne hozzáadni a munkafolyamathoz, telepítse a következő NuGet-csomagot is:
dotnet add package Microsoft.Agents.AI.Workflows.Declarative.Mcp --prerelease

Az első deklaratív munkafolyamat

Hozzunk létre egy egyszerű munkafolyamatot, amely fogadja a felhasználót a bemenetük alapján.

1. lépés: A YAML-fájl létrehozása

Hozzon létre egy fájlt:greeting-workflow.yaml

#
# This workflow demonstrates a simple greeting based on user input.
# The user's message is captured via System.LastMessage.
#
# Example input: 
# Alice
#
kind: Workflow
trigger:

  kind: OnConversationStart
  id: greeting_workflow
  actions:

    # Capture the user's input from the last message
    - kind: SetVariable
      id: capture_name
      displayName: Capture user name
      variable: Local.userName
      value: =System.LastMessage.Text

    # Set a greeting prefix
    - kind: SetVariable
      id: set_greeting
      displayName: Set greeting prefix
      variable: Local.greeting
      value: Hello

    # Build the full message using an expression
    - kind: SetVariable
      id: build_message
      displayName: Build greeting message
      variable: Local.message
      value: =Concat(Local.greeting, ", ", Local.userName, "!")

    # Send the greeting to the user
    - kind: SendActivity
      id: send_greeting
      displayName: Send greeting to user
      activity: =Local.message

2. lépés: Az ügynökszolgáltató konfigurálása

Hozzon létre egy C#-konzolalkalmazást a munkafolyamat végrehajtásához. Először konfigurálja a Foundryhez csatlakozó ügynökszolgáltatót:

using Azure.Identity;
using Microsoft.Agents.AI.Workflows;
using Microsoft.Agents.AI.Workflows.Declarative;
using Microsoft.Extensions.Configuration;

// Load configuration (endpoint should be set in user secrets or environment variables)
IConfiguration configuration = new ConfigurationBuilder()
    .AddUserSecrets<Program>()
    .AddEnvironmentVariables()
    .Build();

string foundryEndpoint = configuration["FOUNDRY_PROJECT_ENDPOINT"] 
    ?? throw new InvalidOperationException("FOUNDRY_PROJECT_ENDPOINT not configured");

// Create the agent provider that connects to Foundry
// WARNING: DefaultAzureCredential is convenient for development but requires 
// careful consideration in production environments.
AzureAgentProvider agentProvider = new(
    new Uri(foundryEndpoint), 
    new DefaultAzureCredential());

3. lépés: A munkafolyamat létrehozása és futtatása

// Define workflow options with the agent provider
DeclarativeWorkflowOptions options = new(agentProvider)
{
    Configuration = configuration,
    // LoggerFactory = loggerFactory, // Optional: Enable logging
    // ConversationId = conversationId, // Optional: Continue existing conversation
};

// Build the workflow from the YAML file
string workflowPath = Path.Combine(AppContext.BaseDirectory, "greeting-workflow.yaml");
Workflow workflow = DeclarativeWorkflowBuilder.Build<string>(workflowPath, options);

Console.WriteLine($"Loaded workflow from: {workflowPath}");
Console.WriteLine(new string('-', 40));

// Create a checkpoint manager (in-memory for this example)
CheckpointManager checkpointManager = CheckpointManager.CreateInMemory();

// Execute the workflow with input
string input = "Alice";
StreamingRun run = await InProcessExecution.RunStreamingAsync(
    workflow, 
    input, 
    checkpointManager);

// Process workflow events
await foreach (WorkflowEvent workflowEvent in run.WatchStreamAsync())
{
    switch (workflowEvent)
    {
        case MessageActivityEvent activityEvent:
            Console.WriteLine($"Activity: {activityEvent.Message}");
            break;
        case AgentResponseEvent responseEvent:
            Console.WriteLine($"Response: {responseEvent.Response.Text}");
            break;
        case WorkflowErrorEvent errorEvent:
            Console.WriteLine($"Error: {errorEvent.Data}");
            break;
    }
}

Console.WriteLine("Workflow completed!");

Várt kimenet

Loaded workflow from: C:\path\to\greeting-workflow.yaml
----------------------------------------
Activity: Hello, Alice!
Workflow completed!

Alapfogalmak

Változó névterek

A C# deklaratív munkafolyamatai névtérbeli változókat használnak az állapot rendszerezéséhez:

Namespace Description Example
Local.* A munkafolyamat helyi változói Local.message
System.* Rendszer által biztosított értékek System.ConversationId, System.LastMessage

Megjegyzés:

A C# deklaratív munkafolyamatok nem használnak Workflow.Inputs vagy Workflow.Outputs névtereket. A bemenet fogadása System.LastMessage és a kimenet elküldése műveleteken keresztül SendActivity történik.

Rendszerváltozók

Variable Description
System.ConversationId Aktuális beszélgetésazonosító
System.LastMessage A legutóbbi felhasználói üzenet
System.LastMessage.Text Az utolsó üzenet szöveges tartalma

Kifejezés nyelve

Az előtaggal = rendelkező értékek kifejezésként lesznek kiértékelve a PowerFx kifejezésnyelv használatával:

# Literal value (no evaluation)
value: Hello

# Expression (evaluated at runtime)
value: =Concat("Hello, ", Local.userName)

# Access last message text
value: =System.LastMessage.Text

Gyakori függvények a következők:

  • Concat(str1, str2, ...) - Sztringek összefűzése
  • If(condition, trueValue, falseValue) - Feltételes kifejezés
  • IsBlank(value) - Ellenőrizze, hogy az érték üres-e
  • Upper(text) / Lower(text) - Kis- és nagybetűk átalakítása
  • Find(searchText, withinText) – Szöveg keresése sztringen belül
  • MessageText(message) – Szöveg kinyerve egy üzenetobjektumból
  • UserMessage(text) – Felhasználói üzenet létrehozása szövegből
  • AgentMessage(text) – Ügynöküzenet létrehozása szövegből

Konfigurációs beállítások

Az DeclarativeWorkflowOptions osztály konfigurációt biztosít a munkafolyamat-végrehajtáshoz:

DeclarativeWorkflowOptions options = new(agentProvider)
{
    // Application configuration for variable substitution
    Configuration = configuration,

    // Continue an existing conversation (optional)
    ConversationId = "existing-conversation-id",

    // Enable logging (optional)
    LoggerFactory = loggerFactory,

    // MCP tool handler for InvokeMcpTool actions (optional)
    McpToolHandler = mcpToolHandler,

    // HTTP request handler for HttpRequestAction actions (optional)
    HttpRequestHandler = new DefaultHttpRequestHandler(),

    // PowerFx expression limits (optional)
    MaximumCallDepth = 50,
    MaximumExpressionLength = 10000,

    // Telemetry configuration (optional)
    ConfigureTelemetry = opts => { /* configure telemetry */ },
    TelemetryActivitySource = activitySource,
};

Ügynökszolgáltató beállítása

A AzureAgentProvider munkafolyamat az Foundry-ügynökökhöz csatlakozik:

using Azure.Identity;
using Microsoft.Agents.AI.Workflows.Declarative;

// Create the agent provider with Azure credentials
AzureAgentProvider agentProvider = new(
    new Uri("https://your-project.api.azureml.ms"), 
    new DefaultAzureCredential())
{
    // Optional: Define functions that agents can automatically invoke
    Functions = [
        AIFunctionFactory.Create(myPlugin.GetData),
        AIFunctionFactory.Create(myPlugin.ProcessItem),
    ],

    // Optional: Allow concurrent function invocation
    AllowConcurrentInvocation = true,

    // Optional: Allow multiple tool calls per response
    AllowMultipleToolCalls = true,
};

Munkafolyamat végrehajtása

Munkafolyamatok futtatására és események kezelésére használható InProcessExecution :

using Microsoft.Agents.AI.Workflows;
using Microsoft.Agents.AI.Workflows.Checkpointing;

// Create checkpoint manager (choose in-memory or file-based)
CheckpointManager checkpointManager = CheckpointManager.CreateInMemory();
// Or persist to disk:
// var checkpointFolder = Directory.CreateDirectory("./checkpoints");
// var checkpointManager = CheckpointManager.CreateJson(
//     new FileSystemJsonCheckpointStore(checkpointFolder));

// Start workflow execution
StreamingRun run = await InProcessExecution.RunStreamingAsync(
    workflow, 
    input, 
    checkpointManager);

// Process events as they occur
await foreach (WorkflowEvent workflowEvent in run.WatchStreamAsync())
{
    switch (workflowEvent)
    {
        case MessageActivityEvent activity:
            Console.WriteLine($"Message: {activity.Message}");
            break;

        case AgentResponseUpdateEvent streamEvent:
            Console.Write(streamEvent.Update.Text); // Streaming text
            break;

        case AgentResponseEvent response:
            Console.WriteLine($"Agent: {response.Response.Text}");
            break;

        case RequestInfoEvent request:
            // Handle external input requests (human-in-the-loop)
            var userInput = await GetUserInputAsync(request);
            await run.SendResponseAsync(request.Request.CreateResponse(userInput));
            break;

        case SuperStepCompletedEvent checkpoint:
            // Checkpoint created - can resume from here if needed
            var checkpointInfo = checkpoint.CompletionInfo?.Checkpoint;
            break;

        case WorkflowErrorEvent error:
            Console.WriteLine($"Error: {error.Data}");
            break;
    }
}

Folytatás ellenőrzőpontokból

A munkafolyamatok hibatűrés céljából az ellenőrzőpontokról folytathatók:

// Save checkpoint info when workflow yields
CheckpointInfo? lastCheckpoint = null;

await foreach (WorkflowEvent workflowEvent in run.WatchStreamAsync())
{
    if (workflowEvent is SuperStepCompletedEvent checkpointEvent)
    {
        lastCheckpoint = checkpointEvent.CompletionInfo?.Checkpoint;
    }
}

// Later: Resume from the saved checkpoint
if (lastCheckpoint is not null)
{
    // Recreate the workflow (can be on a different machine)
    Workflow workflow = DeclarativeWorkflowBuilder.Build<string>(workflowPath, options);

    StreamingRun resumedRun = await InProcessExecution.ResumeStreamingAsync(
        workflow, 
        lastCheckpoint, 
        checkpointManager);

    // Continue processing events...
}

AOT és Trim-Aggressive ellenőrzőpont-készítés

Ha Native AOT-val teszi közzé (dotnet publish -p:PublishAot=true), vagy más módon letiltja a System.Text.Json reflexiós tartalékmechanizmusát (<JsonSerializerIsReflectionEnabledByDefault>false</JsonSerializerIsReflectionEnabledByDefault>), az alapértelmezett CheckpointManager.CreateJson(store) hívás meghiúsul az ellenőrzőpont véglegesítésekor vagy rehidratáláskor.

A declarative-workflow csomag egy forrásgenerált JsonSerializerOptions példányt, DeclarativeWorkflowJsonOptions.Default tartalmaz, amely lefed minden deklaratív csomagtípust, amely az ellenőrzőpont-folyamaton halad át. Adja át második argumentumként a következőnek CheckpointManager.CreateJson:

using Microsoft.Agents.AI.Workflows.Checkpointing;
using Microsoft.Agents.AI.Workflows.Declarative;

// AOT-safe: type info is resolved via the source-generated JsonSerializerContext,
// so no runtime reflection is required.
CheckpointManager checkpointManager = CheckpointManager.CreateJson(
    store,
    DeclarativeWorkflowJsonOptions.Default);

Megjegyzés:

DeclarativeWorkflowJsonOptions.Default A továbbítás biztonságosan használható nem AOT-környezetekben is. Ez egy drop-in frissítés a következőhöz CheckpointManager.CreateJson(store) : a tükröződés-kompatibilis alkalmazások nem látnak viselkedésváltozást. Feltétlenül alkalmazza, hogy ugyanaz a kód továbbra is működjön, ha később AOT-tal vagy lemetszéssel teszi közzé.

DeclarativeWorkflowJsonOptions van megjelölve [Experimental("MAAI001")]. Tiltsa le a diagnosztikát a hívási helyen vagy a projektfájlban:

<PropertyGroup>
  <NoWarn>$(NoWarn);MAAI001</NoWarn>
</PropertyGroup>

Felhasználó által definiált típusok regisztrálása

Ha a munkafolyamat bemenete, az egyéni ActionExecutorResult.Result hasznos terhek vagy a nem primitív jóváhagyásikérelem-argumentumok felhasználó által definiált típusúak, klónozza a(z) Default elemet, és fűzze hozzá a saját forrásgenerált feloldóját:

// Compose: declarative-package types + your app's source-gen context.
JsonSerializerOptions options = new(DeclarativeWorkflowJsonOptions.Default);
options.TypeInfoResolverChain.Add(MyAppJsonContext.Default);
options.MakeReadOnly();

CheckpointManager checkpointManager = CheckpointManager.CreateJson(store, options);

Ahol a(z) MyAppJsonContext egy, az alkalmazásod típusaihoz definiált JsonSerializerContext:

[JsonSourceGenerationOptions(JsonSerializerDefaults.Web)]
[JsonSerializable(typeof(MyWorkflowInput))]
[JsonSerializable(typeof(MyCustomResult))]
internal sealed partial class MyAppJsonContext : JsonSerializerContext;

Tip

A végpontok közötti, futtatható példáért — beleértve a YAML-munkafolyamatot, egy AzureCliCredential által támogatott ügynököt, valamint egy nyomon követhető „drop the options to see the failure” módot — tekintse meg a AotCheckpointing található . A mintakészletek .csprojJsonSerializerIsReflectionEnabledByDefault=false úgy reprodukálják az AOT hibamódját, hogy teljes AOT-közzétételt nem igényelnek.

Műveletek referenciája

A műveletek a deklaratív munkafolyamatok építőelemei. Minden művelet egy adott műveletet hajt végre, és a műveletek egymás után, a YAML-fájlban megjelenő sorrendben lesznek végrehajtva.

Műveleti struktúra

Minden művelet közös tulajdonságokkal rendelkezik:

- kind: ActionType      # Required: The type of action
  id: unique_id         # Optional: Unique identifier for referencing
  displayName: Name     # Optional: Human-readable name for logging
  # Action-specific properties...

Változókezelési műveletek

SetVariable

Beállít egy változót egy megadott értékre.

- kind: SetVariable
  id: set_greeting
  displayName: Set greeting message
  variable: Local.greeting
  value: Hello World

Kifejezéssel:

- kind: SetVariable
  variable: Local.fullName
  value: =Concat(Local.firstName, " ", Local.lastName)

Tulajdonságok:

Ingatlan Kötelező Description
variable Igen Változó útvonal (pl. Local.name, Workflow.Outputs.result)
value Igen Beállítandó érték (literál vagy kifejezés)

SetMultipleVariables

Több változót állít be egyetlen műveletben.

- kind: SetMultipleVariables
  id: initialize_vars
  displayName: Initialize variables
  variables:
    Local.counter: 0
    Local.status: pending
    Local.message: =Concat("Processing order ", Local.orderId)

Tulajdonságok:

Ingatlan Kötelező Description
variables Igen Változó értékekhez vezető útvonalainak térképe

SetTextVariable

Egy szöveges változót egy megadott sztringértékre állít be.

- kind: SetTextVariable
  id: set_text
  displayName: Set text content
  variable: Local.description
  value: This is a text description

Tulajdonságok:

Ingatlan Kötelező Description
variable Igen A szöveges értékhez tartozó változó útvonal
value Igen Beállítandó szövegérték

ResetVariable

Törli egy változó értékét.

- kind: ResetVariable
  id: clear_counter
  variable: Local.counter

Tulajdonságok:

Ingatlan Kötelező Description
variable Igen Az alaphelyzetbe állítás változó elérési útja

ClearAllVariables

Alaphelyzetbe állítja az aktuális környezetben lévő összes változót.

- kind: ClearAllVariables
  id: clear_all
  displayName: Clear all workflow variables

ParseValue

Kinyeri vagy átalakítja az adatokat használható formátumba.

- kind: ParseValue
  id: parse_json
  displayName: Parse JSON response
  source: =Local.rawResponse
  variable: Local.parsedData

Tulajdonságok:

Ingatlan Kötelező Description
source Igen Az elemezni kívánt értéket visszaadó kifejezés
variable Igen Változó elérési útja az elemzési eredmény tárolásához

EditTableV2

Strukturált táblázatformátumban módosítja az adatokat.

- kind: EditTableV2
  id: update_table
  displayName: Update configuration table
  table: Local.configTable
  operation: update
  row:
    key: =Local.settingName
    value: =Local.settingValue

Tulajdonságok:

Ingatlan Kötelező Description
table Igen A táblázat változó elérési útja
operation Igen Művelet típusa (hozzáadás, frissítés, törlés)
row Igen A művelethez tartozó soradatok

Folyamatműveletek vezérlése

Ha

Feltételesen hajt végre műveleteket egy feltétel alapján.

- kind: If
  id: check_age
  displayName: Check user age
  condition: =Local.age >= 18
  then:
    - kind: SendActivity
      activity:
        text: "Welcome, adult user!"
  else:
    - kind: SendActivity
      activity:
        text: "Welcome, young user!"

Tulajdonságok:

Ingatlan Kötelező Description
condition Igen Igaz/hamis értéket kiértékelő kifejezés
then Igen Végrehajtandó műveletek, ha a feltétel igaz
else Nem Végrehajtandó műveletek, ha a feltétel hamis

ConditionGroup

Kiértékel több feltételt, mint egy switch/case utasítás a programozásban.

- kind: ConditionGroup
  id: route_by_category
  displayName: Route based on category
  conditions:
    - condition: =Local.category = "electronics"
      id: electronics_branch
      actions:
        - kind: SetVariable
          variable: Local.department
          value: Electronics Team
    - condition: =Local.category = "clothing"
      id: clothing_branch
      actions:
        - kind: SetVariable
          variable: Local.department
          value: Clothing Team
  elseActions:
    - kind: SetVariable
      variable: Local.department
      value: General Support

Tulajdonságok:

Ingatlan Kötelező Description
conditions Igen Feltétel-/műveletpárok listája (az első találat nyer)
elseActions Nem Műveletek, amikor egyik feltétel sem egyezik

Foreach

Egy gyűjteményen keresztüli iterálás.

- kind: Foreach
  id: process_items
  displayName: Process each item
  source: =Local.items
  itemName: item
  indexName: index
  actions:
    - kind: SendActivity
      activity:
        text: =Concat("Processing item ", index, ": ", item)

Tulajdonságok:

Ingatlan Kötelező Description
source Igen Gyűjteményt visszaadó kifejezés
itemName Nem Az aktuális elem változóneve (alapértelmezett: item)
indexName Nem Az aktuális index változójának neve (alapértelmezett: index)
actions Igen Az egyes elemekhez végrehajtandó műveletek

BreakLoop

Azonnal kilép az aktuális ciklusból.

- kind: Foreach
  source: =Local.items
  actions:
    - kind: If
      condition: =item = "stop"
      then:
        - kind: BreakLoop
    - kind: SendActivity
      activity:
        text: =item

ContinueLoop

Ugrás a hurok következő iterációjára.

- kind: Foreach
  source: =Local.numbers
  actions:
    - kind: If
      condition: =item < 0
      then:
        - kind: ContinueLoop
    - kind: SendActivity
      activity:
        text: =Concat("Positive number: ", item)

GotoAction

Azonosító alapján ugrik egy adott műveletre.

- kind: SetVariable
  id: start_label
  variable: Local.attempts
  value: =Local.attempts + 1

- kind: SendActivity
  activity:
    text: =Concat("Attempt ", Local.attempts)

- kind: If
  condition: =And(Local.attempts < 3, Not(Local.success))
  then:
    - kind: GotoAction
      actionId: start_label

Tulajdonságok:

Ingatlan Kötelező Description
actionId Igen A művelet azonosítója, amelyre ugrani szeretne.

Kimeneti műveletek

SendActivity

Üzenetet küld a felhasználónak.

- kind: SendActivity
  id: send_welcome
  displayName: Send welcome message
  activity:
    text: "Welcome to our service!"

Kifejezéssel:

- kind: SendActivity
  activity:
    text: =Concat("Hello, ", Local.userName, "! How can I help you today?")

Tulajdonságok:

Ingatlan Kötelező Description
activity Igen A küldendő tevékenység
activity.text Igen Üzenet szövege (literál vagy kifejezés)

Ügynökhívási műveletek

InvokeAzureAgent

Meghív egy Foundry-ügynököt.

Alapszintű meghívás:

- kind: InvokeAzureAgent
  id: call_assistant
  displayName: Call assistant agent
  agent:
    name: AssistantAgent
  conversationId: =System.ConversationId

Bemeneti és kimeneti konfigurációval:

- kind: InvokeAzureAgent
  id: call_analyst
  displayName: Call analyst agent
  agent:
    name: AnalystAgent
  conversationId: =System.ConversationId
  input:
    messages: =Local.userMessage
    arguments:
      topic: =Local.topic
  output:
    responseObject: Local.AnalystResult
    messages: Local.AnalystMessages
    autoSend: true

Külső hurokkal (a feltétel teljesüléséig folytatódik):

- kind: InvokeAzureAgent
  id: support_agent
  agent:
    name: SupportAgent
  input:
    externalLoop:
      when: =Not(Local.IsResolved)
  output:
    responseObject: Local.SupportResult

Tulajdonságok:

Ingatlan Kötelező Description
agent.name Igen A regisztrált ügynök neve
conversationId Nem Beszélgetési környezet azonosítója
input.messages Nem Az ügynöknek küldendő üzenetek
input.arguments Nem Az ügynök további argumentumai
input.externalLoop.when Nem Az ügynökhurok folytatásának feltétele
output.responseObject Nem Az ügynök válaszának tárolási útvonala
output.messages Nem Beszélgetési üzenetek tárolásának elérési útja
output.autoSend Nem Válasz automatikus küldése a felhasználónak

Eszköz- és HTTP-műveletek

InvokeFunctionTool

Egy függvénymodult közvetlenül a munkafolyamatból hív meg, anélkül, hogy egy mesterséges intelligencia ügynökön keresztülmenne.

- kind: InvokeFunctionTool
  id: invoke_get_data
  displayName: Get data from function
  functionName: GetUserData
  conversationId: =System.ConversationId
  requireApproval: true
  arguments:
    userId: =Local.userId
  output:
    autoSend: true
    result: Local.UserData
    messages: Local.FunctionMessages

Tulajdonságok:

Ingatlan Kötelező Description
functionName Igen A meghívandó függvény neve
conversationId Nem Beszélgetési környezet azonosítója
requireApproval Nem Felhasználói jóváhagyás megkövetelése végrehajtás előtt
arguments Nem A függvénynek átadni kívánt argumentumok
output.result Nem A függvény eredményének tárolási útvonala
output.messages Nem A függvényüzenetek tárolásának elérési útja
output.autoSend Nem Eredmény automatikus küldése a felhasználónak

Az InvokeFunctionTool C# beállítása:

A függvényeket külső bemenettel WorkflowRunner kell regisztrálni vagy kezelni:

// Define functions that can be invoked
AIFunction[] functions = [
    AIFunctionFactory.Create(myPlugin.GetUserData),
    AIFunctionFactory.Create(myPlugin.ProcessOrder),
];

// Create workflow runner with functions
WorkflowRunner runner = new(functions) { UseJsonCheckpoints = true };
await runner.ExecuteAsync(workflowFactory.CreateWorkflow, input);

InvokeMcpTool

Egy eszközt hív meg egy MCP -kiszolgálón (Model Context Protocol).

- kind: InvokeMcpTool
  id: invoke_docs_search
  displayName: Search documentation
  serverUrl: https://learn.microsoft.com/api/mcp
  serverLabel: microsoft_docs
  toolName: microsoft_docs_search
  conversationId: =System.ConversationId
  requireApproval: false
  headers:
    X-Custom-Header: custom-value
  arguments:
    query: =Local.SearchQuery
  output:
    autoSend: true
    result: Local.SearchResults

A hosztolt forgatókönyvek kapcsolatneve:

- kind: InvokeMcpTool
  id: invoke_hosted_mcp
  serverUrl: https://mcp.ai.azure.com
  toolName: my_tool
  # Connection name is used in hosted scenarios to connect to a ProjectConnectionId in Foundry.
  # Note: This feature is not fully supported yet.
  connection:
    name: my-foundry-connection
  output:
    result: Local.ToolResult

Tulajdonságok:

Ingatlan Kötelező Description
serverUrl Igen Az MCP-kiszolgáló URL-címe
serverLabel Nem Emberi olvasásra alkalmas címke a kiszolgálóhoz
toolName Igen A meghívandó eszköz neve
conversationId Nem Beszélgetési környezet azonosítója
requireApproval Nem Felhasználói jóváhagyás megkövetelése
arguments Nem Az eszköznek továbbítandó argumentumok
headers Nem Egyéni HTTP-fejlécek a kéréshez
connection.name Nem Elnevezett kapcsolat üzemeltetett forgatókönyvekhez (a Foundry ProjectConnectionId-hez csatlakozik, még nem támogatott teljesen)
output.result Nem Az eszköz eredményének tárolási útvonala
output.messages Nem Eredményüzenetek tárolásának elérési útja
output.autoSend Nem Eredmény automatikus küldése a felhasználónak

Az InvokeMcpTool C# beállítása:

Konfigurálja a McpToolHandler munkafolyamat-előállítót:

using Azure.Core;
using Azure.Identity;
using Microsoft.Agents.AI.Workflows.Declarative;

// Create MCP tool handler with authentication callback
DefaultAzureCredential credential = new();
DefaultMcpToolHandler mcpToolHandler = new(
    httpClientProvider: async (serverUrl, cancellationToken) =>
    {
        if (serverUrl.StartsWith("https://mcp.ai.azure.com", StringComparison.OrdinalIgnoreCase))
        {
            // Acquire token for Azure MCP server
            AccessToken token = await credential.GetTokenAsync(
                new TokenRequestContext(["https://mcp.ai.azure.com/.default"]),
                cancellationToken);

            HttpClient httpClient = new();
            httpClient.DefaultRequestHeaders.Authorization =
                new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token.Token);
            return httpClient;
        }

        // Return null for servers that don't require authentication
        return null;
    });

// Configure workflow factory with MCP handler
WorkflowFactory workflowFactory = new("workflow.yaml", foundryEndpoint)
{
    McpToolHandler = mcpToolHandler
};

HttpRequestAction

HTTP-kérést küld a konfigurált IHttpRequestHandler. A sikeres JSON-válaszok elemzése a hozzárendelés előtt történik; a nem 2xx válaszok nem hajtják végre a műveletet.

- kind: HttpRequestAction
  id: fetch_repo_info
  method: GET
  url: "https://api.github.com/repos/Microsoft/agent-framework"
  headers:
    Accept: application/vnd.github+json
    User-Agent: agent-framework
  queryParameters:
    per_page: 10
  response: Local.RepoInfo
  responseHeaders: Local.RepoHeaders

Tulajdonságok:

Ingatlan Kötelező Description
url Igen Abszolút kérés URL-címe
method Nem HTTP-metódus; alapértelmezett érték: GET
headers Nem HTTP-kérés fejlécek
queryParameters Nem Az URL-címhez hozzáfűzött lekérdezési paraméterek
body Nem Kérelem törzse; használja kind: json, rawvagy none
requestTimeoutInMilliseconds Nem Kérelemenkénti időtúllépés
conversationId Nem Sikeres választörzs hozzáadása a beszélgetéshez
response Nem Az elemzési válasz törzsének tárolásának elérési útja
responseHeaders Nem A válaszfejlécek tárolásának elérési útja

Az HttpRequestAction C#-beállítása:

Állítsa be HttpRequestHandler a munkafolyamat létrehozásakor. Ha újrapróbálkozásokra vagy URL engedélyezési listára van szüksége, használjon egyéni kezelőt.

DeclarativeWorkflowOptions options = new(agentProvider)
{
    HttpRequestHandler = new DefaultHttpRequestHandler(),
};

Workflow workflow = DeclarativeWorkflowBuilder.Build<string>("workflow.yaml", options);

Ember a hurokban műveletek

Question

Kérdést tesz fel a felhasználónak, és tárolja a választ.

- kind: Question
  id: ask_name
  displayName: Ask for user name
  question:
    text: "What is your name?"
  variable: Local.userName
  default: "Guest"

Tulajdonságok:

Ingatlan Kötelező Description
question.text Igen A feltenni kívánt kérdés
variable Igen A válasz tárolásának elérési útja
default Nem Alapértelmezett érték, ha nincs válasz

KülsőInputKérése

Külső rendszertől vagy folyamattól kér bemenetet.

- kind: RequestExternalInput
  id: request_approval
  displayName: Request manager approval
  prompt:
    text: "Please provide approval for this request."
  variable: Local.approvalResult
  default: "pending"

Tulajdonságok:

Ingatlan Kötelező Description
prompt.text Igen A szükséges bemenet leírása
variable Igen A bemenet tárolásának elérési útja
default Nem Alapértelmezett érték

Munkafolyamat-vezérlési műveletek

EndWorkflow

Leállítja a munkafolyamat végrehajtását.

- kind: EndWorkflow
  id: finish
  displayName: End workflow

Beszélgetés vége

Véget vet az aktuális beszélgetésnek.

- kind: EndConversation
  id: end_chat
  displayName: End conversation

CreateConversation

Új beszélgetési környezetet hoz létre.

- kind: CreateConversation
  id: create_new_conv
  displayName: Create new conversation
  conversationId: Local.NewConversationId

Tulajdonságok:

Ingatlan Kötelező Description
conversationId Igen Az új beszélgetésazonosító tárolásának elérési útja

Beszélgetési műveletek (csak C# esetén)

ÜzenetHozzáadásaBeszélgetéshez

Üzenetet ad hozzá egy beszélgetési szálhoz.

- kind: AddConversationMessage
  id: add_system_message
  displayName: Add system context
  conversationId: =System.ConversationId
  message:
    role: system
    content: =Local.contextInfo

Tulajdonságok:

Ingatlan Kötelező Description
conversationId Igen Célbeszélgetés azonosítója
message Igen Hozzáadandó üzenet
message.role Igen Üzenetszerepkör (rendszer, felhasználó, asszisztens)
message.content Igen Üzenet tartalma

Beszélgetési üzenetek másolása

Üzenetek másolása egyik beszélgetésből a másikba.

- kind: CopyConversationMessages
  id: copy_context
  displayName: Copy conversation context
  sourceConversationId: =Local.SourceConversation
  targetConversationId: =System.ConversationId
  limit: 10

Tulajdonságok:

Ingatlan Kötelező Description
sourceConversationId Igen Forrásbeszélgetés azonosítója
targetConversationId Igen Célbeszélgetés azonosítója
limit Nem A másolandó üzenetek maximális száma

Beszélgetésüzenet lekérése

Egy adott üzenetet kér le egy beszélgetésből.

- kind: RetrieveConversationMessage
  id: get_message
  displayName: Get specific message
  conversationId: =System.ConversationId
  messageId: =Local.targetMessageId
  variable: Local.retrievedMessage

Tulajdonságok:

Ingatlan Kötelező Description
conversationId Igen Beszélgetés azonosítója
messageId Igen Lekérendő üzenetazonosító
variable Igen A lekért üzenet tárolásának elérési útja

Beszélgetési üzenetek lekérése

Több üzenetet kér le egy beszélgetésből.

- kind: RetrieveConversationMessages
  id: get_history
  displayName: Get conversation history
  conversationId: =System.ConversationId
  limit: 20
  newestFirst: true
  variable: Local.conversationHistory

Tulajdonságok:

Ingatlan Kötelező Description
conversationId Igen Beszélgetés azonosítója
limit Nem Lekérendő üzenetek maximális száma (alapértelmezett: 20)
newestFirst Nem Visszatérés csökkenő sorrendben
after Nem Kurzor lapozáshoz
before Nem Kurzor lapozáshoz
variable Igen A lekért üzenetek tárolásának elérési útja

Műveletek – rövid útmutató

Tevékenység Kategória C# Python Description
SetVariable Variable Egyetlen változó beállítása
SetMultipleVariables Variable Több változó beállítása
SetTextVariable Variable Szövegváltozó beállítása
ResetVariable Variable Változó törlése
ClearAllVariables Variable Az összes változó törlése
ParseValue Variable Adatok elemzése/átalakítása
EditTableV2 Variable Táblaadatok módosítása
If Folyamat vezérlése Feltételes elágaztatás
ConditionGroup Folyamat vezérlése Többágú kapcsoló
Foreach Folyamat vezérlése Végigiterálni a gyűjteményen
BreakLoop Folyamat vezérlése Kilépés az aktuális ciklusból
ContinueLoop Folyamat vezérlése Ugrás a következő iterációra
GotoAction Folyamat vezérlése Ugrás műveletre azonosító szerint
SendActivity Kimenet Üzenet küldése a felhasználónak
InvokeAzureAgent Ügynök Az Azure AI-ügynök meghívása
InvokeFunctionTool Eszköz Függvény meghívása közvetlenül
InvokeMcpTool Eszköz MCP-kiszolgáló eszköz meghívása
HttpRequestAction HTTP HTTP-végpont meghívása
Question Ember a folyamatban Tegyen fel egy kérdést a felhasználónak
RequestExternalInput Ember a folyamatban Külső bemenet kérése
EndWorkflow Munkafolyamat-vezérlés Munkafolyamat leállálása
EndConversation Munkafolyamat-vezérlés Beszélgetés befejezése
CreateConversation Munkafolyamat-vezérlés Új beszélgetés létrehozása
AddConversationMessage Beszélgetés Üzenet hozzáadása a szálhoz
CopyConversationMessages Beszélgetés Üzenetek másolása
RetrieveConversationMessage Beszélgetés Egyetlen üzenet lekérése
RetrieveConversationMessages Beszélgetés Több üzenet lekérése

Haladó minták

Többügynökalapú orkesztráció

Szekvenciális ágens folyamat

Több ügynökön keresztüli munka továbbítása egymás után.

#
# Sequential agent pipeline for content creation
#
kind: Workflow
trigger:

  kind: OnConversationStart
  id: content_workflow
  actions:

    # First agent: Research
    - kind: InvokeAzureAgent
      id: invoke_researcher
      displayName: Research phase
      conversationId: =System.ConversationId
      agent:
        name: ResearcherAgent

    # Second agent: Write draft
    - kind: InvokeAzureAgent
      id: invoke_writer
      displayName: Writing phase
      conversationId: =System.ConversationId
      agent:
        name: WriterAgent

    # Third agent: Edit
    - kind: InvokeAzureAgent
      id: invoke_editor
      displayName: Editing phase
      conversationId: =System.ConversationId
      agent:
        name: EditorAgent

C# beállítás:

using Azure.AI.Projects;
using Azure.AI.Projects.OpenAI;
using Azure.Identity;

// Ensure agents exist in Foundry
AIProjectClient aiProjectClient = new(foundryEndpoint, new DefaultAzureCredential());

await aiProjectClient.CreateAgentAsync(
    agentName: "ResearcherAgent",
    agentDefinition: new DeclarativeAgentDefinition(modelName)
    {
        Instructions = "You are a research specialist..."
    },
    agentDescription: "Research agent for content pipeline");

// Create and run workflow
WorkflowFactory workflowFactory = new("content-pipeline.yaml", foundryEndpoint);
WorkflowRunner runner = new();
await runner.ExecuteAsync(workflowFactory.CreateWorkflow, "Create content about AI");

Feltételes ügynök útválasztása

A kérések átirányítása különböző ügynököknek feltételek alapján.

#
# Route to specialized support agents based on category
#
kind: Workflow
trigger:

  kind: OnConversationStart
  id: support_router
  actions:

    # Capture category from user input or set via another action
    - kind: SetVariable
      id: set_category
      variable: Local.category
      value: =System.LastMessage.Text

    - kind: ConditionGroup
      id: route_request
      displayName: Route to appropriate agent
      conditions:
        - condition: =Local.category = "billing"
          id: billing_route
          actions:
            - kind: InvokeAzureAgent
              id: billing_agent
              agent:
                name: BillingAgent
              conversationId: =System.ConversationId
        - condition: =Local.category = "technical"
          id: technical_route
          actions:
            - kind: InvokeAzureAgent
              id: technical_agent
              agent:
                name: TechnicalAgent
              conversationId: =System.ConversationId
      elseActions:
        - kind: InvokeAzureAgent
          id: general_agent
          agent:
            name: GeneralAgent
          conversationId: =System.ConversationId

Eszközintegrációs minták

Adatok előzetes beolvasása az InvokeFunctionTool használatával

Adatok beolvasása ügynök meghívása előtt:

#
# Pre-fetch menu data before agent interaction
#
kind: Workflow
trigger:

  kind: OnConversationStart
  id: menu_workflow
  actions:
    # Pre-fetch today's specials
    - kind: InvokeFunctionTool
      id: get_specials
      functionName: GetSpecials
      requireApproval: true
      output:
        autoSend: true
        result: Local.Specials

    # Agent uses pre-fetched data
    - kind: InvokeAzureAgent
      id: menu_agent
      conversationId: =System.ConversationId
      agent:
        name: MenuAgent
      input:
        messages: =UserMessage("Describe today's specials: " & Local.Specials)

MCP eszközintegráció

Külső kiszolgáló hívása MCP használatával:

#
# Search documentation using MCP
#
kind: Workflow
trigger:

  kind: OnConversationStart
  id: docs_search
  actions:

    - kind: SetVariable
      variable: Local.SearchQuery
      value: =System.LastMessage.Text

    # Search Microsoft Learn
    - kind: InvokeMcpTool
      id: search_docs
      serverUrl: https://learn.microsoft.com/api/mcp
      toolName: microsoft_docs_search
      conversationId: =System.ConversationId
      arguments:
        query: =Local.SearchQuery
      output:
        result: Local.SearchResults
        autoSend: true

    # Summarize results with agent
    - kind: InvokeAzureAgent
      id: summarize
      agent:
        name: SummaryAgent
      conversationId: =System.ConversationId
      input:
        messages: =UserMessage("Summarize these search results")

Előfeltételek

Mielőtt hozzákezdene, győződjön meg arról, hogy:

  • Python 3.10 – 3.13 (A Python 3.14 a PowerFx kompatibilitása miatt még nem támogatott)
  • Az Agent Framework deklaratív csomagja telepítve van:
pip install agent-framework-declarative --pre

Ez a csomag automatikusan lekéri az alapul szolgáló agent-framework-core részt.

Az első deklaratív munkafolyamat

Hozzunk létre egy egyszerű munkafolyamatot, amely név szerint köszönti a felhasználót.

1. lépés: A YAML-fájl létrehozása

Hozzon létre egy fájlt:greeting-workflow.yaml

name: greeting-workflow
description: A simple workflow that greets the user

inputs:
  name:
    type: string
    description: The name of the person to greet

actions:
  # Set a greeting prefix
  - kind: SetVariable
    id: set_greeting
    displayName: Set greeting prefix
    variable: Local.greeting
    value: Hello

  # Build the full message using an expression
  - kind: SetVariable
    id: build_message
    displayName: Build greeting message
    variable: Local.message
    value: =Concat(Local.greeting, ", ", Workflow.Inputs.name, "!")

  # Send the greeting to the user
  - kind: SendActivity
    id: send_greeting
    displayName: Send greeting to user
    activity:
      text: =Local.message

  # Store the result in outputs
  - kind: SetVariable
    id: set_output
    displayName: Store result in outputs
    variable: Workflow.Outputs.greeting
    value: =Local.message

2. lépés: A munkafolyamat betöltése és futtatása

Hozzon létre egy Python-fájlt a munkafolyamat végrehajtásához:

import asyncio
from pathlib import Path

from agent_framework.declarative import WorkflowFactory


async def main() -> None:
    """Run the greeting workflow."""
    # Create a workflow factory
    factory = WorkflowFactory()

    # Load the workflow from YAML
    workflow_path = Path(__file__).parent / "greeting-workflow.yaml"
    workflow = factory.create_workflow_from_yaml_path(workflow_path)

    print(f"Loaded workflow: {workflow.name}")
    print("-" * 40)

    # Run with a name input
    result = await workflow.run({"name": "Alice"})
    for output in result.get_outputs():
        print(f"Output: {output}")
    for output in result.get_intermediate_outputs():
        print(f"Intermediate: {output}")


if __name__ == "__main__":
    asyncio.run(main())

Várt kimenet

Loaded workflow: greeting-workflow
----------------------------------------
Output: Hello, Alice!

Alapfogalmak

Változó névterek

A deklaratív munkafolyamatok névtérbeli változókat használnak az állapot rendszerezéséhez:

Namespace Description Example
Local.* A munkafolyamat helyi változói Local.message
Workflow.Inputs.* Bemeneti paraméterek Workflow.Inputs.name
Workflow.Outputs.* Kimeneti értékek Workflow.Outputs.result
System.* Rendszer által biztosított értékek System.ConversationId

Kifejezés nyelve

Az előtaggal rendelkező = értékek kifejezésként lesznek kiértékelve:

# Literal value (no evaluation)
value: Hello

# Expression (evaluated at runtime)
value: =Concat("Hello, ", Workflow.Inputs.name)

Gyakori függvények a következők:

  • Concat(str1, str2, ...) - Sztringek összefűzése
  • If(condition, trueValue, falseValue) - Feltételes kifejezés
  • IsBlank(value) - Ellenőrizze, hogy az érték üres-e

Művelettípusok

A deklaratív munkafolyamatok különböző művelettípusokat támogatnak:

Kategória Műveletek
Változókezelés \, \, \
Folyamat vezérlése If, ConditionGroup, Foreach, BreakLoopContinueLoopGotoAction
Kimenet SendActivity
Ügynök meghívása InvokeAzureAgent
Eszközhívás InvokeFunctionTool, InvokeMcpTool
HTTP HttpRequestAction
Ember a folyamatban Question, RequestExternalInput
Munkafolyamat-vezérlés \, \, \

Műveletek referenciája

A műveletek a deklaratív munkafolyamatok építőelemei. Minden művelet egy adott műveletet hajt végre, és a műveletek egymás után, a YAML-fájlban megjelenő sorrendben lesznek végrehajtva.

Műveleti struktúra

Minden művelet közös tulajdonságokkal rendelkezik:

- kind: ActionType      # Required: The type of action
  id: unique_id         # Optional: Unique identifier for referencing
  displayName: Name     # Optional: Human-readable name for logging
  # Action-specific properties...

Változókezelési műveletek

SetVariable

Beállít egy változót egy megadott értékre.

- kind: SetVariable
  id: set_greeting
  displayName: Set greeting message
  variable: Local.greeting
  value: Hello World

Kifejezéssel:

- kind: SetVariable
  variable: Local.fullName
  value: =Concat(Workflow.Inputs.firstName, " ", Workflow.Inputs.lastName)

Tulajdonságok:

Ingatlan Kötelező Description
variable Igen Változó útvonal (pl. Local.name, Workflow.Outputs.result)
value Igen Beállítandó érték (literál vagy kifejezés)

Megjegyzés:

Python támogatja a SetValue művelettípust is, amely a céltulajdonság esetében path helyett variable-t használ. Mind a SetVariable (a variable), mind a SetValue (a path) ugyanazt az eredményt éri el. Például:

- kind: SetValue
  id: set_greeting
  path: Local.greeting
  value: Hello World

SetMultipleVariables

Több változót állít be egyetlen műveletben.

- kind: SetMultipleVariables
  id: initialize_vars
  displayName: Initialize variables
  variables:
    Local.counter: 0
    Local.status: pending
    Local.message: =Concat("Processing order ", Workflow.Inputs.orderId)

Tulajdonságok:

Ingatlan Kötelező Description
variables Igen Változó értékekhez vezető útvonalainak térképe

ResetVariable

Törli egy változó értékét.

- kind: ResetVariable
  id: clear_counter
  variable: Local.counter

Tulajdonságok:

Ingatlan Kötelező Description
variable Igen Az alaphelyzetbe állítás változó elérési útja

Folyamatműveletek vezérlése

Ha

Feltételesen hajt végre műveleteket egy feltétel alapján.

- kind: If
  id: check_age
  displayName: Check user age
  condition: =Workflow.Inputs.age >= 18
  then:
    - kind: SendActivity
      activity:
        text: "Welcome, adult user!"
  else:
    - kind: SendActivity
      activity:
        text: "Welcome, young user!"

Beágyazott feltételek:

- kind: If
  condition: =Workflow.Inputs.role = "admin"
  then:
    - kind: SendActivity
      activity:
        text: "Admin access granted"
  else:
    - kind: If
      condition: =Workflow.Inputs.role = "user"
      then:
        - kind: SendActivity
          activity:
            text: "User access granted"
      else:
        - kind: SendActivity
          activity:
            text: "Access denied"

Tulajdonságok:

Ingatlan Kötelező Description
condition Igen Igaz/hamis értéket kiértékelő kifejezés
then Igen Végrehajtandó műveletek, ha a feltétel igaz
else Nem Végrehajtandó műveletek, ha a feltétel hamis

ConditionGroup

Kiértékel több feltételt, mint egy switch/case utasítás a programozásban.

- kind: ConditionGroup
  id: route_by_category
  displayName: Route based on category
  conditions:
    - condition: =Workflow.Inputs.category = "electronics"
      id: electronics_branch
      actions:
        - kind: SetVariable
          variable: Local.department
          value: Electronics Team
    - condition: =Workflow.Inputs.category = "clothing"
      id: clothing_branch
      actions:
        - kind: SetVariable
          variable: Local.department
          value: Clothing Team
    - condition: =Workflow.Inputs.category = "food"
      id: food_branch
      actions:
        - kind: SetVariable
          variable: Local.department
          value: Food Team
  elseActions:
    - kind: SetVariable
      variable: Local.department
      value: General Support

Tulajdonságok:

Ingatlan Kötelező Description
conditions Igen Feltétel-/műveletpárok listája (az első találat nyer)
elseActions Nem Műveletek, amikor egyik feltétel sem egyezik

Foreach

Egy gyűjteményen keresztüli iterálás.

- kind: Foreach
  id: process_items
  displayName: Process each item
  source: =Workflow.Inputs.items
  itemName: item
  indexName: index
  actions:
    - kind: SendActivity
      activity:
        text: =Concat("Processing item ", index, ": ", item)

Tulajdonságok:

Ingatlan Kötelező Description
source Igen Gyűjteményt visszaadó kifejezés
itemName Nem Az aktuális elem változóneve (alapértelmezett: item)
indexName Nem Az aktuális index változójának neve (alapértelmezett: index)
actions Igen Az egyes elemekhez végrehajtandó műveletek

BreakLoop

Azonnal kilép az aktuális ciklusból.

- kind: Foreach
  source: =Workflow.Inputs.items
  actions:
    - kind: If
      condition: =item = "stop"
      then:
        - kind: BreakLoop
    - kind: SendActivity
      activity:
        text: =item

ContinueLoop

Ugrás a hurok következő iterációjára.

- kind: Foreach
  source: =Workflow.Inputs.numbers
  actions:
    - kind: If
      condition: =item < 0
      then:
        - kind: ContinueLoop
    - kind: SendActivity
      activity:
        text: =Concat("Positive number: ", item)

GotoAction

Azonosító alapján ugrik egy adott műveletre.

- kind: SetVariable
  id: start_label
  variable: Local.attempts
  value: =Local.attempts + 1

- kind: SendActivity
  activity:
    text: =Concat("Attempt ", Local.attempts)

- kind: If
  condition: =And(Local.attempts < 3, Not(Local.success))
  then:
    - kind: GotoAction
      actionId: start_label

Tulajdonságok:

Ingatlan Kötelező Description
actionId Igen A művelet azonosítója, amelyre ugrani szeretne.

Kimeneti műveletek

SendActivity

Üzenetet küld a felhasználónak.

- kind: SendActivity
  id: send_welcome
  displayName: Send welcome message
  activity:
    text: "Welcome to our service!"

Kifejezéssel:

- kind: SendActivity
  activity:
    text: =Concat("Hello, ", Workflow.Inputs.name, "! How can I help you today?")

Tulajdonságok:

Ingatlan Kötelező Description
activity Igen A küldendő tevékenység
activity.text Igen Üzenet szövege (literál vagy kifejezés)

Ügynökhívási műveletek

InvokeAzureAgent

Meghív egy Azure AI-ügynököt.

Alapszintű meghívás:

- kind: InvokeAzureAgent
  id: call_assistant
  displayName: Call assistant agent
  agent:
    name: AssistantAgent
  conversationId: =System.ConversationId

Bemeneti és kimeneti konfigurációval:

- kind: InvokeAzureAgent
  id: call_analyst
  displayName: Call analyst agent
  agent:
    name: AnalystAgent
  conversationId: =System.ConversationId
  input:
    messages: =Local.userMessage
    arguments:
      topic: =Workflow.Inputs.topic
  output:
    responseObject: Local.AnalystResult
    messages: Local.AnalystMessages
    autoSend: true

Külső hurokkal (a feltétel teljesüléséig folytatódik):

- kind: InvokeAzureAgent
  id: support_agent
  agent:
    name: SupportAgent
  input:
    externalLoop:
      when: =Not(Local.IsResolved)
  output:
    responseObject: Local.SupportResult

Tulajdonságok:

Ingatlan Kötelező Description
agent.name Igen A regisztrált ügynök neve
conversationId Nem Beszélgetési környezet azonosítója
input.messages Nem Az ügynöknek küldendő üzenetek
input.arguments Nem Az ügynök további argumentumai
input.externalLoop.when Nem Az ügynökhurok folytatásának feltétele
output.responseObject Nem Az ügynök válaszának tárolási útvonala
output.messages Nem Beszélgetési üzenetek tárolásának elérési útja
output.autoSend Nem Válasz automatikus küldése a felhasználónak

Eszköz- és HTTP-műveletek

InvokeFunctionTool

Egy regisztrált Python-függvényt hív meg közvetlenül a munkafolyamatból, anélkül hogy egy AI-ügynökön keresztül menne.

- kind: InvokeFunctionTool
  id: invoke_weather
  displayName: Get weather data
  functionName: get_weather
  arguments:
    location: =Local.location
    unit: =Local.unit
  output:
    result: Local.weatherInfo
    messages: Local.weatherToolCallItems
    autoSend: true

Tulajdonságok:

Ingatlan Kötelező Description
functionName Igen A meghívandó regisztrált függvény neve
arguments Nem A függvénynek átadni kívánt argumentumok
output.result Nem A függvény eredményének tárolásának elérési útja
output.messages Nem A függvényüzenetek tárolásának elérési útja
output.autoSend Nem Eredmény automatikus küldése a felhasználónak

Python-beállítás az InvokeFunctionToolhoz:

A függvényeket a WorkflowFactory-vel a register_tool használatával kell regisztrálni.

from agent_framework.declarative import WorkflowFactory

# Define your functions
def get_weather(location: str, unit: str = "F") -> dict:
    """Get weather information for a location."""
    # Your implementation here
    return {"location": location, "temp": 72, "unit": unit}

def format_message(template: str, data: dict) -> str:
    """Format a message template with data."""
    return template.format(**data)

# Register functions with the factory
factory = (
    WorkflowFactory()
    .register_tool("get_weather", get_weather)
    .register_tool("format_message", format_message)
)

# Load and run the workflow
workflow = factory.create_workflow_from_yaml_path("workflow.yaml")
result = await workflow.run({"location": "Seattle", "unit": "F"})

InvokeMcpTool

Egy MCP-kiszolgálón lévő eszközt hív meg a konfigurált MCPToolHandler.

- kind: InvokeMcpTool
  id: search_docs
  serverUrl: https://learn.microsoft.com/api/mcp
  serverLabel: microsoft_docs
  toolName: microsoft_docs_search
  arguments:
    query: =Local.searchQuery
  output:
    result: Local.searchResults
    messages: Local.toolMessage
    autoSend: true

Tulajdonságok:

Ingatlan Kötelező Description
serverUrl Igen MCP-kiszolgáló URL-címe
toolName Igen Eszköznév az MCP-kiszolgálón
serverLabel Nem Emberi olvasásra alkalmas kiszolgálócímke
arguments Nem Az eszköznek átadott argumentumok
headers Nem Kérelemfejlécek; üres értékek kihagyása
connection.name Nem Névvel ellátott kapcsolat egyéni kezelők számára
conversationId Nem Sikeres eszközkimenet hozzáadása a beszélgetéshez
requireApproval Nem Jóváhagyás kérése az eszköz meghívása előtt
output.result Nem Az elemzett eszköz kimenetének tárolási útvonala
output.messages Nem Az eszközüzenet tárolásának elérési útja
output.autoSend Nem Eszközkimenetet bocsát ki a munkafolyamat eredményének; alapértelmezett érték: true

Python beállítása az InvokeMcpToolhoz:

Adjon át egy MCP-eszközkiszolgálót a WorkflowFactory. Használjon egyéni kezelőt, ha hitelesítésre, felügyelt kapcsolatokra vagy URL-engedélyezési listára van szüksége.

from agent_framework.declarative import DefaultMCPToolHandler, WorkflowFactory

factory = WorkflowFactory(mcp_tool_handler=DefaultMCPToolHandler())
workflow = factory.create_workflow_from_yaml_path("workflow.yaml")

HttpRequestAction

HTTP-kérést küld a konfigurált HttpRequestHandler. A sikeres JSON-válaszok elemzése a hozzárendelés előtt történik; a nem 2xx válaszok nem hajtják végre a műveletet.

- kind: HttpRequestAction
  id: fetch_repo_info
  method: GET
  url: =Concat("https://api.github.com/repos/", Local.repoName)
  headers:
    Accept: application/vnd.github+json
    User-Agent: agent-framework
  queryParameters:
    per_page: 10
  response: Local.repoInfo
  responseHeaders: Local.repoHeaders

Tulajdonságok:

Ingatlan Kötelező Description
url Igen Abszolút kérés URL-címe
method Nem HTTP-metódus; alapértelmezett érték: GET
headers Nem HTTP-kérés fejlécek
queryParameters Nem Az URL-címhez hozzáfűzött lekérdezési paraméterek
body Nem Kérelem törzse; használja kind: json, rawvagy none
requestTimeoutInMilliseconds Nem Kérelemenkénti időtúllépés
connection.name Nem Névvel ellátott kapcsolat egyéni kezelők számára
conversationId Nem Sikeres választörzs hozzáadása a beszélgetéshez
response Nem Az elemzési válasz törzsének tárolásának elérési útja
responseHeaders Nem A válaszfejlécek tárolásának elérési útja

Python HttpRequestAction beállítása:

Adjon át egy HTTP-kéréskezelőt a WorkflowFactory-nek. Ha hitelesítésre, újrapróbálkoztatásra vagy URL-engedélyezésre van szüksége, használjon egyéni kezelőt.

from agent_framework.declarative import DefaultHttpRequestHandler, WorkflowFactory

factory = WorkflowFactory(http_request_handler=DefaultHttpRequestHandler())
workflow = factory.create_workflow_from_yaml_path("workflow.yaml")

Ember a hurokban műveletek

Question

Kérdést tesz fel a felhasználónak, és tárolja a választ.

- kind: Question
  id: ask_name
  displayName: Ask for user name
  question:
    text: "What is your name?"
  variable: Local.userName
  default: "Guest"

Tulajdonságok:

Ingatlan Kötelező Description
question.text Igen A feltenni kívánt kérdés
variable Igen A válasz tárolásának elérési útja
default Nem Alapértelmezett érték, ha nincs válasz

KülsőInputKérése

Külső rendszertől vagy folyamattól kér bemenetet.

- kind: RequestExternalInput
  id: request_approval
  displayName: Request manager approval
  prompt:
    text: "Please provide approval for this request."
  variable: Local.approvalResult
  default: "pending"

Tulajdonságok:

Ingatlan Kötelező Description
prompt.text Igen A szükséges bemenet leírása
variable Igen A bemenet tárolásának elérési útja
default Nem Alapértelmezett érték

Munkafolyamat-vezérlési műveletek

EndWorkflow

Leállítja a munkafolyamat végrehajtását.

- kind: EndWorkflow
  id: finish
  displayName: End workflow

Beszélgetés vége

Véget vet az aktuális beszélgetésnek.

- kind: EndConversation
  id: end_chat
  displayName: End conversation

CreateConversation

Új beszélgetési környezetet hoz létre.

- kind: CreateConversation
  id: create_new_conv
  displayName: Create new conversation
  conversationId: Local.NewConversationId

Tulajdonságok:

Ingatlan Kötelező Description
conversationId Igen Az új beszélgetésazonosító tárolásának elérési útja

Műveletek – rövid útmutató

Tevékenység Kategória Description
SetVariable Variable Egyetlen változó beállítása
SetMultipleVariables Variable Több változó beállítása
ResetVariable Variable Változó törlése
If Folyamat vezérlése Feltételes elágaztatás
ConditionGroup Folyamat vezérlése Többágú kapcsoló
Foreach Folyamat vezérlése Végigiterálni a gyűjteményen
BreakLoop Folyamat vezérlése Kilépés az aktuális ciklusból
ContinueLoop Folyamat vezérlése Ugrás a következő iterációra
GotoAction Folyamat vezérlése Ugrás műveletre azonosító szerint
SendActivity Kimenet Üzenet küldése a felhasználónak
InvokeAzureAgent Ügynök Az Azure AI-ügynök meghívása
InvokeFunctionTool Eszköz Regisztrált függvény meghívása
InvokeMcpTool Eszköz MCP-kiszolgáló eszköz meghívása
HttpRequestAction HTTP HTTP-végpont meghívása
Question Ember a folyamatban Tegyen fel egy kérdést a felhasználónak
RequestExternalInput Ember a folyamatban Külső bemenet kérése
EndWorkflow Munkafolyamat-vezérlés Munkafolyamat leállálása
EndConversation Munkafolyamat-vezérlés Beszélgetés befejezése
CreateConversation Munkafolyamat-vezérlés Új beszélgetés létrehozása

Kifejezésszintaxis

A deklaratív munkafolyamatok PowerFx-szerű kifejezési nyelvet használnak az állapotok kezeléséhez és a dinamikus értékek kiszámításához. Az előtagú = értékek futásidőben kifejezésként lesznek kiértékelve.

Változó névtér részletei

Namespace Description Access
Local.* Munkafolyamat-helyi változók Olvasás/írás
Workflow.Inputs.* A munkafolyamatnak átadott bemeneti paraméterek Read-only
Workflow.Outputs.* A munkafolyamatból visszaadott értékek Olvasás/írás
System.* Rendszer által biztosított értékek Read-only
Agent.* Ügynökhívások eredményei Read-only

Rendszerváltozók

Variable Description
System.ConversationId Aktuális beszélgetésazonosító
System.LastMessage A legutóbbi üzenet
System.Timestamp Aktuális időbélyeg

Ügynökváltozók

Az ügynök meghívása után a kimeneti változón keresztül érheti el a válaszadatokat:

actions:
  - kind: InvokeAzureAgent
    id: call_assistant
    agent:
      name: MyAgent
    output:
      responseObject: Local.AgentResult

  # Access agent response
  - kind: SendActivity
    activity:
      text: =Local.AgentResult.text

Literál és kifejezésértékek

# Literal string (stored as-is)
value: Hello World

# Expression (evaluated at runtime)
value: =Concat("Hello ", Workflow.Inputs.name)

# Literal number
value: 42

# Expression returning a number
value: =Workflow.Inputs.quantity * 2

Sztringműveletek

Összefűzés

Több karakterlánc összefűzése

value: =Concat("Hello, ", Workflow.Inputs.name, "!")
# Result: "Hello, Alice!" (if Workflow.Inputs.name is "Alice")

value: =Concat(Local.firstName, " ", Local.lastName)
# Result: "John Doe" (if firstName is "John" and lastName is "Doe")

IsBlank

Ellenőrizze, hogy egy érték üres vagy nem definiált-e:

condition: =IsBlank(Workflow.Inputs.optionalParam)
# Returns true if the parameter is not provided

value: =If(IsBlank(Workflow.Inputs.name), "Guest", Workflow.Inputs.name)
# Returns "Guest" if name is blank, otherwise returns the name

Feltételes kifejezések

Ha függvény

Különböző értékeket ad vissza egy feltétel alapján:

value: =If(Workflow.Inputs.age < 18, "minor", "adult")

value: =If(Local.count > 0, "Items found", "No items")

# Nested conditions
value: =If(Workflow.Inputs.role = "admin", "Full access", If(Workflow.Inputs.role = "user", "Limited access", "No access"))

Összehasonlító operátorok

Operátor Description Example
= Egyenlő =Workflow.Inputs.status = "active"
<> Nem egyenlő =Workflow.Inputs.status <> "deleted"
< Kevesebb, mint =Workflow.Inputs.age < 18
> Nagyobb, mint =Workflow.Inputs.count > 0
<= Kisebb vagy egyenlő =Workflow.Inputs.score <= 100
>= Nagyobb vagy egyenlő =Workflow.Inputs.quantity >= 1

Logikai függvények

# Or - returns true if any condition is true
condition: =Or(Workflow.Inputs.role = "admin", Workflow.Inputs.role = "moderator")

# And - returns true if all conditions are true
condition: =And(Workflow.Inputs.age >= 18, Workflow.Inputs.hasConsent)

# Not - negates a condition
condition: =Not(IsBlank(Workflow.Inputs.email))

Matematikai műveletek

# Addition
value: =Workflow.Inputs.price + Workflow.Inputs.tax

# Subtraction
value: =Workflow.Inputs.total - Workflow.Inputs.discount

# Multiplication
value: =Workflow.Inputs.quantity * Workflow.Inputs.unitPrice

# Division
value: =Workflow.Inputs.total / Workflow.Inputs.count

Gyakorlati kifejezési példák

Felhasználó kategorizálása

name: categorize-user
inputs:
  age:
    type: integer
    description: User's age

actions:
  - kind: SetVariable
    variable: Local.age
    value: =Workflow.Inputs.age

  - kind: SetVariable
    variable: Local.category
    value: =If(Local.age < 13, "child", If(Local.age < 20, "teenager", If(Local.age < 65, "adult", "senior")))

  - kind: SendActivity
    activity:
      text: =Concat("You are categorized as: ", Local.category)

  - kind: SetVariable
    variable: Workflow.Outputs.category
    value: =Local.category

Feltételes üdvözlés

name: smart-greeting
inputs:
  name:
    type: string
    description: User's name (optional)
  timeOfDay:
    type: string
    description: morning, afternoon, or evening

actions:
  # Set the greeting based on time of day
  - kind: SetVariable
    variable: Local.timeGreeting
    value: =If(Workflow.Inputs.timeOfDay = "morning", "Good morning", If(Workflow.Inputs.timeOfDay = "afternoon", "Good afternoon", "Good evening"))

  # Handle optional name
  - kind: SetVariable
    variable: Local.userName
    value: =If(IsBlank(Workflow.Inputs.name), "friend", Workflow.Inputs.name)

  # Build the full greeting
  - kind: SetVariable
    variable: Local.fullGreeting
    value: =Concat(Local.timeGreeting, ", ", Local.userName, "!")

  - kind: SendActivity
    activity:
      text: =Local.fullGreeting

Bemeneti ellenőrzés

name: validate-order
inputs:
  quantity:
    type: integer
    description: Number of items to order
  email:
    type: string
    description: Customer email

actions:
  # Check if inputs are valid
  - kind: SetVariable
    variable: Local.isValidQuantity
    value: =And(Workflow.Inputs.quantity > 0, Workflow.Inputs.quantity <= 100)

  - kind: SetVariable
    variable: Local.hasEmail
    value: =Not(IsBlank(Workflow.Inputs.email))

  - kind: SetVariable
    variable: Local.isValid
    value: =And(Local.isValidQuantity, Local.hasEmail)

  - kind: If
    condition: =Local.isValid
    then:
      - kind: SendActivity
        activity:
          text: "Order validated successfully!"
    else:
      - kind: SendActivity
        activity:
          text: =If(Not(Local.isValidQuantity), "Invalid quantity (must be 1-100)", "Email is required")

Haladó minták

A munkafolyamatok összetettségének növekedéséhez olyan mintákra lesz szüksége, amelyek többlépéses folyamatokat, ügynökkoordinációt és interaktív forgatókönyveket kezelnek.

Többügynökalapú orkesztráció

Szekvenciális ágens folyamat

Munkát adjon át több ügynökön keresztül egymás után, ahol minden ügynök az előző ügynök kimenetére épít.

Használati eset: Tartalomlétrehozás folyamatai, ahol különböző szakemberek kezelik a kutatást, az írást és a szerkesztést.

name: content-pipeline
description: Sequential agent pipeline for content creation

kind: Workflow
trigger:
  kind: OnConversationStart
  id: content_workflow
  actions:
    # First agent: Research and analyze
    - kind: InvokeAzureAgent
      id: invoke_researcher
      displayName: Research phase
      conversationId: =System.ConversationId
      agent:
        name: ResearcherAgent

    # Second agent: Write draft based on research
    - kind: InvokeAzureAgent
      id: invoke_writer
      displayName: Writing phase
      conversationId: =System.ConversationId
      agent:
        name: WriterAgent

    # Third agent: Edit and polish
    - kind: InvokeAzureAgent
      id: invoke_editor
      displayName: Editing phase
      conversationId: =System.ConversationId
      agent:
        name: EditorAgent

Python-beállítás:

from agent_framework.declarative import WorkflowFactory

# Create factory and register agents
factory = WorkflowFactory()
factory.register_agent("ResearcherAgent", researcher_agent)
factory.register_agent("WriterAgent", writer_agent)
factory.register_agent("EditorAgent", editor_agent)

# Load and run
workflow = factory.create_workflow_from_yaml_path("content-pipeline.yaml")
result = await workflow.run({"topic": "AI in healthcare"})

Feltételes ügynök útválasztása

A kérések átirányítása különböző ügynököknek a bemeneti vagy köztes eredmények alapján.

Használati eset: A speciális ügynökökhöz a probléma típusa alapján átirányító támogatási rendszerek.

name: support-router
description: Route to specialized support agents

inputs:
  category:
    type: string
    description: Support category (billing, technical, general)

actions:
  - kind: ConditionGroup
    id: route_request
    displayName: Route to appropriate agent
    conditions:
      - condition: =Workflow.Inputs.category = "billing"
        id: billing_route
        actions:
          - kind: InvokeAzureAgent
            id: billing_agent
            agent:
              name: BillingAgent
            conversationId: =System.ConversationId
      - condition: =Workflow.Inputs.category = "technical"
        id: technical_route
        actions:
          - kind: InvokeAzureAgent
            id: technical_agent
            agent:
              name: TechnicalAgent
            conversationId: =System.ConversationId
    elseActions:
      - kind: InvokeAzureAgent
        id: general_agent
        agent:
          name: GeneralAgent
        conversationId: =System.ConversationId

Ügynök külső hurokkal

Folytassa az ügynöki interakciót, amíg egy feltétel nem teljesül, például a probléma megoldása folyamatban van.

Használati eset: Olyan beszélgetések támogatása, amelyek addig folytatódnak, amíg a felhasználó problémája meg nem oldódott.

name: support-conversation
description: Continue support until resolved

actions:
  - kind: SetVariable
    variable: Local.IsResolved
    value: false

  - kind: InvokeAzureAgent
    id: support_agent
    displayName: Support agent with external loop
    agent:
      name: SupportAgent
    conversationId: =System.ConversationId
    input:
      externalLoop:
        when: =Not(Local.IsResolved)
    output:
      responseObject: Local.SupportResult

  - kind: SendActivity
    activity:
      text: "Thank you for contacting support. Your issue has been resolved."

Hurokvezérlési minták

Iteratív ügynök beszélgetése

Ügynökök közötti oda-vissza beszélgetések létrehozása irányított iterációval.

Használati eset: Diák-tanár forgatókönyvek, vitaszimulációk vagy iteratív finomítás.

name: student-teacher
description: Iterative learning conversation between student and teacher

kind: Workflow
trigger:
  kind: OnConversationStart
  id: learning_session
  actions:
    # Initialize turn counter
    - kind: SetVariable
      id: init_counter
      variable: Local.TurnCount
      value: 0

    - kind: SendActivity
      id: start_message
      activity:
        text: =Concat("Starting session for: ", Workflow.Inputs.problem)

    # Student attempts solution (loop entry point)
    - kind: SendActivity
      id: student_label
      activity:
        text: "\n[Student]:"

    - kind: InvokeAzureAgent
      id: student_attempt
      conversationId: =System.ConversationId
      agent:
        name: StudentAgent

    # Teacher reviews
    - kind: SendActivity
      id: teacher_label
      activity:
        text: "\n[Teacher]:"

    - kind: InvokeAzureAgent
      id: teacher_review
      conversationId: =System.ConversationId
      agent:
        name: TeacherAgent
      output:
        messages: Local.TeacherResponse

    # Increment counter
    - kind: SetVariable
      id: increment
      variable: Local.TurnCount
      value: =Local.TurnCount + 1

    # Check completion conditions
    - kind: ConditionGroup
      id: check_completion
      conditions:
        # Success: Teacher congratulated student
        - condition: =Not(IsBlank(Find("congratulations", Local.TeacherResponse)))
          id: success_check
          actions:
            - kind: SendActivity
              activity:
                text: "Session complete - student succeeded!"
            - kind: SetVariable
              variable: Workflow.Outputs.result
              value: success
        # Continue: Under turn limit
        - condition: =Local.TurnCount < 4
          id: continue_check
          actions:
            - kind: GotoAction
              actionId: student_label
      elseActions:
        # Timeout: Reached turn limit
        - kind: SendActivity
          activity:
            text: "Session ended - turn limit reached."
        - kind: SetVariable
          variable: Workflow.Outputs.result
          value: timeout

Számláló-alapú hurkok

Hagyományos számolási ciklusok implementálása változók és GotoAction használatával.

name: counter-loop
description: Process items with a counter

actions:
  - kind: SetVariable
    variable: Local.counter
    value: 0

  - kind: SetVariable
    variable: Local.maxIterations
    value: 5

  # Loop start
  - kind: SetVariable
    id: loop_start
    variable: Local.counter
    value: =Local.counter + 1

  - kind: SendActivity
    activity:
      text: =Concat("Processing iteration ", Local.counter)

  # Your processing logic here
  - kind: SetVariable
    variable: Local.result
    value: =Concat("Result from iteration ", Local.counter)

  # Check if should continue
  - kind: If
    condition: =Local.counter < Local.maxIterations
    then:
      - kind: GotoAction
        actionId: loop_start
    else:
      - kind: SendActivity
        activity:
          text: "Loop complete!"

Korai kilépés a BreakLoop használatával

A BreakLoop használatával korán kiléphet az iterációkból, amikor egy feltétel teljesül.

name: search-workflow
description: Search through items and stop when found

actions:
  - kind: SetVariable
    variable: Local.found
    value: false

  - kind: Foreach
    source: =Workflow.Inputs.items
    itemName: currentItem
    actions:
      # Check if this is the item we're looking for
      - kind: If
        condition: =currentItem.id = Workflow.Inputs.targetId
        then:
          - kind: SetVariable
            variable: Local.found
            value: true
          - kind: SetVariable
            variable: Local.result
            value: =currentItem
          - kind: BreakLoop

      - kind: SendActivity
        activity:
          text: =Concat("Checked item: ", currentItem.name)

  - kind: If
    condition: =Local.found
    then:
      - kind: SendActivity
        activity:
          text: =Concat("Found: ", Local.result.name)
    else:
      - kind: SendActivity
        activity:
          text: "Item not found"

Ember által irányított minták

Interaktív felmérés

Gyűjtsön több információt a felhasználótól.

name: customer-survey
description: Interactive customer feedback survey

actions:
  - kind: SendActivity
    activity:
      text: "Welcome to our customer feedback survey!"

  # Collect name
  - kind: Question
    id: ask_name
    question:
      text: "What is your name?"
    variable: Local.userName
    default: "Anonymous"

  - kind: SendActivity
    activity:
      text: =Concat("Nice to meet you, ", Local.userName, "!")

  # Collect rating
  - kind: Question
    id: ask_rating
    question:
      text: "How would you rate our service? (1-5)"
    variable: Local.rating
    default: "3"

  # Respond based on rating
  - kind: If
    condition: =Local.rating >= 4
    then:
      - kind: SendActivity
        activity:
          text: "Thank you for the positive feedback!"
    else:
      - kind: Question
        id: ask_improvement
        question:
          text: "What could we improve?"
        variable: Local.feedback

  # Collect additional feedback
  - kind: RequestExternalInput
    id: additional_comments
    prompt:
      text: "Any additional comments? (optional)"
    variable: Local.comments
    default: ""

  # Summary
  - kind: SendActivity
    activity:
      text: =Concat("Thank you, ", Local.userName, "! Your feedback has been recorded.")

  - kind: SetVariable
    variable: Workflow.Outputs.survey
    value:
      name: =Local.userName
      rating: =Local.rating
      feedback: =Local.feedback
      comments: =Local.comments

Jóváhagyási munkafolyamat

Jóváhagyás kérése a művelet végrehajtása előtt.

name: approval-workflow
description: Request approval before processing

inputs:
  requestType:
    type: string
    description: Type of request
  amount:
    type: number
    description: Request amount

actions:
  - kind: SendActivity
    activity:
      text: =Concat("Processing ", Workflow.Inputs.requestType, " request for $", Workflow.Inputs.amount)

  # Check if approval is needed
  - kind: If
    condition: =Workflow.Inputs.amount > 1000
    then:
      - kind: SendActivity
        activity:
          text: "This request requires manager approval."

      - kind: Question
        id: get_approval
        question:
          text: =Concat("Do you approve this ", Workflow.Inputs.requestType, " request for $", Workflow.Inputs.amount, "? (yes/no)")
        variable: Local.approved

      - kind: If
        condition: =Local.approved = "yes"
        then:
          - kind: SendActivity
            activity:
              text: "Request approved. Processing..."
          - kind: SetVariable
            variable: Workflow.Outputs.status
            value: approved
        else:
          - kind: SendActivity
            activity:
              text: "Request denied."
          - kind: SetVariable
            variable: Workflow.Outputs.status
            value: denied
    else:
      - kind: SendActivity
        activity:
          text: "Request auto-approved (under threshold)."
      - kind: SetVariable
        variable: Workflow.Outputs.status
        value: auto_approved

Összetett orchesztráció

Támogatási jegy munkafolyamata

Átfogó példa több mintára: ügynök-útválasztás, feltételes logika és beszélgetéskezelés.

name: support-ticket-workflow
description: Complete support ticket handling with escalation

kind: Workflow
trigger:
  kind: OnConversationStart
  id: support_workflow
  actions:
    # Initial self-service agent
    - kind: InvokeAzureAgent
      id: self_service
      displayName: Self-service agent
      agent:
        name: SelfServiceAgent
      conversationId: =System.ConversationId
      input:
        externalLoop:
          when: =Not(Local.ServiceResult.IsResolved)
      output:
        responseObject: Local.ServiceResult

    # Check if resolved by self-service
    - kind: If
      condition: =Local.ServiceResult.IsResolved
      then:
        - kind: SendActivity
          activity:
            text: "Issue resolved through self-service."
        - kind: SetVariable
          variable: Workflow.Outputs.resolution
          value: self_service
        - kind: EndWorkflow
          id: end_resolved

    # Create support ticket
    - kind: SendActivity
      activity:
        text: "Creating support ticket..."

    - kind: SetVariable
      variable: Local.TicketId
      value: =Concat("TKT-", System.ConversationId)

    # Route to appropriate team
    - kind: ConditionGroup
      id: route_ticket
      conditions:
        - condition: =Local.ServiceResult.Category = "technical"
          id: technical_route
          actions:
            - kind: InvokeAzureAgent
              id: technical_support
              agent:
                name: TechnicalSupportAgent
              conversationId: =System.ConversationId
              output:
                responseObject: Local.TechResult
        - condition: =Local.ServiceResult.Category = "billing"
          id: billing_route
          actions:
            - kind: InvokeAzureAgent
              id: billing_support
              agent:
                name: BillingSupportAgent
              conversationId: =System.ConversationId
              output:
                responseObject: Local.BillingResult
      elseActions:
        # Escalate to human
        - kind: SendActivity
          activity:
            text: "Escalating to human support..."
        - kind: SetVariable
          variable: Workflow.Outputs.resolution
          value: escalated

    - kind: SendActivity
      activity:
        text: =Concat("Ticket ", Local.TicketId, " has been processed.")

Ajánlott eljárások

Elnevezési egyezmények

A műveletekhez és változókhoz használjon egyértelmű, leíró neveket:

# Good
- kind: SetVariable
  id: calculate_total_price
  variable: Local.orderTotal

# Avoid
- kind: SetVariable
  id: sv1
  variable: Local.x

Nagyméretű munkafolyamatok rendszerezése

Összetett munkafolyamatok logikai szakaszokra bontása megjegyzésekkel:

actions:
  # === INITIALIZATION ===
  - kind: SetVariable
    id: init_status
    variable: Local.status
    value: started

  # === DATA COLLECTION ===
  - kind: Question
    id: collect_name
    # ...

  # === PROCESSING ===
  - kind: InvokeAzureAgent
    id: process_request
    # ...

  # === OUTPUT ===
  - kind: SendActivity
    id: send_result
    # ...

Hibakezelés

A lehetséges problémák megoldásához használjon feltételes ellenőrzéseket:

actions:
  - kind: SetVariable
    variable: Local.hasError
    value: false

  - kind: InvokeAzureAgent
    id: call_agent
    agent:
      name: ProcessingAgent
    output:
      responseObject: Local.AgentResult

  - kind: If
    condition: =IsBlank(Local.AgentResult)
    then:
      - kind: SetVariable
        variable: Local.hasError
        value: true
      - kind: SendActivity
        activity:
          text: "An error occurred during processing."
    else:
      - kind: SendActivity
        activity:
          text: =Local.AgentResult.message

Tesztelési stratégiák

  1. Egyszerű kezdés: Alapszintű folyamatok tesztelése összetettség hozzáadása előtt
  2. Alapértelmezett értékek használata: A bemenetek ésszerű alapértelmezett értékeinek megadása
  3. Naplózás hozzáadása: A SendActivity használata hibakereséshez a fejlesztés során
  4. Peremhálózati esetek tesztelése: Hiányzó vagy érvénytelen bemenetek viselkedésének ellenőrzése
# Debug logging example
- kind: SendActivity
  id: debug_log
  activity:
    text: =Concat("[DEBUG] Current state: counter=", Local.counter, ", status=", Local.status)

Következő lépések

  • C# deklaratív munkafolyamat-minták – Ismerje meg a teljes munka példákat, például:
    • StudentTeacher – Többügynök beszélgetés iteratív tanulással
    • InvokeMcpTool – MCP-kiszolgálói eszközintegráció
    • InvokeFunctionTool – Közvetlen függvényhívás munkafolyamatokból
    • FunctionTools – Ügynök függvényeszközökkel
    • ToolApproval – Emberi jóváhagyás eszközvégrehajtáshoz
    • CustomerSupport – Összetett támogatási jegy munkafolyamata
    • DeepResearch – Több ügynökkel végzett kutatási munkafolyamat

Megjegyzés:

A funkció Go-támogatása hamarosan érkezik. A legújabb állapotot az Agent Framework Go-adattárában tekinthet meg.