OpenAI Responses API
ADK-Rust stellt einen dedizierten Client für OpenAIs Responses API (/v1/responses Endpoint) — den Nachfolger der Chat Completions API — bereit. Die Responses API ist der empfohlene Weg, um mit OpenAIs neuesten Modellen zu interagieren, einschließlich Reasoning-Modellen (o3, o4-mini) und der GPT-4.1-Serie.
Übersicht
┌─────────────────────────────────────────────────────────────────────┐
│ OpenAI Responses API Client │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ Endpoint: POST /v1/responses │
│ Client: OpenAIResponsesClient │
│ Config: OpenAIResponsesConfig │
│ Feature: openai │
│ │
│ Capabilities: │
│ • Streaming and non-streaming │
│ • Reasoning summaries (o-series models) │
│ • Tool / function calling │
│ • Multi-turn via previous_response_id │
│ • Built-in tools (web search, file search, code interpreter) │
│ • System instructions │
│ • Temperature, top_p, 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) │
│ │
└─────────────────────────────────────────────────────────────────────┘
Wann welchen Client verwenden
| Merkmal | OpenAIClient (Chat-Vervollständigungen) | OpenAIResponsesClient (Antworten) |
|---|---|---|
| Endpunkt | /v1/chat/completions | /v1/responses |
| Modelle | Alle GPT-Modelle | Alle GPT- + o-series Reasoning-Modelle |
| Reasoning-Zusammenfassungen | Nicht verfügbar | Native Unterstützung |
| Integrierte Tools | Nicht verfügbar | Websuche, Dateisuche, Code-Interpreter |
| Server-seitiger Zustand | Manueller Nachrichtenverlauf | previous_response_id |
| Strukturierte Ausgabe | response_format | text.format (geplant) |
| Reifegrad | Stabil, weit verbreitet | Neuer, von OpenAI empfohlen |
Verwenden Sie OpenAIResponsesClient, wenn Sie Reasoning-Modelle mit Zusammenfassungen, integrierten Tools benötigen oder die neueste API von OpenAI nutzen möchten. Verwenden Sie OpenAIClient zur Abwärtskompatibilität mit bestehenden Chat-Vervollständigungs-Workflows.
Installation
[dependencies]
adk-rust = { version = "2.0.0", features = ["openai"] }
adk-tool = "2.0.0"
Oder direkt mit adk-model:
[dependencies]
adk-model = { version = "2.0.0", features = ["openai"] }
Legen Sie Ihren API-Schlüssel fest:
export OPENAI_API_KEY="sk-..."
Schnellstart
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-4.1-nano");
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(())
}
Konfiguration
Grundkonfiguration
use adk_model::openai::{OpenAIResponsesConfig, ReasoningEffort, ReasoningSummary};
// Minimal — just API key and model
let config = OpenAIResponsesConfig::new("sk-...", "gpt-4.1-nano");
// With organization and project
let config = OpenAIResponsesConfig::new("sk-...", "gpt-4.1-mini")
.with_organization("org-...")
.with_project("proj-...");
// Custom base URL (for proxies or compatible APIs)
let config = OpenAIResponsesConfig::new("sk-...", "gpt-4.1-mini")
.with_base_url("https://my-proxy.example.com/v1");
Denkmodelle
Für Modelle der o-Serie (o3, o4-mini) konfigurieren Sie den Denkaufwand und die Zusammenfassung:
use adk_model::openai::{
OpenAIResponsesClient, OpenAIResponsesConfig,
ReasoningEffort, ReasoningSummary,
};
let config = OpenAIResponsesConfig::new("sk-...", "o4-mini")
.with_reasoning_effort(ReasoningEffort::Medium)
.with_reasoning_summary(ReasoningSummary::Detailed);
let model = OpenAIResponsesClient::new(config)?;
| Denkaufwand | Beschreibung |
|---|---|
Low | Minimaler Denkaufwand — am schnellsten, am günstigsten |
Medium | Ausgewogener Denkaufwand (Standard für die meisten Aufgaben) |
High | Maximaler Denkaufwand — am gründlichsten |
| Zusammenfassung der Begründung | Beschreibung |
|---|---|
Auto | Modell entscheidet, ob eine Zusammenfassung enthalten sein soll |
Concise | Kurze Zusammenfassung der Begründung |
Detailed | Ausführliche Zusammenfassung der Begründung |
Zusammenfassungen der Begründung erscheinen als Part::Thinking im Antwortstrom, sodass Sie den Denkprozess des Modells den Benutzern zeigen können.
Wiederholungskonfiguration
use adk_model::retry::RetryConfig;
let client = OpenAIResponsesClient::new(config)?
.with_retry_config(RetryConfig {
max_retries: 3,
..Default::default()
});
Wiederholungsversuche erfolgen automatisch bei Ratenbegrenzungen (429), Serverfehlern (500/502/503/504) und Netzwerkfehlern.
Verfügbare Modelle
| Modell | Typ | Beschreibung |
|---|---|---|
gpt-4.1 | Chat | Neuestes GPT-4.1 mit verbesserter Befolgung von Anweisungen |
gpt-4.1-mini | Chat | Ausgewogene Geschwindigkeit und Fähigkeiten |
gpt-4.1-nano | Chat | Ultraschnelle, günstigste Option |
o3 | Reasoning | Vollständiges Reasoning-Modell |
o3-mini | Reasoning | Effizientes Reasoning-Modell |
o4-mini | Reasoning | Neuestes effizientes Reasoning-Modell |
gpt-5 | Chat | Modernstes, vereinheitlichtes Modell |
gpt-5-mini | Chat | Effiziente Version von GPT-5 |
Funktionen
Werkzeugaufrufe
Funktionswerkzeuge funktionieren auf die gleiche Weise wie bei OpenAIClient — definieren Sie Werkzeuge für den Agenten, und der Runner übernimmt die Schleife der Werkzeugaufrufe:
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-4.1-nano");
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()?;
Gespräche über mehrere Runden
Der Runner verwaltet automatisch den Konversationsverlauf durch Sessions. Der Kontext jeder Runde wird beibehalten:
// 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."
Pro-Anfrage Begründungsüberschreibung
Überschreiben Sie Begründungseinstellungen pro-Anfrage mithilfe von LlmRequest-Erweiterungen:
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()?;
Integrierte Tools
Die Responses API unterstützt von OpenAI gehostete Tools. Bevorzugen Sie die typisierten Wrapper von adk-tool:
use adk_tool::OpenAIWebSearchTool;
use std::sync::Arc;
let agent = LlmAgentBuilder::new("researcher")
.model(model)
.tool(Arc::new(OpenAIWebSearchTool::new().preview()))
.build()?;
Verfügbare Wrapper umfassen OpenAIWebSearchTool, OpenAIFileSearchTool, OpenAICodeInterpreterTool, OpenAIImageGenerationTool, OpenAIComputerUseTool, OpenAIMcpTool, OpenAILocalShellTool, OpenAIShellTool und OpenAIApplyPatchTool.
ID der vorherigen Antwort
Für den serverseitigen Konversationszustand (Umgehung des lokalen Session-Verlaufs) übergeben Sie 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()?;
Streaming-Verhalten
Der Responses API Client streamt Text- und Begründungs-Deltas in Echtzeit:
- Text-Deltas kommen als
Part::Textmitpartial: true - Zusammenfassende Begründungs-Deltas kommen als
Part::Thinkingmitpartial: true - Funktionsaufrufe werden vom finalen
ResponseCompletedEreignis mit korrekten Namen und Argumenten ausgegeben - Das finale Ereignis hat
turn_complete: truemit Nutzungsmetadaten und Abbruchgrund
Das bedeutet, Sie sehen Text Token für Token erscheinen, während das Modell generiert, und Funktionsaufrufe kommen als vollständige Objekte bereit zur Ausführung an.
Provider-Metadaten
Jede Antwort enthält Provider-Metadaten mit dem 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
}
Zusätzliche Metadaten können enthalten:
encrypted_content— von Begründungsmodellen (zur Kontextbewahrung)built_in_tool_outputs— Ergebnisse aus Websuche, Dateisuche, Code-Interpreter
Fehlerbehandlung
Fehler werden auf strukturierte AdkError mit entsprechenden Kategorien abgebildet:
| HTTP-Status | Fehlerkategorie | Wiederholbar |
|---|---|---|
| 401 | Unauthorized | Nein |
| 429 | RateLimited | Ja |
| 500, 502, 503, 504 | Unavailable | Ja |
| Andere | Internal | Nein |
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 */ }
}
Hintergrundmodus & Abbruch
Bei langlaufenden Anfragen mit background: true senden und auf den Abschluss warten:
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?;
Modelle für tiefgehende Forschung (o3-deep-research, o4-mini-deep-research) aktivieren den Hintergrundmodus automatisch ohne explizites background: true.
Beispiel
Ein vollständiges Beispiel mit 7 Szenarien ist unter examples/openai_responses/ verfügbar:
export OPENAI_API_KEY=sk-...
cargo run --manifest-path examples/openai_responses/Cargo.toml
Abgedeckte Szenarien:
- Einfacher Nicht-Streaming-Chat
- Einfacher Streaming-Chat
- Schlussfolgerungsmodell mit Zusammenfassung (o4-mini)
- Tool-Aufrufe mit Funktions-Tools
- Mehrstufige Konversation
- Systemanweisungen
- Temperatur und Generierungskonfiguration
Zusätzliche Beispiele
Sechs eigenständige Beispiel-Crates demonstrieren spezifische Funktionen der Responses API:
| Beispiel | Ausführungsbefehl | Funktion |
|---|---|---|
| WebSocket-Transport | cargo run --manifest-path examples/openai_ws_minimal/Cargo.toml | Persistente Verbindung mit geringer Latenz |
| Hintergrundmodus | cargo run --manifest-path examples/openai_background/Cargo.toml | Workflow zum Senden und Abfragen |
| Konversations-API | cargo run --manifest-path examples/openai_conversations/Cargo.toml | Serververwaltete Mehrfachgespräche |
| Integrierte Tools | cargo run --manifest-path examples/openai_builtin_tools/Cargo.toml | Bilderzeugung, Websuche |
| Tiefenrecherche | cargo run --manifest-path examples/openai_deep_research/Cargo.toml | Automatische Hintergrundrecherche |
| Offene Responses | cargo run --manifest-path examples/openai_open_responses/Cargo.toml | Anbieterunabhängige Endpunkte |
Verwandtes
- Cloud-Modellanbieter — Alle unterstützten LLM-Anbieter
- Ollama (Lokal) — Modelle lokal ausführen
- LlmAgent — Modelle mit Agenten verwenden
- Function Tools — Werkzeuge zu Agenten hinzufügen
Zurück: ← Cloud-Anbieter | Weiter: Ollama (Lokal) →