Spring AI Alibaba 1.x 系列【24】结构化输出(Structured Output)

张开发
2026/4/17 18:02:48 15 分钟阅读

分享文章

Spring AI Alibaba 1.x 系列【24】结构化输出(Structured Output)
文章目录1. 核心概念1.1 什么是结构化输出1.2 Spring AI Alibaba 实现方式2. 快速入门2.1 定义输出 POJO2.2 使用 outputType2.3 使用 outputSchema3. 复杂嵌套结构3.1 商品评价分析嵌套对象3.2 文本实体分析4. 实现原理4.1 模型原生结构化输出最优4.2 ToolCall 兜底通用4.3 指令增强机制5. 错误处理策略5.1 Try-Catch 基础处理5.2 数据验证模式5.3 重试模式1. 核心概念1.1 什么是结构化输出结构化输出允许Agent按照预定义的格式返回数据替代传统的自然语言响应输入用户指令 输出格式规则输出标准JSON字符串 / 直接映射为Java POJO优势类型安全、无歧义、程序可直接消费结构化输出是AI Agent工程化落地的核心能力它让Agent摆脱自然语言的模糊性以固定格式返回数据应用程序可直接解析使用无需复杂的文本提取逻辑。1.2 Spring AI Alibaba 实现方式ReactAgent.Builder提供两个核心方法实现结构化输出outputSchema(String schema)手动指定JSON Schema字符串outputType(Class? type)传入Java类自动生成JSON Schema推荐outputType直接传入Java POJO类框架通过BeanOutputConverter自动生成JSON Schema无需手动编写 编译期类型校验。方法签名BuilderoutputType(Class?outputType)outputSchema手动传入JSON Schema字符串支持完全自定义输出格式。方法签名BuilderoutputSchema(StringoutputSchema)特性outputTypeoutputSchema使用方式直接传入 Java 类传入 JSON Schema 字符串类型安全✅ 编译期校验❌ 运行时校验维护成本低自动生成高手动维护灵活性标准格式完全自定义推荐场景绝大多数业务场景极端自定义格式场景2. 快速入门2.1 定义输出 POJO/** * 联系方式输出实体标准Java POJO */publicstaticclassContactInfo{privateStringname;privateStringemail;privateStringphone;// Getter SetterpublicStringgetName(){returnname;}publicvoidsetName(Stringname){this.namename;}publicStringgetEmail(){returnemail;}publicvoidsetEmail(Stringemail){this.emailemail;}publicStringgetPhone(){returnphone;}publicvoidsetPhone(Stringphone){this.phonephone;}}2.2 使用 outputTypeimportcom.alibaba.cloud.ai.graph.agent.ReactAgent;importcom.alibaba.cloud.ai.graph.checkpoint.savers.MemorySaver;importorg.springframework.ai.chat.messages.AssistantMessage;// 构建Agent直接指定输出类型ReactAgentagentReactAgent.builder().name(contact_extractor).model(chatModel)// 注入ChatModel.outputType(ContactInfo.class)// 核心指定输出POJO.saver(newMemorySaver()).build();// 执行调用AssistantMessageresultagent.call(从以下信息提取联系方式张三zhangsanexample.com(555) 123-4567);// 输出标准JSONSystem.out.println(result.getText());输出结果{name:张三,email:zhangsanexample.com,phone:(555) 123-4567}2.3 使用 outputSchemaimportorg.springframework.ai.converter.BeanOutputConverter;// 自动从POJO生成JSON SchemaBeanOutputConverterContactInfoconverternewBeanOutputConverter(ContactInfo.class);Stringschemaconverter.getFormat();// 构建AgentReactAgentagentReactAgent.builder().name(contact_extractor).model(chatModel).outputSchema(schema)// 传入Schema.build();3. 复杂嵌套结构结构化输出完美支持嵌套对象、数组、复杂实体适用于文本分析、评价提取、实体识别等场景。3.1 商品评价分析嵌套对象/** * 商品评价复杂输出结构 */publicstaticclassProductReview{privateintrating;privateStringsentiment;privateString[]keyPoints;privateReviewDetailsdetails;// 嵌套子类publicstaticclassReviewDetails{privateString[]pros;privateString[]cons;// Getter Setter}// Getter Setter}// 使用BeanOutputConverterProductReviewconverternewBeanOutputConverter(ProductReview.class);ReactAgentagentReactAgent.builder().name(review_analyzer).model(chatModel).outputSchema(converter.getFormat()).build();AssistantMessageresultagent.call(分析评价这个产品很棒5星好评。配送快速但价格稍贵。);3.2 文本实体分析/** * 文本分析输出结构 */publicstaticclassTextAnalysis{privateStringsummary;privateString[]keywords;privateStringsentiment;privateEntitiesentities;publicstaticclassEntities{privateString[]persons;privateString[]locations;privateString[]organizations;// Getter Setter}// Getter Setter}4. 实现原理4.1 模型原生结构化输出最优支持原生结构化输出的模型OpenAI、通义千问DashScope框架自动启用模型内置能力严格保证JSON格式模型服务端自动校验格式示例DashScopeChatOptionsoptionsDashScopeChatOptions.builder().withResponseFormat(DashScopeResponseFormat.builder().type(DashScopeResponseFormat.Type.JSON_OBJECT).build()).build();Spring AI Alibaba框架会增强系统Prompt引导模型输出格式化内容增强用户消息方法示例/InAgentLlmNode.augmentUserMessage()methodpublicvoidaugmentUserMessage(ListMessagemessages,StringoutputSchema){if(!StringUtils.hasText(outputSchema)){return;}for(intimessages.size()-1;i0;i--){Messagemessagemessages.get(i);if(messageinstanceofUserMessageuserMessage){messages.set(i,userMessage.mutate().text(userMessage.getText()System.lineSeparator()outputSchema).build());break;}}}注意相比于DashScope模型是通过增强Prompt提示词实现最终的JSON格式实现的是一个尽最大努力的效果OpenAI模型则是在模型API层面支持Json格式提供格式的严格保证支持。4.2 ToolCall 兜底通用对于不支持原生结构化输出的模型Spring AI Alibaba支持通过调用工具来实现相同效果。此方法适用于所有支持工具调用的模型即大多数现代模型。4.3 指令增强机制框架会自动在用户消息末尾追加格式指令引导模型输出规范内容// 核心增强逻辑为用户消息追加Schema指令publicvoidaugmentUserMessage(ListMessagemessages,StringoutputSchema){for(intimessages.size()-1;i0;i--){Messagemessagemessages.get(i);if(messageinstanceofUserMessageuserMessage){messages.set(i,userMessage.mutate().text(userMessage.getText()\noutputSchema).build());break;}}}5. 错误处理策略模型可能偶尔返回格式异常的JSONSpring AI Alibaba提供三种可靠的错误处理方案。5.1 Try-Catch 基础处理importcom.fasterxml.jackson.databind.ObjectMapper;ObjectMappermappernewObjectMapper();try{AssistantMessageresultagent.call(提取数据);// JSON 转 Java 对象ContactInfodatamapper.readValue(result.getText(),ContactInfo.class);}catch(JsonProcessingExceptione){System.err.println(JSON 解析失败e.getMessage());System.err.println(原始响应result.getText());}5.2 数据验证模式/** * 带校验逻辑的输出实体 */publicclassValidatedOutput{privateStringtitle;privateIntegerrating;// 自定义校验规则publicvoidvalidate(){if(titlenull||title.isEmpty()){thrownewIllegalArgumentException(标题不能为空);}if(rating1||rating5){thrownewIllegalArgumentException(评分必须在1-5之间);}}}AssistantMessageresultagent.call(生成评价);ValidatedOutputoutputmapper.readValue(result.getText(),ValidatedOutput.class);output.validate();// 如果无效则抛出异常5.3 重试模式intmaxRetries3;ContactInfodatanull;ObjectMappermappernewObjectMapper();for(inti0;imaxRetries;i){try{AssistantMessageresultagent.call(提取联系方式);datamapper.readValue(result.getText(),ContactInfo.class);break;}catch(Exceptione){if(imaxRetries-1){thrownewRuntimeException(重试maxRetries次后失败,e);}System.out.println(第(i1)次失败正在重试...);}}

更多文章