استجابات OpenAI API
يوفّر ADK-Rust عميلاً مخصصًا لـ OpenAI استجابات API (نقطة النهاية /v1/responses) — وهي البديل عن API لإكمالات المحادثة. وتُعدّ استجابات API الطريقة الموصى بها لاستخدام نماذج GPT-5.6 الحالية، بما في ذلك النطاق الكامل لجهد الاستدلال.
نظرة عامة
┌─────────────────────────────────────────────────────────────────────┐
│ OpenAI Responses API Client │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ Endpoint: POST /v1/responses │
│ Client: OpenAIResponsesClient │
│ Config: OpenAIResponsesConfig │
│ Feature: openai │
│ │
│ Capabilities: │
│ • Streaming and non-streaming │
│ • Reasoning summaries │
│ • Tool / function calling │
│ • Multi-turn via previous_response_id │
│ • Built-in tools (web search, file search, code interpreter) │
│ • System instructions │
│ • Model-aware sampling controls and max_output_tokens │
│ • Automatic retry with exponential backoff │
│ │
│ vs Chat Completions (OpenAIClient): │
│ • Stateful conversations (server-side context) │
│ • Native reasoning summaries │
│ • Built-in tool hosting │
│ • Simpler multi-turn (no manual message history) │
│ │
└─────────────────────────────────────────────────────────────────────┘
متى تستخدم أي عميل؟
| الميزة | OpenAIClient (إكمالات المحادثة) | OpenAIResponsesClient (الاستجابات) |
|---|---|---|
| نقطة النهاية | /v1/chat/completions | /v1/responses |
| النماذج | نماذج متوافقة مع المحادثة | GPT الحالية ونماذج الاستدلال |
| ملخصات الاستدلال | غير متاح | دعم أصلي |
| الأدوات المضمنة | غير متاح | البحث على الويب، البحث في الملفات، مفسر التعليمات البرمجية |
| الحالة من جانب الخادم | سجل الرسائل اليدوي | previous_response_id |
| المخرجات المهيكلة | response_format | text.format (مخطط لها) |
| مستوى النضج | مستقر ومعتمد على نطاق واسع | أحدث، ويوصى به من قِبل OpenAI |
استخدم OpenAIResponsesClient عندما تحتاج إلى نماذج استدلال مع ملخصات أو أدوات مضمّنة، أو عندما تريد استخدام أحدث API من OpenAI. استخدم OpenAIClient للتوافق مع الإصدارات السابقة لسير عمل Chat Completions الحالي.
التثبيت
[dependencies]
adk-rust = { version = "2.1.0", features = ["openai"] }
adk-tool = "2.1.0"
أو باستخدام adk-model مباشرةً:
[dependencies]
adk-model = { version = "2.1.0", features = ["openai"] }
عيّن مفتاح API الخاص بك:
export OPENAI_API_KEY="sk-..."
البدء السريع
use adk_rust::prelude::*;
use adk_rust::session::{CreateRequest, SessionService};
use adk_rust::futures::StreamExt;
use adk_model::openai::{OpenAIResponsesClient, OpenAIResponsesConfig};
use std::collections::HashMap;
use std::sync::Arc;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
dotenvy::dotenv().ok();
let api_key = std::env::var("OPENAI_API_KEY")?;
// 1. Create the Responses API client
let config = OpenAIResponsesConfig::new(&api_key, "gpt-5.6-terra");
let model = Arc::new(OpenAIResponsesClient::new(config)?);
// 2. Build an agent
let agent = Arc::new(
LlmAgentBuilder::new("assistant")
.instruction("You are a helpful assistant. Be concise.")
.model(model)
.build()?,
);
// 3. Create a session
let sessions: Arc<dyn SessionService> = Arc::new(InMemorySessionService::new());
sessions.create(CreateRequest {
app_name: "my_app".into(),
user_id: "user".into(),
session_id: Some("s1".into()),
state: HashMap::new(),
}).await?;
// 4. Run through the Runner
let runner = Runner::builder()
.app_name("my_app")
.agent(agent)
.session_service(sessions)
.build()?;
let message = Content::new("user").with_text("What is the capital of France?");
let mut stream = runner.run(
adk_rust::UserId::new("user")?,
adk_rust::SessionId::new("s1")?,
message,
).await?;
while let Some(event) = stream.next().await {
let event = event?;
if let Some(content) = &event.llm_response.content {
for part in &content.parts {
if let Some(text) = part.text() {
print!("{text}");
}
}
}
}
println!();
Ok(())
}
التكوين
التكوين الأساسي
use adk_model::openai::OpenAIResponsesConfig;
// Minimal — just API key and model
let config = OpenAIResponsesConfig::new("sk-...", "gpt-5.6-luna");
// With organization and project
let config = OpenAIResponsesConfig::new("sk-...", "gpt-5.6-terra")
.with_organization("org-...")
.with_project("proj-...");
// Custom base URL (for proxies or compatible APIs)
let config = OpenAIResponsesConfig::new("sk-...", "gpt-5.6-terra")
.with_base_url("https://my-proxy.example.com/v1");
نماذج الاستدلال
بالنسبة إلى نماذج الاستدلال GPT-5.6، اضبط جهد الاستدلال والملخص:
use adk_model::openai::{
OpenAIReasoningEffort, OpenAIResponsesClient,
OpenAIResponsesConfig, ReasoningSummary,
};
let config = OpenAIResponsesConfig::new("sk-...", "gpt-5.6-terra")
.with_reasoning_summary(ReasoningSummary::Detailed);
let model = OpenAIResponsesClient::new_with_reasoning_effort(
config,
OpenAIReasoningEffort::Max,
)?;
| جهد الاستدلال | الوصف |
|---|---|
None | تعطيل الاستدلال لتحقيق أقل زمن استجابة |
Minimal | الاستدلال الأدنى القديم في النماذج التي تدعمه |
Low | جهد استدلال منخفض |
Medium | استدلال متوازن |
High | جهد استدلال مرتفع |
XHigh | جهد استدلال مرتفع للغاية |
Max | الحد الأقصى للاستدلال على النماذج المدعومة |
يدعم GPT-5.6 None وLow وMedium وHigh وXHigh وMax عبر واجهة API للاستجابات. تدعم إكمالات الدردشة ما يصل إلى XHigh.
| ملخص الاستدلال | الوصف |
|---|---|
Auto | يقرر النموذج ما إذا كان سيضمّن ملخصًا |
Concise | ملخص موجز للاستدلال |
Detailed | ملخص شامل للاستدلال |
تظهر ملخصات الاستدلال بصيغة Part::Thinking في تدفق الاستجابة، مما يتيح لك عرض عملية تفكير النموذج للمستخدمين.
إعداد إعادة المحاولة
use adk_model::retry::RetryConfig;
let client = OpenAIResponsesClient::new(config)?
.with_retry_config(RetryConfig {
max_retries: 3,
..Default::default()
});
تتم إعادة المحاولة تلقائيًا عند تجاوز حدود المعدل (429)، وأخطاء الخادم (500/502/503/504)، وفشل الشبكة.
النماذج المتاحة
| النموذج | النوع | الوصف |
|---|---|---|
gpt-5.6-terra | استدلال | الخيار الافتراضي المتوازن للوكلاء في بيئة الإنتاج |
gpt-5.6-sol | استدلال | الاستدلال والبرمجة الرائدان |
gpt-5.6-luna | الاستدلال | أعباء العمل عالية الحجم والكفاءة من حيث التكلفة |
gpt-5.6 | الاستدلال | الاسم المستعار للنموذج الرائد |
gpt-5 | الاستدلال | التوافق مع الجيل السابق |
gpt-4.1 العائلة | المحادثة | التوافق وعناصر التحكم الصريحة في أخذ العينات |
o3 / o4-mini | الاستدلال | التوافق مع الاستدلال من الجيل السابق |
الميزات
استدعاء الأدوات
تعمل أدوات الدوال بالطريقة نفسها كما في OpenAIClient — عرّف الأدوات على الوكيل، ويتولى المشغّل حلقة استدعاء الأداة:
use adk_rust::prelude::*;
use adk_model::openai::{OpenAIResponsesClient, OpenAIResponsesConfig};
use adk_tool::FunctionTool;
use std::sync::Arc;
async fn get_weather(
_ctx: Arc<dyn ToolContext>,
args: serde_json::Value,
) -> Result<serde_json::Value> {
let city = args["city"].as_str().unwrap_or("unknown");
Ok(serde_json::json!({
"city": city,
"temperature_f": 72,
"conditions": "Sunny"
}))
}
let weather_tool = FunctionTool::new(
"get_weather",
"Get current weather for a city. Requires a 'city' string parameter.",
get_weather,
);
let config = OpenAIResponsesConfig::new(&api_key, "gpt-5.6-terra");
let model = Arc::new(OpenAIResponsesClient::new(config)?);
let agent = LlmAgentBuilder::new("weather_agent")
.instruction("Use the get_weather tool to answer weather questions.")
.model(model)
.tool(Arc::new(weather_tool))
.build()?;
المحادثات متعددة الأدوار
يدير المشغّل سجل المحادثة تلقائيًا من خلال الجلسات. ويتم الحفاظ على سياق كل دور:
// Turn 1
let msg1 = Content::new("user").with_text("My name is Alice.");
let mut stream = runner.run(uid.clone(), sid.clone(), msg1).await?;
// ... consume stream ...
// Turn 2 — the model remembers the previous turn
let msg2 = Content::new("user").with_text("What is my name?");
let mut stream = runner.run(uid.clone(), sid.clone(), msg2).await?;
// Response: "Your name is Alice."
تجاوز الاستدلال لكل طلب
يمكن تجاوز إعدادات الاستدلال لكل طلب باستخدام امتدادات LlmRequest:
use adk_rust::prelude::*;
let agent = LlmAgentBuilder::new("flexible_reasoner")
.model(model)
.generate_content_config(GenerateContentConfig {
extensions: {
let mut ext = std::collections::HashMap::new();
ext.insert("openai".to_string(), serde_json::json!({
"reasoning": {
"effort": "high",
"summary": "detailed"
}
}));
ext
},
..Default::default()
})
.build()?;
الأدوات المضمّنة
يدعم عميل Responses API الأدوات المستضافة بواسطة OpenAI. ويُفضّل استخدام الأغلفة المكتوبة من adk-tool:
use adk_tool::OpenAIWebSearchTool;
use std::sync::Arc;
let agent = LlmAgentBuilder::new("researcher")
.model(model)
.tool(Arc::new(OpenAIWebSearchTool::new().preview()))
.build()?;
تشمل الأغلفة المتاحة OpenAIWebSearchTool وOpenAIFileSearchTool وOpenAICodeInterpreterTool وOpenAIImageGenerationTool وOpenAIComputerUseTool وOpenAIMcpTool وOpenAILocalShellTool وOpenAIShellTool وOpenAIApplyPatchTool.
معرّف الاستجابة السابقة
للحصول على حالة المحادثة من جانب الخادم (مع تجاوز سجل الجلسة المحلي)، مرّر previous_response_id:
let agent = LlmAgentBuilder::new("stateful")
.model(model)
.generate_content_config(GenerateContentConfig {
extensions: {
let mut ext = std::collections::HashMap::new();
ext.insert("openai".to_string(), serde_json::json!({
"previous_response_id": "resp_abc123"
}));
ext
},
..Default::default()
})
.build()?;
سلوك البث
يبث عميل Responses API النص وتغيّرات الاستدلال في الوقت الفعلي:
- تصل تغيّرات النص باعتبارها
Part::Textمعpartial: true - تصل تغيّرات ملخص الاستدلال باعتبارها
Part::Thinkingمعpartial: true - تُصدر استدعاءات الدوال من حدث
ResponseCompletedالنهائي، مع الأسماء والوسائط الصحيحة - يتضمن الحدث النهائي
turn_complete: trueمع بيانات استخدام وصف سبب الإنهاء
يعني هذا أنك ترى النص يظهر رمزًا تلو الآخر أثناء التوليد، بينما تصل استدعاءات الدوال ككائنات مكتملة جاهزة للتنفيذ.
بيانات تعريف المزوّد
تتضمن كل استجابة بيانات تعريف المزوّد مع response_id:
if let Some(meta) = &response.provider_metadata {
let response_id = meta["openai"]["response_id"].as_str();
// Use for previous_response_id, logging, debugging
}
قد تتضمن البيانات الوصفية الإضافية ما يلي:
encrypted_content— من نماذج الاستدلال (للحفاظ على السياق)built_in_tool_outputs— نتائج البحث على الويب، والبحث في الملفات، ومفسّر التعليمات البرمجية
معالجة الأخطاء
تُحوَّل الأخطاء إلى AdkError منظَّمة مع الفئات المناسبة:
| HTTP الحالة | فئة الخطأ | قابل لإعادة المحاولة |
|---|---|---|
| 401 | Unauthorized | لا |
| 429 | RateLimited | نعم |
| 500, 502, 503, 504 | Unavailable | نعم |
| أخرى | Internal | لا |
match runner.run(uid, sid, message).await {
Ok(stream) => { /* process stream */ }
Err(e) if e.is_retryable() => { /* retry logic */ }
Err(e) if e.is_unauthorized() => { /* check API key */ }
Err(e) => { /* handle other errors */ }
}
الوضع في الخلفية والإلغاء
بالنسبة إلى الطلبات طويلة الأمد، أرسل الطلب باستخدام background: true واستعلم دوريًا عن اكتماله:
use adk_model::openai::{OpenAIResponsesClient, OpenAIResponsesConfig};
let client = OpenAIResponsesClient::new(config)?;
// Submit with background: true via extensions
let mut gen_config = GenerateContentConfig::default();
gen_config.extensions.insert("openai".into(), serde_json::json!({ "background": true }));
// ... send request, extract response_id from provider_metadata ...
// Poll until terminal status
let response = client.poll_response("resp_abc123").await?;
// Check provider_metadata["openai"]["status"]: "completed", "in_progress", "failed", "cancelled"
// Cancel a running background response
let cancelled = client.cancel_response("resp_abc123").await?;
تفعّل نماذج البحث المتعمق (o3-deep-research وo4-mini-deep-research) الوضع في الخلفية تلقائيًا من دون استخدام background: true بشكل صريح.
مثال
يتوفر مثال كامل مكوّن من 7 سيناريوهات على examples/openai_responses/:
export OPENAI_API_KEY=sk-...
cargo run --manifest-path examples/openai_responses/Cargo.toml
السيناريوهات المشمولة:
- محادثة أساسية من دون بث
- محادثة أساسية مع البث
- نموذج استدلال مع ملخص (مسار التوافق مع
o4-mini) - استدعاء الأدوات باستخدام أدوات الدوال
- محادثة متعددة الأدوار
- تعليمات النظام
- إعداد درجة الحرارة وإعدادات التوليد (مسار التوافق مع
gpt-4.1-nano)
أمثلة إضافية
توضّح ستة صناديق أمثلة مستقلة ميزات Responses API محددة:
| المثال | أمر التشغيل | الميزة |
|---|---|---|
| نقل WebSocket | cargo run --manifest-path examples/openai_ws_minimal/Cargo.toml | اتصال دائم منخفض زمن الاستجابة |
| الوضع في الخلفية | cargo run --manifest-path examples/openai_background/Cargo.toml | سير عمل الإرسال والاستطلاع |
| المحادثات API | cargo run --manifest-path examples/openai_conversations/Cargo.toml | متعدد الجولات مُدار من الخادم |
| الأدوات المضمنة | cargo run --manifest-path examples/openai_builtin_tools/Cargo.toml | توليد الصور، البحث على الويب |
| البحث المتعمق | cargo run --manifest-path examples/openai_deep_research/Cargo.toml | بحث تلقائي في الخلفية |
| الاستجابات المفتوحة | cargo run --manifest-path examples/openai_open_responses/Cargo.toml | نقاط نهاية مستقلة عن المزوّد |
ذات صلة
- موفرو النماذج السحابية — جميع موفري LLM المدعومين
- Ollama (محلي) — تشغيل النماذج محليًا
- LlmAgent — استخدام النماذج مع الوكلاء
- أدوات الدوال — إضافة الأدوات إلى الوكلاء
السابق: ← موفرو السحابة | التالي: Ollama (محلي) →