मल्टी-एजेंट सिस्टम

विशेषज्ञ एजेंटों को टीमों में संयोजित करके परिष्कृत एप्लिकेशन बनाएं।

एजेंट पदानुक्रम अवलोकन

Rendering architecture…

आप क्या बनाएंगे

इस गाइड में, आप एक ग्राहक सेवा प्रणाली बनाएंगे जहाँ एक समन्वयक (coordinator) प्रश्नों को विशेषज्ञों (specialists) तक पहुँचाता है:

                        ┌─────────────────────┐
       User Query       │                     │
      ────────────────▶ │    COORDINATOR      │
                        │  "Route to expert"  │
                        └──────────┬──────────┘
                                   │
                   ┌───────────────┴───────────────┐
                   │                               │
                   ▼                               ▼
        ┌──────────────────┐            ┌──────────────────┐
        │  BILLING AGENT   │            │  SUPPORT AGENT   │
        │                  │            │                  │
        │  💰 Payments     │            │  🔧 Tech Issues  │
        │  📄 Invoices     │            │  🐛 Bug Reports  │
        │  💳 Subscriptions│            │  ❓ How-To       │
        └──────────────────┘            └──────────────────┘

मुख्य अवधारणाएँ:

  • समन्वयक (Coordinator) - सभी अनुरोध प्राप्त करता है, तय करता है कि उन्हें कौन संभालेगा
  • विशेषज्ञ (Specialists) - केंद्रित एजेंट जो विशिष्ट डोमेन में उत्कृष्ट होते हैं
  • हस्तांतरण (Transfer) - समन्वयक से विशेषज्ञ को निर्बाध हस्तांतरण

त्वरित शुरुआत

1. अपना प्रोजेक्ट बनाएं

cargo new multi_agent_demo
cd multi_agent_demo

Cargo.toml में निर्भरताएँ जोड़ें:

[dependencies]
adk-rust = "2.0.0"
tokio = { version = "1", features = ["full"] }
dotenvy = "0.15"

अपनी API कुंजी के साथ .env बनाएं:

echo 'GOOGLE_API_KEY=your-api-key' > .env

2. ग्राहक सेवा उदाहरण

यहाँ एक पूर्ण कार्यशील उदाहरण दिया गया है:

use adk_rust::prelude::*;
use adk_rust::Launcher;
use std::sync::Arc;

#[tokio::main]
async fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
    dotenvy::dotenv().ok();
    let api_key = std::env::var("GOOGLE_API_KEY")?;
    let model = Arc::new(GeminiModel::new(&api_key, "gemini-2.5-flash")?);

    // Specialist: Billing Agent
    let billing_agent = LlmAgentBuilder::new("billing_agent")
        .description("Handles billing questions: payments, invoices, subscriptions, refunds")
        .instruction("You are a billing specialist. Help customers with:\n\
                     - Invoice questions and payment history\n\
                     - Subscription plans and upgrades\n\
                     - Refund requests\n\
                     - Payment method updates\n\
                     Be professional and provide clear information about billing matters.")
        .model(model.clone())
        .build()?;

    // Specialist: Technical Support Agent
    let support_agent = LlmAgentBuilder::new("support_agent")
        .description("Handles technical support: bugs, errors, troubleshooting, how-to questions")
        .instruction("You are a technical support specialist. Help customers with:\n\
                     - Troubleshooting errors and bugs\n\
                     - How-to questions about using the product\n\
                     - Configuration and setup issues\n\
                     - Performance problems\n\
                     Be patient and provide step-by-step guidance.")
        .model(model.clone())
        .build()?;

    // Coordinator: Routes to appropriate specialist
    let coordinator = LlmAgentBuilder::new("coordinator")
        .description("Main customer service coordinator")
        .instruction("You are a customer service coordinator. Analyze each customer request:\n\n\
                     - For BILLING questions (payments, invoices, subscriptions, refunds):\n\
                       Transfer to billing_agent\n\n\
                     - For TECHNICAL questions (errors, bugs, how-to, troubleshooting):\n\
                       Transfer to support_agent\n\n\
                     - For GENERAL greetings or unclear requests:\n\
                       Respond yourself and ask clarifying questions\n\n\
                     When transferring, briefly acknowledge the customer and explain the handoff.")
        .model(model.clone())
        .sub_agent(Arc::new(billing_agent))
        .sub_agent(Arc::new(support_agent))
        .build()?;

    println!("🏢 Customer Service Center");
    println!("   Coordinator → Billing Agent | Support Agent");
    println!();

    Launcher::new(Arc::new(coordinator)).run().await?;
    Ok(())
}

उदाहरण इंटरैक्शन:

You: I have a question about my last invoice

[Agent: coordinator]
Assistant: I'll connect you with our billing specialist to help with your invoice question.

[Agent: billing_agent]
Assistant: Hello! I can help you with your invoice. What specific question do you have about your last invoice?

You: Why was I charged twice?

[Agent: billing_agent]
Assistant: I understand your concern about the duplicate charge. Let me help you investigate this...

मल्टी-एजेंट ट्रांसफर कैसे काम करता है

बड़ी तस्वीर

जब आप एक पैरेंट एजेंट में सब-एजेंट जोड़ते हैं, तो LLM को कार्यों को सौंपने (delegate) की क्षमता मिलती है:

                    ┌─────────────────────┐
    User Message    │                     │
   ─────────────────▶    COORDINATOR      │
                    │                     │
                    └──────────┬──────────┘
                               │
           "This is a billing question..."
                               │
              ┌────────────────┴────────────────┐
              │                                 │
              ▼                                 ▼
   ┌──────────────────┐              ┌──────────────────┐
   │  billing_agent   │              │  support_agent   │
   │  💰 Payments     │              │  🔧 Tech Issues  │
   │  📄 Invoices     │              │  🐛 Bug Reports  │
   └──────────────────┘              └──────────────────┘

चरण-दर-चरण हस्तांतरण प्रवाह

यहाँ ठीक वही बताया गया है जो तब होता है जब कोई उपयोगकर्ता बिलिंग संबंधी प्रश्न पूछता है:

┌──────────────────────────────────────────────────────────────────────┐
│ STEP 1: User sends message                                           │
├──────────────────────────────────────────────────────────────────────┤
│                                                                      │
│   User: "Why was I charged twice on my invoice?"                     │
│                                                                      │
│                              ↓                                       │
│                                                                      │
│   ┌──────────────────────────────────────┐                          │
│   │         COORDINATOR AGENT            │                          │
│   │  Receives message first              │                          │
│   └──────────────────────────────────────┘                          │
│                                                                      │
└──────────────────────────────────────────────────────────────────────┘
                              ↓
┌──────────────────────────────────────────────────────────────────────┐
│ STEP 2: LLM analyzes and decides to transfer                         │
├──────────────────────────────────────────────────────────────────────┤
│                                                                      │
│   🧠 LLM thinks: "This is about an invoice charge..."                │
│                  "Invoice = billing topic..."                        │
│                  "I should transfer to billing_agent"                │
│                                                                      │
│   📞 LLM calls: transfer_to_agent(agent_name="billing_agent")        │
│                                                                      │
└──────────────────────────────────────────────────────────────────────┘
                              ↓
┌──────────────────────────────────────────────────────────────────────┐
│ STEP 3: Runner detects transfer and invokes target                   │
├──────────────────────────────────────────────────────────────────────┤
│                                                                      │
│   ┌─────────┐     transfer event      ┌─────────────────┐           │
│   │ Runner  │ ─────────────────────▶  │  billing_agent  │           │
│   └─────────┘   (same user message)   └─────────────────┘           │
│                                                                      │
│   • Runner finds "billing_agent" in agent tree                       │
│   • Creates new context with SAME user message                       │
│   • Invokes billing_agent immediately                                │
│                                                                      │
└──────────────────────────────────────────────────────────────────────┘
                              ↓
┌──────────────────────────────────────────────────────────────────────┐
│ STEP 4: Target agent responds                                        │
├──────────────────────────────────────────────────────────────────────┤
│                                                                      │
│   ┌─────────────────────────────────────────┐                       │
│   │           billing_agent responds        │                       │
│   │                                         │                       │
│   │  "I can help with your duplicate        │                       │
│   │   charge. Let me investigate..."        │                       │
│   └─────────────────────────────────────────┘                       │
│                                                                      │
│   ✅ User sees seamless response - no interruption!                  │
│                                                                      │
└──────────────────────────────────────────────────────────────────────┘

यह कैसे काम करता है

घटकभूमिका
.sub_agent()मूल के तहत विशेषज्ञों को पंजीकृत करता है
transfer_to_agent toolजब उप-एजेंट मौजूद होते हैं तो स्वतः इंजेक्ट किया जाता है
Agent विवरणLLM को यह तय करने में मदद करता है कि कौन सा Agent क्या संभालता है
Runnerस्थानांतरण घटनाओं का पता लगाता है और लक्ष्य Agent को आमंत्रित करता है
साझा Sessionस्थानांतरणों में स्थिति और इतिहास संरक्षित रहता है

सब-एजेंट जोड़ने से पहले बनाम बाद में

सब-एजेंट के बिना - एक एजेंट सब कुछ करता है:

User ──▶ coordinator ──▶ Response (handles billing AND support)

सब-एजेंट के साथ - विशेषज्ञ अपने डोमेन को संभालते हैं:

User ──▶ coordinator ──▶ billing_agent ──▶ Response (billing expert)
                    ──▶ support_agent ──▶ Response (tech expert)

पदानुक्रमित मल्टी-एजेंट सिस्टम

जटिल परिदृश्यों के लिए, आप बहु-स्तरीय पदानुक्रम बना सकते हैं। प्रत्येक एजेंट के अपने सब-एजेंट हो सकते हैं, जिससे एक ट्री बनता है:

दृश्य: 3-स्तरीय सामग्री टीम

                    ┌─────────────────────┐
                    │  PROJECT MANAGER    │  ← Level 1: Top-level coordinator
                    │  "Manage projects"  │
                    └──────────┬──────────┘
                               │
                               ▼
                    ┌─────────────────────┐
                    │  CONTENT CREATOR    │  ← Level 2: Mid-level coordinator  
                    │  "Coordinate R&W"   │
                    └──────────┬──────────┘
                               │
              ┌────────────────┴────────────────┐
              │                                 │
              ▼                                 ▼
   ┌──────────────────┐              ┌──────────────────┐
   │   RESEARCHER     │              │     WRITER       │  ← Level 3: Specialists
   │                  │              │                  │
   │  📚 Gather facts │              │  ✍️ Write content │
   │  🔍 Analyze data │              │  📝 Polish text  │
   │  📊 Find sources │              │  🎨 Style & tone │
   └──────────────────┘              └──────────────────┘

अनुरोध कैसे नीचे प्रवाहित होते हैं

User: "Create a blog post about electric vehicles"
                        │
                        ▼
┌─────────────────────────────────────────────────────────────┐
│  PROJECT MANAGER: "This is a content task"                  │
│  → transfers to content_creator                             │
└─────────────────────────────────────────────────────────────┘
                        │
                        ▼
┌─────────────────────────────────────────────────────────────┐
│  CONTENT CREATOR: "Need research first, then writing"       │
│  → transfers to researcher                                  │
└─────────────────────────────────────────────────────────────┘
                        │
                        ▼
┌─────────────────────────────────────────────────────────────┐
│  RESEARCHER: "Here's what I found about EVs..."             │
│  → provides research summary                                │
└─────────────────────────────────────────────────────────────┘

पूर्ण उदाहरण कोड

use adk_rust::prelude::*;
use adk_rust::Launcher;
use std::sync::Arc;

#[tokio::main]
async fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
    dotenvy::dotenv().ok();
    let api_key = std::env::var("GOOGLE_API_KEY")?;
    let model = Arc::new(GeminiModel::new(&api_key, "gemini-2.5-flash")?);

    // Level 3: Leaf specialists
    let researcher = LlmAgentBuilder::new("researcher")
        .description("Researches topics and gathers comprehensive information")
        .instruction("You are a research specialist. When asked to research a topic:\n\
                     - Gather key facts and data\n\
                     - Identify main themes and subtopics\n\
                     - Note important sources or references\n\
                     Provide thorough, well-organized research summaries.")
        .model(model.clone())
        .build()?;

    let writer = LlmAgentBuilder::new("writer")
        .description("Writes polished content based on research")
        .instruction("You are a content writer. When asked to write:\n\
                     - Create engaging, clear content\n\
                     - Use appropriate tone for the audience\n\
                     - Structure content logically\n\
                     - Polish for grammar and style\n\
                     Produce professional, publication-ready content.")
        .model(model.clone())
        .build()?;

    // Level 2: Content coordinator
    let content_creator = LlmAgentBuilder::new("content_creator")
        .description("Coordinates content creation by delegating research and writing")
        .instruction("You are a content creation lead. For content requests:\n\n\
                     - If RESEARCH is needed: Transfer to researcher\n\
                     - If WRITING is needed: Transfer to writer\n\
                     - For PLANNING or overview: Handle yourself\n\n\
                     Coordinate between research and writing phases.")
        .model(model.clone())
        .sub_agent(Arc::new(researcher))
        .sub_agent(Arc::new(writer))
        .build()?;

    // Level 1: Top-level manager
    let project_manager = LlmAgentBuilder::new("project_manager")
        .description("Manages projects and coordinates with content team")
        .instruction("You are a project manager. For incoming requests:\n\n\
                     - For CONTENT creation tasks: Transfer to content_creator\n\
                     - For PROJECT STATUS or general questions: Handle yourself\n\n\
                     Keep track of overall project goals and deadlines.")
        .model(model.clone())
        .sub_agent(Arc::new(content_creator))
        .build()?;

    println!("📊 Hierarchical Multi-Agent System");
    println!();
    println!("   project_manager");
    println!("       └── content_creator");
    println!("               ├── researcher");
    println!("               └── writer");
    println!();

    Launcher::new(Arc::new(project_manager)).run().await?;
    Ok(())
}

एजेंट पदानुक्रम:

project_manager
└── content_creator
    ├── researcher
    └── writer

उदाहरण प्रॉम्प्ट:

  • "स्वास्थ्य सेवा में AI के बारे में एक ब्लॉग पोस्ट बनाएँ" → PM → Content Creator → Writer
  • "इलेक्ट्रिक वाहनों पर शोध करें" → PM → Content Creator → Researcher

सब-एजेंट कॉन्फ़िगरेशन

किसी भी LlmAgent में sub_agent() बिल्डर विधि का उपयोग करके सब-एजेंट जोड़ें:

let parent = LlmAgentBuilder::new("parent")
    .description("Coordinates specialized tasks")
    .instruction("Route requests to appropriate specialists.")
    .model(model.clone())
    .sub_agent(Arc::new(specialist_a))
    .sub_agent(Arc::new(specialist_b))
    .build()?;

मुख्य बिंदु:

  • प्रत्येक एजेंट के कई सब-एजेंट हो सकते हैं
  • सब-एजेंट के अपने सब-एजेंट हो सकते हैं (बहु-स्तरीय पदानुक्रम)
  • एजेंट के नाम पदानुक्रम के भीतर अद्वितीय होने चाहिए
  • विवरण LLM को यह तय करने में मदद करते हैं कि किस एजेंट को स्थानांतरित करना है

प्रभावी स्थानांतरण निर्देश लिखना

सफल एजेंट स्थानांतरण के लिए, स्पष्ट निर्देश और विवरण प्रदान करें:

पैरेंट एजेंट निर्देश

let coordinator = LlmAgentBuilder::new("coordinator")
    .description("Main customer service coordinator")
    .instruction("You are a customer service coordinator. Analyze each request:\n\n\
                 - For BILLING questions (payments, invoices, subscriptions):\n\
                   Transfer to billing_agent\n\n\
                 - For TECHNICAL questions (errors, bugs, troubleshooting):\n\
                   Transfer to support_agent\n\n\
                 - For GENERAL greetings or unclear requests:\n\
                   Respond yourself and ask clarifying questions")
    .model(model.clone())
    .sub_agent(Arc::new(billing_agent))
    .sub_agent(Arc::new(support_agent))
    .build()?;

सब-एजेंट विवरण

let billing_agent = LlmAgentBuilder::new("billing_agent")
    .description("Handles billing questions: payments, invoices, subscriptions, refunds")
    .instruction("You are a billing specialist. Help with payment and subscription issues.")
    .model(model.clone())
    .build()?;

let support_agent = LlmAgentBuilder::new("support_agent")
    .description("Handles technical support: bugs, errors, troubleshooting, how-to questions")
    .instruction("You are a technical support specialist. Provide step-by-step guidance.")
    .model(model.clone())
    .build()?;

सर्वोत्तम अभ्यास:

  • वर्णनात्मक एजेंट नामों का उपयोग करें जो उनके उद्देश्य को स्पष्ट रूप से इंगित करते हैं
  • विस्तृत विवरण लिखें - LLM इनका उपयोग स्थानांतरण तय करने के लिए करता है
  • विवरणों में विशिष्ट कीवर्ड शामिल करें जो संभावित उपयोगकर्ता अनुरोधों से मेल खाते हों
  • पैरेंट एजेंट निर्देशों में स्पष्ट प्रतिनिधिमंडल नियम दें
  • एजेंट विवरणों में सुसंगत शब्दावली का उपयोग करें

अपने मल्टी-एजेंट सिस्टम का परीक्षण करना

उदाहरण चलाना

cargo run --manifest-path examples/tier_examples/enterprise/Cargo.toml --bin 14-enterprise-multi-agent

उदाहरण परीक्षण प्रॉम्प्ट

ग्राहक सेवा:

  • "मेरे पिछले चालान के बारे में मेरा एक प्रश्न है" → billing_agent पर रूट होना चाहिए
  • "ऐप क्रैश होता रहता है" → support_agent पर रूट होना चाहिए
  • "मैं अपनी योजना कैसे अपग्रेड करूं?" → billing_agent पर रूट होना चाहिए
  • "नमस्ते, मुझे मदद चाहिए" → स्पष्टीकरण के लिए coordinator के साथ रहना चाहिए

पदानुक्रमित:

  • "स्वास्थ्य सेवा में AI के बारे में एक ब्लॉग पोस्ट बनाएँ" → PM → Content Creator → Writer
  • "इलेक्ट्रिक वाहनों के इतिहास पर शोध करें" → PM → Content Creator → Researcher
  • "हमारी वर्तमान परियोजनाओं की स्थिति क्या है?" → project_manager के साथ रहना चाहिए

स्थानांतरण समस्याओं को डीबग करना

यदि स्थानांतरण अपेक्षा के अनुसार काम नहीं कर रहे हैं:

  1. एजेंट के नाम जांचें - स्थानांतरण कॉल में बिल्कुल मेल खाना चाहिए
  2. विवरणों की समीक्षा करें - उन्हें अधिक विशिष्ट और कीवर्ड-समृद्ध बनाएं
  3. निर्देशों को स्पष्ट करें - कब स्थानांतरित करना है, इसके बारे में स्पष्ट रहें
  4. एज मामलों का परीक्षण करें - रूटिंग व्यवहार देखने के लिए अस्पष्ट अनुरोधों का प्रयास करें
  5. स्थानांतरण संकेतकों की तलाश करें - [Agent: name] दिखाता है कि कौन सा एजेंट प्रतिक्रिया दे रहा है

ग्लोबल इंस्ट्रक्शन

मूल उपयोग

let agent = LlmAgentBuilder::new("assistant")
    .description("A helpful assistant")
    .global_instruction(
        "You are a professional assistant for Acme Corp. \
         Always maintain a friendly but professional tone. \
         Our company values are: customer-first, innovation, and integrity."
    )
    .instruction("Help users with their questions and tasks.")
    .model(model.clone())
    .build()?;

ग्लोबल बनाम एजेंट इंस्ट्रक्शन

  • ग्लोबल इंस्ट्रक्शन: पदानुक्रम में सभी एजेंटों पर लागू होता है, समग्र व्यक्तित्व/संदर्भ निर्धारित करता है
  • एजेंट इंस्ट्रक्शन: प्रत्येक एजेंट के लिए विशिष्ट, उसकी विशेष भूमिका और व्यवहार को परिभाषित करता है

दोनों निर्देश वार्तालाप इतिहास में शामिल होते हैं, जिसमें ग्लोबल इंस्ट्रक्शन पहले दिखाई देता है।

डायनामिक ग्लोबल इंस्ट्रक्शन

अधिक उन्नत परिदृश्यों के लिए, आप एक ग्लोबल इंस्ट्रक्शन प्रोवाइडर का उपयोग कर सकते हैं जो निर्देश को गतिशील रूप से गणना करता है:

use adk_core::GlobalInstructionProvider;

let provider: GlobalInstructionProvider = Arc::new(|ctx| {
    Box::pin(async move {
        // Access context information
        let user_id = ctx.user_id();
        
        // Compute dynamic instruction
        let instruction = format!(
            "You are assisting user {}. Tailor your responses to their preferences.",
            user_id
        );
        
        Ok(instruction)
    })
});

let agent = LlmAgentBuilder::new("assistant")
    .description("A personalized assistant")
    .global_instruction_provider(provider)
    .model(model.clone())
    .build()?;

स्टेट वेरिएबल इंजेक्शन

ग्लोबल और एजेंट दोनों निर्देश {variable} सिंटैक्स का उपयोग करके स्टेट वेरिएबल इंजेक्शन का समर्थन करते हैं:

// Set state in a previous agent or tool
// state["company_name"] = "Acme Corp"
// state["user_role"] = "manager"

let agent = LlmAgentBuilder::new("assistant")
    .global_instruction(
        "You are an assistant for {company_name}. \
         The user is a {user_role}."
    )
    .instruction("Help with {user_role}-level tasks.")
    .model(model.clone())
    .build()?;

फ्रेमवर्क स्वचालित रूप से सेशन स्टेट से मानों को इंस्ट्रक्शन टेम्प्लेट में इंजेक्ट करता है।

सामान्य मल्टी-एजेंट पैटर्न

कोऑर्डिनेटर/डिस्पैचर पैटर्न

एक केंद्रीय एजेंट विशेष सब-एजेंटों को अनुरोध रूट करता है:

let billing = LlmAgentBuilder::new("billing")
    .description("Handles billing and payment questions")
    .model(model.clone())
    .build()?;

let support = LlmAgentBuilder::new("support")
    .description("Provides technical support")
    .model(model.clone())
    .build()?;

let coordinator = LlmAgentBuilder::new("coordinator")
    .instruction("Route requests to billing or support agents as appropriate.")
    .sub_agent(Arc::new(billing))
    .sub_agent(Arc::new(support))
    .model(model.clone())
    .build()?;

उदाहरण वार्तालाप:

User: I have a question about my last invoice

[Agent: coordinator]
Assistant: I'll connect you with our billing specialist.
🔄 [Transfer requested to: billing]

[Agent: billing]
Assistant: Hello! I can help you with your invoice. 
What specific question do you have?

User: Why was I charged twice?

[Agent: billing]
Assistant: Let me investigate that duplicate charge for you...

मुख्य बिंदु:

  • कोऑर्डिनेटर अनुरोध का विश्लेषण करता है और बिलिंग एजेंट को स्थानांतरित करता है
  • बिलिंग एजेंट उसी टर्न में तुरंत प्रतिक्रिया देता है
  • बाद के संदेश बिलिंग एजेंट के साथ जारी रहते हैं
  • स्थानांतरण संकेतक (🔄) दिखाते हैं कि हैंडऑफ़ कब होते हैं

पदानुक्रमित कार्य अपघटन

जटिल कार्यों को तोड़ने के लिए बहु-स्तरीय पदानुक्रम:

// Low-level specialists
let researcher = LlmAgentBuilder::new("researcher")
    .description("Researches topics and gathers information")
    .model(model.clone())
    .build()?;

let writer = LlmAgentBuilder::new("writer")
    .description("Writes content based on research")
    .model(model.clone())
    .build()?;

// Mid-level coordinator
let content_creator = LlmAgentBuilder::new("content_creator")
    .description("Creates content by coordinating research and writing")
    .sub_agent(Arc::new(researcher))
    .sub_agent(Arc::new(writer))
    .model(model.clone())
    .build()?;

// Top-level manager
let project_manager = LlmAgentBuilder::new("project_manager")
    .description("Manages content creation projects")
    .sub_agent(Arc::new(content_creator))
    .model(model.clone())
    .build()?;

वर्कफ़्लो एजेंटों के साथ संयोजन

मल्टी-एजेंट सिस्टम वर्कफ़्लो एजेंटों (Sequential, Parallel, Loop) के साथ अच्छी तरह से काम करते हैं:

use adk_agent::workflow::{SequentialAgent, ParallelAgent};

// Create specialized agents
let validator = LlmAgentBuilder::new("validator")
    .instruction("Validate the input data.")
    .output_key("validation_result")
    .model(model.clone())
    .build()?;

let processor = LlmAgentBuilder::new("processor")
    .instruction("Process data if {validation_result} is valid.")
    .output_key("processed_data")
    .model(model.clone())
    .build()?;

// Combine in a sequential workflow
let pipeline = SequentialAgent::new(
    "validation_pipeline",
    vec![Arc::new(validator), Arc::new(processor)]
);

// Use the pipeline as a sub-agent
let coordinator = LlmAgentBuilder::new("coordinator")
    .description("Coordinates data processing")
    .sub_agent(Arc::new(pipeline))
    .model(model.clone())
    .build()?;

एजेंटों के बीच संचार

पदानुक्रम में एजेंट साझा सेशन स्टेट के माध्यम से संवाद करते हैं:

// Agent A saves data to state
let agent_a = LlmAgentBuilder::new("agent_a")
    .instruction("Analyze the topic and save key points.")
    .output_key("key_points")  // Automatically saves output to state
    .model(model.clone())
    .build()?;

// Agent B reads data from state
let agent_b = LlmAgentBuilder::new("agent_b")
    .instruction("Expand on the key points: {key_points}")
    .model(model.clone())
    .build()?;

output_key कॉन्फ़िगरेशन स्वचालित रूप से एक एजेंट की अंतिम प्रतिक्रिया को सेशन स्टेट में सहेजता है, जिससे यह बाद के एजेंटों के लिए उपलब्ध हो जाती है।

AgentTool स्टेट और आर्टिफैक्ट फ़ॉरवर्डिंग

जब एजेंटों को टूल के रूप में रैप करने के लिए AgentTool का उपयोग किया जाता है, तो सब-एजेंटों से स्टेट परिवर्तन और आर्टिफैक्ट स्वचालित रूप से पैरेंट संदर्भ में अग्रेषित किए जाते हैं:

use adk_tool::AgentTool;

// Create a sub-agent that modifies state
let data_processor = LlmAgentBuilder::new("data_processor")
    .instruction("Process the data and save results.")
    .output_key("processed_data")
    .model(model.clone())
    .build()?;

// Wrap as a tool - state_delta and artifact_delta are forwarded
let processor_tool = AgentTool::new(Arc::new(data_processor));

// Parent agent can use the tool and see state changes
let coordinator = LlmAgentBuilder::new("coordinator")
    .instruction("Use the data_processor tool, then access {processed_data}.")
    .model(model.clone())
    .tool(Arc::new(processor_tool))
    .build()?;

AgentTool आंतरिक रूप से सब-एजेंटों को नॉन-स्ट्रीमिंग मोड (StreamingMode::None) में चलाता है, इसलिए सब-एजेंट पैरेंट को वापस करने से पहले अपनी पूरी प्रतिक्रिया जमा करता है। यह उन समस्याओं को रोकता है जहां आंशिक स्ट्रीमिंग चंक खाली परिणाम उत्पन्न कर सकते हैं।

यह AgentTool पैटर्न का उपयोग करते समय पैरेंट और चाइल्ड एजेंटों के बीच सहज डेटा प्रवाह को सक्षम बनाता है।

मल्टी-एजेंट सिस्टम चलाना

लॉन्चर का उपयोग करना

Launcher मल्टी-एजेंट सिस्टम को चलाने और परीक्षण करने का एक आसान तरीका प्रदान करता है:

use adk_rust::Launcher;

let coordinator = /* your multi-agent setup */;

Launcher::new(Arc::new(coordinator))
    .run()
    .await?;

रन मोड:

# Interactive console mode
cargo run --manifest-path examples/tier_examples/enterprise/Cargo.toml --bin 14-enterprise-multi-agent

# Use a generated API project when you need HTTP serving
cargo adk new multi_agent_api --template api

विशेषताएं:

  • एजेंट संकेतक: दिखाता है कि कौन सा एजेंट प्रतिक्रिया दे रहा है [Agent: coordinator]
  • स्थानांतरण विज़ुअलाइज़ेशन: स्थानांतरण घटनाओं को प्रदर्शित करता है 🔄 [Transfer requested to: billing_agent]
  • सहज हैंडऑफ़: लक्ष्य एजेंट स्थानांतरण के तुरंत बाद प्रतिक्रिया देता है
  • वार्तालाप इतिहास: एजेंट स्थानांतरणों में संदर्भ बनाए रखता है

स्थानांतरणों का परीक्षण करना

यह सत्यापित करने के लिए कि आपका मल्टी-एजेंट सिस्टम सही ढंग से काम करता है:

  1. एजेंट के नाम जांचें जब वे प्रतिक्रिया देते हैं तो कोष्ठकों में दिखाई देते हैं
  2. जब एजेंट हैंडऑफ़ करते हैं तो स्थानांतरण संकेतकों (🔄) की तलाश करें
  3. लक्ष्य एजेंटों से बिना फिर से प्रॉम्प्ट किए तत्काल प्रतिक्रियाओं को सत्यापित करें
  4. उचित रूटिंग सुनिश्चित करने के लिए विभिन्न अनुरोध प्रकारों का परीक्षण करें
  5. एज मामलों की जांच करें जैसे कि गैर-मौजूद एजेंटों को स्थानांतरित करना

स्थानांतरण समस्याओं को डीबग करना

यदि स्थानांतरण काम नहीं कर रहे हैं:

  • सत्यापित करें कि सब-एजेंट .sub_agent() के माध्यम से जोड़े गए हैं
  • एजेंट विवरण जांचें - LLM इनका उपयोग स्थानांतरण तय करने के लिए करता है
  • निर्देशों की समीक्षा करें - पैरेंट को यह बताना चाहिए कि कब स्थानांतरित करना है
  • एजेंट के नाम जांचें - स्थानांतरण कॉल में बिल्कुल मेल खाना चाहिए
  • इवेंट स्ट्रीम में स्थानांतरण क्रियाओं को देखने के लिए लॉगिंग सक्षम करें

सर्वोत्तम अभ्यास

  1. स्पष्ट विवरण: LLM को अच्छे स्थानांतरण निर्णय लेने में मदद करने के लिए वर्णनात्मक एजेंट नाम और विवरण लिखें
  2. विशिष्ट निर्देश: प्रत्येक एजेंट को उसकी भूमिका के लिए स्पष्ट, केंद्रित निर्देश दें
  3. ग्लोबल इंस्ट्रक्शन का उपयोग करें: सभी एजेंटों में सुसंगत व्यक्तित्व और संदर्भ सेट करें
  4. स्टेट मैनेजमेंट: एजेंट संचार के लिए output_key और स्टेट वेरिएबल का उपयोग करें
  5. पदानुक्रम की गहराई सीमित करें: बेहतर रखरखाव के लिए पदानुक्रम को उथला (2-3 स्तर) रखें
  6. स्थानांतरण तर्क का परीक्षण करें: सत्यापित करें कि एजेंट विभिन्न अनुरोधों के लिए सही सब-एजेंटों को स्थानांतरित करते हैं
  • LLM Agent - कोर एजेंट कॉन्फ़िगरेशन
  • Workflow Agents - Sequential, Parallel, और Loop एजेंट
  • Sessions - सेशन स्टेट मैनेजमेंट

पिछला: ← Workflow Agents | अगला: Graph Agents →

मल्टी-एजेंट सिस्टम - ADK-Rust दस्तावेज़ीकरण | ADK-Rust