本课目标

.entity() 让模型直接返回 Java 对象,理解底层原理与局限。


你跟模型说"提取产品信息",它给了你一段人模人样的文字。然后你开始写正则:价格在哪?名称在哪?稍微换个格式又炸了。这就是 AI 应用的初级形态——每次都用字符串解析,写一堆 fragile 的代码。Spring AI 给的答案是:模型直接返回 Java 对象,你拿到手就是反序列化好的。本讲教你怎么做、底层怎么跑、以及什么时候会翻车。

核心内容

从模型拿到一段文字再用正则解析,是 AI 应用的初级形态。Spring AI 的结构化输出直接给你反序列化好的对象:

record ProductInfo(String name, String category, double price, List<String> features) {}

ProductInfo info = chatClient.prompt()
    .user("提取产品信息:索尼 WH-1000XM5 头戴降噪耳机,售价 2999 元,支持 LDAC、30 小时续航")
    .call()
    .entity(ProductInfo.class);

底层做了三件事:

  1. 根据你的 Java 类型生成 JSON Schema 描述
  2. 把 Schema 附加到提示词末尾,要求模型按格式输出
  3. 拿到响应后用 Jackson 反序列化,失败时自动重试

支持的目标类型:record、POJO、List<T>Map<String, T>、参数化类型都可以。

List<ProductInfo> list = chatClient.prompt()
    .user("提取以下三款产品的信息:...")
    .call()
    .entity(new ParameterizedTypeReference<List<ProductInfo>>() {});

实战要点

  • 字段加 @JsonPropertyDescription("...") 能显著提升抽取准确率——等于给模型写字段说明。同样的 prompt,加了注解准确率提升 20%-50% 是常见现象。
  • 嵌套结构别超过 3 层。层数越深,模型越容易把内层字段"提升"到外层或直接漏掉。不是模型不行,是 JSON Schema 本身就越来越模糊。
  • 对稳定性要求极高的场景(金融、医疗、合同),改用模型厂商原生的 JSON mode 或 Function Calling(第 04 讲),比提示词约束更可靠。提示词约束本质上是"建议",原生 mode 是"强制"。
  • 反序列化失败会自动重试,但重试次数有限(默认 2 次)。关键路径务必加兜底:重试失败后记录原始响应、返回错误状态而不是抛异常。

一个踩坑经验:模型有时会在 JSON 前后加一段"解释性文字",比如"好的,提取结果如下:{...}"。Spring AI 会尝试从响应中提取 JSON,但不保证 100% 成功。如果你的业务不能容忍这个不确定性,加原生 JSON mode。