LangChain4j 让 AI 返回 Java 对象
本文介绍如何 LangChain4j 的结构化输出,让 AI 返回 Java 对象, 这是 LangChain4j 最强大的功能之一!你可以让 AI 直接返回 JSON,并自动映射成 Java 对象。
一、痛点:AI返回字符串,然后呢?
上一篇文章中,我们让AI回答了一个问题,返回的是String。但在实际业务中,我们想要的往往不止是一段文字:
- 做一个情感分析,想要返回
POSITIVE、NEGATIVE、NEUTRAL枚举 - 做信息抽取,想要直接得到一个
Person对象(包含姓名、年龄、地址) - 做意图识别,想要返回结构化的意图分类和参数
如果每次都解析字符串,代码会变成这样:
java
1 | String response = ai.chat("张三,25岁,住在北京"); |
LangChain4j直接解决了这个问题:你告诉它你要什么类型,它自动把AI输出转成那个类型。支持String、基本类型、枚举、List、Map,以及自定义POJO。
二、开箱即用的类型支持
2.1 基本类型和包装类
最简单的用法:直接让AI返回int、boolean、double等。
java
1 |
|
使用示例:
java
1 |
|
2.2 枚举类型
适合情感分析、意图识别等场景:
java
1 |
|
调用效果:
java
1 | Sentiment result = analyzer.analyze("这个产品太棒了!"); |
2.3 List和Set集合
当AI需要返回多个结果时非常实用:
java
1 |
|
💡 小技巧:在
@UserMessage中提示AI返回JSON数组格式,成功率会大幅提升。
三、核心技巧:自定义POJO对象
这才是真正的杀手锏。定义一个普通的Java类,LangChain4j会自动把AI输出映射成这个对象。
3.1 基础用法
java
1 | // 1. 定义POJO |
调用一下看看效果:
java
1 | String text = "我叫张三,今年28岁,在上海工作。"; |
就这么简单!LangChain4j内部使用Jackson/Gson自动解析JSON,你完全不用操心解析逻辑。
注意:
💡 虽然我们定义的枚举类型是英文,但是 AI 会自动将提示词文本信息中的中文信息与英文做适配,查看请求日志会发现LangChain4j 帮我们加了:
You must answer strictly in the following JSON format: {\n"name": (type: string),\n"age": (type: integer),\n"city": (type: string)\n}”
AI 在训练时做了大量了中英文翻译对照,所以对于一些常见的单词是可以做适配的。
3.2 @Description:给字段加”说明书”
AI毕竟不是人,有时候不知道字段的含义。@Description注解可以给字段添加说明,帮助AI更准确地填充数据:
java
1 |
|
@Description就像是在告诉AI:”这个字段是干这个用的,你看着填”。对于复杂的业务场景,这个注解能显著提高输出准确率。
3.3 嵌套对象
POJO里面套POJO?没问题,LangChain4j完全支持:
java
1 |
|
四、进阶技巧:处理复杂场景
4.1 @V注解:动态模板变量
@V注解用于将方法参数绑定到提示词模板中的变量{{变量名}}:
java
1 |
|
1 |
|
4.2 @StructuredPrompt:结构化提示词
当提示词比较复杂时,可以封装成一个带注解的类:
java
1 |
|
这样调用起来更优雅:
java
1 | LegalPrompt prompt = new LegalPrompt(); |
4.3 Result:获取更多元信息
如果除了AI的回答内容,你还想要token消耗、调用原因等信息,可以用Result<T>包装:
java
1 |
|
Result<T>会保留完整的调用上下文,非常适合生产环境的监控和调试。
4.4 开启JSON模式提高准确性
对于支持JSON模式的模型(如OpenAI、通义千问),可以开启严格JSON模式,强制AI输出合法的JSON:
java
1 | OpenAiChatModel model = OpenAiChatModel.builder() |
开启后,AI输出不符合JSON规范时会自动重试或报错,大大提高了结构化输出的成功率。
附:
{{it}}在 LangChain4j 中的含义是 LangChain4j 提示词模板中的一个**特殊占位符变量**,表示"当前输入参数"。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
1. 为什么会有 `{{it}}`?
在 `@UserMessage` 注解中,你可以动态插入方法参数的值。最常用的是**命名变量**(如 ```{{text}}```),但当方法只有一个参数且没有指定变量名时,框架会自动将这个参数绑定到 ```{{it}}```。
简单说:**```{{it}}``` 就是"它",代表那个唯一的输入参数**。
2. 具体用法对比
2.1 只有一个参数,没写 `@V`
```java
@AiService
public interface MyAssistant {
// 只有一个参数,可以直接用 {{it}}
@UserMessage("翻译成中文:{{it}}")
String translate(String text);
}
// 调用时,text的值会自动替换 {{it}}
translate.translate("Hello World");
// 实际发送给AI的提示词:翻译成中文:Hello World2.2 只有一个参数,但写了
@V
1
2
3
4
5
6
7
public interface MyAssistant {
// 用 @V 指定了变量名为 content,这时就不能用 {{it}} 了
String translate( String text);
}2.3 多个参数,必须用命名变量
1
2
3
4
5
6
7
8
9
10
11
public interface MyAssistant {
// 多个参数时,必须用 @V 指定变量名,不能用 {{it}}
String translate(
String text,
String sourceLang,
String targetLang
);
}
- 与其他语法的对比
写法 含义 适用场景 {{it}}代表唯一的那个参数 只有一个参数,且没写 @V{{变量名}}代表 @V("变量名")绑定的参数多个参数,或想明确命名 {{?变量名}}可选参数,如果为null则替换为空 参数可能为空时
实际代码示例
1
2
3
4
5
6
7
8
9
10
11
12 // 正确示例1:参数名随意,用 {{it}} 表示它
String analyze(String anyName); // anyName 自动绑定到 it
// 正确示例2:明确指定变量名
String analyze( String text); //
// 正确示例3:利用编译参数 -parameters,可以省略 @V
// 前提是 Maven/Gradle 配置了 -parameters 编译选项
String analyze(String text); // 参数名 text 自动作为变量名最佳实践建议
- 单参数简单场景:用
{{it}}最简洁- 多参数或复杂场景:用
@V命名变量,代码可读性更好- 团队协作项目:建议统一使用
@V命名变量,避免{{it}}带来的困惑
1
2
3
4
5
6
7 // 推荐:清晰明确
String extract( String text, String field);
// 可以但不推荐:it 语义不清晰
String extract(String text);
五、实战:完整的信息抽取示例
把上面学到的综合起来,实现一个完整的信息抽取服务:
java
1 | // POJO定义 |
输入一段非结构化文本:
“张小明,电话18888888888,邮箱zhangxm@example.com,就职于某某科技有限公司,担任技术经理。”
输出就是一个完整的ContactInfo对象,所有字段都已填好。
六、注意事项与最佳实践
6.1 给AI足够的提示
结构化输出的关键在于提示词要清晰。如果AI总是填不对,试试:
- 在
@UserMessage中明确说明输出格式 - 使用
@Description给字段加说明 - 在SystemMessage中强调”只返回JSON,不要有其他内容”
6.2 字段命名用英文
AI训练数据中英文字段名更常见。如果你的POJO字段是中文名,AI可能不知道该怎么填。
6.3 处理异常情况
AI的输出不一定100%符合预期,建议加一层兜底。
七、总结
LangChain4j的结构化输出能力,让Java开发者可以像调用普通方法一样使用大模型——输入文本,输出对象。核心要点:
| 场景 | 推荐方案 |
|---|---|
| 简单类型(数字、布尔) | 直接用int、boolean作为返回类型 |
| 枚举类型 | 定义enum,AI自动匹配 |
| 集合类型 | 用List<T>、Set<T> |
| 复杂对象 | 自定义POJO + @Description |
| 需要token等元信息 | 用Result<T>包装 |
| 动态提示词 | 用@V绑定参数 |
- Title: LangChain4j 让 AI 返回 Java 对象
- Author: 薛定谔的汪
- Created at : 2025-03-15 18:01:54
- Updated at : 2026-04-07 19:24:34
- Link: https://www.zhengyk.cn/2025/03/15/ai/langchain4j_02_pojo/
- License: This work is licensed under CC BY-NC-SA 4.0.