ملحق دائم

يوفر Durable Extension ل Microsoft Agent Framework تنفيذا دائما للوكلاء وتنسيقات العوامل المتعددة وسير عمل إطار عمل العامل Microsoft. يمكنك استخدامه لاستمرار جلسات عمل العامل وتنسيق نقاط التحقق وتقدم سير العمل، والتعافي من حالات الفشل، وتوسيع نطاق العمل عبر المضيفين الموزعين دون تغيير منطق العامل الأساسي.

يدعم الملحق نموذجين للاستضافة في C# Python:

  • دالات Azure للاستضافة المدارة بلا خادم مع نموذج البرمجة دالات Azure.
  • اجلب الحساب الخاص بك / المستضاف ذاتيا لتشغيل عوامل دائمة ومهام سير العمل في عملية العامل الخاصة بك أو الخدمة أو الحاوية أو بيئة Kubernetes أو البنية الأساسية للتطبيقات الحالية.

Note

انتقل إلى دعم ل Durable Extension قريبا. لاستضافة Go اليوم، راجع استضافة A2Aومستودع Agent Framework Go.

نظرة عامة

يجمع الوكلاء الدائمون بين نموذج برمجة إطار عمل العامل والبنية الأساسية للمهمة الدائمة، مثل جدولة المهام الدائمة، لإنشاء عوامل:

  • استمرار الحالة تلقائيا عبر الطلبات وعمليات تنفيذ العامل
  • استئناف بعد الفشل دون فقدان سياق المحادثة أو تكرار العمل المكتمل
  • توسيع نطاق العمال الموزعين عديمي الجنسية بناء على الطلب
  • تنسيق مهام سير العمل متعددة العوامل مع ضمانات تنفيذ موثوقة
  • مهام سير عمل إطار عمل عامل نقطة التحقق التي تم إنشاؤها باستخدام نموذج سير العمل المستند إلى الرسم البياني
  • إيقاف مؤقت للإدخل البشري أو الأحداث الخارجية دون استهلاك الرموز المميزة للحساب أو النموذج أثناء الانتظار
  • استجابات الدفق بشكل موثوق عند تكوينها باستخدام وسيط دفق موثوق به، مثل Redis
  • إدارة دورة حياة الجلسة من خلال تنظيف جلسة العمل لفترة البقاء (TTL) والمراقبة المستندة إلى لوحة المعلومات

متى تستخدم العوامل المتينة

اختر عوامل دائمة عند الحاجة:

  • حالة المحادثة المستمرة: تنجو جلسات العامل من تعطل العملية وإعادة التشغيل وأحداث التوسيع
  • التنسيقات المعقدة: تنسيق عوامل متعددة مع مهام سير عمل محددة وموثوقة يمكن تشغيلها لأيام أو أسابيع
  • التزامن المستند إلى الحدث: التكامل مع المشغلات أو قوائم الانتظار أو خطافات الويب أو المؤقتات أو أحداث التطبيق الحالية
  • حالة المحادثة التلقائية: تتم إدارة محفوظات محادثة الوكيل واستمرارها تلقائيا دون الحاجة إلى معالجة حالة صريحة في التعليمات البرمجية الخاصة بك
  • مهام سير عمل Durable Agent Framework: جعل مهام سير عمل Microsoft إطار عمل العامل المستندة إلى الرسم البياني دائمة بحيث يمكن التحقق من كل خطوة واستئنافها
  • جلسات طويلة الأمد: حافظ على توفر محادثات مفيدة أثناء استخدام تنظيف جلسة العمل لفترة البقاء (TTL) لإزالة جلسات العمل الخاملة تلقائيا
  • استجابات موثوقة في الوقت الحقيقي: إخراج رمز الدفق بشكل دائم للتطبيقات التي تحتاج إلى تجربة مستخدم في الوقت الحقيقي مع ضمانات التسليم

يختلف نهج الاستضافة هذا عن استضافة الوكيل المدار المستند إلى الخدمة (مثل Foundry Agent Service)، والذي يوفر بنية أساسية مدارة بالكامل دون مطالبتك بنشر أو إدارة مضيفي العاملين. تعد العوامل الدائمة مثالية عندما تحتاج إلى مرونة نشر التعليمات البرمجية أولا جنبا إلى جنب مع إدارة الحالة الدائمة.

اختيار نموذج استضافة

نموذج الاستضافة اختره عندما تحتاج
دالات Azure نموذج استضافة مدار بلا خادم؛ التوسيع المدمج والتحجيم إلى الصفر؛ دالات Azure المشغلات والروابط؛ نقاط نهاية HTTP التي تم إنشاؤها بواسطة نموذج برمجة الوظائف؛ مشغل خادم MCP؛ والحد الأدنى من إدارة البنية الأساسية للمضيف.
إحضار الحوسبة الخاصة بك / المستضافة ذاتيا مزيد من التحكم في عملية المضيف أو بيئة النشر أو دورة حياة وقت التشغيل أو البنية الأساسية أو الشبكات أو المصادقة أو التكامل مع تطبيق أو خدمة موجودة. استخدم هذا النموذج للحاويات أو Kubernetes أو العمال الذين يعملون لفترة طويلة أو تطبيقات وحدة التحكم أو الخدمات المخصصة أو البيئات التي تستضيف غير الوظائف.

عند استضافتها في خطة استضافة دالات Azure Flex Consumption، يمكن للوكلاء التوسع إلى آلاف المثيلات أو إلى صفر مثيلات عندما لا تكون قيد الاستخدام، ما يسمح لك بالدفع فقط مقابل الحساب الذي تحتاجه. في السيناريوهات المستضافة ذاتيا، تتم معالجة مدة بقاء عناصر تحكم المضيف والتحجيم والشبكات والنشر.

الشروع في العمل

في مشروع .NET، اختر مجموعة الحزمة لنموذج الاستضافة الخاص بك.

لاستضافة دالات Azure، أضف حزمة تكامل دالات Azure وحزم عامل الوظائف.

dotnet add package Azure.AI.Projects --prerelease
dotnet add package Azure.Identity
dotnet add package Microsoft.Agents.AI.Foundry --prerelease
dotnet add package Microsoft.Agents.AI.Hosting.AzureFunctions --prerelease

Note

بالإضافة إلى هذه الحزم، تأكد من أن مشروعك يستخدم الإصدار 2.2.0 أو أحدث من Microsoft.Azure. حزمة Functions.Worker.

لاستضافة الحوسبة الخاصة بك، أضف حزمة تكامل Durable Task الأساسية وحزم Durable Task Scheduler worker/client المستخدمة من قبل المضيف الخاص بك:

dotnet add package Microsoft.Agents.AI.DurableTask --prerelease
dotnet add package Microsoft.DurableTask.Client.AzureManaged
dotnet add package Microsoft.DurableTask.Worker.AzureManaged
dotnet add package Microsoft.Extensions.Hosting

في مشروع Python، اختر الحزمة لنموذج الاستضافة الخاص بك.

لاستضافة دالات Azure، قم بتثبيت حزمة تكامل دالات Azure.

pip install azure-identity
pip install agent-framework-azurefunctions --pre

لاستضافة الحوسبة الخاصة بك، قم بتثبيت حزمة تكامل Durable Task.

pip install azure-identity
pip install agent-framework-durabletask --pre

استضافة دالات Azure

باستخدام Durable Extension، يمكنك نشر عوامل إطار عمل عامل Microsoft واستضافتها في دالات Azure مع نقاط نهاية HTTP المضمنة والاستدعاء المستند إلى التزامن. يوفر دالات Azure تسعيرا مدفوعا بالحدث والدفع لكل استدعاء مع التحجيم التلقائي والحد الأدنى من إدارة البنية التحتية.

عند تكوين عامل دائم في دالات Azure، ينشئ الملحق تلقائيا نقاط نهاية HTTP للوكيل الخاص بك ويدير البنية الأساسية لتخزين حالة المحادثة ومعالجة الطلبات المتزامنة وتنسيق مهام سير العمل متعددة العوامل. يوفر تكامل استضافة دالات Azure أيضا وسائل راحة خاصة بالوظائف مثل واجهات برمجة تطبيقات REST التي تم إنشاؤها لإرسال الرسائل والتحقق من الحالة وإدارة الجلسات، بالإضافة إلى مشغلات مثل مشغل خادم MCP لوكلاء الاستضافة كخوادم MCP دون كتابة لصق المشغل.

using System;
using Azure.AI.Projects;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Agents.AI.Hosting.AzureFunctions;
using Microsoft.Azure.Functions.Worker.Builder;
using Microsoft.Extensions.Hosting;

var endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT");
var deploymentName = Environment.GetEnvironmentVariable("AZURE_OPENAI_DEPLOYMENT") ?? "gpt-4o-mini";

// Create an AI agent following the standard Microsoft Agent Framework pattern
AIAgent agent = new AIProjectClient(new Uri(endpoint), new DefaultAzureCredential())
    .AsAIAgent(
        model: deploymentName,
        instructions: "You are good at telling jokes.",
        name: "Joker");

// Configure the function app to host the agent with durable thread management
// This automatically creates HTTP endpoints and manages state persistence
using IHost app = FunctionsApplication
    .CreateBuilder(args)
    .ConfigureFunctionsWebApplication()
    .ConfigureDurableAgents(options =>
        options.AddAIAgent(agent)
    )
    .Build();
app.Run();

تحذير

DefaultAzureCredential مناسب للتنمية ولكنه يتطلب دراسة متأنية في الإنتاج. في الإنتاج، ضع في اعتبارك استخدام بيانات اعتماد محددة (على سبيل المثال، ManagedIdentityCredential) لتجنب مشكلات زمن الانتقال، وبحث بيانات الاعتماد غير المقصودة، والمخاطر الأمنية المحتملة من الآليات الاحتياطية.

import os
from agent_framework.azure import AgentFunctionApp
from agent_framework.openai import OpenAIChatCompletionClient
from azure.identity import DefaultAzureCredential

endpoint = os.getenv("AZURE_OPENAI_ENDPOINT")
deployment_name = os.getenv("AZURE_OPENAI_CHAT_COMPLETION_MODEL", "gpt-4o-mini")
api_version = os.getenv("AZURE_OPENAI_API_VERSION")

# Create an AI agent following the standard Microsoft Agent Framework pattern
agent = OpenAIChatCompletionClient(
    azure_endpoint=endpoint,
    model=deployment_name,
    api_version=api_version,
    credential=DefaultAzureCredential()
).as_agent(
    instructions="You are good at telling jokes.",
    name="Joker"
)

# Configure the function app to host the agent with durable thread management
# This automatically creates HTTP endpoints and manages state persistence
app = AgentFunctionApp(agents=[agent])

إحضار الحوسبة الخاصة بك / استضافة ذاتية الاستضافة

استخدم استضافة إحضار الحوسبة الخاصة بك عندما تريد قدرات Durable Extension دون استخدام نموذج البرمجة دالات Azure. في هذا النموذج، تبدأ العملية الخاصة بك عامل Durable Task، وتسجل عوامل دائمة أو مهام سير عمل، وتتصل بخلفية Durable Task Scheduler. يمكن تشغيل التعليمات البرمجية للعميل في نفس العملية أو في خدمة منفصلة.

يستخدم العمال المستضافون ذاتيا نفس قدرات Durable Extension الأساسية مثل استضافة دالات Azure: نقاط التفتيش والاستئناف، وتنسيق العامل المحدد، وسير عمل إطار عمل العامل الدائم، والانتظارات البشرية في الحلقة، والدفق الموثوق به، وتنظيف جلسة العمل الخاملة، ورؤية لوحة المعلومات، والتنفيذ الموزع عبر مثيلات العامل عديمة الحالة. المضيف الخاص بك مسؤول عن كشف واجهات برمجة التطبيقات الخاصة به، وإدارة دورة الحياة، والشبكات، والمصادقة، ونموذج النشر.

تكوين المضيف الخاص بك مع حزمة تكامل Durable Task الأساسية. استخدم ConfigureDurableAgents للوكلاء الدائمين ولتدفقات ConfigureDurableWorkflows عمل إطار عمل عامل Microsoft المستندة إلى الرسم البياني.

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

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

await host.StartAsync();

راجع نماذج وحدة تحكم .NET Durable Agentsوعينات وحدة تحكم .NET Durable Workflows للحصول على أمثلة مستضافة ذاتيا قابلة للتشغيل.

استخدم حزمة تكامل Durable Task لتشغيل عملية عامل تسجل الوكلاء وتستمع للطلبات. يمكن أن تتصل التعليمات البرمجية للعميل بنفس مركز مهام Durable Task Scheduler من عملية أخرى.

from agent_framework.azure import DurableAIAgentWorker
from durabletask.azuremanaged.worker import DurableTaskSchedulerWorker

worker = DurableTaskSchedulerWorker(
    host_address="http://localhost:8080",
    secure_channel=False,
    taskhub="default",
)

agent_worker = DurableAIAgentWorker(worker)
agent_worker.add_agent(agent)

worker.start()

راجع نماذج Python Durable Task للحصول على أمثلة العميل العامل، بما في ذلك استضافة عامل واحد، والتوجيه متعدد العوامل، والتدفق الموثوق به، وتسلسل التزامن، والتزامن، والمشروطات، وأنماط الإنسان في التكرار الحلقي.

مهام سير عمل Durable Agent Framework

لا تقتصر القدرة على الصمود على التنسيقات الدائمة. Microsoft يمكن أيضا جعل مهام سير عمل Agent Framework التي تم إنشاؤها باستخدام نموذج سير العمل المستند إلى الرسم البياني دائمة. لا يتكرر تنفيذ سير عمل نقاط التحقق Durable Extension لذلك المنفذ المكتمل وخطوات العامل بعد إعادة تشغيل العملية أو فشلها.

استخدم التنسيقات الدائمة عندما تريد التنسيق الإلزامي مع التفريع المستند إلى التعليمات البرمجية والموقتات والأنشطة والأحداث الخارجية. استخدم مهام سير عمل إطار عمل العامل الدائم عندما تريد رسما بيانيا تعريفيا للمنفذين والوكلاء مع التوجيه المطبعي أو توزيع المهام/المروحة أو الحواف الشرطية أو أحداث سير العمل أو الحالة المشتركة أو مهام سير العمل الفرعية أو منافذ طلب human-in-the-loop.

Note

تختلف مهام سير عمل Durable Agent Framework عن تخزين نقاط التحقق في مهام سير العمل القياسية. يساعد تخزين نقطة التحقق على استئناف تشغيل سير العمل في وقت تشغيل إطار عمل العامل. يقوم Durable Extension بتشغيل سير العمل على البنية الأساسية للمهمة الدائمة بحيث يتم التحقق من تقدم سير العمل واسترداده عبر العمال الدائمين الموزعين. للاطلاع على نقاط التحقق القياسية لسير العمل، راجع نقاط التحقق والاستئناس.

تسجيل مهام سير العمل المستندة إلى الرسم البياني مع ConfigureDurableWorkflows للتطبيقات المستضافة ذاتيا أو ConfigureDurableWorkflows على منشئ تطبيقات الوظائف لاستضافة دالات Azure.

راجع نماذج دالات Azure .NET Durable Workflowsوعينات وحدة تحكم .NET Durable Workflows.

تتوفر نماذج سير عمل دائمة لاستضافة دالات Azure، بما في ذلك الحالة المشتركة، وعدم وجود حالة مشتركة، وتنفيذ سير العمل المتوازي، وسير العمل البشري في التكرار الحلقي.

راجع نماذج Python دالات Azure لأمثلة العامل الدائم والتزامن وخادم MCP وسير العمل.

Samples

اللغة نموذج الاستضافة Samples
C#‎ دالات Azure .NET Durable Agents - دالات Azure.NET Durable Workflows - دالات Azure
C#‎ إحضار الحوسبة الخاصة بك / المستضافة ذاتيا .NET Durable Agents - تطبيقات وحدة التحكم، .NET Durable Workflows - تطبيقات وحدة التحكم
Python دالات Azure عينات Python دالات Azure
Python إحضار الحوسبة الخاصة بك / المستضافة ذاتيا عينات Python Durable Task
Go غير مدعوم حاليا راجع مستودع Agent Framework Go للحصول على أحدث حالة.

مؤشرات ترابط عامل الحالة مع محفوظات المحادثات

تحتفظ العوامل بمؤشرات الترابط المستمرة التي تنجو عبر تفاعلات متعددة. يتم تحديد كل مؤشر ترابط بواسطة معرف مؤشر ترابط فريد ويخزن محفوظات المحادثات الكاملة في تخزين دائم تديره البنية الأساسية للمهمة الدائمة، مثل Durable Task Scheduler.

يتيح هذا النمط استمرارية المحادثة حيث يتم الاحتفاظ بحالة العامل من خلال تعطل العملية وإعادة تشغيلها، ما يسمح بالاحتفاظ بمحفوظات المحادثات الكاملة عبر مؤشرات ترابط المستخدم. يضمن التخزين الدائم أنه حتى في حالة إعادة تشغيل عملية المضيف أو استئناف العمل على مثيل عامل مختلف، تستمر المحادثة بسلاسة من حيث توقفت.

استخدم تنظيف مدة البقاء (TTL) لأحمال العمل التي تحتاج إلى استمرارية دائمة أثناء الاستخدام النشط ولكن يجب تنظيف المحادثات الخاملة تلقائيا. يمنع التنظيف المستند إلى TTL الجلسات غير المستخدمة ومحفوظات المحادثات من التراكم إلى أجل غير مسمى مع الحفاظ على حالة جلسة العمل النشطة.

يوضح المثال دالات Azure التالي طلبات HTTP متعددة إلى نفس مؤشر الترابط، مع إظهار كيفية استمرار سياق المحادثة. في التطبيقات المستضافة ذاتيا، استخدم واجهات برمجة تطبيقات عميل Durable Task من العملية أو الخدمة الخاصة بك.

# First interaction - start a new thread
curl -X POST https://your-function-app.azurewebsites.net/api/agents/Joker/run \
  -H "Content-Type: text/plain" \
  -d "Tell me a joke about pirates"

# Response includes thread ID in x-ms-thread-id header and joke as plain text
# HTTP/1.1 200 OK
# Content-Type: text/plain
# x-ms-thread-id: @dafx-joker@263fa373-fa01-4705-abf2-5a114c2bb87d
#
# Why don't pirates shower before they walk the plank? Because they'll just wash up on shore later!

# Second interaction - continue the same thread with context
curl -X POST "https://your-function-app.azurewebsites.net/api/agents/Joker/run?thread_id=@dafx-joker@263fa373-fa01-4705-abf2-5a114c2bb87d" \
  -H "Content-Type: text/plain" \
  -d "Tell me another one about the same topic"

# Agent remembers the pirate context from the first message and responds with plain text
# What's a pirate's favorite letter? You'd think it's R, but it's actually the C!

يتم الحفاظ على حالة العامل في التخزين الدائم، مما يتيح التنفيذ الموزع عبر مثيلات متعددة. يمكن لأي مثيل استئناف تنفيذ العامل بعد الانقطاعات أو الفشل، ما يضمن التشغيل المستمر.

تدفق موثوق به

يدعم Durable Extension تدفقا موثوقا للتطبيقات التي تحتاج إلى تسليم الرمز المميز في الوقت الحقيقي مع ضمانات التسليم الدائم. يمكن استخدام الدفق مع الملحق الأساسي في كلا نموذجي الاستضافة، ولكن المضيفين الموزعين يحتاجون إلى وسيط دفق موثوق به، مثل Redis، بحيث يمكن تسليم تدفقات الرمز المميز باستمرار عبر عمليات إعادة تشغيل العملية أو إعادة الاتصال أو تغييرات العامل.

استخدم الدفق الموثوق به عندما تعتمد تجربة المستخدم على الاستجابات المتزايدة، ولكن حمل العمل لا يزال يحتاج إلى دلالات تنفيذ دائمة. للحصول على أمثلة قابلة للتشغيل، راجع نماذج Python Durable Task، والتي تتضمن أنماط تدفق موثوقة.

تنسيقات محددة متعددة العوامل

يدعم Durable Extension إنشاء مهام سير عمل محددة تنسق عوامل متعددة باستخدام تنسيقات Durable Task. في دالات Azure، تستخدم هذه التنسيقات Durable Functions؛ في إحضار مضيفي الحساب الخاص بك، يتم تشغيلها من خلال عامل المهام الدائمة والعميل الذي تقوم بتكوينه.

التنسيقات هي مهام سير عمل تستند إلى التعليمات البرمجية تنسق عمليات متعددة (مثل استدعاءات العامل أو استدعاءات واجهة برمجة التطبيقات الخارجية أو المؤقتات) بطريقة موثوقة. تعني محددة أن التعليمات البرمجية للتنسيق تنفذ بنفس الطريقة عند إعادة تشغيلها بعد الفشل، ما يجعل مهام سير العمل موثوقة وقابلة لتصحيح الأخطاء - عند إعادة تشغيل محفوظات التزامن، يمكنك أن ترى بالضبط ما حدث في كل خطوة.

تنفذ التزامنات بشكل موثوق، ونجاة من الفشل بين استدعاءات العامل، وتوفر عمليات يمكن التنبؤ بها وقابلة للتكرار. وهذا يجعلها مثالية للسيناريوهات المعقدة متعددة العوامل حيث تحتاج إلى ترتيب تنفيذ مضمون والتسامح مع الخطأ.

تنسيقات متتالية

في النمط التسلسلي متعدد العوامل، يتم تنفيذ الوكلاء المتخصصين بترتيب معين، حيث يمكن أن يؤثر إخراج كل عامل على تنفيذ العامل التالي. يدعم هذا النمط المنطق الشرطي والتفريع استنادا إلى استجابات العامل.

عند استخدام العوامل في التنسيقات، يجب استخدام context.GetAgent() واجهة برمجة التطبيقات للحصول على مثيل DurableAIAgent ، وهو فئة فرعية خاصة من النوع القياسي AIAgent الذي يلتف مع أحد الوكلاء المسجلين. DurableAIAgent يضمن برنامج التضمين تعقب استدعاءات العامل بشكل صحيح ونقاط التفتيش بواسطة إطار عمل التزامن الدائم.

using Microsoft.Azure.Functions.Worker;
using Microsoft.DurableTask;
using Microsoft.Agents.AI.DurableTask;

[Function(nameof(SpamDetectionOrchestration))]
public static async Task<string> SpamDetectionOrchestration(
    [OrchestrationTrigger] TaskOrchestrationContext context)
{
    Email email = context.GetInput<Email>();

    // Check if the email is spam
    DurableAIAgent spamDetectionAgent = context.GetAgent("SpamDetectionAgent");
    AgentSession spamSession = await spamDetectionAgent.CreateSessionAsync();

    AgentResponse<DetectionResult> spamDetectionResponse = await spamDetectionAgent.RunAsync<DetectionResult>(
        message: $"Analyze this email for spam: {email.EmailContent}",
        session: spamSession);
    DetectionResult result = spamDetectionResponse.Result;

    if (result.IsSpam)
    {
        return await context.CallActivityAsync<string>(nameof(HandleSpamEmail), result.Reason);
    }

    // Generate response for legitimate email
    DurableAIAgent emailAssistantAgent = context.GetAgent("EmailAssistantAgent");
    AgentSession emailSession = await emailAssistantAgent.CreateSessionAsync();

    AgentResponse<EmailResponse> emailAssistantResponse = await emailAssistantAgent.RunAsync<EmailResponse>(
        message: $"Draft a professional response to: {email.EmailContent}",
        session: emailSession);

    return await context.CallActivityAsync<string>(nameof(SendEmail), emailAssistantResponse.Result.Response);
}

عند استخدام العوامل في التنسيقات، يجب استخدام app.get_agent() الأسلوب للحصول على مثيل عامل دائم، وهو برنامج تضمين خاص حول أحد الوكلاء المسجلين. يضمن برنامج تضمين العامل الدائم تعقب استدعاءات العامل بشكل صحيح ونقاط التفتيش بواسطة إطار عمل التزامن الدائم.

import azure.durable_functions as df
from typing import cast
from agent_framework.azure import AgentFunctionApp
from pydantic import BaseModel

class SpamDetectionResult(BaseModel):
    is_spam: bool
    reason: str

class EmailResponse(BaseModel):
    response: str

app = AgentFunctionApp(agents=[spam_detection_agent, email_assistant_agent])

@app.orchestration_trigger(context_name="context")
def spam_detection_orchestration(context: df.DurableOrchestrationContext):
    email = context.get_input()

    # Check if the email is spam
    spam_agent = app.get_agent(context, "SpamDetectionAgent")
    spam_thread = spam_agent.create_session()

    spam_result_raw = yield spam_agent.run(
        messages=f"Analyze this email for spam: {email['content']}",
        session=spam_thread,
        options={"response_format": SpamDetectionResult},
    )
    spam_result = cast(SpamDetectionResult, spam_result_raw.get("structured_response"))

    if spam_result.is_spam:
        result = yield context.call_activity("handle_spam_email", spam_result.reason)
        return result

    # Generate response for legitimate email
    email_agent = app.get_agent(context, "EmailAssistantAgent")
    email_thread = email_agent.create_session()

    email_response_raw = yield email_agent.run(
        messages=f"Draft a professional response to: {email['content']}",
        session=email_thread,
        options={"response_format": EmailResponse},
    )
    email_response = cast(EmailResponse, email_response_raw.get("structured_response"))

    result = yield context.call_activity("send_email", email_response.response)
    return result

تنسق التزامنات العمل عبر عوامل متعددة، ما ينجو من حالات الفشل بين استدعاءات العامل. يوفر سياق التزامن أساليب لاسترداد العوامل المستضافة والتفاعل معها ضمن التنسيقات.

التنسيقات المتوازية

في النمط المتوازي متعدد العوامل، يمكنك تنفيذ عوامل متعددة بشكل متزامن ثم تجميع نتائجها. هذا النمط مفيد لجمع وجهات نظر متنوعة أو معالجة المهام الفرعية المستقلة في وقت واحد.

using Microsoft.Azure.Functions.Worker;
using Microsoft.DurableTask;
using Microsoft.Agents.AI.DurableTask;

[Function(nameof(ResearchOrchestration))]
public static async Task<string> ResearchOrchestration(
    [OrchestrationTrigger] TaskOrchestrationContext context)
{
    string topic = context.GetInput<string>();

    // Execute multiple research agents in parallel
    DurableAIAgent technicalAgent = context.GetAgent("TechnicalResearchAgent");
    DurableAIAgent marketAgent = context.GetAgent("MarketResearchAgent");
    DurableAIAgent competitorAgent = context.GetAgent("CompetitorResearchAgent");

    // Start all agent runs concurrently
    Task<AgentResponse<TextResponse>> technicalTask = 
        technicalAgent.RunAsync<TextResponse>($"Research technical aspects of {topic}");
    Task<AgentResponse<TextResponse>> marketTask = 
        marketAgent.RunAsync<TextResponse>($"Research market trends for {topic}");
    Task<AgentResponse<TextResponse>> competitorTask = 
        competitorAgent.RunAsync<TextResponse>($"Research competitors in {topic}");

    // Wait for all tasks to complete
    await Task.WhenAll(technicalTask, marketTask, competitorTask);

    // Aggregate results
    string allResearch = string.Join("\n\n", 
        technicalTask.Result.Result.Text,
        marketTask.Result.Result.Text,
        competitorTask.Result.Result.Text);

    DurableAIAgent summaryAgent = context.GetAgent("SummaryAgent");
    AgentResponse<TextResponse> summaryResponse = 
        await summaryAgent.RunAsync<TextResponse>($"Summarize this research:\n{allResearch}");

    return summaryResponse.Result.Text;
}
import azure.durable_functions as df
from agent_framework.azure import AgentFunctionApp

app = AgentFunctionApp(agents=[technical_agent, market_agent, competitor_agent, summary_agent])

@app.orchestration_trigger(context_name="context")
def research_orchestration(context: df.DurableOrchestrationContext):
    topic = context.get_input()

    # Execute multiple research agents in parallel
    technical_agent = app.get_agent(context, "TechnicalResearchAgent")
    market_agent = app.get_agent(context, "MarketResearchAgent")
    competitor_agent = app.get_agent(context, "CompetitorResearchAgent")

    technical_task = technical_agent.run(messages=f"Research technical aspects of {topic}")
    market_task = market_agent.run(messages=f"Research market trends for {topic}")
    competitor_task = competitor_agent.run(messages=f"Research competitors in {topic}")

    # Wait for all tasks to complete
    results = yield context.task_all([technical_task, market_task, competitor_task])

    # Aggregate results
    all_research = "\n\n".join([r.get('response', '') for r in results])

    summary_agent = app.get_agent(context, "SummaryAgent")
    summary = yield summary_agent.run(messages=f"Summarize this research:\n{all_research}")

    return summary.get('response', '')

يتم تعقب التنفيذ المتوازي باستخدام قائمة المهام. تضمن نقاط التفتيش التلقائية عدم تكرار أو فقدان عمليات تنفيذ العامل المكتملة في حالة حدوث فشل أثناء التجميع.

تزامنات بشرية في التكرار الحلقي

يمكن أن تتوقف تنسيقات العامل المحدد مؤقتا للإدخال البشري أو الموافقة أو المراجعة دون استهلاك موارد الحوسبة. يتيح التنفيذ الدائم للتزامنات الانتظار لأيام أو حتى أسابيع أثناء انتظار الاستجابات البشرية. عند دمجها مع الاستضافة بلا خادم، يتم تجميع جميع موارد الحوسبة أثناء فترة الانتظار، ما يلغي تكاليف الحوسبة حتى يوفر الإنسان مدخلاته.

using Microsoft.Azure.Functions.Worker;
using Microsoft.DurableTask;
using Microsoft.Agents.AI.DurableTask;

[Function(nameof(ContentApprovalWorkflow))]
public static async Task<string> ContentApprovalWorkflow(
    [OrchestrationTrigger] TaskOrchestrationContext context)
{
    string topic = context.GetInput<string>();

    // Generate content using an agent
    DurableAIAgent contentAgent = context.GetAgent("ContentGenerationAgent");
    AgentResponse<GeneratedContent> contentResponse = 
        await contentAgent.RunAsync<GeneratedContent>($"Write an article about {topic}");
    GeneratedContent draftContent = contentResponse.Result;

    // Send for human review
    await context.CallActivityAsync(nameof(NotifyReviewer), draftContent);

    // Wait for approval with timeout
    HumanApprovalResponse approvalResponse;
    try
    {
        approvalResponse = await context.WaitForExternalEvent<HumanApprovalResponse>(
            eventName: "ApprovalDecision",
            timeout: TimeSpan.FromHours(24));
    }
    catch (OperationCanceledException)
    {
        // Timeout occurred - escalate for review
        return await context.CallActivityAsync<string>(nameof(EscalateForReview), draftContent);
    }

    if (approvalResponse.Approved)
    {
        return await context.CallActivityAsync<string>(nameof(PublishContent), draftContent);
    }

    return "Content rejected";
}
import azure.durable_functions as df
from datetime import timedelta
from agent_framework.azure import AgentFunctionApp

app = AgentFunctionApp(agents=[content_agent])

@app.orchestration_trigger(context_name="context")
def content_approval_workflow(context: df.DurableOrchestrationContext):
    topic = context.get_input()

    # Generate content using an agent
    content_agent = app.get_agent(context, "ContentGenerationAgent")
    draft_content = yield content_agent.run(
        messages=f"Write an article about {topic}"
    )

    # Send for human review
    yield context.call_activity("notify_reviewer", draft_content)

    # Wait for approval with timeout
    approval_task = context.wait_for_external_event("ApprovalDecision")
    timeout_task = context.create_timer(
        context.current_utc_datetime + timedelta(hours=24)
    )

    winner = yield context.task_any([approval_task, timeout_task])

    if winner == approval_task:
        timeout_task.cancel()
        approval_data = approval_task.result
        if approval_data.get("approved"):
            result = yield context.call_activity("publish_content", draft_content)
            return result
        return "Content rejected"

    # Timeout occurred - escalate for review
    result = yield context.call_activity("escalate_for_review", draft_content)
    return result

يمكن أن تنتظر تنسيقات العامل المحدد الأحداث الخارجية، وتستمر بشكل دائم في حالتها أثناء انتظار التعليقات البشرية، والفشل المستمر، وإعادة التشغيل، وفترات الانتظار الممتدة. عند وصول الاستجابة البشرية، يستأنف التنسيق تلقائيا مع سياق المحادثة الكامل وحالة التنفيذ دون تغيير.

توفير المدخلات البشرية

لإرسال الموافقة أو الإدخال إلى تنسيق انتظار، قم برفع حدث خارجي إلى مثيل التنسيق باستخدام SDK عميل Durable Task أو نقاط نهاية ملحق دائم دالات Azure. على سبيل المثال، قد يوافق المراجع على المحتوى من خلال نموذج ويب يستدعي:

await client.RaiseEventAsync(instanceId, "ApprovalDecision", new HumanApprovalResponse 
{ 
    Approved = true,
    Feedback = "Looks great!"
});
approval_data = {
    "approved": True,
    "feedback": "Looks great!"
}
await client.raise_event(instance_id, "ApprovalDecision", approval_data)

كفاءة التكلفة

تعد مهام سير العمل البشرية في الحلقة مع عوامل دائمة فعالة للغاية من حيث التكلفة عند استضافتها على خطة استهلاك دالات Azure Flex. بالنسبة لسير عمل ينتظر 24 ساعة للموافقة عليه، فإنك تدفع فقط لبضع ثوان من وقت التنفيذ (وقت إنشاء المحتوى وإرسال الإعلام ومعالجة الاستجابة) - وليس 24 ساعة من الانتظار. أثناء فترة الانتظار، لا يتم استهلاك موارد الحوسبة.

إمكانية المراقبة مع جدولة المهام الدائمة

جدولة المهام الدائمة (DTS) هي الواجهة الخلفية الدائمة الموصى بها لوكلاءك الدائمين، وتقدم أفضل أداء، والبنية الأساسية المدارة بالكامل، وإمكانية المراقبة المضمنة من خلال لوحة معلومات واجهة المستخدم. يمكن للتطبيقات دالات Azure استخدام الواجهات الخلفية للتخزين الأخرى (مثل تخزين Azure)، ولكن تم تحسين DTS خصيصا لأحمال العمل الدائمة ويوفر أداء فائقا وقدرات مراقبة. يستخدم العمال المستضافون ذاتيا أيضا DTS للجدولة الدائمة والحالة ورؤية لوحة المعلومات.

نتائج تحليلات جلسة العامل

  • محفوظات المحادثات: عرض محفوظات المحادثة الكاملة لكل جلسة عمل عامل، بما في ذلك جميع الرسائل ومكالمات الأدوات وسياق المحادثة في أي وقت
  • توقيت المهمة: مراقبة المدة التي تستغرقها المهام المحددة وتفاعلات العامل لإكمالها

لقطة شاشة للوحة معلومات Durable Task Scheduler تعرض محفوظات دردشة الوكيل مع مؤشرات ترابط المحادثات والرسائل.

نتائج تحليلات التزامن

  • مرئيات متعددة العوامل: راجع تدفق التنفيذ عند استدعاء عوامل متخصصة متعددة مع تمثيل مرئي لعمليات التنفيذ المتوازية والتفريع الشرطي
  • محفوظات التنفيذ: الوصول إلى سجلات التنفيذ التفصيلية
  • المراقبة في الوقت الحقيقي: تعقب التنسيقات النشطة وعناصر العمل في قائمة الانتظار وحالات العامل عبر التوزيع
  • مقاييس الأداء: مراقبة أوقات استجابة العامل واستخدام الرمز المميز ومدة التزامن

لقطة شاشة للوحة معلومات Durable Task Scheduler تعرض تصور التنسيق مع تفاعلات عامل متعددة وتنفيذ سير العمل.

قدرات تصحيح الأخطاء

  • عرض مخرجات العامل المنظم ونتائج استدعاء الأداة
  • استدعاءات أدوات التتبع ونتائجها
  • مراقبة معالجة الأحداث الخارجية لسيناريوهات الإنسان في التكرار الحلقي

تمكنك لوحة المعلومات من فهم ما يفعله وكلاؤك بالضبط، وتشخيص المشكلات بسرعة، وتحسين الأداء استنادا إلى بيانات التنفيذ الحقيقي.

البرنامج التعليمي: إنشاء عامل دائم وتشغيله باستخدام دالات Azure

يوضح لك هذا البرنامج التعليمي كيفية إنشاء وتشغيل عامل ذكاء اصطناعي دائم باستخدام نموذج استضافة دالات Azure ل Durable Extension. ستقوم بإنشاء تطبيق دالات Azure يستضيف وكيلا ذو حالة مع نقاط نهاية HTTP مضمنة، وستتعرف على كيفية مراقبته باستخدام لوحة معلومات Durable Task Scheduler. بالنسبة للوكلاء المستضافين ذاتيا، راجع العينات.

المتطلبات الأساسية

قبل البدء، تأكد من أن لديك المتطلبات الأساسية التالية:

Note

يتم دعم Microsoft Agent Framework مع جميع الإصدارات المدعومة بنشاط من .NET. لأغراض هذه العينة، نوصي .NET 9 SDK أو إصدار أحدث.

تنزيل مشروع التشغيل السريع

استخدم Azure Developer CLI لتهيئة مشروع جديد من قالب التشغيل السريع للوكلاء الدائمين.

  1. أنشئ دليلا جديدا لمشروعك وانتقل إليه:

    mkdir MyDurableAgent
    cd MyDurableAgent
    

  1. تهيئة المشروع من القالب:

    azd init --template durable-agents-quickstart-dotnet
    

    عند مطالبتك باسم بيئة، أدخل اسما مثل my-durable-agent.

يؤدي هذا إلى تنزيل مشروع التشغيل السريع مع جميع الملفات الضرورية، بما في ذلك تكوين دالات Azure ورمز العامل والبنية الأساسية كقوالب تعليمات برمجية.

  1. أنشئ دليلا جديدا لمشروعك وانتقل إليه:

    mkdir MyDurableAgent
    cd MyDurableAgent
    

  1. تهيئة المشروع من القالب:

    azd init --template durable-agents-quickstart-python
    

    عند مطالبتك باسم بيئة، أدخل اسما مثل my-durable-agent.

  2. أنشئ وفعل بيئة افتراضية:

    uv venv .venv
    source .venv/bin/activate
    

Note

python3 -m venv .venvيعمل أيضا، ولكن يمكن تعليقه إلى أجل غير مسمى على Windows مع Microsoft Store Python بسبب مشكلة معروفةensurepip. استخدم uv venv .venv لتجنب ذلك.

  1. قم بتثبيت الحزم المطلوبة:

    python -m pip install -r requirements.txt
    

يؤدي هذا إلى تنزيل مشروع التشغيل السريع مع جميع الملفات الضرورية، بما في ذلك تكوين دالات Azure ورمز العامل والبنية الأساسية كقوالب تعليمات برمجية. كما أنه يعد بيئة ظاهرية مع التبعيات المطلوبة.

توفير موارد Azure

استخدم Azure Developer CLI لإنشاء موارد Azure المطلوبة لعاملك الدائم.

  1. توفير البنية الأساسية:

    azd provision
    

    ينشئ هذا الأمر:

    • خدمة Azure OpenAI مع نشر gpt-4o-mini
    • تطبيق دالات Azure مع خطة استضافة Flex Consumption
    • حساب تخزين Azure لوقت تشغيل دالات Azure والتخزين الدائم
    • مثيل Durable Task Scheduler (خطة الاستهلاك) لإدارة حالة العامل
    • تكوينات الشبكات والهوية الضرورية
  2. عند مطالبتك، حدد اشتراكك في Azure واختر موقعا للموارد.

تستغرق عملية التوفير بضع دقائق. بمجرد الانتهاء، يخزن azd معلومات المورد التي تم إنشاؤها في بيئتك.

مراجعة التعليمات البرمجية للعامل

الآن دعونا نفحص التعليمات البرمجية التي تحدد الوكيل الدائم الخاص بك.

افتح Program.cs لمشاهدة تكوين العامل:

using Azure.AI.Projects;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Agents.AI.Hosting.AzureFunctions;
using Microsoft.Azure.Functions.Worker.Builder;
using Microsoft.Extensions.Hosting;

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

// Create an AI agent following the standard Microsoft Agent Framework pattern
AIAgent agent = new AIProjectClient(new Uri(endpoint), new DefaultAzureCredential())
    .AsAIAgent(
        model: deploymentName,
        instructions: "You are a helpful assistant that can answer questions and provide information.",
        name: "MyDurableAgent");

using IHost app = FunctionsApplication
    .CreateBuilder(args)
    .ConfigureFunctionsWebApplication()
    .ConfigureDurableAgents(options => options.AddAIAgent(agent))
    .Build();
app.Run();

هذا الرمز:

  1. استرداد تكوين openAI Azure من متغيرات البيئة.
  2. إنشاء عميل Azure OpenAI باستخدام بيانات اعتماد Azure.
  3. إنشاء عامل الذكاء الاصطناعي مع إرشادات واسم.
  4. تكوين تطبيق دالات Azure لاستضافة العامل مع إدارة مؤشر ترابط دائم.

افتح function_app.py لمشاهدة تكوين العامل:

import os
from agent_framework.azure import AgentFunctionApp
from agent_framework.openai import OpenAIChatCompletionClient
from azure.identity import DefaultAzureCredential

endpoint = os.getenv("AZURE_OPENAI_ENDPOINT")
if not endpoint:
    raise ValueError("AZURE_OPENAI_ENDPOINT is not set.")
deployment_name = os.getenv("AZURE_OPENAI_CHAT_COMPLETION_MODEL", "gpt-4o-mini")
api_version = os.getenv("AZURE_OPENAI_API_VERSION")

# Create an AI agent following the standard Microsoft Agent Framework pattern
agent = OpenAIChatCompletionClient(
    azure_endpoint=endpoint,
    model=deployment_name,
    api_version=api_version,
    credential=DefaultAzureCredential()
).as_agent(
    instructions="You are a helpful assistant that can answer questions and provide information.",
    name="MyDurableAgent"
)

# Configure the function app to host the agent with durable thread management
app = AgentFunctionApp(agents=[agent])

هذا الرمز:

  • استرداد تكوين openAI Azure من متغيرات البيئة.
  • إنشاء عميل Azure OpenAI باستخدام بيانات اعتماد Azure.
  • إنشاء عامل الذكاء الاصطناعي مع إرشادات واسم.
  • تكوين تطبيق دالات Azure لاستضافة العامل مع إدارة مؤشر ترابط دائم.

العامل جاهز الآن للاستضافة في دالات Azure. ينشئ ملحق المهمة الدائمة تلقائيا نقاط نهاية HTTP للتفاعل مع الوكيل الخاص بك ويدير حالة المحادثة عبر طلبات متعددة.

تكوين الإعدادات المحلية

local.settings.json إنشاء ملف للتطوير المحلي استنادا إلى نموذج الملف المضمن في المشروع.

  1. انسخ نموذج ملف الإعدادات:

    cp local.settings.sample.json local.settings.json
    

  1. احصل على نقطة نهاية OpenAI Azure من الموارد المتوفرة:

    azd env get-value AZURE_OPENAI_ENDPOINT
    
  2. افتح local.settings.json واستبدل <your-resource-name> في AZURE_OPENAI_ENDPOINT القيمة بنقطة النهاية من الأمر السابق.

local.settings.json يجب أن تبدو كما يلي:

{
  "IsEncrypted": false,
  "Values": {
    // ... other settings ...
    "AZURE_OPENAI_ENDPOINT": "https://your-openai-resource.openai.azure.com",
    "AZURE_OPENAI_DEPLOYMENT": "gpt-4o-mini",
    "TASKHUB_NAME": "default"
  }
}

Note

local.settings.json يتم استخدام الملف للتطوير المحلي فقط ولا يتم نشره على Azure. بالنسبة إلى عمليات نشر الإنتاج، يتم تكوين هذه الإعدادات تلقائيا في تطبيق دالات Azure بواسطة قوالب البنية الأساسية.

بدء تبعيات التطوير المحلية

لتشغيل عوامل دائمة محليا، تحتاج إلى بدء خدمتين:

  • Azurite: يحاكي خدمات تخزين Azure (التي تستخدمها دالات Azure لإدارة المشغلات والحالة الداخلية).
  • محاكي جدولة المهام الدائمة (DTS): يدير الحالة الدائمة (محفوظات المحادثات وحالة التزامن) والجدولة لوكلاءك

بدء تشغيل Azurite

يحاكي Azurite خدمات تخزين Azure محليا. يستخدمه دالات Azure لإدارة الحالة الداخلية. ستحتاج إلى تشغيل هذا في نافذة محطة طرفية جديدة والحفاظ عليها قيد التشغيل أثناء تطوير وكيلك الدائم واختباره.

  1. افتح نافذة محطة طرفية جديدة واسحب صورة Azurite Docker:

    docker pull mcr.microsoft.com/azure-storage/azurite
    
  2. ابدأ تشغيل Azurite في نافذة محطة طرفية:

    docker run -p 10000:10000 -p 10001:10001 -p 10002:10002 mcr.microsoft.com/azure-storage/azurite
    

    سيبدأ Azurite ويستمع إلى المنافذ الافتراضية لخدمات Blob (10000) وقائمة الانتظار (10001) والجدول (10002).

احتفظ بنافذة المحطة الطرفية هذه مفتوحة أثناء تطوير وكيلك الدائم واختباره.

Tip

لمزيد من المعلومات حول Azurite، بما في ذلك أساليب التثبيت البديلة، راجع استخدام محاكي Azurite لتطوير تخزين Azure المحلية.

بدء تشغيل محاكي جدولة المهام الدائمة

يوفر محاكي DTS الخلفية الدائمة لإدارة حالة العامل والتزامنات. يخزن محفوظات المحادثات ويضمن استمرار حالة وكيلك عبر عمليات إعادة التشغيل. كما أنه يؤدي إلى تنسيقات ووكلاء دائمين. ستحتاج إلى تشغيل هذا في نافذة محطة طرفية جديدة منفصلة والحفاظ عليها قيد التشغيل أثناء تطوير واختبار وكيلك الدائم.

  1. افتح نافذة طرفية جديدة أخرى واسحب صورة Docker لمحاكي DTS:

    docker pull mcr.microsoft.com/dts/dts-emulator:latest
    
  2. تشغيل محاكي DTS:

    docker run -p 8080:8080 -p 8082:8082 mcr.microsoft.com/dts/dts-emulator:latest
    

    يبدأ هذا الأمر المحاكي ويعرض:

    • المنفذ 8080: نقطة نهاية gRPC لجدولة المهام الدائمة (المستخدمة من قبل تطبيق الوظائف)
    • المنفذ 8082: لوحة المعلومات الإدارية
  3. ستكون لوحة المعلومات متاحة في http://localhost:8082.

احتفظ بنافذة المحطة الطرفية هذه مفتوحة أثناء تطوير وكيلك الدائم واختباره.

Tip

لمعرفة المزيد حول محاكي DTS، بما في ذلك كيفية تكوين مراكز مهام متعددة والوصول إلى لوحة المعلومات، راجع التطوير باستخدام Durable Task Scheduler.

شغل تطبيق الوظائف

أنت الآن جاهز لتشغيل تطبيق دالات Azure الخاص بك باستخدام العامل الدائم.

  1. في نافذة محطة طرفية جديدة (مع الاحتفاظ بكل من Azurite ومحاكي DTS قيد التشغيل في نوافذ منفصلة)، انتقل إلى دليل المشروع الخاص بك.

  2. ابدأ وقت تشغيل دالات Azure:

    func start
    
  3. يجب أن تشاهد الإخراج الذي يشير إلى أن تطبيق الوظائف قيد التشغيل، بما في ذلك نقاط نهاية HTTP لعاملك:

    Functions:
         http-MyDurableAgent: [POST] http://localhost:7071/api/agents/MyDurableAgent/run
         dafx-MyDurableAgent: entityTrigger
    

تدير نقاط النهاية هذه حالة المحادثة تلقائيا - لا تحتاج إلى إنشاء كائنات مؤشر الترابط أو إدارتها بنفسك.

اختبر الوكيل محليا

الآن يمكنك التفاعل مع الوكيل الدائم الخاص بك باستخدام طلبات HTTP. يحافظ العامل على حالة المحادثة عبر طلبات متعددة، ما يتيح المحادثات متعددة الأدوار.

بدء محادثة جديدة

إنشاء مؤشر ترابط جديد وإرسال رسالتك الأولى:

curl -i -X POST http://localhost:7071/api/agents/MyDurableAgent/run \
  -H "Content-Type: text/plain" \
  -d "What are three popular programming languages?"

نموذج الاستجابة (لاحظ أن x-ms-thread-id العنوان يحتوي على معرف مؤشر الترابط):

HTTP/1.1 200 OK
Content-Type: text/plain
x-ms-thread-id: @dafx-mydurableagent@263fa373-fa01-4705-abf2-5a114c2bb87d
Content-Length: 189

Three popular programming languages are Python, JavaScript, and Java. Python is known for its simplicity and readability, JavaScript powers web interactivity, and Java is widely used in enterprise applications.

احفظ معرف مؤشر الترابط من x-ms-thread-id العنوان (على سبيل المثال، @dafx-mydurableagent@263fa373-fa01-4705-abf2-5a114c2bb87d) للطلب التالي.

تابع الحديث

إرسال رسالة متابعة إلى نفس مؤشر الترابط عن طريق تضمين معرف مؤشر الترابط كمعلمة استعلام:

curl -X POST "http://localhost:7071/api/agents/MyDurableAgent/run?thread_id=@dafx-mydurableagent@263fa373-fa01-4705-abf2-5a114c2bb87d" \
  -H "Content-Type: text/plain" \
  -d "Which one is best for beginners?"

استبدل @dafx-mydurableagent@263fa373-fa01-4705-abf2-5a114c2bb87d بمعرف مؤشر الترابط الفعلي من عنوان الاستجابة x-ms-thread-id السابقة.

عينة استجابة:

Python is often considered the best choice for beginners among those three. Its clean syntax reads almost like English, making it easier to learn programming concepts without getting overwhelmed by complex syntax. It's also versatile and widely used in education.

لاحظ أن العامل يتذكر السياق من الرسالة السابقة (لغات البرمجة الثلاث) دون الحاجة إلى تحديدها مرة أخرى. نظرا لأنه يتم تخزين حالة المحادثة بشكل دائم بواسطة Durable Task Scheduler، تستمر هذه المحفوظات حتى إذا قمت بإعادة تشغيل تطبيق الدالة أو تم استئناف المحادثة بواسطة مثيل مختلف.

المراقبة باستخدام لوحة معلومات Durable Task Scheduler

يوفر Durable Task Scheduler لوحة معلومات مضمنة لمراقبة وتصحيح أخطاء الوكلاء الدائمين. توفر لوحة المعلومات رؤية عميقة لعمليات الوكيل ومحفوظات المحادثات وتدفق التنفيذ.

الوصول إلى لوحة المعلومات

  1. افتح لوحة المعلومات لمحاكي DTS المحلي في http://localhost:8082 مستعرض الويب الخاص بك.

  2. حدد مركز المهام الافتراضي من القائمة لعرض تفاصيله.

  3. حدد أيقونة الترس في الزاوية العلوية اليسرى لفتح الإعدادات، وتأكد من تحديد الخيار تمكين صفحات العامل ضمن ميزات المعاينة .

استكشاف محادثات الوكيل

  1. في لوحة المعلومات، انتقل إلى علامة التبويب Agents .

  2. حدد مؤشر ترابط الوكيل الدائم (على سبيل المثال، mydurableagent - 263fa373-fa01-4705-abf2-5a114c2bb87d) من القائمة.

    سترى طريقة عرض مفصلة لمؤشر ترابط العامل، بما في ذلك محفوظات المحادثات الكاملة مع جميع الرسائل والاستجابات.

    لقطة شاشة للوحة معلومات Durable Task Scheduler تعرض محفوظات محادثات مؤشر ترابط العامل.

توفر لوحة المعلومات طريقة عرض المخطط الزمني لمساعدتك على فهم تدفق المحادثة. تتضمن المعلومات الرئيسية ما يلي:

  • الطوابع الزمنية والمدة لكل تفاعل
  • محتوى المطالبة والاستجابة
  • عدد الرموز المميزة المستخدمة

Tip

توفر لوحة معلومات DTS تحديثات في الوقت الحقيقي، بحيث يمكنك مشاهدة سلوك وكيلك أثناء التفاعل معه من خلال نقاط نهاية HTTP.

النشر إلى Azure

الآن بعد أن اختبرت الوكيل الدائم محليا، انشره على Azure.

  1. نشر التطبيق:

    azd deploy
    

    يقوم هذا الأمر بحزم التطبيق الخاص بك ونشره في تطبيق دالات Azure الذي تم إنشاؤه أثناء التوفير.

  2. انتظر حتى يكتمل التوزيع. سيتم تأكيد الإخراج عند تشغيل العامل في Azure.

اختبر الوكيل المنشور

بعد التوزيع، اختبر عاملك الذي يعمل في Azure.

الحصول على مفتاح الدالة

يتطلب دالات Azure مفتاح API للوظائف التي يتم تشغيلها من قبل HTTP في الإنتاج:

API_KEY=`az functionapp function keys list --name $(azd env get-value AZURE_FUNCTION_NAME) --resource-group $(azd env get-value AZURE_RESOURCE_GROUP) --function-name http-MyDurableAgent --query default -o tsv`

بدء محادثة جديدة في Azure

إنشاء مؤشر ترابط جديد وإرسال رسالتك الأولى إلى العامل المنشور:

curl -i -X POST "https://$(azd env get-value AZURE_FUNCTION_NAME).azurewebsites.net/api/agents/MyDurableAgent/run?code=$API_KEY" \
  -H "Content-Type: text/plain" \
  -d "What are three popular programming languages?"

لاحظ معرف مؤشر الترابط الذي تم إرجاعه في عنوان الاستجابة x-ms-thread-id .

متابعة المحادثة في Azure

إرسال رسالة متابعة في نفس مؤشر الترابط. استبدل <thread-id> بمعرف مؤشر الترابط من الاستجابة السابقة:

THREAD_ID="<thread-id>"
curl -X POST "https://$(azd env get-value AZURE_FUNCTION_NAME).azurewebsites.net/api/agents/MyDurableAgent/run?code=$API_KEY&thread_id=$THREAD_ID" \
  -H "Content-Type: text/plain" \
  -d "Which is easiest to learn?"

يحتفظ العامل بسياق المحادثة في Azure تماما كما فعل محليا، مما يدل على متانة حالة العامل.

مراقبة العامل المنشور

يمكنك مراقبة العامل المنشور باستخدام لوحة معلومات Durable Task Scheduler في Azure.

  1. احصل على اسم مثيل Durable Task Scheduler:

    azd env get-value DTS_NAME
    
  2. افتح مدخل Azure وابحث عن اسم Durable Task Scheduler من الخطوة السابقة.

  3. في جزء النظرة العامة لمورد Durable Task Scheduler، حدد مركز المهام الافتراضي من القائمة.

  4. حدد فتح لوحة المعلومات في أعلى صفحة مركز المهام لفتح لوحة معلومات المراقبة.

  5. اعرض محادثات وكيلك تماما كما فعلت مع المحاكي المحلي.

توفر لوحة المعلومات المستضافة Azure نفس إمكانات التصحيح والمراقبة مثل المحاكي المحلي، مما يسمح لك بفحص محفوظات المحادثات واستدعاءات أدوات التتبع وتحليل الأداء في بيئة الإنتاج الخاصة بك.

البرنامج التعليمي: تنسيق العوامل الدائمة مع دالات Azure

يوضح لك هذا البرنامج التعليمي كيفية تنسيق العديد من وكلاء الذكاء الاصطناعي الدائمين باستخدام نموذج استضافة دالات Azure ونمط توزيع المهام/المروحة. ستقوم بتوسيع العامل الدائم من البرنامج التعليمي السابق لإنشاء نظام متعدد الوكلاء يعالج سؤال المستخدم، ثم يترجم الاستجابة إلى لغات متعددة في وقت واحد. للحصول على أمثلة التزامن المستضاف ذاتيا، راجع العينات.

فهم نمط التزامن

يتبع التنسيق الذي ستقوم بإنشاءه هذا التدفق:

  1. إدخال المستخدم - سؤال أو رسالة من المستخدم
  2. العامل الرئيسي - يقوم MyDurableAgent البرنامج التعليمي الأول بمعالجة السؤال
  3. توزيع المهام - يتم إرسال استجابة العامل الرئيسي بشكل متزامن إلى كل من وكيلي الترجمة
  4. وكلاء الترجمة - وكيلان متخصصان يترجمان الاستجابة (الفرنسية والإسبانية)
  5. Fan-in - يتم تجميع النتائج في استجابة JSON واحدة مع الاستجابة الأصلية والترجمات

يتيح هذا النمط المعالجة المتزامنة، ما يقلل من إجمالي وقت الاستجابة مقارنة بالترجمة التسلسلية.

تسجيل الوكلاء عند بدء التشغيل

لاستخدام العوامل بشكل صحيح في التنسيقات الدائمة، قم بتسجيلها في بدء تشغيل التطبيق. يمكن استخدامها عبر عمليات تنفيذ التزامن.

قم بتحديث الخاص بك Program.cs لتسجيل وكلاء الترجمة جنبا إلى جنب مع الموجود MyDurableAgent:

using System;
using Azure.AI.Projects;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Agents.AI.Hosting.AzureFunctions;
using Microsoft.Azure.Functions.Worker.Builder;
using Microsoft.Extensions.Hosting;

// Get the Azure OpenAI configuration
string endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT")
    ?? throw new InvalidOperationException("AZURE_OPENAI_ENDPOINT is not set.");
string deploymentName = Environment.GetEnvironmentVariable("AZURE_OPENAI_DEPLOYMENT")
    ?? "gpt-4o-mini";

// Create the Microsoft Foundry client
AIProjectClient client = new(new Uri(endpoint), new DefaultAzureCredential());

// Create the main agent from the first tutorial
AIAgent mainAgent = client.AsAIAgent(
    model: deploymentName,
    instructions: "You are a helpful assistant that can answer questions and provide information.",
    name: "MyDurableAgent");

// Create translation agents
AIAgent frenchAgent = client.AsAIAgent(
    model: deploymentName,
    instructions: "You are a translator. Translate the following text to French. Return only the translation, no explanations.",
    name: "FrenchTranslator");

AIAgent spanishAgent = client.AsAIAgent(
    model: deploymentName,
    instructions: "You are a translator. Translate the following text to Spanish. Return only the translation, no explanations.",
    name: "SpanishTranslator");

// Build and configure the Functions host
using IHost app = FunctionsApplication
    .CreateBuilder(args)
    .ConfigureFunctionsWebApplication()
    .ConfigureDurableAgents(options =>
    {
        // Register all agents for use in orchestrations and HTTP endpoints
        options.AddAIAgent(mainAgent);
        options.AddAIAgent(frenchAgent);
        options.AddAIAgent(spanishAgent);
    })
    .Build();

app.Run();

قم بتحديث الخاص بك function_app.py لتسجيل وكلاء الترجمة جنبا إلى جنب مع الموجود MyDurableAgent:

import os
from azure.identity import DefaultAzureCredential
from agent_framework.azure import AgentFunctionApp
from agent_framework.openai import OpenAIChatCompletionClient

# Get the Azure OpenAI configuration
endpoint = os.getenv("AZURE_OPENAI_ENDPOINT")
if not endpoint:
    raise ValueError("AZURE_OPENAI_ENDPOINT is not set.")
deployment_name = os.getenv("AZURE_OPENAI_CHAT_COMPLETION_MODEL", "gpt-4o-mini")
api_version = os.getenv("AZURE_OPENAI_API_VERSION")

# Create the Azure OpenAI client
chat_client = OpenAIChatCompletionClient(
    azure_endpoint=endpoint,
    model=deployment_name,
    api_version=api_version,
    credential=DefaultAzureCredential()
)

# Create the main agent from the first tutorial
main_agent = chat_client.as_agent(
    instructions="You are a helpful assistant that can answer questions and provide information.",
    name="MyDurableAgent"
)

# Create translation agents
french_agent = chat_client.as_agent(
    instructions="You are a translator. Translate the following text to French. Return only the translation, no explanations.",
    name="FrenchTranslator"
)

spanish_agent = chat_client.as_agent(
    instructions="You are a translator. Translate the following text to Spanish. Return only the translation, no explanations.",
    name="SpanishTranslator"
)

# Create the function app and register all agents
app = AgentFunctionApp(agents=[main_agent, french_agent, spanish_agent])

إنشاء دالة تزامن

تنسق دالة التزامن سير العمل عبر عوامل متعددة. يسترد الوكلاء المسجلين من السياق الدائم وينسق تنفيذهم، ويستدعي أولا العامل الرئيسي، ثم يجن إلى وكلاء الترجمة في وقت واحد.

إنشاء ملف جديد باسم AgentOrchestration.cs في دليل المشروع الخاص بك:

using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.Agents.AI;
using Microsoft.Agents.AI.DurableTask;
using Microsoft.Azure.Functions.Worker;
using Microsoft.DurableTask;

namespace MyDurableAgent;

public static class AgentOrchestration
{
    // Define a strongly-typed response structure for agent outputs
    public sealed record TextResponse(string Text);

    [Function("agent_orchestration_workflow")]
    public static async Task<Dictionary<string, string>> AgentOrchestrationWorkflow(
        [OrchestrationTrigger] TaskOrchestrationContext context)
    {
        var input = context.GetInput<string>() ?? throw new ArgumentNullException(nameof(context), "Input cannot be null");

        // Step 1: Get the main agent's response
        DurableAIAgent mainAgent = context.GetAgent("MyDurableAgent");
        AgentResponse<TextResponse> mainResponse = await mainAgent.RunAsync<TextResponse>(input);
        string agentResponse = mainResponse.Result.Text;

        // Step 2: Fan out - get the translation agents and run them concurrently
        DurableAIAgent frenchAgent = context.GetAgent("FrenchTranslator");
        DurableAIAgent spanishAgent = context.GetAgent("SpanishTranslator");

        Task<AgentResponse<TextResponse>> frenchTask = frenchAgent.RunAsync<TextResponse>(agentResponse);
        Task<AgentResponse<TextResponse>> spanishTask = spanishAgent.RunAsync<TextResponse>(agentResponse);

        // Step 3: Wait for both translation tasks to complete (fan-in)
        await Task.WhenAll(frenchTask, spanishTask);

        // Get the translation results
        TextResponse frenchResponse = (await frenchTask).Result;
        TextResponse spanishResponse = (await spanishTask).Result;

        // Step 4: Combine results into a dictionary
        var result = new Dictionary<string, string>
        {
            ["original"] = agentResponse,
            ["french"] = frenchResponse.Text,
            ["spanish"] = spanishResponse.Text
        };

        return result;
    }
}

أضف دالة التنسيق إلى الملف:function_app.py

import azure.durable_functions as df

@app.orchestration_trigger(context_name="context")
def agent_orchestration_workflow(context: df.DurableOrchestrationContext):
    """
    Orchestration function that coordinates multiple agents.
    Returns a dictionary with the original response and translations.
    """
    input_text = context.get_input()

    # Step 1: Get the main agent's response
    main_agent = app.get_agent(context, "MyDurableAgent")
    main_response = yield main_agent.run(input_text)
    agent_response = main_response.text

    # Step 2: Fan out - get the translation agents and run them concurrently
    french_agent = app.get_agent(context, "FrenchTranslator")
    spanish_agent = app.get_agent(context, "SpanishTranslator")

    parallel_tasks = [
        french_agent.run(agent_response),
        spanish_agent.run(agent_response)
    ]

    # Step 3: Wait for both translation tasks to complete (fan-in)
    translations = yield context.task_all(parallel_tasks) # type: ignore

    # Step 4: Combine results into a dictionary
    result = {
        "original": agent_response,
        "french": translations[0].text,
        "spanish": translations[1].text
    }

    return result

Note

سيتوفر الدعم لهذه الميزة قريبا. راجع مستودع Agent Framework Go للحصول على أحدث حالة.

اختبار التنسيق

تأكد من أن تبعيات التطوير المحلية من البرنامج التعليمي الأول لا تزال قيد التشغيل:

  • Azurite في نافذة طرفية واحدة
  • محاكي جدولة المهام الدائمة في نافذة طرفية أخرى

مع تشغيل تبعيات التطوير المحلية:

  1. ابدأ تشغيل تطبيق دالات Azure في نافذة طرفية جديدة:

    func start
    
  2. ينشئ ملحق Durable Functions تلقائيا نقاط نهاية HTTP مضمنة لإدارة التنسيقات. ابدأ التزامن باستخدام واجهة برمجة التطبيقات المضمنة:

    curl -X POST http://localhost:7071/runtime/webhooks/durabletask/orchestrators/agent_orchestration_workflow \
      -H "Content-Type: application/json" \
      -d '"\"What are three popular programming languages?\""'
    

  1. تتضمن الاستجابة عناوين URL لإدارة مثيل التنسيق:

    {
      "id": "abc123def456",
      "statusQueryGetUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/abc123def456",
      "sendEventPostUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/abc123def456/raiseEvent/{eventName}",
      "terminatePostUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/abc123def456/terminate",
      "purgeHistoryDeleteUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/abc123def456"
    }
    
  2. الاستعلام عن حالة التزامن باستخدام statusQueryGetUri (استبدل abc123def456 بمعرف المثيل الفعلي):

    curl http://localhost:7071/runtime/webhooks/durabletask/instances/abc123def456
    

  1. اقص نقطة نهاية الحالة حتى runtimeStatus تكون Completed. عند الانتهاء، سترى إخراج التنسيق مع استجابة العامل الرئيسي وترجماته:

    {
      "name": "agent_orchestration_workflow",
      "instanceId": "abc123def456",
      "runtimeStatus": "Completed",
      "output": {
        "original": "Three popular programming languages are Python, JavaScript, and Java. Python is known for its simplicity...",
        "french": "Trois langages de programmation populaires sont Python, JavaScript et Java. Python est connu pour sa simplicité...",
        "spanish": "Tres lenguajes de programación populares son Python, JavaScript y Java. Python es conocido por su simplicidad..."
      }
    }
    

مراقبة التنسيق في لوحة المعلومات

توفر لوحة معلومات Durable Task Scheduler رؤية في التنسيق الخاص بك:

  1. افتح http://localhost:8082 في متصفحك.

  2. حدد مركز المهام "الافتراضي".

  3. حدد علامة التبويب "Orchestrations".

  4. ابحث عن مثيل التنسيق في القائمة.

  5. حدد المثيل الذي تريد رؤيته:

    • المخطط الزمني للتنسيق
    • تنفيذ العامل الرئيسي متبوعا بوكلاء الترجمة المتزامنين
    • تنفيذ كل عامل (MyDurableAgent، ثم المترجمون الفرنسيون والإسبان)
    • أنماط توزيع المروحة والمروحة مرئية
    • التوقيت والمدة لكل خطوة

نشر التنسيق إلى Azure

انشر التطبيق المحدث باستخدام Azure Developer CLI:

azd deploy

يؤدي هذا إلى نشر التعليمات البرمجية المحدثة باستخدام دالة التنسيق الجديدة والوكلاء الإضافيين إلى تطبيق دالات Azure الذي تم إنشاؤه في البرنامج التعليمي الأول.

اختبار التزامن المنشور

بعد التوزيع، اختبر التزامن الذي يعمل في Azure.

  1. احصل على مفتاح النظام للملحق الدائم:

    SYSTEM_KEY=$(az functionapp keys list --name $(azd env get-value AZURE_FUNCTION_NAME) --resource-group $(azd env get-value AZURE_RESOURCE_GROUP) --query "systemKeys.durabletask_extension" -o tsv)
    

  1. ابدأ التزامن باستخدام واجهة برمجة التطبيقات المضمنة:

    curl -X POST "https://$(azd env get-value AZURE_FUNCTION_NAME).azurewebsites.net/runtime/webhooks/durabletask/orchestrators/agent_orchestration_workflow?code=$SYSTEM_KEY" \
      -H "Content-Type: application/json" \
      -d '"\"What are three popular programming languages?\""'
    

  1. statusQueryGetUri استخدم من الاستجابة للاستقصاء لإكمال النتائج وعرضها مع الترجمات.

الخطوات التالية

موارد إضافية: