正在统计访客…
浏览全部文档
开始 · 9找到适合你的 Runifold 学习路径45 分钟掌握 Runifold理解完整的 Runifold 平台第一次可信运行选择正确的执行 API选择 Crate 与 Cargo Feature构建常见 Runifold 应用Runifold 常见问题排查 Runifold 应用故障
执行内核 · 7理解 RunContext安全协调外部副作用使用预算与取消限制工作安全地处理错误与重试事件、Journal 与执行证据设计 Capability 安全执行从 Checkpoint 安全恢复
模型与服务商 · 7在避免重复输出的前提下路由模型选择并配置模型服务商使用服务商中立的模型协议基于 Provider Runtime 契约构建使用 OpenAI 控制面与 Realtime API测试与 Benchmark Provider Adapter配置 OpenAI、Anthropic、Gemini 与 Ollama
Agent · 7构建并配置 Agent为 Agent 添加类型化工具加入会话与语义记忆安全地委派给子 Agent返回结构化 Rust 值在不丢失语义的前提下流式输出使用检索为 Agent 提供事实依据
持久工作流 · 7组合确定性工作流让工作流持久化运行持久工作流 Worker协调 Timer、Signal 与持久等待运行多租户工作流基础设施运行并行 Branch 与安全 Race对持久 Workflow 进行版本管理
集成 · 7通过 MCP 连接外部能力选择存储与持久化边界通过 MCP Tasks 暴露持久工作构建并评估检索流水线使用 MCP Resources、Prompts 与 Sampling在不跨越权限的前提下缓存 MCP 响应在 Rust Web Service 中部署 Runifold
质量与运维 · 10在没有网络的情况下测试评估质量并阻止回归观测完整运行树在浏览器与边缘环境安全运行准确理解可靠性声明在 CI 中运行可复现评测使用 SLO 运维 Runifold治理 Task 保留与删除把审计证据归档到 S3-Compatible WORM 存储管理兼容性与可信发布
文档/模型与服务商
第一次使用?通过 45 分钟核心课程建立完整心智模型
模型与服务商

使用 OpenAI 控制面与 Realtime API

管理模型、文件、Batch、Hosted Tool、Media Task、WebSocket 或 WebRTC 实时会话与有界重连。

实践指南·18 min

安装正确的 API 面

常规 OpenAI Adapter、控制面、Hosted Tool、图像生成、语音合成与转写都位于 openai Feature 下。Realtime 是独立的可选能力,普通服务端应用不会因此引入它的传输实现。

cargo add runifold@0.9.0
cargo add runifold-providers@0.9.0 --features openai
# 只在使用 WebSocket 或浏览器 WebRTC Realtime 时添加:
cargo add runifold-providers@0.9.0 --features openai,openai-realtime

两个 API 面

Runifold 的 OpenAI 集成除了模型数据面,还有两个专业接口:用于 Model、File、Batch 与 Realtime 临时凭证的 OpenAiControlPlane,以及面向 WebSocket 或浏览器 WebRTC 会话的 模型绑定 Realtime Connector。

它们不是 Agent 快捷方法,而是由应用或持久 Workflow 显式协调的生命周期操作。

控制面

OpenAiClient::control_plane() 共享经过验证的 Endpoint、连接池与凭证策略。类型化输入 限制文件名、上传大小、File Purpose、Batch Endpoint、Metadata 和未来状态值。

库可以列出模型、上传有界文件、创建 Batch、读取一次状态或请求取消,但不会隐式轮询。 持久化 Batch Identity,并在应用自己的 Deadline、预算与 Workflow 恢复策略下显式检查。

Realtime

OpenAiClient::realtime(model) 创建 Connector,提供 Session Update、文本、有界音频、 Response Create、取消、Transcript 与 Function Call Argument Delta 的类型化命令和事件。

状态机要求先创建 Session,只允许一个活跃 Response,把 Delta 关联到它,限制 Frame 与 Queue,并保存未知事件。WebRTC 与 WebSocket 共享生命周期、取消和 Deadline 语义。

凭证边界

原生服务端连接可以使用配置的长期凭证;浏览器构建拒绝长期 Provider Secret,必须通过 应用控制的 Gateway。

浏览器 Realtime 使用短期 Client Secret,每次重连都获取全新凭证。不要把 API Key 放进 WASM、JavaScript、WebSocket Query、日志或持久 Session 状态。

恢复语义

系统不会自动 Replay。Session 创建前或空闲时断开,可以安全替换;活跃 Response 期间 断开属于 AmbiguousResponseInFlight,因为输出可能已经提交。

Reconnect Controller 只在有界策略内自动执行安全替换,不存储 Secret、SDP、Transcript、 Command 或模型输出。应用负责协调不确定 Response,并决定让用户重试、继续还是启动新 Session。

使用控制平面

控制平面是显式 API:持久化返回的 ID,再由自己的 Workflow 安排后续读取; 它不会暗中轮询或重试。

use runifold::ModelCallContext;
use runifold_providers::openai::{OpenAiBatchEndpoint, OpenAiBatchRequest};
 
let control = client.control_plane();
let models = control.list_models(ModelCallContext::new()).await?;
 
let request = OpenAiBatchRequest::new("file_input", OpenAiBatchEndpoint::Responses)?
    .with_metadata("tenant", "acme")?;
let created = control.create_batch(request, ModelCallContext::new()).await?;
persist_batch_id(&created.id).await?;
 
let current = control
    .get_batch(load_batch_id().await?, ModelCallContext::new())
    .await?;

外围 Workflow 要设置总截止时间和轮询间隔。未来新增的未知状态应记录为数据, 不能当作成功。超时后保留 Batch ID,让运维人员或后续 Workflow 可以对账, 不要重新提交同一输入文件。

使用 OpenAI Hosted Tool

Hosted Tool 在 Provider 内部执行,不同于在你的进程内执行的 Runifold Tool。 用类型化构造器创建它,转为 Provider Tool Spec,再附加到 ModelRequest

use runifold::{Message, ModelRef, ModelRequest};
use runifold_providers::openai::OpenAiHostedTool;
 
let request = ModelRequest::new(
    ModelRef::new("openai", "gpt-5"),
    Message::user("找到最新的公开发布说明并总结。"),
)
.provider_tool(OpenAiHostedTool::web_search().into())
.provider_tool(
    OpenAiHostedTool::file_search(["vs_product_docs"])?
        .into(),
);

可用构造器包括 web_search()image_generation()code_interpreter_auto()file_search(...)remote_mcp(label, url)file_search 要求 1–100 个非空 Vector Store ID;remote_mcp 只接受 HTTP(S) URL,并保留 OpenAI 默认的审批语义。with_option 只用于 Provider 扩展项, 不允许覆盖保留的 type 字段。

Hosted Tool 不是本地 Capability:Runifold 无法在 Provider 内执行你的本地工具沙箱。 应用边界必须限制 Model、数据源、Vector Store、远程 MCP Endpoint、花费与用户可见审批。

生成图像、语音与转写

Media Task 使用独立的 Provider-neutral Trait,不会把二进制结果假装成 Chat 文本。 OpenAI Client 实现了 ImageGenerationModelSpeechModelTranscriptionModel

use runifold::{
    ImageFormat, ImageGenerationModel, ImageGenerationRequest, ModelCallContext,
    ModelRef, SpeechFormat, SpeechModel, SpeechRequest,
};
 
let image = client.generate_image(
    ImageGenerationRequest {
        model: ModelRef::new("openai", "gpt-image-1"),
        prompt: "一张精确的持久工作流等距示意图".into(),
        count: 1,
        size: Some("1024x1024".into()),
        quality: Some("high".into()),
        format: ImageFormat::Png,
        transparent: false,
    },
    ModelCallContext::new(),
).await?;
 
let speech = client.synthesize_speech(
    SpeechRequest {
        model: ModelRef::new("openai", "gpt-4o-mini-tts"),
        input: "工作流已安全完成。".into(),
        voice: "alloy".into(),
        instructions: None,
        format: SpeechFormat::Mp3,
        speed: None,
    },
    ModelCallContext::new(),
).await?;

转写通过 TranscriptionModel::transcribe 执行,TranscriptionRequest 应包含有界 文件名、Media Type、字节,以及可选 Language / Prompt。返回字节或远程 Media 必须显式存储; 默认不要记录二进制 Payload、签名 URL、Transcript 或用户音频。