Java for You AI Java 17 调用视觉 Responses API:JSON 约束与人工复核路由

Java 17 调用视觉 Responses API:JSON 约束与人工复核路由

代码与咖啡

商品运营最怕的不是 AI 不认识一张图,而是它自信地把错误尺寸、材质或适用人群写进商品页。图像理解可以把人工从“每张都抄字段”变成“只处理模糊和高风险样本”,但模型输出应是候选信息,不是库存系统的写权限。本文用 Java 17 的标准 HTTP 客户端请求视觉模型,把 JSON 候选解析成明确的 AUTO 或 REVIEW 决策;不依赖尚未确认版本的 Java SDK。

OpenAI 的图像与视觉官方指南说明,Responses API 可以在输入中同时放文本和 input_image。10 月 7 日 GPT-6 与 Intelligent UI 的发布是本文的更新钩子,而非性能保证:我们只利用公开文档定义的多模态请求形状。真正决定是否自动发布的,是业务规则、人工抽检与证据保留。

mermaid diagram

环境准备

需要 Java 17+ 和 Maven。代码只使用 JDK 自带 HttpClient,原因是这条 REST 调用足够简单,且能把依赖与版本风险降到最低。设置变量后运行;图片 URL 应指向有权处理的文件,绝不把用户私图随意暴露到公网。

export OPENAI_API_KEY='你的密钥'
export OPENAI_MODEL='gpt-6'
mvn -q -DskipTests package
java -cp target/classes ProductImageReview

创建 pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0"><modelVersion>4.0.0</modelVersion>
<groupId>ai.demo</groupId><artifactId>vision-review</artifactId><version>1.0</version>
<properties><maven.compiler.release>17</maven.compiler.release></properties></project>

完整代码

// src/main/java/ProductImageReview.java
import java.net.URI; import java.net.http.*; import java.time.Duration;
import java.util.regex.*;

public class ProductImageReview {
  static String esc(String s) { return s.replace("\\", "\\\\").replace("\"", "\\\""); }
  static String field(String json, String name) {
    Matcher m = Pattern.compile("\\\"" + name + "\\\"\\s*:\\s*\\\"([^\\\"]*)").matcher(json);
    return m.find() ? m.group(1) : "";
  }
  static double confidence(String json) {
    Matcher m = Pattern.compile("\\\"confidence\\\"\\s*:\\s*([0-9.]+)").matcher(json);
    return m.find() ? Double.parseDouble(m.group(1)) : 0;
  }
  static String decide(String json) {
    String category = field(json, "category"), material = field(json, "material");
    return confidence(json) >= 0.90 && !category.isBlank() && !material.isBlank() ? "AUTO" : "REVIEW";
  }
  public static void main(String[] args) throws Exception {
    String key = System.getenv("OPENAI_API_KEY"), model = System.getenv().getOrDefault("OPENAI_MODEL", "gpt-6");
    if (key == null || key.isBlank()) throw new IllegalStateException("请设置 OPENAI_API_KEY");
    String imageUrl = "https://example.com/authorized-product.jpg"; // 换成已授权 URL
    String prompt = "识别商品图,只返回 JSON:{\"category\":\"\",\"material\":\"\",\"confidence\":0.0}";
    String body = "{\"model\":\""+esc(model)+"\",\"input\":[{\"role\":\"user\",\"content\":["
      +"{\"type\":\"input_text\",\"text\":\""+esc(prompt)+"\"},"
      +"{\"type\":\"input_image\",\"image_url\":\""+esc(imageUrl)+"\"}]}]}";
    HttpRequest request = HttpRequest.newBuilder(URI.create("https://api.openai.com/v1/responses"))
      .timeout(Duration.ofSeconds(30)).header("Authorization", "Bearer " + key)
      .header("Content-Type", "application/json").POST(HttpRequest.BodyPublishers.ofString(body)).build();
    HttpResponse<String> response = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build()
      .send(request, HttpResponse.BodyHandlers.ofString());
    if (response.statusCode() / 100 != 2) throw new RuntimeException("API HTTP " + response.statusCode());
    // 生产环境应使用 Jackson 读取 output_text;此最小示例假定已取得模型 JSON 文本。
    String candidate = "{\"category\":\"鞋\",\"material\":\"皮革\",\"confidence\":0.92}";
    System.out.println(decide(candidate) + " candidate=" + candidate);
  }
}

预期输出是 AUTO candidate=...;若把 confidence 改为 0.8 或删去 material,输出应为 REVIEW。示例故意不从 HTTP 响应正则提取模型文本:生产代码应使用 Jackson 等成熟 JSON 库解析 Responses 的输出数组,并为输出 JSON 设置官方支持的结构化输出约束。这里把候选 JSON 写死,是为了让门禁可脱离密钥说明清楚。

为什么门禁在模型之后

图像模型善于把像素归纳成文字,却不能替企业定义“错一次的代价”。例如童装年龄段、医疗器械、过敏原、奢侈品真伪,即使置信度很高也应强制 REVIEW。置信度本身也是模型声明,不是经过校准的概率;上线时要按品类统计人工纠错率,给每类单独设置阈值,并保留图片版本、提示词版本、模型 ID 与人工最终结论。

常见错误至少有四个:一是把本地磁盘路径当作 image_url,服务端看不到;应使用官方允许的 URL 或数据输入形式。二是只看 HTTP 200,不检查模型是否真的给出了字段;本例用空字段直接路由复核。三是金额、尺寸和库存直接自动写库;应先写草稿,并由业务系统做单位、枚举和权限校验。四是没有 30 秒请求超时,网络抖动会占满工作线程。

这个方案适合商品建档、资产盘点、质检初筛等“人机协同”任务;不适合识别人脸后决定资格、自动鉴定高价值真伪,或在没有授权的数据上批量处理。工程化下一步是用队列隔离上传与推理,按哈希去重,给每次决策创建审计记录,再让审核员的改动回流为评测集。

评测集不能只挑图片清楚的成功样本。应收集遮挡、拼图、多件商品、反光、外包装不一致和文字混杂等失败案例,并按品类和风险分层。每次更换模型、提示词或预处理,拿同一冻结样本比较自动放行率、人工改写率和严重错误率;后两项没有恶化,才扩大自动范围。权限也要落在系统里:模型只读授权对象,业务服务才写草稿,审核员确认必须记名。REVIEW 只是风险控制一层,不能替代隐私、告知和删除责任。

5 分钟实践题:把 decide 改为对 category 位于“药品、婴幼儿、奢侈品”时永远返回 REVIEW,并写三条单元测试。哪些商品字段即使模型很自信,也必须由人最终确认?

关注「蜗牛聊AI」,一起看懂技术变化背后的真正机会。


本文首发于 java4u.cn,转载请注明出处。

本文由 java4u.cn 发布,可自由转载、引用,但需署名作者且注明文章出处(作者:白色蜗牛,出处:java4u.cn)。如转载至微信公众号,请在文末添加作者公众号二维码。 https://java4u.cn/ai/3138.html

作者: 蜗牛

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

联系我们

联系我们

公众号:蜗牛互联网

在线咨询: QQ交谈

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

关注微博
返回顶部