LlmAgent
الـ LlmAgent هو نوع العميل الأساسي في adk-rust الذي يستخدم نموذجًا لغويًا كبيرًا (Large Language Model) للاستدلال واتخاذ القرار.
بدء سريع
أنشئ مشروعًا جديدًا:
cargo new llm_agent
cd llm_agent
أضف التبعيات إلى Cargo.toml:
[dependencies]
adk-rust = "0.2.0"
tokio = { version = "1.40", features = ["full"] }
dotenvy = "0.15"
serde_json = "1.0"
أنشئ ملف .env باستخدام مفتاح API الخاص بك:
echo 'GOOGLE_API_KEY=your-api-key' > .env
استبدل محتوى src/main.rs:
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 = GeminiModel::new(&api_key, "gemini-2.5-flash")?;
let agent = LlmAgentBuilder::new("my_agent")
.instruction("You are a helpful assistant.")
.model(Arc::new(model))
.build()?;
Launcher::new(Arc::new(agent)).run().await?;
Ok(())
}
قم بتشغيله:
cargo run
التفاعل مع عميلك (Agent)
سترى موجهًا تفاعليًا:
🤖 العميل جاهز! اكتب أسئلتك (أو 'exit' للخروج).
أنت: مرحباً! بماذا يمكنك مساعدتي؟
المساعد: مرحباً! أنا مساعد مفيد. يمكنني مساعدتك في:
- الإجابة على الأسئلة حول مواضيع مختلفة
- شرح المفاهيم بوضوح
- إجراء محادثة
ماذا تود أن تعرف؟
أنت: exit
👋 وداعاً!
تحديد سلوك Agent باستخدام التعليمات
يحدد الأسلوب instruction() شخصية وسلوك Agent الخاص بك. هذا هو موجه النظام الذي يوجه كل استجابة:
// A formal business assistant
let formal_agent = LlmAgentBuilder::new("formal_assistant")
.instruction("You are a professional business consultant. \
Use formal language. Be concise and data-driven.")
.model(Arc::new(model))
.build()?;
// A friendly coding tutor
let tutor_agent = LlmAgentBuilder::new("code_tutor")
.instruction("You are a friendly coding tutor for beginners. \
Explain concepts simply. Use examples. \
Encourage questions. Never make the user feel bad for not knowing.")
.model(Arc::new(model))
.build()?;
// A creative storyteller
let story_agent = LlmAgentBuilder::new("storyteller")
.instruction("You are a creative storyteller. \
Craft engaging narratives with vivid descriptions. \
Use plot twists and memorable characters.")
.model(Arc::new(model))
.build()?;
أمثلة على المخرجات
موجه المستخدم: "What is Rust?"
مساعد الأعمال الرسمي:
Rust is a systems programming language focused on performance, memory safety,
and concurrency. Key metrics: 0 runtime overhead, 0 garbage collection.
Adoption growing 30% YoY in enterprise. Recommended for performance-critical
applications where reliability is paramount.
معلم البرمجة الودود:
Great question! 🎉 Rust is a programming language that helps you write fast
and safe code. Think of it like a helpful friend who stops you from making
mistakes before they happen!
Here's a simple example:
let name = "Alice"; // This creates a variable
What makes Rust special is that it catches bugs at compile time, not when
your program is running. Pretty cool, right? Want me to explain more?
القصاص المبدع:
In the twilight of 2010, in a secret Mozilla laboratory, a lone developer
named Graydon Hoare breathed life into something extraordinary—a language
that would challenge the old gods of C and C++.
They called it Rust, named for a fungus that survives against all odds.
Like a phoenix rising from the ashes of segmentation faults and memory
leaks, Rust promised a new era: speed without sacrifice, power without peril.
And so, the revolution began...
قوالب التعليمات
تدعم التعليمات حقن المتغيرات باستخدام بناء الجملة {var}. يتم حل المتغيرات من حالة الجلسة في وقت التشغيل:
let agent = LlmAgentBuilder::new("personalized")
.instruction("You are helping {user_name}. Their role is {user_role}. \
Tailor your responses to their expertise level.")
.model(Arc::new(model))
.build()?;
دليل خطوة بخطوة لاستخدام القوالب:
- أنشئ Agent باستخدام متغيرات القالب في التعليمات
- قم بإعداد Runner و SessionService لإدارة الحالة
- أنشئ جلسة مع متغيرات الحالة التي تتطابق مع القالب الخاص بك
- قم بتشغيل Agent - يتم استبدال القوالب تلقائيًا
إليك مثال عملي كامل:
use adk_rust::prelude::*;
use adk_rust::runner::{Runner, RunnerConfig};
use adk_rust::session::{CreateRequest, InMemorySessionService, SessionService};
use adk_rust::futures::StreamExt;
use serde_json::json;
use std::collections::HashMap;
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 = GeminiModel::new(&api_key, "gemini-2.5-flash")?;
// 1. Agent with templated instruction
let agent = LlmAgentBuilder::new("personalized")
.instruction("You are helping {user_name}. Their role is {user_role}. \
Tailor your responses to their expertise level.")
.model(Arc::new(model))
.build()?;
// 2. Create session service and runner
let session_service = Arc::new(InMemorySessionService::new());
let runner = Runner::new(RunnerConfig {
app_name: "templating_demo".to_string(),
agent: Arc::new(agent),
session_service: session_service.clone(),
artifact_service: None,
memory_service: None,
run_config: None,
})?;
// 3. Create session with state variables
let mut state = HashMap::new();
state.insert("user_name".to_string(), json!("Alice"));
state.insert("user_role".to_string(), json!("Senior Developer"));
let session = session_service.create(CreateRequest {
app_name: "templating_demo".to_string(),
user_id: "user123".to_string(),
session_id: None,
state,
}).await?;
// 4. Run the agent - instruction becomes:
// "You are helping Alice. Their role is Senior Developer..."
let mut response_stream = runner.run(
"user123".to_string(),
session.id().to_string(),
Content::new("user").with_text("Explain async/await in Rust"),
).await?;
// Print the response
while let Some(event) = response_stream.next().await {
let event = event?;
if let Some(content) = event.content() {
for part in &content.parts {
if let Part::Text { text } = part {
print!("{}", text);
}
}
}
}
Ok(())
}
أنواع متغيرات القالب:
| النمط | مثال | المصدر |
|---|---|---|
{var} | {user_name} | حالة الجلسة |
{prefix:var} | {user:name}, {app:config} | حالة مسبوقة |
{var?} | {user_name?} | اختياري (فارغ إذا كان مفقودًا) |
{artifact.file} | {artifact.resume.pdf} | محتوى الـArtifact |
مثال على المخرجات:
القالب: "You are helping {user_name}. Their role is {user_role}."
يصبح: "You are helping Alice. Their role is Senior Developer."
سيقوم Agent بعد ذلك بالرد بمحتوى مخصص بناءً على اسم المستخدم ومستوى خبرته!
إضافة الأدوات
تمنح الأدوات وكيلك قدرات تتجاوز المحادثة - يمكنها جلب البيانات، إجراء العمليات الحسابية، البحث في الويب، أو استدعاء واجهات برمجة التطبيقات الخارجية. يقرر LlmAgent متى يستخدم أداة بناءً على طلب المستخدم.
كيف تعمل الأدوات
- يتلقى الوكيل رسالة المستخدم ← "ما هو الطقس في طوكيو؟"
- يقرر LlmAgent استدعاء الأداة ← يختار
get_weatherمع{"city": "Tokyo"} - تنفذ الأداة ← تعيد
{"temperature": "22°C", "condition": "sunny"} - يقوم LlmAgent بتنسيق الاستجابة ← "الطقس في طوكيو مشمس ودرجة الحرارة 22 درجة مئوية."
إنشاء أداة باستخدام FunctionTool
FunctionTool هي أبسط طريقة لإنشاء أداة - قم بتغليف أي دالة Rust غير متزامنة ويمكن لـ LlmAgent استدعائها. توفر اسمًا ووصفًا ودالة معالجة تتلقى وسائط JSON وتعيد نتيجة JSON.
let weather_tool = FunctionTool::new(
"get_weather", // Tool name (used by LLM)
"Get the current weather for a city", // Description (helps LLM decide when to use it)
|_ctx, args| async move { // Handler function
let city = args.get("city") // Extract arguments from JSON
.and_then(|v| v.as_str())
.unwrap_or("unknown");
Ok(json!({ "city": city, "temperature": "22°C" })) // Return JSON result
},
);
⚠️ ملاحظة: قيد حالي: الأدوات المدمجة مثل
GoogleSearchToolغير متوافقة حاليًا معFunctionToolفي نفس الوكيل. استخدم إما الأدوات المدمجة أوFunctionTools المخصصة، ولكن ليس كلاهما معًا. 💡 حل بديل: أنشئ وكلاء فرعيين منفصلين، لكل منهم نوع الأداة الخاص به، ونسق بينهم باستخدام LLMAgent رئيسي، أو وكلاء سير العمل، أو أنماط الوكلاء المتعددة.
بناء وكيل متعدد الأدوات
أنشئ مشروعًا جديدًا:
cargo new tool_agent
cd tool_agent
أضف التبعيات إلى Cargo.toml:
[dependencies]
adk-rust = { version = "0.2.0", features = ["tools"] }
tokio = { version = "1.40", features = ["full"] }
dotenvy = "0.15"
serde_json = "1.0"
أنشئ .env:
echo 'GOOGLE_API_KEY=your-api-key' > .env
استبدل src/main.rs بوكيل يحتوي على ثلاث أدوات:
use adk_rust::prelude::*;
use adk_rust::Launcher;
use serde_json::json;
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 = GeminiModel::new(&api_key, "gemini-2.5-flash")?;
// Tool 1: Weather lookup
let weather_tool = FunctionTool::new(
"get_weather",
"Get the current weather for a city. Parameters: city (string)",
|_ctx, args| async move {
let city = args.get("city").and_then(|v| v.as_str()).unwrap_or("unknown");
Ok(json!({ "city": city, "temperature": "22°C", "condition": "sunny" }))
},
);
// Tool 2: Calculator
let calculator = FunctionTool::new(
"calculate",
"Perform arithmetic. Parameters: a (number), b (number), operation (add/subtract/multiply/divide)",
|_ctx, args| async move {
let a = args.get("a").and_then(|v| v.as_f64()).unwrap_or(0.0);
let b = args.get("b").and_then(|v| v.as_f64()).unwrap_or(0.0);
let op = args.get("operation").and_then(|v| v.as_str()).unwrap_or("add");
let result = match op {
"add" => a + b,
"subtract" => a - b,
"multiply" => a * b,
"divide" => if b != 0.0 { a / b } else { 0.0 },
_ => 0.0,
};
Ok(json!({ "result": result }))
},
);
// Tool 3: Built-in Google Search (Note: Currently unsupported in ADK-Rust)
// let search_tool = GoogleSearchTool::new();
// Build agent with weather and calculator tools
let agent = LlmAgentBuilder::new("multi_tool_agent")
.instruction("You are a helpful assistant. Use tools when needed: \
- get_weather for weather questions \
- calculate for math")
.model(Arc::new(model))
.tool(Arc::new(weather_tool))
.tool(Arc::new(calculator))
// .tool(Arc::new(search_tool)) // Currently unsupported
.build()?;
Launcher::new(Arc::new(agent)).run().await?;
Ok(())
}
قم بتشغيل وكيلك:
cargo run
مثال على التفاعل
You: What's 15% of 250?
Assistant: [Using calculate tool with a=250, b=0.15, operation=multiply]
15% of 250 is 37.5.
You: What's the weather in Tokyo?
Assistant: [Using get_weather tool with city=Tokyo]
The weather in Tokyo is sunny with a temperature of 22°C.
You: Search for latest Rust features
Assistant: I don't have access to search functionality at the moment, but I can help with other questions about Rust or perform calculations!
مخرجات منظمة باستخدام JSON Schema
للتطبيقات التي تحتاج إلى بيانات منظمة، استخدم output_schema():
use adk_rust::prelude::*;
use serde_json::json;
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 = GeminiModel::new(&api_key, "gemini-2.5-flash")?;
let extractor = LlmAgentBuilder::new("entity_extractor")
.instruction("Extract entities from the given text.")
.model(Arc::new(model))
.output_schema(json!({
"type": "object",
"properties": {
"people": {
"type": "array",
"items": { "type": "string" }
},
"locations": {
"type": "array",
"items": { "type": "string" }
},
"dates": {
"type": "array",
"items": { "type": "string" }
}
},
"required": ["people", "locations", "dates"]
}))
.build()?;
println!("Entity extractor ready!");
Ok(())
}
مثال على مخرجات JSON
الإدخال: "John met Sarah in Paris on December 25th"
الإخراج:
{
"people": ["John", "Sarah"],
"locations": ["Paris"],
"dates": ["December 25th"]
}
ميزات متقدمة
تضمين المحتويات
التحكم في رؤية سجل المحادثة:
// سجل كامل (افتراضي)
.include_contents(IncludeContents::Default)
// عديم الحالة - يرى الإدخال الحالي فقط
.include_contents(IncludeContents::None)
مفتاح الإخراج
حفظ استجابات Agent إلى حالة Session:
.output_key("summary") // يتم حفظ الاستجابة في state["summary"]
تعليمات ديناميكية
حساب التعليمات في وقت التشغيل:
.instruction_provider(|ctx| {
Box::pin(async move {
let user_id = ctx.user_id();
Ok(format!("You are assisting user {}.", user_id))
})
})
Callbacks
اعتراض سلوك Agent:
.before_model_callback(|ctx, request| {
Box::pin(async move {
println!("About to call LLM with {} messages", request.contents.len());
Ok(BeforeModelResult::Continue)
})
})
مرجع Builder
| Method | الوصف |
|---|---|
new(name) | ينشئ Builder باسم Agent |
model(Arc<dyn Llm>) | يضبط LLM (مطلوب) |
description(text) | وصف Agent |
instruction(text) | موجه النظام |
tool(Arc<dyn Tool>) | يضيف Tool |
output_schema(json) | JSON schema للمخرجات المنظمة |
output_key(key) | يحفظ الاستجابة إلى الحالة |
include_contents(mode) | رؤية السجل |
build() | ينشئ Agent |
مثال كامل
عميل جاهز للإنتاج مزود بأدوات متعددة (الطقس، الآلة الحاسبة، البحث) ويتم حفظ الإخراج في حالة الجلسة:
use adk_rust::prelude::*;
use adk_rust::Launcher;
use serde_json::json;
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 = GeminiModel::new(&api_key, "gemini-2.5-flash")?;
// Weather tool
let weather = FunctionTool::new(
"get_weather",
"Get weather for a city. Parameters: city (string)",
|_ctx, args| async move {
let city = args.get("city").and_then(|v| v.as_str()).unwrap_or("unknown");
Ok(json!({
"city": city,
"temperature": "22°C",
"humidity": "65%",
"condition": "partly cloudy"
}))
},
);
// Calculator tool
let calc = FunctionTool::new(
"calculate",
"Math operations. Parameters: expression (string like '2 + 2')",
|_ctx, args| async move {
let expr = args.get("expression").and_then(|v| v.as_str()).unwrap_or("0");
Ok(json!({ "expression": expr, "result": "computed" }))
},
);
// Build the full agent
let agent = LlmAgentBuilder::new("assistant")
.description("A helpful assistant with weather and calculation abilities")
.instruction("You are a helpful assistant. \
Use the weather tool for weather questions. \
Use the calculator for math. \
Be concise and friendly.")
.model(Arc::new(model))
.tool(Arc::new(weather))
.tool(Arc::new(calc))
// .tool(Arc::new(GoogleSearchTool::new())) // Currently unsupported with FunctionTool
.output_key("last_response")
.build()?;
println!("✅ Agent '{}' ready!", agent.name());
Launcher::new(Arc::new(agent)).run().await?;
Ok(())
}
جرب هذه المطالبات:
You: What's 25 times 4?
Assistant: It's 100.
You: How's the weather in New York?
Assistant: The weather in New York is partly cloudy with a temperature of 22°C and 65% humidity.
You: Calculate 15% tip on $85
Assistant: A 15% tip on $85 is $12.75, making the total $97.75.
ذات صلة
- Workflow Agents - عملاء تسلسليون ومتوازيون وحلقيون
- Multi-Agent Systems - بناء تسلسلات هرمية للعملاء
- Function Tools - إنشاء أدوات مخصصة
- Callbacks - اعتراض سلوك العميل
السابق: Quickstart | التالي: Workflow Agents →