Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Deklarativní pracovní postupy umožňují definovat logiku pracovního postupu pomocí konfiguračních souborů YAML místo psaní programového kódu. Tento přístup usnadňuje čtení, úpravy a sdílení pracovních postupů napříč týmy.
Overview
Díky deklarativním pracovním postupům popíšete, co má pracovní postup dělat, a ne jak ho implementovat. Architektura zpracovává základní provádění a převádí definice YAML na spustitelné grafy pracovních postupů.
Klíčové výhody:
- Čitelný formát: Syntaxe YAML je snadno pochopitelná, a to i pro vývojáře, kteří nejsou vývojáři
- Přenosná: Definice pracovního postupu je možné sdílet, upravovat a upravovat bez změn kódu.
- Rychlá iterace: Úprava chování pracovního postupu úpravou konfiguračních souborů
- Konzistentní struktura: Předdefinované typy akcí zajišťují, aby pracovní postupy dodržovaly osvědčené postupy.
Kdy použít deklarativní a programové pracovní postupy
| Scenario | Doporučený přístup |
|---|---|
| Standardní vzory orchestrace | Deklarativní |
| Pracovní postupy, které se často mění | Deklarativní |
| Vývojáři, kteří nejsou vývojáři, potřebují upravovat pracovní postupy | Deklarativní |
| Složitá vlastní logika | Programmatic |
| Maximální flexibilita a řízení | Programmatic |
| Integrace s existujícím kódem Pythonu | Programmatic |
Základní struktura YAML
Struktura YAML se mírně liší mezi implementacemi jazyka C# a Python. Podrobnosti najdete v následujících částech pro konkrétní jazyk.
Typy akcí
Deklarativní pracovní postupy podporují širokou škálu druhů akcí, které pokrývají správu proměnných, tok řízení, vyvolání agentů a nástrojů, integraci HTTP a MCP, human-in-the-loop a řízení konverzací. Kompletní referenční informace specifické pro jazyk se zobrazí v každé níže uvedené zóně; Přehledné matice dostupnosti v obou jazycích najdete v části Rychlé referenční informace k akcím v dolní části tohoto článku.
C# YAML – struktura
Deklarativní pracovní postupy jazyka C# používají strukturu založenou na triggerech:
#
# 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
Prvky struktury
| prvek | Povinné | Description |
|---|---|---|
kind |
Ano | Musí být Workflow |
trigger.kind |
Ano | Typ triggeru OnConversationStart(obvykle) |
trigger.id |
Ano | Jedinečný identifikátor pracovního postupu |
trigger.actions |
Ano | Seznam akcí, které se mají provést |
Python YAML – struktura
Deklarativní pracovní postupy Pythonu používají strukturu založenou na názvu s volitelnými vstupy:
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
Prvky struktury
| prvek | Povinné | Description |
|---|---|---|
name |
Ano | Jedinečný identifikátor pracovního postupu |
description |
No | Popis čitelný pro člověka |
inputs |
No | Vstupní parametry, které pracovní postup přijímá |
actions |
Ano | Seznam akcí, které se mají provést |
Prerequisites
Než začnete, ujistěte se, že máte:
- .NET 8.0 nebo novější
- Projekt Microsoft Foundry s alespoň jedním nasazeným agentem
- Nainstalovali jsme následující balíčky NuGet:
dotnet add package Microsoft.Agents.AI.Workflows.Declarative --prerelease
dotnet add package Microsoft.Agents.AI.Workflows.Declarative.AzureAI --prerelease
- Pokud chcete do pracovního postupu přidat akci vyvolání nástroje MCP, nainstalujte také následující balíček NuGet:
dotnet add package Microsoft.Agents.AI.Workflows.Declarative.Mcp --prerelease
- Základní znalost syntaxe YAML
- Porozumění konceptům pracovních postupů
První deklarativní pracovní postup
Pojďme vytvořit jednoduchý pracovní postup, který uživatele pozdraví na základě jejich vstupu.
Krok 1: Vytvoření souboru YAML
Vytvořte soubor s názvem 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
Krok 2: Konfigurace zprostředkovatele agenta
Vytvořte konzolovou aplikaci jazyka C#, která spustí pracovní postup. Nejprve nakonfigurujte zprostředkovatele agenta, který se připojuje k Foundry:
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());
Krok 3: Sestavení a spuštění pracovního postupu
// 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 AgentResponseEvent responseEvent:
Console.WriteLine($"Response: {responseEvent.Response.Text}");
break;
case WorkflowErrorEvent errorEvent:
Console.WriteLine($"Error: {errorEvent.Data}");
break;
}
}
Console.WriteLine("Workflow completed!");
Očekávaný výstup
Loaded workflow from: C:\path\to\greeting-workflow.yaml
----------------------------------------
Response: Hello, Alice!
Workflow completed!
Základní koncepty
Namespace proměnných
Deklarativní pracovní postupy v jazyce C# používají k uspořádání stavu proměnné s oborem názvů:
| Namespace | Description | Příklad |
|---|---|---|
Local.* |
Místní proměnné pro pracovní tok | Local.message |
System.* |
Systémové hodnoty |
System.ConversationId, System.LastMessage |
Poznámka:
Deklarativní pracovní postupy jazyka C# nepoužívají Workflow.Inputs ani Workflow.Outputs obory názvů. Vstup se přijímá prostřednictvím System.LastMessage a výstup se odesílá prostřednictvím SendActivity akcí.
Systémové proměnné
| Proměnné | Description |
|---|---|
System.ConversationId |
Identifikátor aktuální konverzace |
System.LastMessage |
Nejnovější zpráva uživatele |
System.LastMessage.Text |
Textový obsah poslední zprávy |
Jazyk výrazů
Hodnoty s předponou jsou vyhodnoceny = jako výrazy pomocí jazyka výrazů PowerFx:
# Literal value (no evaluation)
value: Hello
# Expression (evaluated at runtime)
value: =Concat("Hello, ", Local.userName)
# Access last message text
value: =System.LastMessage.Text
Mezi běžné funkce patří:
-
Concat(str1, str2, ...): Zřetězení řetězců -
If(condition, trueValue, falseValue)– Podmíněný výraz -
IsBlank(value)– Zkontrolujte, jestli je hodnota prázdná. -
Upper(text)/Lower(text)- Převod případu -
Find(searchText, withinText)– Vyhledání textu v řetězci -
MessageText(message)– Extrahování textu z objektu zprávy -
UserMessage(text)- Vytvoření zprávy uživatele z textu -
AgentMessage(text)– Vytvoření zprávy agenta z textu
Možnosti konfigurace
Třída DeclarativeWorkflowOptions poskytuje konfiguraci pro provádění pracovního postupu:
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,
};
Nastavení poskytovatele agenta
Pracovní AzureAgentProvider postup se připojí k agentům Foundry:
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,
};
Provádění pracovního postupu
Slouží InProcessExecution ke spouštění pracovních postupů a zpracování událostí. Tento příklad zobrazuje dokončené odpovědi a zpracovává vstupní požadavky samostatně. Nezobrazuje ani průběžné aktualizace, ani oznámení o aktivitě pro stejnou odpověď:
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 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;
}
}
Výběr událostí odpovědi, které se mají zobrazit
Stream událostí pracovního postupu obsahuje několik zobrazení stejné akce. Například textová SendActivity akce vytvoří:
| Event | Purpose |
|---|---|
MessageActivityEvent |
Oznámení o aktivitě obsahující text zprávy. |
AgentResponseUpdateEvent |
AgentResponseUpdate obsahující text pro příjemce streamu |
AgentResponseEvent |
Dokončené AgentResponse, dostupné jako výstup pracovního postupu. |
Tyto události nepředstavují tři samostatné zprávy ani tři spuštění akce. Při tisku textu z každé události se opakovaně zobrazí stejná zpráva.
Neexistuje nastavení YAML SendActivity nebo Question, které vybírá AgentResponseEvent místo AgentResponseUpdateEvent. Zvolte, co zobrazuje obslužná rutina události jazyka C#:
- U dokončených odpovědí zacházejte s
AgentResponseEventstejně jako v příkladu výše. Stále můžete použítRunStreamingAsynck rychlému příjmu dalších událostí pracovního postupu. - U streamovaného textu zpracujte
AgentResponseUpdateEvent. Nepřidávejte znovu text dokončené odpovědi, pokud už byly jeho zprávy streamovány. ProSendActivitymají aktualizace i dokončená odpověď stejné ID odpovědi a ID zprávy. Při korelaci streamovaných a dokončených zpráv sledujte ID exekutoru a ID zprávy. - Zpracovávejte
RequestInfoEventsamostatně, aby pracovní postup mohl přijímat externí vstup. Filtrování textu odpovědi neodebere potřebu odpovídat na požadavky.
Při použití workflow.AsAIAgent() argument includeWorkflowOutputsInResponse určuje, jak jsou výstupy pracovního postupu zahrnuty do odpovědí agenta. Nemění události, které akce YAML vysílá, a nejedná se o přepínač pro zakázání aktualizací streamování.
Obnovení z kontrolních bodů
Pracovní postupy je možné obnovit z kontrolních bodů kvůli odolnosti proti chybám:
// 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 a agresivní vytváření kontrolních bodů při ořezávání
Když publikujete pomocí Native AOT (dotnet publish -p:PublishAot=true) nebo jinak zakážete záložní mechanismus reflexe v System.Text.Json (<JsonSerializerIsReflectionEnabledByDefault>false</JsonSerializerIsReflectionEnabledByDefault>), výchozí volání CheckpointManager.CreateJson(store) selže při uložení kontrolního bodu nebo obnovení stavu.
Balíček declarative-workflow obsahuje instanci JsonSerializerOptions vygenerovanou ze zdrojového kódu, DeclarativeWorkflowJsonOptions.Default která pokrývá všechny typy balíčku declarative-package, které procházejí kanálem checkpoint. Předejte jej jako druhý argument do 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);
Poznámka:
Předávání DeclarativeWorkflowJsonOptions.Default je bezpečné pro použití i v prostředích bez AOT. Jde o přímou aktualizaci za CheckpointManager.CreateJson(store) — aplikace využívající reflexi nezaznamenají žádnou změnu v chování. Používejte jej bez výhrad, aby stejný kód fungoval i v případě, že aplikaci později publikujete s AOT nebo trimováním.
DeclarativeWorkflowJsonOptions je označen [Experimental("MAAI001")]. Potlačte diagnostiku v místě volání nebo v souboru vašeho projektu:
<PropertyGroup>
<NoWarn>$(NoWarn);MAAI001</NoWarn>
</PropertyGroup>
Registrace uživatelem definovaných typů
Pokud jsou vstup pracovního postupu, vlastní datové zátěže ActionExecutorResult.Result nebo neprimitivní argumenty žádosti o schválení typy definovanými uživatelem, naklonujte Default a připojte vlastní resolver generovaný ze zdrojového kódu:
// 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);
Kde MyAppJsonContext je JsonSerializerContext, který definujete pro typy ve vaší aplikaci:
[JsonSourceGenerationOptions(JsonSerializerDefaults.Web)]
[JsonSerializable(typeof(MyWorkflowInput))]
[JsonSerializable(typeof(MyCustomResult))]
internal sealed partial class MyAppJsonContext : JsonSerializerContext;
Tip
Kompletní spustitelný příklad — včetně workflow v YAML, agenta využívajícího AzureCliCredential, a pozorovatelného režimu „po odebrání voleb uvidíte selhání“ — viz ukázku AotCheckpointing v dotnet/samples/03-workflows/Declarative/AotCheckpointing.
.csproj Ukázka nastavíJsonSerializerIsReflectionEnabledByDefault=false, aby reprodukovala režim selhání AOT, aniž by vyžadovala úplné publikování AOT.
Referenční dokumentace k akcím
Akce jsou stavební bloky deklarativních pracovních postupů. Každá akce provede konkrétní operaci a akce se sekvenčně spustí v pořadí, v jakém se zobrazí v souboru YAML.
Struktura akcí
Všechny akce sdílejí společné vlastnosti:
- 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...
Správa akcí proměnných
SetVariable
Nastaví proměnnou na zadanou hodnotu.
- kind: SetVariable
id: set_greeting
displayName: Set greeting message
variable: Local.greeting
value: Hello World
S výrazem:
- kind: SetVariable
variable: Local.fullName
value: =Concat(Local.firstName, " ", Local.lastName)
Vlastnosti:
| Vlastnictví | Povinné | Description |
|---|---|---|
variable |
Ano | Proměnná cesta (např. Local.name, Workflow.Outputs.result) |
value |
Ano | Hodnota, která se má nastavit (literál nebo výraz) |
NastavitVíceProměnných
Nastaví více proměnných v jedné akci.
- kind: SetMultipleVariables
id: initialize_vars
displayName: Initialize variables
variables:
Local.counter: 0
Local.status: pending
Local.message: =Concat("Processing order ", Local.orderId)
Vlastnosti:
| Vlastnictví | Povinné | Description |
|---|---|---|
variables |
Ano | Mapování proměnných cest k hodnotám |
SetTextVariable
Nastaví textovou proměnnou na zadanou řetězcovou hodnotu.
- kind: SetTextVariable
id: set_text
displayName: Set text content
variable: Local.description
value: This is a text description
Vlastnosti:
| Vlastnictví | Povinné | Description |
|---|---|---|
variable |
Ano | Proměnná cesta pro textová hodnota |
value |
Ano | Textová hodnota, která se má nastavit |
ResetVariable
Vymaže hodnotu proměnné.
- kind: ResetVariable
id: clear_counter
variable: Local.counter
Vlastnosti:
| Vlastnictví | Povinné | Description |
|---|---|---|
variable |
Ano | Proměnná cesta k resetování |
Vymazat všechny proměnné
Obnoví všechny proměnné v aktuálním kontextu.
- kind: ClearAllVariables
id: clear_all
displayName: Clear all workflow variables
ParseValue
Extrahuje nebo převádí data do použitelného formátu.
- kind: ParseValue
id: parse_json
displayName: Parse JSON response
source: =Local.rawResponse
variable: Local.parsedData
Vlastnosti:
| Vlastnictví | Povinné | Description |
|---|---|---|
source |
Ano | Výraz vracející hodnotu k analýze |
variable |
Ano | Proměnná cesta k uložení analyzovaného výsledku |
EditTableV2
Upraví data ve strukturovaném formátu tabulky.
- kind: EditTableV2
id: update_table
displayName: Update configuration table
table: Local.configTable
operation: update
row:
key: =Local.settingName
value: =Local.settingValue
Vlastnosti:
| Vlastnictví | Povinné | Description |
|---|---|---|
table |
Ano | Proměnná cesta k tabulce |
operation |
Ano | Typ operace (přidání, aktualizace, odstranění) |
row |
Ano | Řádková data pro operaci |
Řídící tokové akce
If
Provádí akce podmíněně na základě podmínky.
- 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!"
Vlastnosti:
| Vlastnictví | Povinné | Description |
|---|---|---|
condition |
Ano | Výraz, který se vyhodnotí jako true nebo false |
then |
Ano | Akce, které se mají provést, pokud je podmínka pravdivá |
else |
No | Akce, které se mají provést, pokud je podmínka nepravdivá |
SkupinaPodmínek
Vyhodnotí více podmínek, jako je příkaz switch/case.
- 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
Vlastnosti:
| Vlastnictví | Povinné | Description |
|---|---|---|
conditions |
Ano | Seznam párů podmínek a akcí (první nalezená shoda platí) |
elseActions |
No | Akce, pokud neodpovídá žádné podmínce |
Foreach
Iteruje přes kolekci.
- 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)'
Vlastnosti:
| Vlastnictví | Povinné | Description |
|---|---|---|
source |
Ano | Výraz vracející kolekci |
itemName |
No | Název proměnné pro aktuální položku (výchozí: item) |
indexName |
No | Název proměnné pro aktuální index (výchozí: index) |
actions |
Ano | Akce, které se mají provést pro každou položku |
BreakLoop
Okamžitě ukončí aktuální smyčku.
- kind: Foreach
source: =Local.items
actions:
- kind: If
condition: =item = "stop"
then:
- kind: BreakLoop
- kind: SendActivity
activity:
text: =item
ContinueLoop
Přeskočí na další iteraci smyčky.
- kind: Foreach
source: =Local.numbers
actions:
- kind: If
condition: =item < 0
then:
- kind: ContinueLoop
- kind: SendActivity
activity:
text: '=Concat("Positive number: ", item)'
GotoAction
Přeskočí na konkrétní akci podle ID.
- 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
Vlastnosti:
| Vlastnictví | Povinné | Description |
|---|---|---|
actionId |
Ano | ID akce pro přechod na |
Výstupní akce
SendActivity
Odešle uživateli zprávu.
Textová aktivita generuje kromě svého oznámení o aktivitě také průběžnou aktualizaci a dokončenou odpověď. Viz Vyberte, které události odpovědi se mají zobrazit, abyste zabránili opakovanému zobrazení stejného textu.
- kind: SendActivity
id: send_welcome
displayName: Send welcome message
activity:
text: "Welcome to our service!"
S výrazem:
- kind: SendActivity
activity:
text: =Concat("Hello, ", Local.userName, "! How can I help you today?")
Vlastnosti:
| Vlastnictví | Povinné | Description |
|---|---|---|
activity |
Ano | Aktivita, která se má odeslat |
activity.text |
Ano | Text zprávy (literál nebo výraz) |
SendMessage
Odešle uživateli textovou zprávu se šablonou. Použijte SendMessage , když potřebujete jenom odeslat text a nepotřebujete obrazec objektu celé aktivity.
- kind: SendMessage
id: show_repo_summary
message: "Fetched repo: visibility={Local.RepoInfo.visibility}, description={Local.RepoInfo.description}"
Vlastnosti:
| Vlastnictví | Povinné | Description |
|---|---|---|
message |
Ano | Text zprávy, který chcete odeslat. Chcete-li zahrnout hodnoty stavu pracovního postupu, použijte zástupné prvky {Variable.Path}. |
Poznámka:
Deklarativní implementace pracovního postupu jazyka C# podporuje SendMessage. Používá se SendActivity pro pracovní postupy Python.
Akce vyvolání agenta
InvokeAzureAgent
Vyvolá agenta Foundry.
Základní vyvolání:
- kind: InvokeAzureAgent
id: call_assistant
displayName: Call assistant agent
agent:
name: AssistantAgent
conversationId: =System.ConversationId
S konfigurací vstupu a výstupu:
- 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
S externí smyčkou (pokračuje až do splnění podmínky):
- kind: InvokeAzureAgent
id: support_agent
agent:
name: SupportAgent
input:
externalLoop:
when: =Not(Local.IsResolved)
output:
responseObject: Local.SupportResult
Vlastnosti:
| Vlastnictví | Povinné | Description |
|---|---|---|
agent.name |
Ano | Název registrovaného agenta |
conversationId |
No | Identifikátor kontextu konverzace |
input.messages |
No | Zprávy, které se mají odeslat agentu |
input.arguments |
No | Další argumenty pro agenta |
input.externalLoop.when |
No | Podmínka pro pokračování smyčky agenta |
output.responseObject |
No | Cesta k uložení odpovědi agenta |
output.messages |
No | Cesta k ukládání zpráv konverzace |
output.autoSend |
No | Automatické odeslání odpovědi uživateli |
Nástroje a akce HTTP
InvokeFunctionTool
Vyvolá nástroj funkce přímo z pracovního postupu bez použití agenta AI.
- 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
Vlastnosti:
| Vlastnictví | Povinné | Description |
|---|---|---|
functionName |
Ano | Název funkce, která se má vyvolat |
conversationId |
No | Identifikátor kontextu konverzace |
requireApproval |
No | Zda se má před spuštěním vyžadovat schválení uživatelem |
arguments |
No | Argumenty, které se mají předat funkci |
output.result |
No | Cesta k uložení výsledku funkce |
output.messages |
No | Cesta k ukládání zpráv funkcí |
output.autoSend |
No | Automatické odeslání výsledku uživateli |
Instalační program jazyka C# pro InvokeFunctionTool:
Funkce musí být registrovány pomocí WorkflowRunner nebo zpracovány prostřednictvím externího vstupu:
// 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
Vyvolá nástroj na serveru MCP (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
S názvem připojení pro hostované scénáře:
- 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
Vlastnosti:
| Vlastnictví | Povinné | Description |
|---|---|---|
serverUrl |
Ano | Adresa URL serveru MCP |
serverLabel |
No | Popisek pro server čitelný pro člověka |
toolName |
Ano | Název nástroje, který se má vyvolat |
conversationId |
No | Identifikátor kontextu konverzace |
requireApproval |
No | Zda se má vyžadovat schválení uživatelem |
arguments |
No | Argumenty, které se mají předat nástroji |
headers |
No | Vlastní hlavičky HTTP pro požadavek |
connection.name |
No | Pojmenované připojení pro hostované scénáře (připojuje se k ProjectConnectionId v Foundry, zatím není plně podporované) |
output.result |
No | Cesta k uložení výsledku nástroje |
output.messages |
No | Cesta k ukládání zpráv výsledků |
output.autoSend |
No | Automatické odeslání výsledku uživateli |
Nastavení jazyka C# pro InvokeMcpTool:
Nakonfigurujte v McpToolHandler továrně pracovních postupů:
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
Odešle požadavek HTTP prostřednictvím nakonfigurovaného IHttpRequestHandler. Úspěšné odpovědi JSON se analyzují před přiřazením; odpovědi se stavem jiným než 2xx způsobí selhání akce.
- 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
Vlastnosti:
| Vlastnictví | Povinné | Description |
|---|---|---|
url |
Ano | Absolutní adresa URL požadavku |
method |
No | metoda HTTP; výchozí hodnota GET |
headers |
No | Hlavičky žádosti |
queryParameters |
No | Parametry dotazu připojené k adrese URL |
body |
No | Text žádosti; použít kind: json, rawnebo none |
requestTimeoutInMilliseconds |
No | Časový limit pro jednotlivé požadavky |
conversationId |
No | Přidá do konverzace text úspěšné odpovědi. |
response |
No | Cesta k uložení analyzovaného textu odpovědi |
responseHeaders |
No | Cesta k ukládání hlaviček odpovědí |
Nastavení jazyka C# pro HttpRequestAction:
Nastavte HttpRequestHandler při vytváření pracovního postupu. Pokud potřebujete opakování nebo seznam povolených adres URL, použijte vlastní obslužný program.
DeclarativeWorkflowOptions options = new(agentProvider)
{
HttpRequestHandler = new DefaultHttpRequestHandler(),
};
Workflow workflow = DeclarativeWorkflowBuilder.Build<string>("workflow.yaml", options);
Akce lidské zásahy v rámci procesu
Question
Položí uživateli otázku a uloží odpověď.
Pro přímé provádění pracovního postupu zpracujte otázku RequestInfoEvent. Jeho ExternalInputRequest.AgentResponse obsahuje výzvu; vlastnost AgentResponse je datová zátěž, nikoli samostatná AgentResponseEvent. Vraťte v žádosti prvek ExternalInputResponse, aby bylo možné obnovit pracovní postup. Níže uvedené nastavení autoSend řídí, jak se přijatá odpověď přidává do konverzace, nikoli které události odpovědí jsou generovány.
Sady SDK jazyka C# a Python používají pro výzvu k zadání otázky různé názvy polí. Tento příklad používá nejmenší sdílené chování: požádá o text a uloží odpověď do stavu pracovního postupu.
- kind: Question
id: ask_name
displayName: Ask for user name
property: Local.userName
prompt:
kind: Message
text:
- "What is your name?"
entity:
kind: StringPrebuiltEntity
Vlastnosti:
| Vlastnictví | Povinné | Description |
|---|---|---|
prompt |
Ano | Šablona aktivity, která se má odeslat jako otázka. Používá se kind: Message se seznamem text pro výzvy k zprávám. |
property |
Ano | Cesta k uložení extrahované odpovědi |
entity |
Ano | Typ entity použitý k analýze a ověření odpovědi. Používejte StringPrebuiltEntity pro odpovědi bez textu. |
alwaysPrompt |
No | Vynutí, aby byla otázka kladena i v případě, že cílová vlastnost již má hodnotu. |
skipQuestionMode |
No | Určuje, zda chcete přeskočit výzvu, pokud cílová vlastnost již má hodnotu. Podporované hodnoty jsou AlwaysSkipIfVariableHasValue, SkipOnFirstExecutionIfVariableHasValuea AlwaysAsk. |
repeatCount |
No | Maximální počet neplatných nebo nerozpoznaných odpovědí před uložením defaultValue. |
defaultValue |
No | Hodnota, která se má uložit, když repeatCount je dosaženo bez platné odpovědi. |
defaultValueResponse |
No | Šablona aktivity zprávy k odeslání při použití výchozí hodnoty |
invalidPrompt |
No | Šablona aktivity zprávy, která se má odeslat, když text odpovědi neodpovídá nakonfigurované entitě. |
unrecognizedPrompt |
No | Šablona aktivity zprávy, která se má odeslat, když odpověď neobsahuje zprávy. |
autoSend |
No | Přidá platnou odpověď do konverzace pracovního postupu a aktualizuje System.LastMessage. Výchozí hodnota je true. |
RequestExternalInput (PožadavekExterníhoVstupu)
Vyžaduje vstup z externího systému nebo procesu.
- kind: RequestExternalInput
id: request_approval
displayName: Request manager approval
prompt:
text: "Please provide approval for this request."
variable: Local.approvalResult
default: "pending"
Vlastnosti:
| Vlastnictví | Povinné | Description |
|---|---|---|
prompt.text |
Ano | Popis požadovaného vstupu |
variable |
Ano | Cesta k uložení vstupu |
default |
No | Výchozí hodnota |
Akce řízení pracovního postupu
EndWorkflow
Ukončí provádění pracovního postupu.
- kind: EndWorkflow
id: finish
displayName: End workflow
Ukončit konverzaci
Ukončí aktuální konverzaci.
- kind: EndConversation
id: end_chat
displayName: End conversation
Vytvořit Rozhovor
Vytvoří nový kontext konverzace.
- kind: CreateConversation
id: create_new_conv
displayName: Create new conversation
conversationId: Local.NewConversationId
Vlastnosti:
| Vlastnictví | Povinné | Description |
|---|---|---|
conversationId |
Ano | Cesta k uložení ID nové konverzace |
Akce konverzace (jenom C#)
PřidatZprávuKonverzace
Přidá zprávu do vlákna konverzace.
- kind: AddConversationMessage
id: add_system_message
displayName: Add system context
conversationId: =System.ConversationId
message:
role: system
content: =Local.contextInfo
Vlastnosti:
| Vlastnictví | Povinné | Description |
|---|---|---|
conversationId |
Ano | Identifikátor cílové konverzace |
message |
Ano | Zpráva, kterou chcete přidat |
message.role |
Ano | Role zprávy (systém, uživatel, asistent) |
message.content |
Ano | Obsah zprávy |
ZkopírovatZprávyRozhovoru
Zkopíruje zprávy z jedné konverzace do druhé.
- kind: CopyConversationMessages
id: copy_context
displayName: Copy conversation context
sourceConversationId: =Local.SourceConversation
targetConversationId: =System.ConversationId
limit: 10
Vlastnosti:
| Vlastnictví | Povinné | Description |
|---|---|---|
sourceConversationId |
Ano | Identifikátor zdrojové konverzace |
targetConversationId |
Ano | Identifikátor cílové konverzace |
limit |
No | Maximální počet zpráv ke zkopírování |
ZískatKonverzačníZprávu
Načte konkrétní zprávu z konverzace.
- kind: RetrieveConversationMessage
id: get_message
displayName: Get specific message
conversationId: =System.ConversationId
messageId: =Local.targetMessageId
variable: Local.retrievedMessage
Vlastnosti:
| Vlastnictví | Povinné | Description |
|---|---|---|
conversationId |
Ano | Identifikátor konverzace |
messageId |
Ano | Identifikátor zprávy, který se má načíst |
variable |
Ano | Cesta k uložení načtené zprávy |
RetrieveConversationMessages
Načte více zpráv z konverzace.
- kind: RetrieveConversationMessages
id: get_history
displayName: Get conversation history
conversationId: =System.ConversationId
limit: 20
newestFirst: true
variable: Local.conversationHistory
Vlastnosti:
| Vlastnictví | Povinné | Description |
|---|---|---|
conversationId |
Ano | Identifikátor konverzace |
limit |
No | Maximální počet zpráv k načtení (výchozí hodnota: 20) |
newestFirst |
No | Seřadit v sestupném pořadí |
after |
No | Kurzor pro stránkování |
before |
No | Kurzor pro stránkování |
variable |
Ano | Cesta k ukládání načtených zpráv |
Rychlé referenční informace k akcím
| Action | Kategorie | jazyk C# | Python | Description |
|---|---|---|---|---|
SetVariable |
Proměnné | ✅ | ✅ | Nastavení jedné proměnné |
SetMultipleVariables |
Proměnné | ✅ | ✅ | Nastavení více proměnných |
SetTextVariable |
Proměnné | ✅ | ✅ | Nastavení textové proměnné |
ResetVariable |
Proměnné | ✅ | ✅ | Vymazat proměnnou |
ClearAllVariables |
Proměnné | ✅ | ✅ | Vymazat všechny proměnné |
ParseValue |
Proměnné | ✅ | ✅ | Analýza a transformace dat |
EditTableV2 |
Proměnné | ✅ | ✅ | Úprava dat tabulky |
If |
Řízení toku | ✅ | ✅ | Podmíněné větvení |
ConditionGroup |
Řízení toku | ✅ | ✅ | Přepínač s více větvemi |
Foreach |
Řízení toku | ✅ | ✅ | Iterace nad kolekcí |
BreakLoop |
Řízení toku | ✅ | ✅ | Ukončit aktuální smyčku |
ContinueLoop |
Řízení toku | ✅ | ✅ | Přeskočit na další iteraci |
GotoAction |
Řízení toku | ✅ | ✅ | Přejít na akci podle ID |
SendActivity |
Výstup | ✅ | ✅ | Odeslat zprávu uživateli |
SendMessage |
Výstup | ✅ | ❌ | Odeslání textové zprávy se šablonou |
InvokeAzureAgent |
Agent | ✅ | ✅ | Volání agenta Azure AI |
InvokeFunctionTool |
nástroj | ✅ | ✅ | Přímé vyvolání funkce |
InvokeMcpTool |
nástroj | ✅ | ✅ | Vyvolání nástroje serveru MCP |
HttpRequestAction |
HTTP | ✅ | ✅ | Volání koncového bodu HTTP |
Question |
Člověk ve smyčce | ✅ | ✅ | Položte uživateli otázku |
RequestExternalInput |
Člověk ve smyčce | ✅ | ✅ | Vyžádání externího vstupu |
EndWorkflow |
Ovládací prvek pracovního postupu | ✅ | ✅ | Ukončit pracovní postup |
EndConversation |
Ovládací prvek pracovního postupu | ✅ | ✅ | Ukončit konverzaci |
CreateConversation |
Ovládací prvek pracovního postupu | ✅ | ✅ | Vytvoření nové konverzace |
AddConversationMessage |
Konverzace | ✅ | ❌ | Přidání zprávy do vlákna |
CopyConversationMessages |
Konverzace | ✅ | ❌ | Kopírování zpráv |
RetrieveConversationMessage |
Konverzace | ✅ | ❌ | Získat jednu zprávu |
RetrieveConversationMessages |
Konverzace | ✅ | ❌ | Získání více zpráv |
Pokročilé vzory
Orchestrace s více agenty
Sekvenční potrubí agenta
Proveďte úkol skrz několik agentů za sebou.
#
# 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
Nastavení jazyka C#:
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");
Podmíněné směrování agentů
Směrujte požadavky na různé agenty na základě podmínek.
#
# 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
Vzory integrace nástrojů
Předběžné načtení dat pomocí InvokeFunctionTool
Načtení dat před voláním agenta:
#
# 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)'
Integrace nástrojů MCP
Volání externího serveru pomocí MCP:
#
# 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")
Prerequisites
Než začnete, ujistěte se, že máte:
- Python 3.10 – 3.13 (Python 3.14 se zatím nepodporuje kvůli kompatibilitě PowerFx)
- Nainstalovaný deklarativní balíček Agent Framework:
pip install agent-framework-declarative --pre
Tento balíček automaticky zahrnuje podkladový prvek agent-framework-core.
- Základní znalost syntaxe YAML
- Porozumění konceptům pracovních postupů
První deklarativní pracovní postup
Pojďme vytvořit jednoduchý pracovní postup, který uživatele pozdraví jménem.
Krok 1: Vytvoření souboru YAML
Vytvořte soubor s názvem 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
Krok 2: Načtení a spuštění pracovního postupu
Vytvořte soubor Pythonu pro spuštění pracovního postupu:
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())
Očekávaný výstup
Loaded workflow: greeting-workflow
----------------------------------------
Output: Hello, Alice!
Základní koncepty
Namespace proměnných
Deklarativní pracovní postupy používají k uspořádání stavu proměnné s oborem názvů:
| Namespace | Description | Příklad |
|---|---|---|
Local.* |
Místní proměnné pro pracovní tok | Local.message |
Workflow.Inputs.* |
Vstupní parametry | Workflow.Inputs.name |
Workflow.Outputs.* |
Výstupní hodnoty | Workflow.Outputs.result |
System.* |
Systémové hodnoty | System.ConversationId |
Jazyk výrazů
Hodnoty s předponou = jsou vyhodnoceny jako výrazy:
# Literal value (no evaluation)
value: Hello
# Expression (evaluated at runtime)
value: =Concat("Hello, ", Workflow.Inputs.name)
Mezi běžné funkce patří:
-
Concat(str1, str2, ...): Zřetězení řetězců -
If(condition, trueValue, falseValue)– Podmíněný výraz -
IsBlank(value)– Zkontrolujte, jestli je hodnota prázdná.
Limity procházení stavu PowerFx
Python ověří deklarativní stav před zápisem stavu a snímky a před převodem hodnot na symboly PowerFx. Cyklické struktury jsou zamítnuty místo toho, aby byly zkráceny.
Každý průchod používá tyto pevné limity:
- Maximální hloubka je 64, přičemž kořenová hodnota je v hloubce 0.
- Maximálně 10 000 navštívených hodnot, včetně kontejnerů a mapovacích klíčů.
- Maximální agregační velikost 1 048 576 řetězcových znaků a binárních bajtů.
Opakované odkazy a aliasy se při každém průchodu znovu započítávají. Cyklus nebo překročení limitu vyvolá chybu ValueError během zápisu stavu nebo vytváření snímku anebo při převodu PowerFx. Tyto limity procházení neomezují vykonávání výrazů PowerFx ani hooky pro kopírování nebo převod v Pythonu definované aplikací.
Typy akcí
Deklarativní pracovní postupy podporují různé typy akcí:
| Kategorie | Akce |
|---|---|
| Správa proměnných |
SetVariable, SetMultipleVariables, ResetVariable |
| Řízení toku |
If, ConditionGroup, Foreach, BreakLoop, , ContinueLoopGotoAction |
| Výstup | SendActivity |
| Vyvolání agenta | InvokeAzureAgent |
| Vyvolání nástroje |
InvokeFunctionTool, InvokeMcpTool |
| HTTP | HttpRequestAction |
| Člověk ve smyčce |
Question, RequestExternalInput |
| Ovládací prvek pracovního postupu |
EndWorkflow, EndConversation, CreateConversation |
Referenční dokumentace k akcím
Akce jsou stavební bloky deklarativních pracovních postupů. Každá akce provede konkrétní operaci a akce se sekvenčně spustí v pořadí, v jakém se zobrazí v souboru YAML.
Struktura akcí
Všechny akce sdílejí společné vlastnosti:
- 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...
Správa akcí proměnných
SetVariable
Nastaví proměnnou na zadanou hodnotu.
- kind: SetVariable
id: set_greeting
displayName: Set greeting message
variable: Local.greeting
value: Hello World
S výrazem:
- kind: SetVariable
variable: Local.fullName
value: =Concat(Workflow.Inputs.firstName, " ", Workflow.Inputs.lastName)
Vlastnosti:
| Vlastnictví | Povinné | Description |
|---|---|---|
variable |
Ano | Proměnná cesta (např. Local.name, Workflow.Outputs.result) |
value |
Ano | Hodnota, která se má nastavit (literál nebo výraz) |
Poznámka:
Python také podporuje druh akce SetValue, který pro cílovou vlastnost používá path místo variable. Oba SetVariable (s variable) a SetValue (s path) dosáhnou stejného výsledku. Příklady:
- kind: SetValue
id: set_greeting
path: Local.greeting
value: Hello World
NastavitVíceProměnných
Nastaví více proměnných v jedné akci.
- kind: SetMultipleVariables
id: initialize_vars
displayName: Initialize variables
variables:
Local.counter: 0
Local.status: pending
Local.message: =Concat("Processing order ", Workflow.Inputs.orderId)
Vlastnosti:
| Vlastnictví | Povinné | Description |
|---|---|---|
variables |
Ano | Mapování proměnných cest k hodnotám |
ResetVariable
Vymaže hodnotu proměnné.
- kind: ResetVariable
id: clear_counter
variable: Local.counter
Vlastnosti:
| Vlastnictví | Povinné | Description |
|---|---|---|
variable |
Ano | Proměnná cesta k resetování |
Řídící tokové akce
If
Provádí akce podmíněně na základě podmínky.
- 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!"
Vnořené podmínky:
- 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"
Vlastnosti:
| Vlastnictví | Povinné | Description |
|---|---|---|
condition |
Ano | Výraz, který se vyhodnotí jako true nebo false |
then |
Ano | Akce, které se mají provést, pokud je podmínka pravdivá |
else |
No | Akce, které se mají provést, pokud je podmínka nepravdivá |
SkupinaPodmínek
Vyhodnotí více podmínek, jako je příkaz switch/case.
- 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
Vlastnosti:
| Vlastnictví | Povinné | Description |
|---|---|---|
conditions |
Ano | Seznam párů podmínek a akcí (první nalezená shoda platí) |
elseActions |
No | Akce, pokud neodpovídá žádné podmínce |
Foreach
Iteruje přes kolekci.
- 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)'
Vlastnosti:
| Vlastnictví | Povinné | Description |
|---|---|---|
source |
Ano | Výraz vracející kolekci |
itemName |
No | Název proměnné pro aktuální položku (výchozí: item) |
indexName |
No | Název proměnné pro aktuální index (výchozí: index) |
actions |
Ano | Akce, které se mají provést pro každou položku |
BreakLoop
Okamžitě ukončí aktuální smyčku.
- kind: Foreach
source: =Workflow.Inputs.items
actions:
- kind: If
condition: =item = "stop"
then:
- kind: BreakLoop
- kind: SendActivity
activity:
text: =item
ContinueLoop
Přeskočí na další iteraci smyčky.
- kind: Foreach
source: =Workflow.Inputs.numbers
actions:
- kind: If
condition: =item < 0
then:
- kind: ContinueLoop
- kind: SendActivity
activity:
text: '=Concat("Positive number: ", item)'
GotoAction
Přeskočí na konkrétní akci podle ID.
- 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
Vlastnosti:
| Vlastnictví | Povinné | Description |
|---|---|---|
actionId |
Ano | ID akce pro přechod na |
Výstupní akce
SendActivity
Odešle uživateli zprávu.
- kind: SendActivity
id: send_welcome
displayName: Send welcome message
activity:
text: "Welcome to our service!"
S výrazem:
- kind: SendActivity
activity:
text: =Concat("Hello, ", Workflow.Inputs.name, "! How can I help you today?")
Vlastnosti:
| Vlastnictví | Povinné | Description |
|---|---|---|
activity |
Ano | Aktivita, která se má odeslat |
activity.text |
Ano | Text zprávy (literál nebo výraz) |
V Pythonu se text vytvořený uživatelem, který začíná na =, vyhodnocuje a generuje jako data. Výsledek výrazu se znovu nezpracuje pro {Variable.Path} interpolaci. Vytvořte šablonu přímo, například Hello, {Local.name}!, nebo vytvořte úplný řetězec ve výrazu, například ="Hello, " & Local.name & "!".
Akce vyvolání agenta
InvokeAzureAgent
Vyvolá agenta Azure AI.
Základní vyvolání:
- kind: InvokeAzureAgent
id: call_assistant
displayName: Call assistant agent
agent:
name: AssistantAgent
conversationId: =System.ConversationId
S konfigurací vstupu a výstupu:
- 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
S externí smyčkou (pokračuje až do splnění podmínky):
- kind: InvokeAzureAgent
id: support_agent
agent:
name: SupportAgent
input:
externalLoop:
when: =Not(Local.IsResolved)
output:
responseObject: Local.SupportResult
Vlastnosti:
| Vlastnictví | Povinné | Description |
|---|---|---|
agent.name |
Ano | Název registrovaného agenta |
conversationId |
No | Identifikátor kontextu konverzace |
input.messages |
No | Zprávy, které se mají odeslat agentu |
input.arguments |
No | Argumenty pro vyhodnocení a přidání do vstupního textu agenta |
input.externalLoop.when |
No | Podmínka pro pokračování smyčky agenta |
output.responseObject |
No | Cesta k uložení odpovědi agenta |
output.messages |
No | Cesta k ukládání zpráv konverzace |
output.autoSend |
No | Automaticky odešle odpověď do výstupu pracovního postupu. Přijímá logickou hodnotu nebo výraz = a výchozí hodnota je true. |
V Python InvokeAzureAgent vyhodnocuje každou nakonfigurovanou input.arguments hodnotu a formátuje neprázdné argumenty jako key: value řádky. Pokud nastavíte input.messages, text vyhodnocené zprávy následuje za řádky argumentu. Pokud input.arguments obsahuje alespoň jeden argument a vynecháte input.messages, Python použije pouze text argumentu a nepřidá náhradní hodnoty z Local.input, , Local.userInputSystem.LastMessage.Textnebo Workflow.Inputs.
Python vyhodnocuje output.autoSend vzhledem k aktuálnímu stavu pracovního postupu před každým spuštěním, včetně obnovených iterací externí smyčky. Hodnota false potlačí pouze automatický výstup pracovního postupu; agent se však stále spustí a nakonfigurované výstupy odpovědí a zpráv se i nadále ukládají.
Nástroje a akce HTTP
InvokeFunctionTool
Vyvolá zaregistrovanou funkci Pythonu přímo z pracovního postupu bez použití agenta AI.
- 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
Vlastnosti:
| Vlastnictví | Povinné | Description |
|---|---|---|
functionName |
Ano | Název registrované funkce, která se má vyvolat |
arguments |
No | Argumenty, které se mají předat funkci |
output.result |
No | Cesta k uložení výsledku funkce |
output.messages |
No | Cesta k ukládání zpráv funkcí |
output.autoSend |
No | Automaticky odešle výsledek do výstupu pracovního postupu. Přijímá logickou hodnotu nebo výraz = a výchozí hodnota je true. |
Python vyhodnotí output.autoSend aktuální stav pracovního postupu bezprostředně před spuštěním nástroje. Výsledek false potlačí pouze automatický výstup pracovního postupu; nástroj stále běží a nakonfigurované výstupy výsledků a zpráv jsou stále uložené. Zamítnuté schválení se dokončí, aniž by se vyhodnotil výraz.
Nastavení Pythonu pro InvokeFunctionTool:
Funkce musí být registrovány pomocí WorkflowFactory :register_tool
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
Vyvolá nástroj na serveru MCP prostřednictvím nakonfigurovaného 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
Vlastnosti:
| Vlastnictví | Povinné | Description |
|---|---|---|
serverUrl |
Ano | Adresa URL serveru MCP |
toolName |
Ano | Název nástroje na serveru MCP |
serverLabel |
No | Popisek serveru čitelný pro člověka |
arguments |
No | Argumenty předané nástroji |
headers |
No | Hlavičky požadavku; prázdné hodnoty se přeskočí. |
connection.name |
No | Pojmenované připojení pro vlastní obslužné rutiny |
conversationId |
No | Přidá do konverzace úspěšný výstup nástroje. |
requireApproval |
No | Žádost o schválení před vyvoláním nástroje |
output.result |
No | Cesta k uložení výstupu analyzovaného nástroje |
output.messages |
No | Cesta k uložení zprávy nástroje |
output.autoSend |
No | Generuje výstup nástroje do výsledku pracovního postupu; výchozí hodnota true |
Když je requireApprovaltrue, běhové prostředí Pythonu přiřadí hlavičky vyhodnocené akce k žádosti o schválení. Požadavek obsahuje názvy hlaviček, ale ne hodnoty hlaviček. Pokud se hlavičky změní, dojde k obměně přihlašovacích údajů nebo obnovený starší požadavek nemá ověřitelný stav svázání, pracovní postup vygeneruje náhradní žádost o schválení s novým ID požadavku a nespustí nástroj. Chraňte úložiště kontrolních bodů pracovního postupu, protože obsahuje samostatný ověřovací klíč. Vlastní handlery zůstávají odpovědné za přihlašovací údaje, které získají mimo headers akce.
Nastavení Python pro InvokeMcpTool:
Předejte obslužnou rutinu nástroje MCP .WorkflowFactory Pokud potřebujete ověřování, spravovaná připojení nebo seznam povolených adres URL, použijte vlastní obslužnou rutinu.
from agent_framework.declarative import DefaultMCPToolHandler, WorkflowFactory
factory = WorkflowFactory(mcp_tool_handler=DefaultMCPToolHandler())
workflow = factory.create_workflow_from_yaml_path("workflow.yaml")
Bez client_provider používá DefaultMCPToolHandler relace MCP znovu pomocí omezené mezipaměti. S použitím client_provider vytvoří a ukončí samostatný nástroj MCP a relaci pro každé volání, včetně tools/list, i když poskytovatel vrátí stejného klienta nebo None. Obslužná metoda uzavírá interně vytvořené záložní klienty HTTP, ale instance httpx.AsyncClient, které poskytl volající, zůstávají ve vlastnictví volajícího.
Vyvolání založené na poskytovateli nezachovává stav relace serveru. Pokud váš pracovní postup vyžaduje kontinuitu relací MCP, implementujte vlastní MCPToolHandler s explicitním ověřováním a kontraktem životnosti.
HttpRequestAction
Odešle požadavek HTTP prostřednictvím nakonfigurovaného HttpRequestHandler. Úspěšné odpovědi JSON se analyzují před přiřazením. Odpovědi jiné než 2xx způsobí selhání akce. V Python chyba obsahuje adresu URL požadavku a stavový kód, ale vynechá text odpovědi.
- 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
Vlastnosti:
| Vlastnictví | Povinné | Description |
|---|---|---|
url |
Ano | Absolutní adresa URL požadavku |
method |
No | metoda HTTP; výchozí hodnota GET |
headers |
No | Hlavičky žádosti |
queryParameters |
No | Parametry dotazu připojené k adrese URL |
body |
No | Text žádosti; použít kind: json, rawnebo none |
requestTimeoutInMilliseconds |
No | Časový limit pro jednotlivé požadavky |
connection.name |
No | Pojmenované připojení pro vlastní obslužné rutiny |
conversationId |
No | Přidá do konverzace text úspěšné odpovědi. |
response |
No | Cesta k uložení analyzovaného textu odpovědi |
responseHeaders |
No | Cesta k ukládání hlaviček odpovědí |
nastavení Python pro HttpRequestAction:
Předejte obslužný program požadavku HTTP do WorkflowFactory. Pokud potřebujete ověřování, opakování nebo seznam povolených adres URL, použijte vlastní obslužnou rutinu.
from agent_framework.declarative import DefaultHttpRequestHandler, WorkflowFactory
factory = WorkflowFactory(http_request_handler=DefaultHttpRequestHandler())
workflow = factory.create_workflow_from_yaml_path("workflow.yaml")
Výchozí obslužná rutina odmítne adresy URL, které nejsou absolutními adresami URL HTTP nebo HTTPS. Normalizuje adresu URL a připojí queryParameters za existující část dotazu při zachování jejího stávajícího pořadí a bajtové podoby.
A client_provider obdrží normalizovaný HttpRequestInfo snímek. Snímek obsahuje složenou adresu URL info.url a prázdnou info.query_parameters; původní informace o požadavku se nezmění. Výchozí hodnoty vybraného klienta se stále použijí. Chování přesměrování je nadále řízeno nastavením follow_redirects tohoto klienta a poskytovatel se při jednotlivých krocích přesměrování znovu nevolá.
Výchozí obslužná rutina znovu používá interně vlastněného klienta HTTP, ale neuchovává soubory cookie odpovědí. Pokud pracovní postup vyžaduje soubory cookie pro autentizaci, zachování relace nebo afinitu nástroje pro vyrovnávání zatížení, předejte nakonfigurovaný httpx.AsyncClient prostřednictvím client= nebo jej vraťte z client_provider=. Omezte klienty používající soubory cookie na jednu ověřenou identitu a ve své aplikaci zavírejte klienty poskytnuté volajícím. Explicitní Cookie hlavičky požadavků a hlavičky odpovědi Set-Cookie zůstanou dostupné.
Akce lidské zásahy v rámci procesu
Question
Položí uživateli otázku a uloží odpověď.
Sady SDK jazyka C# a Python používají pro výzvu k zadání otázky různé názvy polí. Tato část používá nejmenší sdílené chování: požádejte o text a uložte odpověď do stavu pracovního postupu.
- kind: Question
id: ask_name
displayName: Ask for user name
question:
text: "What is your name?"
property: Local.userName
Vlastnosti:
| Vlastnictví | Povinné | Description |
|---|---|---|
question |
Ano | Otázka, která se má položit. Použijte question.text pro vnořenou formu nebo řetězcovou hodnotu pro kompaktní formu. |
variable |
Ano | Cesta k uložení odpovědi Pokud chcete, aby název pole na nejvyšší úrovni odpovídal názvu cílového pole v jazyce C#, použijte property jako jeho alternativní název. |
default |
No | Výchozí hodnota zahrnutá v metadatech požadavku, kterou má volající použít. |
choices |
No | Seznam možností přidaných do metadat požadavku Každá volba může být řetězec nebo objekt s volitelnými valuelabel poli. |
allowFreeText |
No | Určuje, zda volající může přijmout text mimo nakonfigurované choices. Výchozí hodnota je true. |
Python také přijímá alternativní názvy polí kvůli kompatibilitě. Používejte na nejvyšší úrovni text místo question a defaultValue místo default.
- kind: Question
id: ask_color
text: "Choose a color:"
property: Local.color
choices:
- value: red
label: Red
- blue
allowFreeText: false
RequestExternalInput (PožadavekExterníhoVstupu)
Vyžaduje vstup z externího systému nebo procesu.
- kind: RequestExternalInput
id: request_approval
displayName: Request manager approval
prompt:
text: "Please provide approval for this request."
variable: Local.approvalResult
default: "pending"
Vlastnosti:
| Vlastnictví | Povinné | Description |
|---|---|---|
prompt.text |
Ano | Popis požadovaného vstupu |
variable |
Ano | Cesta k uložení vstupu |
default |
No | Výchozí hodnota |
Akce řízení pracovního postupu
EndWorkflow
Ukončí provádění pracovního postupu.
- kind: EndWorkflow
id: finish
displayName: End workflow
Ukončit konverzaci
Ukončí aktuální konverzaci.
- kind: EndConversation
id: end_chat
displayName: End conversation
Vytvořit Rozhovor
Vytvoří nový kontext konverzace.
- kind: CreateConversation
id: create_new_conv
displayName: Create new conversation
conversationId: Local.NewConversationId
Vlastnosti:
| Vlastnictví | Povinné | Description |
|---|---|---|
conversationId |
Ano | Cesta k uložení ID nové konverzace |
Rychlé referenční informace k akcím
| Action | Kategorie | Description |
|---|---|---|
SetVariable |
Proměnné | Nastavení jedné proměnné |
SetMultipleVariables |
Proměnné | Nastavení více proměnných |
ResetVariable |
Proměnné | Vymazat proměnnou |
If |
Řízení toku | Podmíněné větvení |
ConditionGroup |
Řízení toku | Přepínač s více větvemi |
Foreach |
Řízení toku | Iterace nad kolekcí |
BreakLoop |
Řízení toku | Ukončit aktuální smyčku |
ContinueLoop |
Řízení toku | Přeskočit na další iteraci |
GotoAction |
Řízení toku | Přejít na akci podle ID |
SendActivity |
Výstup | Odeslat zprávu uživateli |
InvokeAzureAgent |
Agent | Volání agenta Azure AI |
InvokeFunctionTool |
nástroj | Vyvolání registrované funkce |
InvokeMcpTool |
nástroj | Vyvolání nástroje serveru MCP |
HttpRequestAction |
HTTP | Volání koncového bodu HTTP |
Question |
Člověk ve smyčce | Položte uživateli otázku |
RequestExternalInput |
Člověk ve smyčce | Vyžádání externího vstupu |
EndWorkflow |
Ovládací prvek pracovního postupu | Ukončit pracovní postup |
EndConversation |
Ovládací prvek pracovního postupu | Ukončit konverzaci |
CreateConversation |
Ovládací prvek pracovního postupu | Vytvoření nové konverzace |
Syntaxe výrazu
Deklarativní pracovní postupy používají jazyk výrazů podobný PowerFx ke správě stavu a výpočtů dynamických hodnot. Hodnoty s předponou = jsou vyhodnoceny jako výrazy během běhu programu.
Podrobnosti o jmenném prostoru proměnných
| Namespace | Description | Access |
|---|---|---|
Local.* |
Místní proměnné pracovního postupu | Čtení a zápis |
Workflow.Inputs.* |
Vstupní parametry předané pracovnímu postupu | Read-only |
Workflow.Outputs.* |
Hodnoty vrácené z pracovního postupu | Čtení a zápis |
System.* |
Systémové hodnoty | Read-only |
Agent.* |
Výsledky vyvolání agenta | Read-only |
Systémové proměnné
| Proměnné | Description |
|---|---|
System.ConversationId |
Identifikátor aktuální konverzace |
System.LastMessage |
Poslední zpráva |
System.Timestamp |
Aktuální časové razítko |
Proměnné agenta
Po vyvolání agenta získejte přístup k datům odpovědi prostřednictvím výstupní proměnné:
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 versus hodnoty výrazů
# 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
Operace s řetězci
Zřetězení
Zřetězení více řetězců:
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
Zkontrolujte, jestli je hodnota prázdná nebo nedefinovaná:
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
Podmíněné výrazy
If – funkce
Vrátí různé hodnoty na základě podmínky:
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"))
Operátory porovnání
| Operator | Description | Příklad |
|---|---|---|
= |
Rovná se | =Workflow.Inputs.status = "active" |
<> |
Nerovná se | =Workflow.Inputs.status <> "deleted" |
< |
Je menší než | =Workflow.Inputs.age < 18 |
> |
Je větší než | =Workflow.Inputs.count > 0 |
<= |
Menší než nebo rovno | =Workflow.Inputs.score <= 100 |
>= |
Větší nebo rovno | =Workflow.Inputs.quantity >= 1 |
Logické funkce
# 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))
Matematické operace
# 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
Příklady praktických výrazů
Kategorizace uživatelů
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
Podmíněné pozdravy
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
Ověření vstupu
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")
Pokročilé vzory
S rostoucí složitostí pracovních postupů budete potřebovat vzory, které zpracovávají vícekrokové procesy, koordinaci agentů a interaktivní scénáře.
Orchestrace s více agenty
Sekvenční potrubí agenta
Projděte si několik agentů v posloupnosti, kde každý agent vychází z výstupu předchozího agenta.
Případ použití: Kanály pro vytváření obsahu, kde různí specialisté zpracovávají výzkum, psaní a úpravy.
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
Nastavení Pythonu:
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"})
Podmíněné směrování agentů
Směrujte požadavky na různé agenty na základě vstupních nebo průběžných výsledků.
Use case: Podpůrné systémy, které směrují na specializované agenty na základě typu problému.
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
Agent s externí smyčkou
Pokračujte v interakci s agenty, dokud nebude splněna podmínka, například problém, který se řeší.
Případ použití: Podpora konverzací, které potrvají, dokud se problém uživatele nevyřeší.
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."
Vzory řízení smyčky
Iterativní konverzace agenta
Vytvářejte konverzace mezi agenty s kontrolovanou iterací.
Případ použití: Scénáře student-učitel, simulace debat nebo iterativní zdokonalování.
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
Smyčky na základě čítače
Implementujte tradiční smyčky počítání pomocí proměnných a GotoAction.
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!"
Předčasné ukončení pomocí BreakLoop
K předčasnému ukončení iterací při splnění podmínky použijte BreakLoop.
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"
Systémy se zapojením člověka
Interaktivní průzkum
Shromážděte od uživatele více informací.
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
Pracovní postup schválení
Než budete pokračovat v akci, požádejte o schválení.
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
Složitá orchestrace
Pracovní postup lístku podpory
Komplexní příklad kombinování více vzorů: směrování agentů, podmíněná logika a správa konverzací.
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.")
Osvědčené postupy
Názvové konvence
Pro akce a proměnné použijte jasné popisné názvy:
# Good
- kind: SetVariable
id: calculate_total_price
variable: Local.orderTotal
# Avoid
- kind: SetVariable
id: sv1
variable: Local.x
Uspořádání velkých pracovních postupů
Rozdělte složité pracovní postupy do logických oddílů s komentáři:
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
# ...
Zpracování chyb
Použití podmíněných kontrol ke zpracování potenciálních problémů:
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
Strategie testování
- Začněte jednoduše: Testování základních toků před přidáním složitosti
- Použití výchozích hodnot: Poskytnutí rozumných výchozích hodnot pro vstupy
- Přidání protokolování: Použití funkce SendActivity k ladění během vývoje
- Testovací hraniční případy: Ověření chování s chybějícími nebo neplatnými vstupy
# Debug logging example
- kind: SendActivity
id: debug_log
activity:
text: '=Concat("[DEBUG] Current state: counter=", Local.counter, ", status=", Local.status)'
Další kroky
-
Ukázky deklarativních pracovních postupů jazyka C# – Prozkoumejte kompletní funkční příklady, mezi které patří:
- StudentTeacher – konverzace s více agenty s iterativním učením
- InvokeMcpTool – Integrace nástroje serveru MCP
- InvokeFunctionTool – Přímé vyvolání funkce z pracovních postupů
- FunctionTools – Agent s nástroji funkcí
- ToolApproval – Lidské schválení pro provádění nástroje
- CustomerSupport – Komplexní pracovní postup podpory lístku
- DeepResearch – Výzkumný pracovní tok s více agenty
- Ukázky deklarativních pracovních postupů Pythonu – Prozkoumání kompletních pracovních příkladů
Poznámka:
Podpora této funkce v Go již brzy. Nejnovější stav najdete v úložišti Agent Framework Go .