You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Plumber API中与`req$postBody`进行有效交互?

问题描述

我们团队正在用vetiver包将模型部署到生产环境,预测端点接收JSON请求的功能正常,但需要在请求发送到预测端点前,对请求体做检查和数据补充。目前的问题是没法和req$postBody有效交互。

我们试过在过滤器端点里用jsonlite::fromJSON(req$postBody)转换请求,也试过直接对req$postBody执行ncol()这类操作,代码示例如下:

library(plumber)
library(vetiver)

cars_lm <- lm(mpg ~ ., data = mtcars)
v <- vetiver_model(cars_lm, "cars_linear")

augment_data <- data.frame(
  'extra_1' = 4,
  'extra_2' = 2
)

pr() %>% 
  pr_filter("/dim", function(req) {cat(ncol(req$postBody)); plumber::forward()}) %>%
  pr_filter("/augment", function(req) {req$postBody <- cbind(req$postBody, augment_data); plumber::forward()}) %>%
  vetiver_api(v) %>%
  pr_run()
解决方案

req$postBody本质是原始JSON字符串,不是数据框,所以直接用ncol()或cbind()这类数据框操作会失效。正确的处理流程是:解析JSON为数据框 → 检查/修改数据 → 重新序列化为JSON字符串。

修正后的代码如下:

library(plumber)
library(vetiver)
library(jsonlite)

cars_lm <- lm(mpg ~ ., data = mtcars)
v <- vetiver_model(cars_lm, "cars_linear")

# 生成匹配请求行数的补充数据
get_augment_data <- function(n_rows) {
  data.frame(
    extra_1 = rep(4, n_rows),
    extra_2 = rep(2, n_rows)
  )
}

pr() %>% 
  # 检查请求体列数的过滤器
  pr_filter("/predict", function(req) {
    # 解析JSON为数据结构
    req_data <- fromJSON(req$postBody)
    # 统一转换为数据框(兼容单条/批量请求)
    if (is.list(req_data) && !is.data.frame(req_data)) {
      req_data <- as.data.frame(req_data)
    }
    cat("请求体列数:", ncol(req_data), "\n")
    plumber::forward()
  }) %>%
  # 补充数据的过滤器
  pr_filter("/predict", function(req) {
    # 解析JSON为数据框
    req_data <- fromJSON(req$postBody)
    # 处理单条请求的列表格式
    if (is.list(req_data) && !is.data.frame(req_data)) {
      req_data <- as.data.frame(req_data)
    }
    # 拼接补充数据,保证行数匹配
    augmented_data <- cbind(req_data, get_augment_data(nrow(req_data)))
    # 重新序列化为JSON,覆盖原请求体
    req$postBody <- toJSON(augmented_data, auto_unbox = FALSE)
    plumber::forward()
  }) %>%
  vetiver_api(v) %>%
  pr_run(port = 8080)
关键注意点
  • 兼容单条/批量请求:单条JSON请求解析后是列表,批量请求是数据框,需统一转换为数据框处理。
  • 保证数据行数匹配:批量请求时,补充数据的行数要和请求数据一致,避免拼接报错。
  • 序列化格式正确:用auto_unbox = FALSE确保输出的JSON符合vetiver预测端点的格式要求。

内容的提问来源于stack exchange,提问作者robtimus_prime

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 11:35:36