Microsoft Agent Framework İş Akışları Düzenlemeleri - Sıralı

Sıralı düzenlemede aracılar bir işlem hattında düzenlenir. Her acente sırayla görevi işlerken çıkışını sıralamadaki bir sonraki acenteye geçirir. Bu, belge gözden geçirme, veri işleme işlem hatları veya çok aşamalı mantık gibi her adımın önceki adıma göre derlendiği iş akışları için idealdir.

Sıralı Düzenleme

Önemli

Varsayılan olarak, dizideki her aracı önceki aracının tam konuşmasını (hem önceki aracıya sağlanan giriş iletileri hem de yanıt iletileri) tüketir. Bunun yerine aracıları yalnızca önceki aracının yanıt iletilerini kullanacak şekilde yapılandırabilirsiniz. Ayrıntılar için bkz. Aracılar Arasındaki Bağlamı Denetleme .

Öğrenecekler

  • Agent'lerin sıralı ardışık işlem hattı nasıl oluşturulur
  • Her birinin bir öncekinin çıktısı üzerine inşa edildiği aracıları zincirleme kullanmak
  • Hassas araç çağrıları için döngüde insan onayı ekleme
  • Özel görevler için aracıları özel olarak tasarlanmış yürütücülerle birleştirme
  • Konuşma akışını işlem hattı üzerinden izleme.

Ajanlarınızı Tanımlayın

Sıralı düzenlemede aracılar, her aracının sırayla görevi işlediği bir işlem hattında düzenlenir ve çıktıyı dizideki bir sonraki aracıya geçirir.

Azure OpenAI İstemcisini Ayarlama

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Azure.AI.Projects;
using Azure.Identity;
using Microsoft.Agents.AI.Workflows;
using Microsoft.Extensions.AI;
using Microsoft.Agents.AI;

// 1) Set up the Azure OpenAI client
var endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT") ??
    throw new InvalidOperationException("AZURE_OPENAI_ENDPOINT is not set.");
var deploymentName = Environment.GetEnvironmentVariable("AZURE_OPENAI_DEPLOYMENT_NAME") ?? "gpt-4o-mini";
var client = new AIProjectClient(new Uri(endpoint), new DefaultAzureCredential())
    .GetProjectOpenAIClient()
    .GetProjectResponsesClient()
    .AsIChatClient(deploymentName);

Uyarı

DefaultAzureCredential geliştirme için uygundur ancak üretimde dikkatli bir şekilde dikkate alınması gerekir. Üretimde gecikme sorunları, istenmeyen kimlik bilgisi yoklama ve geri dönüş mekanizmalarından kaynaklanan olası güvenlik risklerini önlemek için belirli bir kimlik bilgisi (ör ManagedIdentityCredential. ) kullanmayı göz önünde bulundurun.

Sırayla çalışacak özel aracılar oluşturun:

// 2) Helper method to create translation agents
static ChatClientAgent GetTranslationAgent(string targetLanguage, IChatClient chatClient) =>
    new(chatClient,
        $"You are a translation assistant who only responds in {targetLanguage}. Respond to any " +
        $"input by outputting the name of the input language and then translating the input to {targetLanguage}.");

// Create translation agents for sequential processing
var translationAgents = (from lang in (string[])["French", "Spanish", "English"]
                         select GetTranslationAgent(lang, client));

Sıralı Orkestrasyonu Kurma

kullanarak AgentWorkflowBuilderiş akışını oluşturun:

// 3) Build sequential workflow
var workflow = AgentWorkflowBuilder.BuildSequential(translationAgents);

Sıralı İş Akışını Çalıştırma

İş akışını uygulayın ve olayları işleyin.

// 4) Run the workflow
var messages = new List<ChatMessage> { new(ChatRole.User, "Hello, world!") };

await using StreamingRun run = await InProcessExecution.RunStreamingAsync(workflow, messages);
await run.TrySendMessageAsync(new TurnToken(emitEvents: true));

string? lastExecutorId = null;
List<ChatMessage> result = [];
await foreach (WorkflowEvent evt in run.WatchStreamAsync())
{
    if (evt is AgentResponseUpdateEvent e)
    {
        if (e.ExecutorId != lastExecutorId)
        {
            lastExecutorId = e.ExecutorId;
            Console.WriteLine();
            Console.Write($"{e.ExecutorId}: ");
        }

        Console.Write(e.Update.Text);
    }
    else if (evt is WorkflowOutputEvent outputEvt)
    {
        result = outputEvt.As<List<ChatMessage>>()!;
        break;
    }
}

// Display final result
Console.WriteLine();
foreach (var message in result)
{
    Console.WriteLine($"{message.Role}: {message.Text}");
}

Örnek Çıkış

French_Translation: User: Hello, world!
French_Translation: Assistant: English detected. Bonjour, le monde !
Spanish_Translation: Assistant: French detected. ¡Hola, mundo!
English_Translation: Assistant: Spanish detected. Hello, world!

İnsan Katılımıyla Sıralı Orkestrasyon

Sıralı düzenleme, araç onayı aracılığıyla döngüdeki insan etkileşimlerini destekler. Aracılar, ApprovalRequiredAIFunction ile sarmalanmış araçları kullandığında, iş akışı durdurulur ve bir RequestInfoEvent içeren ToolApprovalRequestContent çıkış sağlar. Dış sistemler (insan operatörü gibi) araç çağrısını inceleyebilir, onaylayabilir veya reddedebilir ve iş akışı buna göre devam eder.

İnsan Katılımıyla Sıralı Orkestrasyon

Tavsiye

İstek ve yanıt modeli hakkında daha fazla bilgi için bkz. Döngüde İnsan.

Onay Gerektiren Araçlarla Ajanları Tanımlama

Hassas araçların ApprovalRequiredAIFunction ile sarmalandığı aracılar oluşturun.

ChatClientAgent deployAgent = new(
    client,
    "You are a DevOps engineer. Check staging status first, then deploy to production.",
    "DeployAgent",
    "Handles deployments",
    [
        AIFunctionFactory.Create(CheckStagingStatus),
        new ApprovalRequiredAIFunction(AIFunctionFactory.Create(DeployToProduction))
    ]);

ChatClientAgent verifyAgent = new(
    client,
    "You are a QA engineer. Verify that the deployment was successful and summarize the results.",
    "VerifyAgent",
    "Verifies deployments");

Onay İşleme ile Derleme ve Çalıştırma

Sıralı iş akışını normal şekilde oluşturun. Onay akışı olay akışı üzerinden işlenir:

var workflow = AgentWorkflowBuilder.BuildSequential([deployAgent, verifyAgent]);

await foreach (WorkflowEvent evt in run.WatchStreamAsync())
{
    if (evt is RequestInfoEvent e &&
        e.Request.TryGetDataAs(out ToolApprovalRequestContent? approvalRequest))
    {
        await run.SendResponseAsync(
            e.Request.CreateResponse(approvalRequest.CreateResponse(approved: true)));
    }
}

Uyarı

AgentWorkflowBuilder.BuildSequential() , araç onayını kullanıma sunulduktan sonra destekler; ek yapılandırma gerekmez. ApprovalRequiredAIFunction kullanılarak sarılmış bir aracı bir aracı çağırdığında, iş akışı otomatik olarak duraklatılır ve bir RequestInfoEvent yayar.

Tavsiye

Bu onay akışının tam bir çalıştırılabilir örneği için örneğeGroupChatToolApproval bakın. RequestInfoEvent Aynı işleme düzeni diğer düzenlemelerde de geçerlidir.

Önemli Kavramlar

  • Sıralı İşleme: Her bir temsilci, önceki temsilcinin çıkışını sırayla işler
  • AgentWorkflowBuilder.BuildSequential(): Bir dizi aracı kullanarak bir iş akışı oluşturur
  • ChatClientAgent: Belirli yönergelerle sohbet istemcisi tarafından desteklenen bir aracıyı temsil eder
  • InProcessExecution.RunStreamingAsync(): İş akışını çalıştırır ve gerçek zamanlı olay akışı için bir StreamingRun döndürür
  • Olay İşleme: Aracının ilerlemesini AgentResponseUpdateEvent, tamamlanmasını WorkflowOutputEvent izleme
  • Araç Onayı: Yürütmeden önce insan onayı istemek için hassas araçları ApprovalRequiredAIFunction ile sarmak
  • RequestInfoEvent: Bir araç onay gerektirdiğinde ortaya çıkar; araç arama ayrıntılarıyla birlikte içerir ToolApprovalRequestContent

Sıralı orkestrasyonda, her aracı görevi sırayla yönetir ve çıkış, birinden diğerine akarak devam eder. İki aşamalı bir işlem için aracıları tanımlayarak başlayın:

import os
from agent_framework.foundry import FoundryChatClient
from azure.identity import AzureCliCredential

# 1) Create agents using FoundryChatClient
chat_client = FoundryChatClient(
    project_endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"],
    model=os.environ["FOUNDRY_MODEL"],
    credential=AzureCliCredential(),
)

writer = chat_client.as_agent(
    instructions=(
        "You are a concise copywriter. Provide a single, punchy marketing sentence based on the prompt."
    ),
    name="writer",
)

reviewer = chat_client.as_agent(
    instructions=(
        "You are a thoughtful reviewer. Give brief feedback on the previous assistant message."
    ),
    name="reviewer",
)

Sıralı Orkestrasyonu Kurma

Bu SequentialBuilder sınıfı, etmenlerin görevleri sırayla işlediği bir işlem hattı oluşturur. Her temsilci konuşma geçmişinin tamamını görür ve yanıtını ekler.

from agent_framework.orchestrations import SequentialBuilder

# 2) Build sequential workflow: writer -> reviewer
workflow = SequentialBuilder(participants=[writer, reviewer]).build()

Sıralı İş Akışını Çalıştırma

İş akışını yürüt ve son çıktıyı topla. Terminal çıkışı, son aracının yanıt iletilerini içeren bir AgentResponse çıktıdır:

from agent_framework import AgentResponse

# 3) Run and print the last agent's response
events = await workflow.run("Write a tagline for a budget-friendly eBike.")
outputs = events.get_outputs()

if outputs:
    print("===== Final Response =====")
    final: AgentResponse = outputs[0]
    for msg in final.messages:
        name = msg.author_name or "assistant"
        print(f"[{name}]\n{msg.text}")

Örnek Çıkış

===== Final Response =====
[reviewer]
This tagline clearly communicates affordability and the benefit of extended travel, making it
appealing to budget-conscious consumers. It has a friendly and motivating tone, though it could
be slightly shorter for more punch. Overall, a strong and effective suggestion!

Gelişmiş: Özel Yürütücülerle Ajanların Birleştirilmesi

Sıralı orkestrasyon, özel işlem gerektiren durumlar için aracıların özel yürütücülerle karıştırılmasını destekler. LLM gerektirmeyen özel bir mantığa ihtiyacınız olduğunda bu yararlı olur:

Özel Yürütücü Tanımlama

Uyarı

Bir özel yürütücü, dizide bir aracıyı takip ettiğinde, işleyicisi bir AgentExecutorResponse alır (çünkü aracılar, AgentExecutor ile dahili olarak sarmalanır). Konuşma geçmişinin tamamına erişmek için kullanın agent_response.full_conversation . Özel bir yürütücü, son katılımcı (sonlandırıcı) olarak kullanıldığında, çıkışının iş akışının terminal çıkışı olması için ctx.yield_output(AgentResponse(...)) çağrısı yapmalıdır.

from agent_framework import AgentExecutorResponse, AgentResponse, Executor, WorkflowContext, handler
from agent_framework import Message
from typing_extensions import Never

class Summarizer(Executor):
    """Terminator custom executor: consumes full conversation and yields a summary as the workflow's final answer."""

    @handler
    async def summarize(
        self,
        agent_response: AgentExecutorResponse,
        ctx: WorkflowContext[Never, AgentResponse]
    ) -> None:
        if not agent_response.full_conversation:
            await ctx.yield_output(AgentResponse(messages=[Message("assistant", ["No conversation to summarize."])]))
            return

        users = sum(1 for m in agent_response.full_conversation if m.role == "user")
        assistants = sum(1 for m in agent_response.full_conversation if m.role == "assistant")
        summary = Message("assistant", [f"Summary -> users:{users} assistants:{assistants}"])
        await ctx.yield_output(AgentResponse(messages=[summary]))

Karma Sıralı İş Akışı Oluşturma

# Create a content agent
content = chat_client.as_agent(
    instructions="Produce a concise paragraph answering the user's request.",
    name="content",
)

# Build sequential workflow: content -> summarizer
summarizer = Summarizer(id="summarizer")
workflow = SequentialBuilder(participants=[content, summarizer]).build()

Özel Yürütücü ile Örnek Çıktı

===== Final Summary =====
Summary -> users:1 assistants:1

Ajanlar Arasındaki Bağlamı Denetleme

Varsayılan olarak, bir SequentialBuilder iş akışındaki her bir ajan, önceki ajanın tam konuşmasını (giriş + yanıt iletileri) kullanır. Ayarı chain_only_agent_responses=True , dizideki tüm aracıları yalnızca önceki aracının yanıt iletilerini kullanacak şekilde yapılandırıyor:

workflow = SequentialBuilder(
    participants=[writer, translator, reviewer],
    chain_only_agent_responses=True,
).build()

Bu, çeviri işlem hatları, aşamalı iyileştirme ve her bir aracın, öncesindeki aracın çıktılarını dönüştürmeye odaklanırken, önceki konuşma döngülerinden etkilenmeden çalışması gereken diğer senaryolar için faydalıdır.

Tam bir örnek için bkz. Agent Framework deposundaki sequential_chain_only_agent_responses.py .

Tavsiye

Özel filtre işlevleri dahil olmak üzere bağlam akışı üzerinde daha ayrıntılı denetim için bkz. Aracı Yürütücüsü başvurusundaki Bağlam Modları .

Ara Çıkışlar

Varsayılan olarak, SequentialBuilderson katılımcıyı terminal çıkış kaynağı (final_output_from ) olarak seçer. Yalnızca o katılımcının çıktısı, bir "output" olayı olarak görünür.

Önceki katılımcıların çıktılarını da görüntülemek için, ara kaynak olarak belirlemek istediğiniz katılımcılarla birlikte intermediate_output_from iletin. Bu, bu katılımcıları varsayılan final kümesinden örtük olarak çıkarır — "output" olayları yerine "intermediate" olayları üretirler:

workflow = SequentialBuilder(
    participants=[writer, reviewer, editor],
    intermediate_output_from=[writer, reviewer],
).build()

Hem "intermediate" hem de "output" olaylarını akış modunda gerçek zamanlı işleyebilirsiniz:

from agent_framework import AgentResponseUpdate

# Track the last author to format streaming output.
last_author: str | None = None

async for event in workflow.run("Write a tagline for a budget-friendly eBike.", stream=True):
    if event.type in ("output", "intermediate") and isinstance(event.data, AgentResponseUpdate):
        update = event.data
        author = update.author_name
        if author != last_author:
            if last_author is not None:
                print()  # Newline between different authors
            label = "FINAL" if event.type == "output" else "intermediate"
            print(f"[{label}] {author}: {update.text}", end="", flush=True)
            last_author = author
        else:
            print(update.text, end="", flush=True)

İnsan Katılımıyla Sıralı Orkestrasyon

Sıralı orkestrasyonlar, insan girdisi olan etkileşimleri iki şekilde destekler: hassas araç çağrılarını denetlemek için araç onayı ve her bir aracı yanıtından sonra duraklatıp geri bildirim toplamak için bilgi isteme.

İnsan Katılımıyla Sıralı Orkestrasyon

Tavsiye

İstek ve yanıt modeli hakkında daha fazla bilgi için bkz. Döngüde İnsan.

Sıralı İş Akışlarında Araç Onayı

Yürütmeden önce insan onayı gerektiren araçları işaretlemek için kullanın @tool(approval_mode="always_require") . Ajan aracı çağırdığında iş akışı durur ve bir request_info olayı yayar.

@tool(approval_mode="always_require")
def execute_database_query(query: str) -> str:
    return f"Query executed successfully: {query}"


database_agent = Agent(
    client=chat_client,
    name="DatabaseAgent",
    instructions="You are a database assistant.",
    tools=[execute_database_query],
)

workflow = SequentialBuilder(participants=[database_agent]).build()

Olay akışını işleme ve onay isteklerini işleme:

async def process_event_stream(stream):
    responses = {}
    async for event in stream:
        if event.type == "request_info" and event.data.type == "function_approval_request":
            responses[event.request_id] = event.data.to_function_approval_response(approved=True)
    return responses if responses else None

stream = workflow.run("Check the schema and update all pending orders", stream=True)

pending_responses = await process_event_stream(stream)
while pending_responses is not None:
    stream = workflow.run(stream=True, responses=pending_responses)
    pending_responses = await process_event_stream(stream)

Tavsiye

Tam bir çalıştırılabilir örnek için bkz sequential_builder_tool_approval.py. . Araç onayı, ek bir oluşturucu yapılandırmasına gerek kalmadan SequentialBuilder ile birlikte çalışır.

Aracı Geri Bildirimi için Bilgi İste

Belirli aracılar yanıt verdikten sonra duraklatmak için .with_request_info() kullanarak bir sonraki aracı başlamadan önce dış girdiye (insan incelemesi gibi) izin verin.

drafter = Agent(
    client=chat_client,
    name="drafter",
    instructions="You are a document drafter. Create a brief draft on the given topic.",
)

editor = Agent(
    client=chat_client,
    name="editor",
    instructions="You are an editor. Review and improve the draft. Incorporate any human feedback.",
)

finalizer = Agent(
    client=chat_client,
    name="finalizer",
    instructions="You are a finalizer. Create a polished final version.",
)

# Enable request info for the editor agent only
workflow = (
    SequentialBuilder(participants=[drafter, editor, finalizer])
    .with_request_info(agents=["editor"])
    .build()
)

async def process_event_stream(stream):
    responses = {}
    async for event in stream:
        if event.type == "request_info":
            responses[event.request_id] = AgentRequestInfoResponse.approve()
    return responses if responses else None

stream = workflow.run("Write a brief introduction to artificial intelligence.", stream=True)

pending_responses = await process_event_stream(stream)
while pending_responses is not None:
    stream = workflow.run(stream=True, responses=pending_responses)
    pending_responses = await process_event_stream(stream)

Tavsiye

Tam örneklere bakın: sıralı araç onayı ve sıralı istek bilgileri.

Önemli Kavramlar

  • Paylaşılan Bağlam: Varsayılan olarak, her bir aracı, giriş ve yanıt iletileri dahil olmak üzere önceki aracın tam konuşmasını tüketir
  • Bağlam Denetimi: Aracıları yalnızca önceki aracının yanıt iletilerini kullanacak şekilde yapılandırmak için kullanın chain_only_agent_responses=True
  • AgentResponse Çıktısı: İş akışının terminal çıkışı, son aracının yanıtını içeren bir AgentResponse çıktıdır (konuşmanın tamamını değil)
  • Order Matters: Ajanlar kesinlikle listede participants belirtilen sırayla yürütülür
  • Esnek Katılımcılar: Aracıları ve özel yürütücüleri istediğiniz sırada karıştırabilirsiniz
  • Özel Sonlandırıcı Sözleşmesi: Son katılımcı olarak kullanılan özel yürütücü, terminal çıkışını üretmek için ctx.yield_output(AgentResponse(...)) çağırmalıdır.
  • Ara Çıkışlar: Yalnızca son katılımcının değil, her katılımcının çıktısını bir iş akışı intermediate_outputs=True olayı olarak ortaya çıkacak şekilde yapılandırın output
  • Araç Onayı: İnsan incelemesi gerektiren hassas işlemler için kullanın @tool(approval_mode="always_require")
  • Bilgi Talebi: Dış geri bildirim almak için belirli aracıların ardından .with_request_info(agents=[...]) ile duraklatma yapın

Sonraki Adımlar