正在统计访客…
浏览全部文档
开始 · 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 分钟核心课程建立完整心智模型
部署指南

在 Rust Web Service 中部署 Runifold

构建完整 Axum API,把凭证和策略放在服务端边界,并在流式响应与持久后台任务之间选择。

实践指南·10 min

把 Runifold 放在应用服务边界之后

Web Service 应负责 Provider 凭证、用户认证、Admission、Run 构建、错误映射与可观测性。 浏览器只把产品输入发送给你的服务,不能持有长期密钥直接调用模型 Provider。

client → authentication → admission → RunContext → Agent → Provider
                                ↘ journal / metrics / traces

Provider Client 与 Runtime 在启动时创建一次。请求级策略使用新的 Agent 或 RunContext。

构建完整的 Axum 服务

cargo new runifold-api
cd runifold-api
cargo add runifold@0.9.0
cargo add runifold-providers@0.9.0 --features openai
cargo add axum@0.8
cargo add serde@1 --features derive
cargo add tokio@1 --features macros,rt-multi-thread,net

替换 src/main.rs

use axum::{Json, Router, extract::State, http::StatusCode, routing::post};
use runifold::{ProviderModelExt, ProviderRuntime};
use runifold_providers::openai::OpenAiClient;
use serde::{Deserialize, Serialize};
 
#[derive(Clone)]
struct AppState { runtime: ProviderRuntime }
 
#[derive(Deserialize)]
struct PromptRequest { prompt: String }
 
#[derive(Serialize)]
struct PromptResponse { answer: String }
 
async fn prompt(
    State(state): State<AppState>,
    Json(request): Json<PromptRequest>,
) -> Result<Json<PromptResponse>, (StatusCode, String)> {
    let answer = state.runtime
        .agent("http-assistant")
        .system("Answer precisely and expose uncertainty.")
        .prompt_text(request.prompt)
        .await
        .map_err(|error| (
            StatusCode::BAD_GATEWAY,
            format!("model request failed: {error}"),
        ))?;
 
    Ok(Json(PromptResponse { answer }))
}
 
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let runtime = OpenAiClient::from_api_key(
        std::env::var("OPENAI_API_KEY")?
    )?.runtime("gpt-5")?;
 
    let app = Router::new()
        .route("/prompt", post(prompt))
        .with_state(AppState { runtime });
    let listener = tokio::net::TcpListener::bind("127.0.0.1:3000").await?;
 
    axum::serve(listener, app).await?;
    Ok(())
}

设置 OPENAI_API_KEY,运行 cargo run,然后向 POST /prompt 发送 JSON。这个完整服务 会在文档 CI 中编译。

对外开放前增加请求策略

最小服务只能证明集成成功,还不是生产安全边界。请补充:

  • 已认证的 Tenant 与 Actor Identity;
  • 输入长度和 Body Size 限制;
  • 按租户的 Admission 与并发限制;
  • 包含 Token、Turn、Tool 和 Wall Time 预算的显式 RunContext
  • 由授权结果派生的 Capability,绝不能来自请求 JSON;
  • 客户端断连时取消 Run;
  • 不泄露 Provider Body 的稳定公开错误码。

请求信封请继续阅读 RunContext预算Capability 安全

选择流式响应或后台任务

用户等待增量输出时使用 SSE 或 WebSocket。必须保留成功、拒绝、用量与失败终态,不能把 Stream 简化成纯文本 Chunk。

任务需要跨进程恢复、等待 Signal 或在 HTTP 请求结束后继续运行时,使用持久 Workflow。 HTTP 层返回 Task ID,由 Worker 接管执行;不要为了数小时任务一直保持连接。

通过部署检查

上线前确认:

  1. Secret 只从部署环境进入;
  2. Health Check 不调用付费模型;
  3. Graceful Shutdown 会取消或交接活跃 Run;
  4. 只有被标记为安全的错误才重试;
  5. 日志能关联 Tenant、Run、Provider 与模型且不包含敏感内容;
  6. 延迟、错误、拒绝、预算与饱和度指标有告警;
  7. 一个 Live Smoke Request 验证了部署后的真实网络路径。