LangChain4j结构化输出教程:从文本中提取结构化数据
什么是结构化输出
结构化输出是指让大型语言模型(LLM)按照预定义的结构格式(通常是JSON)生成输出内容的能力。这种能力对于从非结构化文本中提取结构化数据特别有用,可以方便地将输出映射到Java对象并在应用程序中使用。
应用场景示例
假设我们需要从以下非结构化文本中提取个人信息:
John今年42岁,过着独立的生活。
他身高1.75米,举止自信。
目前未婚,享受着专注于个人目标和兴趣的自由。
我们希望将这些信息提取到一个Person对象中:
record Person(String name, int age, double height, boolean married) {}
实现结构化输出的三种方法
LangChain4j提供了三种实现结构化输出的方法,按可靠性从高到低排序:
- JSON Schema(最可靠)
- 提示词+JSON模式
- 仅使用提示词
本文将重点介绍最可靠的JSON Schema方法。
JSON Schema方法详解
JSON Schema是一种描述JSON数据结构的规范。通过为LLM提供JSON Schema,我们可以确保模型输出符合我们预期的格式。
支持的LLM提供商
目前支持JSON Schema功能的LLM提供商包括:
- Azure OpenAI
- Google AI Gemini
- Mistral
- Ollama
- OpenAI
底层ChatModel API使用示例
在底层ChatModel API中,可以通过ResponseFormat和JsonSchema来指定输出格式:
// 1. 定义响应格式和JSON Schema
ResponseFormat responseFormat = ResponseFormat.builder()
.type(JSON)
.jsonSchema(JsonSchema.builder()
.name("Person")
.rootElement(JsonObjectSchema.builder()
.addStringProperty("name")
.addIntegerProperty("age")
.addNumberProperty("height")
.addBooleanProperty("married")
.required("name", "age", "height", "married")
.build())
.build())
.build();
// 2. 创建用户消息
UserMessage userMessage = UserMessage.from("John今年42岁...");
// 3. 创建聊天请求
ChatRequest chatRequest = ChatRequest.builder()
.responseFormat(responseFormat)
.messages(userMessage)
.build();
// 4. 创建并配置ChatModel
ChatModel chatModel = OpenAiChatModel.builder()
.apiKey("your-api-key")
.modelName("gpt-4")
.build();
// 5. 发送请求并处理响应
ChatResponse chatResponse = chatModel.chat(chatRequest);
String output = chatResponse.aiMessage().text();
Person person = new ObjectMapper().readValue(output, Person.class);
JSON Schema元素类型
LangChain4j提供了多种JSON Schema元素类型来构建复杂的数据结构:
- JsonObjectSchema:表示对象类型
- JsonStringSchema:字符串类型
- JsonIntegerSchema:整数类型
- JsonNumberSchema:数字类型
- JsonBooleanSchema:布尔类型
- JsonEnumSchema:枚举类型
- JsonArraySchema:数组类型
- JsonReferenceSchema:支持递归引用
- JsonAnyOfSchema:支持多态类型
复杂示例:递归结构
// 定义递归结构(如Person包含children)
String reference = "person";
JsonObjectSchema personSchema = JsonObjectSchema.builder()
.addStringProperty("name")
.addProperty("children", JsonArraySchema.builder()
.items(JsonReferenceSchema.builder()
.reference(reference)
.build())
.build())
.definitions(Map.of(reference, JsonObjectSchema.builder()
.addStringProperty("name")
.addProperty("children", JsonArraySchema.builder()
.items(JsonReferenceSchema.builder()
.reference(reference)
.build())
.build())
.build()))
.build();
高层AI Service API使用示例
使用AI Service API可以更简洁地实现相同功能:
interface PersonExtractor {
@UserMessage("从以下文本中提取个人信息: {{it}}")
Person extractPerson(String text);
}
// 配置ChatModel
ChatModel chatModel = OpenAiChatModel.builder()
.apiKey("your-api-key")
.modelName("gpt-4")
.supportedCapabilities(Set.of(RESPONSE_FORMAT_JSON_SCHEMA))
.strictJsonSchema(true)
.build();
// 创建AI服务
PersonExtractor extractor = AiServices.create(PersonExtractor.class, chatModel);
// 使用服务
Person person = extractor.extractPerson("John今年42岁...");
最佳实践与注意事项
- 必填字段:默认所有字段都是可选的,必须显式指定required()来标记必填字段
- 描述信息:为字段添加描述可以提高输出质量
- 类型限制:
- JsonReferenceSchema和JsonAnyOfSchema目前仅支持部分提供商
- 流式模式下JSON Schema可能不受支持
- 启用JSON Schema:必须显式启用JSON Schema功能
总结
LangChain4j的JSON Schema功能为从非结构化文本中提取结构化数据提供了强大而可靠的方法。通过合理设计Schema,开发者可以确保LLM输出符合预期的数据结构,从而简化后续的数据处理流程。无论是使用底层API还是高层AI Service,LangChain4j都提供了简洁而强大的工具来实现这一目标。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考