927 字
约 3 分钟
2
Spring AI 结构化返回:把 LLM 输出变成 Java 对象

Spring AI 结构化返回:把 LLM 输出变成 Java 对象

大模型最麻烦的一点是:它喜欢返回自然语言,但业务代码需要结构化数据。

比如用户输入:

我是 2026 届计算机硕士,想去武汉国企做 Java 开发。

我们真正希望得到的是:

UserInterest(
    "2026",
    "武汉",
    "国企",
    "Java开发"
)

Spring AI 的 Structured Output 就是用来解决这个问题的。

1. .entity():最常用的方式

UserInfo result = chatClient.prompt()
        .user(text)
        .call()
        .entity(UserInfo.class);

Spring AI 会根据 UserInfo 生成结构约束,让模型按指定 JSON 返回,再自动转成 Java 对象。

可以简单理解为:

自然语言
→ LLM
→ JSON
→ Java Object

所以只要 LLM 的结果还要继续交给程序处理,优先考虑 .entity(),而不是直接拿 String

2. record 很适合结构化返回

推荐这样定义 DTO:

public record UserInfo(

    @JsonPropertyDescription("城市,如 武汉、北京、上海")
    String city,

    @JsonPropertyDescription("公司类型,如 国企、私企、事业单位")
    String companyType,

    @JsonPropertyDescription("岗位方向,如 Java开发、前端开发")
    String position

) {}

record 字段固定、不可变,很适合作为 LLM 返回对象。

而且 @JsonPropertyDescription 不只是注释,它其实也是 Prompt 的一部分

比如:

@JsonPropertyDescription("公司类型")

不如:

@JsonPropertyDescription("公司类型,如 国企、私企、事业单位")

后者能明显缩小模型自由发挥的范围。

3. 三个典型使用场景

意图识别

用户消息
→ LLM
→ intent + confidence + reason
→ 业务路由

例如:

public record IntentResult(
    IntentType intent,
    double confidence,
    String reason
) {}

适合客服分类、消息路由、任务分类。

信息抽取

自由文本
→ LLM
→ Java DTO
→ 数据库

适合:

简历解析
用户画像
合同解析
招聘信息提取
订单信息提取

数据采集

网页
→ 爬虫
→ LLM
→ Structured Output
→ 数据库

LLM 在这里其实扮演的是:

非结构化数据 → 结构化数据转换器。

4. 泛型要用 ParameterizedTypeReference

单个对象:

.entity(UserInfo.class);

如果返回:

List<UserInfo>

则需要保留泛型信息:

.entity(
    new ParameterizedTypeReference<List<UserInfo>>() {}
);

这是 Java 类型擦除导致的。

5. 结构化返回不代表绝对可靠

即使用了 .entity(),依然可能遇到:

JSON 格式错误
字段缺失
字段值不合法
输出太长被截断
模型理解错误

所以生产环境还需要:

Validation
Try-Catch
Fallback
Retry

例如:

try {
    Result result = chatClient.prompt()
            .user(text)
            .call()
            .entity(Result.class);

    validate(result);

} catch (Exception e) {
    fallback();
}

6. 大数据量要防止截断

如果一次让模型返回几十、上百条数据,JSON 很容易因为 Token 上限被截断。

这时不能完全依赖 .entity(),而要考虑:

ChatMemory
+
多轮续写
+
手动解析
+
保留已成功数据

核心思想是:

能成功多少就保留多少,不要因为最后一次失败,把前面已经解析的数据全部丢掉。

7. 最值得沉淀的一句话

Structured Output 真正解决的不是“JSON 转 Java”。

而是:

在 LLM 和业务代码之间建立一个强类型、可验证、可降级的数据边界。

以后看到下面这种场景:

自然语言
→ 业务需要固定字段

第一反应就应该是:

Structured Output
+
record
+
@JsonPropertyDescription
+
Validation
+
Fallback

这才是 Spring AI 结构化返回真正值得掌握的地方。

Spring AI 结构化返回:把 LLM 输出变成 Java 对象
http://www.clxhxhhr.top/posts/655/
作者
clxstart
发布于
2026-09-17
许可协议
CC BY-NC-SA 4.0
评论
0 条
还没有评论,先写一条吧。