الأدوات المضمّنة

يوفّر ADK-Rust عدة أدوات مضمّنة توسّع إمكانات الوكيل دون الحاجة إلى تنفيذ مخصّص. هذه الأدوات جاهزة للاستخدام مباشرةً، وتت integration بسلاسة مع إطار عمل الوكيل.

يتم الآن التصريح عن الأدوات الأصلية للمزوّد من خلال Tool API العادي بدلاً من كتل GenerateContentConfig.extensions الخاصة بالمزوّد. وهذا يعني أنه يمكنك مزج الأدوات الأصلية مثل Gemini Google Search وAnthropic Web Search أو البحث على الويب في Responses الخاص بـ OpenAI مع مثيلات FunctionTool العادية في الوكيل نفسه.

نظرة عامة

الأداةالغرضحالة الاستخدام
ماكرو #[tool]أدوات مخصصة دون تعليمات برمجية روتينيةأي دالة مخصصة — راجع أدوات الدوال
FunctionToolتسجيل يدوي لأداة مخصصةأدوات ديناميكية، عمليات إغلاق
GoogleSearchToolالبحث على الويب عبر Geminiاسترداد المعلومات في الوقت الفعلي
UrlContextToolإرساء Gemini URLتلخيص أو الاستدلال على URLs المباشر
GoogleMapsToolإرساء Gemini في خرائط Googleالأماكن والمسارات والسياق المحلي
GeminiCodeExecutionToolتنفيذ التعليمات البرمجية الأصلي في Geminiتنفيذ Python من جهة الخادم
WebSearchToolالبحث الأصلي عبر الويب من Anthropicالبحث عبر الويب من جهة خادم Claude
OpenAIWebSearchToolOpenAI البحث عبر الويب في Responsesالاسترجاع المستضاف بواسطة OpenAI
AgentToolتغليف الوكلاء كأدوات قابلة للاستدعاءتركيب الوكلاء وتفويض المهام
ExitLoopToolإنهاء الحلقةالتحكم في تكرارات LoopAgent
LoadArtifactsToolتحميل المصنوعات الرقميةالوصول إلى البيانات الثنائية المخزنة

GoogleSearchTool

يُمكّن GoogleSearchTool الوكلاء من البحث في الويب باستخدام Google Search. تتم معالجة هذه الأداة داخليًا بواسطة نماذج Gemini من خلال ميزة grounding، ما يعني أن البحث يُجرى على جانب الخادم بواسطة النموذج نفسه.

الاستخدام الأساسي

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

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

    // Create the GoogleSearchTool
    let search_tool = GoogleSearchTool;

    // Add to agent
    let agent = LlmAgentBuilder::new("research_assistant")
        .description("An assistant that can search the web for information")
        .instruction(
            "You are a research assistant. When asked about current events, \
             recent news, or factual information, use the google_search tool \
             to find accurate, up-to-date information."
        )
        .model(Arc::new(model))
        .tool(Arc::new(search_tool))
        .build()?;

    println!("Agent created with Google Search capability!");
    Ok(())
}

آلية العمل

بخلاف أدوات الدوال العادية، تعمل GoogleSearchTool بطريقة مختلفة:

  1. التنفيذ على جانب الخادم: تُجرى عملية البحث بواسطة ميزة grounding في Gemini، وليس محليًا
  2. الاستدعاء التلقائي: يقرر النموذج متى يجري البحث استنادًا إلى الاستعلام
  3. النتائج المدمجة: تُدمج نتائج البحث مباشرةً في استجابة النموذج

يعيد تنفيذ الأداة خطأً عند استدعائه مباشرةً، لأن البحث الفعلي يحدث داخل API في Gemini:

// This is handled internally - you don't call it directly
async fn execute(&self, _ctx: Arc<dyn ToolContext>, _args: Value) -> Result<Value> {
    Err(AdkError::tool("GoogleSearch is handled internally by Gemini"))
}

تفاصيل الأداة

الخاصيةالقيمة
الاسمgoogle_search
الوصف"يُجري بحثًا على Google لاسترداد المعلومات من الويب."
المعلماتيحددها نموذج Gemini
التنفيذمن جانب الخادم (إرساء Gemini)

حالات الاستخدام

  • الأحداث الجارية: "ماذا حدث في الأخبار اليوم؟"
  • الاستفسارات الواقعية: "ما عدد سكان طوكيو؟"
  • المعلومات الحديثة: "ما آخر التطورات في مجال الذكاء الاصطناعي؟"
  • مهام البحث: "اعثر على معلومات حول اتجاهات الطاقة المتجددة"

أمثلة على الاستفسارات

// The agent will automatically use Google Search for queries like:
// - "What's the weather forecast for New York this week?"
// - "Who won the latest championship game?"
// - "What are the current stock prices for tech companies?"

AgentTool

تغلف AgentTool أي وكيل كأداة قابلة للاستدعاء، مما يتيح التركيب بأسلوب التفويض ثم الإرجاع: يستدعي المستدعي وكيلاً فرعياً، ويتلقى نتيجته، ثم يستأنف التنفيذ. تُدمج فروقات الحالة والنتائج التي يصدرها الوكيل الفرعي في حدث الأداة الخاص بالوكيل الأب. كما تطبق جلسة الوكيل الفرعي كل حدث فوراً، بحيث ترى الخطوات اللاحقة في سير العمل المفوَّض تغييرات الحالة والسجل السابقة.

تظل الإعدادات الافتراضية القديمة معزولة ومتوافقة مع الإصدارات السابقة. وتختار الفرق المحمولة صراحةً لقطات الحالة والسجل الخاصة بالوكيل الأب، وتمرير الذاكرة، والأخطاء المُرحَّلة، وحداً أقصى محدوداً لعمق التفويض، وإسقاطات دقيقة للحالة والسجل، والتنفيذ الداخلي لعمليات التسليم الفرعية المسجلة. تظل عملية التسليم الفرعية المستهلكة ظاهرةً كحدث، لكن يُزال إجراء النقل الخاص بها قبل التمرير، حتى لا يتمكن Runner الأب من تنفيذها مرتين. تتبع بيانات تعريف الطلب، والإلغاء، والنطاقات، والأسرار، والنتائج، والحالة المشتركة المتوازية سياسة التمرير المُهيَّأة. لا ينفذ AgentTool بحد ذاته حلقة التسليم العامة الخاصة بـ Runner؛ إذ يوفر TeamSpec مُجمَّعاً سجل التسليم المتداخل الدقيق للتركيبات المختلطة. كما تختار الفرق المُجمَّعة صراحةً تمرير الأحداث المتداخلة، بحيث يظل النشاط المفوَّض ظاهراً في دفق أحداث الوكيل الأب؛ بينما يحافظ AgentTool المستقل على مخرجات الأحداث القديمة ما لم يتم اختيار forward_events(true).

لإجراء الكتابة العكسية الخاضعة للتحكم، استخدم output_state_keys بشكل مستقل عن إسقاط الإدخال state_keys. يقارن state_merge_policy(RejectConflicts) قيمة الوالد الحالية باللقطة المأخوذة عند بدء التفويض، ويرفض عمليات الكتابة المتعارضة بشكل ذري. يطبّق artifact_prefixes المبدأ نفسه لقائمة السماح على أسماء المصنوعات. تظل القيم الافتراضية المستقلة تعمل وفق مبدأ الفائز بالكتابة الأخيرة، مع إخراج غير مقيّد للتوافق مع الإصدارات السابقة؛ بينما تختار الفرق المجمّعة سياسة الحواف الخاصة بها بدقة.

الاستخدام الأساسي

use adk_rust::prelude::*;
use adk_tool::AgentTool;
use std::sync::Arc;

let sub_agent = LlmAgentBuilder::new("summarizer")
    .description("Summarizes text content")
    .instruction("Summarize the provided text concisely.")
    .model(model.clone())
    .build()?;

let agent_tool = AgentTool::new(Arc::new(sub_agent));

let coordinator = LlmAgentBuilder::new("coordinator")
    .instruction("Use the summarizer tool when asked to summarize content.")
    .model(model.clone())
    .tool(Arc::new(agent_tool))
    .build()?;

آلية العمل

  1. يقرر الوكيل الوالد استدعاء الوكيل المغلّف كأداة
  2. ينشئ AgentTool سياق استدعاء باستخدام StreamingMode::None
  3. يعمل الوكيل الفرعي حتى الاكتمال ويجمع استجابته الكاملة
  4. يُعاد نص الاستجابة إلى الوكيل الوالد
  5. تُمرَّر فروق الحالة وفروق المصنوعات إلى سياق الوالد

تفاصيل الأداة

الخاصيةالقيمة
الاسمنفس اسم الوكيل المُغلَّف
الوصفنفس وصف الوكيل المُغلَّف
المعلماتrequest: string (المدخل المُرسَل إلى الوكيل الفرعي)
تُرجع{"response": "..."} مع المخرجات النصية للوكيل الفرعي

السلوك الأساسي

  • تعمل الوكلاء الفرعيون داخليًا في وضع عدم التدفق لالتقاط الاستجابات بشكل موثوق
  • تنتقل تغييرات الحالة (output_key) من الوكيل الفرعي إلى الجلسة الأصلية
  • تُمرَّر العناصر المحفوظة بواسطة الوكيل الفرعي إلى سياق الجلسة الأصلية
  • راجع الأنظمة متعددة الوكلاء لمعرفة المزيد عن أنماط تكوين الوكلاء

ExitLoopTool

ExitLoopTool هي أداة تحكم تُستخدم مع LoopAgent للإشارة إلى الوقت الذي ينبغي فيه إنهاء عملية تكرارية. عند استدعائها، تضبط علامة escalate، مما يتسبب في خروج الحلقة.

الاستخدام الأساسي

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

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

    // Create an agent with ExitLoopTool for iterative refinement
    let refiner = LlmAgentBuilder::new("content_refiner")
        .description("Iteratively improves content quality")
        .instruction(
            "Review the content and improve it. Check for:\n\
             1. Clarity and readability\n\
             2. Grammar and spelling\n\
             3. Logical flow\n\n\
             If the content meets all quality standards, call the exit_loop tool.\n\
             Otherwise, provide an improved version."
        )
        .model(Arc::new(model))
        .tool(Arc::new(ExitLoopTool::new()))
        .build()?;

    // Use in a LoopAgent
    let loop_agent = LoopAgent::new(
        "iterative_refiner",
        vec![Arc::new(refiner)],
    ).with_max_iterations(5);

    println!("Loop agent created with exit capability!");
    Ok(())
}

آلية العمل

  1. يقيّم الوكيل ما إذا كان ينبغي المتابعة أو الخروج
  2. عندما يصبح جاهزًا للخروج، يستدعي الوكيل exit_loop
  3. تضبط الأداة actions.escalate = true وactions.skip_summarization = true
  4. يكتشف LoopAgent علامة التصعيد ويتوقف عن التكرار

تفاصيل الأداة

الخاصيةالقيمة
الاسمexit_loop
الوصف"يخرج من الحلقة. استدعِ هذه الدالة فقط عندما يُطلب منك ذلك."
المعلماتلا شيء
تُرجعكائن فارغ {}

أفضل الممارسات

  1. معايير خروج واضحة: حدّد شروطًا محددة في تعليمات الوكيل
  2. اضبط max_iterations دائمًا: امنع الحلقات اللانهائية كإجراء للسلامة
  3. تعليمات ذات معنى: ساعد الوكيل على فهم متى يخرج
// Good: Clear exit criteria
.instruction(
    "Improve the text until it:\n\
     - Has no grammatical errors\n\
     - Is under 100 words\n\
     - Uses active voice\n\
     When all criteria are met, call exit_loop."
)

// Avoid: Vague criteria
.instruction("Improve the text. Exit when done.")

LoadArtifactsTool

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

الاستخدام الأساسي

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

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

    // Create agent with artifact loading capability
    let agent = LlmAgentBuilder::new("document_analyzer")
        .description("Analyzes stored documents")
        .instruction(
            "You can load and analyze stored artifacts. \
             Use the load_artifacts tool to retrieve documents by name. \
             The tool accepts an array of artifact names."
        )
        .model(Arc::new(model))
        .tool(Arc::new(LoadArtifactsTool::new()))
        .build()?;

    println!("Agent created with artifact loading capability!");
    Ok(())
}

تفاصيل الأداة

الخاصيةالقيمة
الاسمload_artifacts
الوصف"يحمّل العناصر المادية بالاسم ويُرجع محتواها. يقبل مصفوفة من أسماء العناصر المادية."
المعلماتartifact_names: مصفوفة من السلاسل النصية
Returnsكائن يحتوي على مصفوفة artifacts

المعلمات

تتوقع الأداة كائنًا من JSON يحتوي على مصفوفة artifact_names:

{
  "artifact_names": ["document.txt", "image.png", "data.json"]
}

تنسيق الاستجابة

تعيد الأداة كائنًا يحتوي على العناصر المُحمّلة:

{
  "artifacts": [
    {
      "name": "document.txt",
      "content": "The text content of the document..."
    },
    {
      "name": "image.png",
      "content": {
        "mime_type": "image/png",
        "data": "base64-encoded-data..."
      }
    },
    {
      "name": "missing.txt",
      "error": "Artifact not found"
    }
  ]
}

المتطلبات

لكي يعمل LoadArtifactsTool، تحتاج إلى:

  1. ArtifactService مُكوَّن في المُشغِّل
  2. عناصر محفوظة مسبقًا في الخدمة
  3. إضافة الأداة إلى الوكيل
use adk_rust::prelude::*;
use std::sync::Arc;

// Set up artifact service
let artifact_service = Arc::new(InMemoryArtifactService::new());

// Configure runner with artifact service
let runner = Runner::new(agent)
    .with_artifact_service(artifact_service);

دمج الأدوات المضمّنة

يمكنك استخدام عدة أدوات مضمّنة معًا:

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

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

    // Create agent with multiple built-in tools
    let agent = LlmAgentBuilder::new("research_agent")
        .description("Research agent with search and artifact capabilities")
        .instruction(
            "You are a research agent. You can:\n\
             - Search the web using google_search for current information\n\
             - Load stored documents using load_artifacts\n\
             Use these tools to help answer questions comprehensively."
        )
        .model(Arc::new(model))
        .tool(Arc::new(GoogleSearchTool))
        .tool(Arc::new(LoadArtifactsTool::new()))
        .build()?;

    println!("Multi-tool agent created!");
    Ok(())
}

إنشاء أدوات مضمّنة مخصّصة

يمكنك إنشاء أدواتك الخاصة باتباع النمط نفسه المستخدم في الأدوات المضمّنة، وذلك بتنفيذ سمة Tool:

use adk_rust::prelude::*;
use async_trait::async_trait;
use serde_json::{json, Value};
use std::sync::Arc;

pub struct MyCustomTool;

impl MyCustomTool {
    pub fn new() -> Self {
        Self
    }
}

#[async_trait]
impl Tool for MyCustomTool {
    fn name(&self) -> &str {
        "my_custom_tool"
    }

    fn description(&self) -> &str {
        "Description of what this tool does"
    }

    async fn execute(&self, ctx: Arc<dyn ToolContext>, args: Value) -> Result<Value> {
        // Your tool logic here
        Ok(json!({ "result": "success" }))
    }
}

مرجع API

GoogleSearchTool

impl GoogleSearchTool {
    /// Create a new GoogleSearchTool instance
    pub fn new() -> Self;
}

ExitLoopTool

impl ExitLoopTool {
    /// Create a new ExitLoopTool instance
    pub fn new() -> Self;
}

LoadArtifactsTool

impl LoadArtifactsTool {
    /// Create a new LoadArtifactsTool instance
    pub fn new() -> Self;
}

impl Default for LoadArtifactsTool {
    fn default() -> Self;
}

السابق: ← أدوات الدوال | التالي: أدوات المتصفح →