Runner
وقت تشغيل التنفيذ من adk-runner الذي يقوم بتنسيق تنفيذ Agent.
نظرة عامة
يدير Runner دورة الحياة الكاملة لتنفيذ Agent:
- إدارة Session (إنشاء/استرداد Sessions)
- حقن Memory (البحث عن Memories ذات الصلة وحقنها)
- التعامل مع Artifact (وصول Artifact محدد النطاق)
- تدفق Event (معالجة وإعادة توجيه Events)
- عمليات نقل Agent (التعامل مع التسليمات المتعددة بين Agent)
التثبيت
[dependencies]
adk-runner = "0.2.0"
RunnerConfig
قم بتكوين Runner بالخدمات المطلوبة:
use adk_runner::{Runner, RunnerConfig};
use adk_session::InMemorySessionService;
use adk_artifact::InMemoryArtifactService;
use std::sync::Arc;
let config = RunnerConfig {
app_name: "my_app".to_string(),
agent: Arc::new(my_agent),
session_service: Arc::new(InMemorySessionService::new()),
artifact_service: Some(Arc::new(InMemoryArtifactService::new())),
memory_service: None,
run_config: None,
};
let runner = Runner::new(config)?;
حقول التكوين
| الحقل | النوع | مطلوب | الوصف |
|---|---|---|---|
app_name | String | نعم | معرّف التطبيق |
agent | Arc<dyn Agent> | نعم | Agent الجذر المراد تنفيذه |
session_service | Arc<dyn SessionService> | نعم | واجهة تخزين Session |
artifact_service | Option<Arc<dyn ArtifactService>> | لا | تخزين Artifact |
memory_service | Option<Arc<dyn Memory>> | لا | ذاكرة طويلة المدى |
run_config | Option<RunConfig> | لا | خيارات التنفيذ |
تشغيل Agents
نفّذ Agent بمدخلات المستخدم:
use adk_core::Content;
use futures::StreamExt;
let user_content = Content::new("user").with_text("Hello!");
let mut stream = runner.run(
"user-123".to_string(),
"session-456".to_string(),
user_content,
).await?;
while let Some(event) = stream.next().await {
match event {
Ok(e) => {
if let Some(content) = e.content() {
for part in &content.parts {
if let Some(text) = part.text() {
print!("{}", text);
}
}
}
}
Err(e) => eprintln!("Error: {}", e),
}
}
تدفق التنفيذ
┌─────────────────────────────────────────────────────────────┐
│ Runner.run() │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 1. استرجاع الجلسة │
│ │
│ SessionService.get(app_name, user_id, session_id) │
│ → ينشئ جلسة جديدة إذا لم تكن موجودة │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 2. اختيار Agent │
│ │
│ التحقق من حالة الجلسة لوجود Agent نشط │
│ → استخدام root agent أو transferred agent │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 3. إنشاء السياق │
│ │
│ InvocationContext مع: │
│ - Session (قابل للتعديل) │
│ - Artifacts (محددة بالنطاق للجلسة) │
│ - Memory (إذا تم تكوينها) │
│ - Run config │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 4. تنفيذ Agent │
│ │
│ agent.run(ctx) → EventStream │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 5. معالجة الأحداث │
│ │
│ لكل حدث: │
│ - تحديث حالة الجلسة │
│ - التعامل مع عمليات النقل │
│ - إعادة التوجيه إلى المتصل │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 6. حفظ الجلسة │
│ │
│ SessionService.append_event(session, events) │
└─────────────────────────────────────────────────────────────┘
InvocationContext
السياق المقدم للوكلاء أثناء التنفيذ:
pub trait InvocationContext: CallbackContext {
/// الوكيل الذي يتم تنفيذه
fn agent(&self) -> Arc<dyn Agent>;
/// خدمة الذاكرة (إذا تم تهيئتها)
fn memory(&self) -> Option<Arc<dyn Memory>>;
/// الجلسة الحالية
fn session(&self) -> &dyn Session;
/// تهيئة التنفيذ
fn run_config(&self) -> &RunConfig;
/// إشارة نهاية الاستدعاء
fn end_invocation(&self);
/// التحقق مما إذا كان الاستدعاء قد انتهى
fn ended(&self) -> bool;
}
RunConfig
خيارات التنفيذ:
pub struct RunConfig {
/// وضع البث للاستجابات
pub streaming_mode: StreamingMode,
}
pub enum StreamingMode {
/// لا يوجد بث، إرجاع استجابة كاملة
None,
/// أحداث مرسلة من الخادم (افتراضي)
SSE,
/// بث ثنائي الاتجاه (في الوقت الفعلي)
Bidi,
}
ملاحظة: من المخطط إضافة حقول إضافية مثل
max_turnsوinclude_historyفي الإصدارات المستقبلية.
عمليات نقل Agent
يتعامل Runner مع عمليات نقل multi-agent تلقائيًا:
// في أداة agent أو وظيفة رد الاتصال
if should_transfer {
// تعيين النقل في EventActions
ctx.set_actions(EventActions {
transfer_to_agent: Some("specialist_agent".to_string()),
..Default::default()
});
}
سيقوم Runner بما يلي:
- اكتشاف طلب النقل في الحدث
- البحث عن agent الهدف في sub_agents
- تحديث حالة session باستخدام active agent الجديد
- متابعة التنفيذ باستخدام الـ agent الجديد
التكامل مع Launcher
يستخدم Launcher الـ Runner داخليًا:
// Launcher ينشئ Runner باستخدام الخدمات الافتراضية
Launcher::new(agent)
.app_name("my_app")
.run()
.await?;
// ما يعادله:
let runner = Runner::new(RunnerConfig {
app_name: "my_app".to_string(),
agent,
session_service: Arc::new(InMemorySessionService::new()),
artifact_service: Some(Arc::new(FileArtifactService::new("./artifacts")?)),
memory_service: None,
run_config: None,
})?;
الاستخدام المخصص لـ Runner
للسيناريوهات المتقدمة، استخدم Runner مباشرة:
use adk_runner::{Runner, RunnerConfig};
use adk_session::DatabaseSessionService;
use adk_artifact::S3ArtifactService;
use adk_memory::QdrantMemoryService;
// تهيئة الإنتاج
let config = RunnerConfig {
app_name: "production_app".to_string(),
agent: my_agent,
session_service: Arc::new(DatabaseSessionService::new(db_pool)),
artifact_service: Some(Arc::new(S3ArtifactService::new(s3_client))),
memory_service: Some(Arc::new(QdrantMemoryService::new(qdrant_client))),
run_config: None, // يستخدم بث SSE الافتراضي
};
let runner = Runner::new(config)?;
// يُستخدم في معالج HTTP
async fn chat_handler(runner: &Runner, request: ChatRequest) -> Response {
let stream = runner.run(
request.user_id,
request.session_id,
request.content,
).await?;
// بث الأحداث إلى العميل
Response::sse(stream)
}
السابق: ← Core Types | التالي: Launcher →