基于Spring AI构建智能Text-to-SQL转换器:一个完整的MCP

本文涉及的产品
模型在线服务 PAI-EAS,A10/V100等 500元 1个月
模型训练 PAI-DLC,100CU*H 3个月
交互式建模 PAI-DSW,每月250计算时 3个月
简介: Spring AI 更新结构化输出转换器,弃用旧版 Parser 类,引入与 Spring 框架对齐的 Converter 体系,提升命名规范与功能兼容性。新版本支持 JSON、XML 及 Java 对象转换,确保 LLM 输出结构化,便于下游应用处理。

截至 2024年5月2日,原有的 OutputParserBeanOutputParserListOutputParserMapOutputParser 类已弃用,替换为新的 StructuredOutputConverterBeanOutputConverterListOutputConverterMapOutputConverter 实现。新版本是旧版的直接替代品,功能完全兼容。此次变更主要出于命名规范调整(避免“解析”歧义),同时与 Spring 框架的 org.springframework.core.convert.converter 包对齐,引入改进功能。

结构化输出的重要性

LLM(大语言模型)生成结构化输出的能力对依赖可靠解析输出的下游应用至关重要。开发者需要快速将 AI 模型的输出转换为 JSON、XML 或 Java 类等数据类型,以便传递给其他应用功能或方法。

架构设计

Spring AI 的结构化输出转换器围绕 LLM 文本补全端点运作:

Structured Output Converter Architecture

1.调用前处理

  • 转换器将格式指令附加到提示词中,指导模型生成指定结构的输出。

2.调用后处理

  • 转换器将模型输出的原始文本转换为结构化类型实例(如 JSON、XML 或领域对象)。

注意

  • 结构化输出转换器为“尽力而为”模式,模型可能无法完全遵循格式要求,建议实现验证机制。
  • 不适用于 LLM 工具调用(Tool Calling),因其默认提供结构化输出。

结构化输出 API

StructuredOutputConverter 接口定义:

public interface StructuredOutputConverter<T> extends Converter<String, T>, FormatProvider {}

结合 Spring 的 Converter<String, T>FormatProvider 接口:

public interface FormatProvider {  
    String getFormat();  
}

数据流示例

数据流示例详细说明

以下为 StructuredOutputConverter 在 LLM 调用前后处理数据流的完整流程说明,包含代码示例和步骤分解:

1. 格式指令生成(FormatProvider 阶段)

FormatProvider 接口负责生成指导模型输出的结构化指令。以 BeanOutputConverter 为例,其生成的格式指令可能如下:

您的响应应为 JSON 格式,  
且数据结构必须严格匹配以下 JSON Schema(基于 Java 类生成):  
{  
  "type": "object",  
  "properties": {  
    "actor": {"type": "string"},  
    "movies": {"type": "array", "items": {"type": "string"}}  
  },  
  "required": ["actor", "movies"]  
}  
请勿添加任何解释性文本,仅返回符合上述 Schema 的 JSON 响应。

此指令通过 outputConverter.getFormat() 方法获取。

2. 提示词模板组装

将格式指令动态注入用户输入模板。假设原始用户请求为:

请为演员 {actor} 生成包含 5 部代表作的列表。

通过 PromptTemplate 插入格式指令:

// 定义包含占位符的模板  
String userInputTemplate = """  
    请为演员 {actor} 生成包含 5 部代表作的列表。  
    {format}  
    """;  
// 创建 PromptTemplate 并替换占位符  
Map<String, Object> params = new HashMap<>();  
params.put("actor", "汤姆·汉克斯");  
params.put("format", outputConverter.getFormat()); // 注入格式指令  
PromptTemplate promptTemplate = new PromptTemplate(userInputTemplate, params);  
Message message = promptTemplate.createMessage();  
Prompt prompt = new Prompt(message);

最终生成的提示词将包含:

请为演员 汤姆·汉克斯 生成包含 5 部代表作的列表。  
您的响应应为 JSON 格式,  
且数据结构必须严格匹配以下 JSON Schema(基于 Java 类生成):  
{  
  "type": "object",  
  "properties": {  
    "actor": {"type": "string"},  
    "movies": {"type": "array", "items": {"type": "string"}}  
  },  
  "required": ["actor", "movies"]  
}  
请勿添加任何解释性文本,仅返回符合上述 Schema 的 JSON 响应。

3. 调用 LLM 模型

通过 ChatModel发送组装后的提示词并获取原始文本输出:

// 调用模型  
ChatResponse response = chatModel.call(prompt);  
String rawOutput = response.getResult().getOutput().getText();  
// 示例模型返回结果  
// rawOutput = """  
//     {  
//       "actor": "汤姆·汉克斯",  
//       "movies": ["阿甘正传", "拯救大兵瑞恩", "费城故事", "西雅图未眠夜", "荒岛余生"]  
//     }  
//     """

4. 结构化转换(Converter 阶段)

使用 Converter 将原始文本转换为目标类型:

// 初始化转换器  
BeanOutputConverter<ActorsFilms> converter =  
    new BeanOutputConverter<>(ActorsFilms.class);  
// 执行转换  
ActorsFilms actorsFilms = converter.convert(rawOutput);  
// 输出结果  
System.out.println(actorsFilms.actor()); // 汤姆·汉克斯  
System.out.println(actorsFilms.movies()); // [阿甘正传, 拯救大兵瑞恩, ...]

完整数据流图示

关键处理细节

  • 错误处理
  • 若模型返回的 JSON 不符合 Schema,BeanOutputConverter 将抛出 JsonProcessingException
  • 建议在代码中添加异常捕获逻辑:
try {  
    ActorsFilms result = converter.convert(rawOutput);  
} catch (JsonProcessingException e) {  
 // 处理无效 JSON 格式  
} catch (IllegalArgumentException e) {  
 // 处理字段缺失或类型不匹配  
}
  • 元数据注入
  • 若目标类包含元数据字段(如 @JsonProperty 注解),转换器会自动映射:
record ActorsFilms(  
    @JsonProperty("actor_name") String actor,  
    @JsonProperty("filmography") List<String> movies  
) {}

可处理键名不一致的 JSON 输入。

  • 内容净化
  • 转换器会自动忽略 JSON 外的额外文本(如模型生成的解释性前缀/后缀):好的,以下是汤姆·汉克斯的五部代表作:
{  
  "actor": "汤姆·汉克斯",  
  "movies": ["阿甘正传", "拯救大兵瑞恩"...]  
}  
希望这个列表对您有帮助!

转换器仍能正确提取 JSON 部分。

可用转换器

Spring AI 提供以下转换器实现:

转换器类 功能描述
AbstractConversionServiceOutputConverter<T> 基于 GenericConversionService 转换输出,无默认格式提供逻辑。
AbstractMessageOutputConverter<T> 基于 MessageConverter 转换输出,无默认格式提供逻辑。
BeanOutputConverter<T> 通过 JSON Schema(基于目标类生成)指导模型输出,并用 ObjectMapper 反序列化为 Java 对象。
MapOutputConverter 生成符合 RFC8259 的 JSON,并转换为 Map<String, Object> 实例。
ListOutputConverter 生成逗号分隔列表,并通过 ConversionService 转换为 List 实例。

使用示例

Bean 输出转换器

目标类定义

@JsonPropertyOrder({"actor", "movies"})  
record ActorsFilms(String actor, List<String> movies) {}

高阶 API 调用

ActorsFilms actorsFilms = ChatClient.create(chatModel).prompt()  
        .user(u -> u.text("为 {actor} 生成5部电影作品列表。")  
                    .param("actor", "汤姆·汉克斯"))  
        .call()  
        .entity(ActorsFilms.class);

低阶 API 调用

BeanOutputConverter<ActorsFilms> converter = new BeanOutputConverter<>(ActorsFilms.class);  
String format = converter.getFormat();  
String template = "为 {actor} 生成5部电影作品列表。\n{format}";  
Prompt prompt = new PromptTemplate(template, Map.of("www.bestall.com.cn", "汤姆·汉克斯", "format", format)).create();  
Generation generation = chatModel.call(prompt).getResult();  
ActorsFilms result = converter.convert(generation.getOutput().getText());

Map 输出转换器

MapOutputConverter converter = new MapOutputConverter();  
String format = converter.getFormat();  
String template = "提供 {subject}\n{format}";  
Prompt prompt = new PromptTemplate(template,  
        Map.of("subject", "键名为 'www.hnsea.net' 的1到9数字数组", "format", format)).create();  
Map<String, Object> result = converter.convert(chatModel.call(prompt).getResult().getOutput().getText());

List 输出转换器

ListOutputConverter converter = new ListOutputConverter(new DefaultConversionService());  
String format = converter.getFormat();  
String template = "列出五种 {subject}\n{format}";  
Prompt prompt = new PromptTemplate(template,  
        Map.of("subject", "冰淇淋口味", "format", format)).create();  
List<String> flavors = converter.convert(chatModel.call(prompt).getResult().getOutput().getText());

支持结构化输出的 AI 模型

模型 集成测试类/示例
OpenAI OpenAiChatModelIT
Anthropic Claude 3 AnthropicChatModelIT.java
Azure OpenAI AzureOpenAiChatModelIT.java
Mistral AI MistralAiChatModelIT.java
Ollama OllamaChatModelIT.java
Vertex AI Gemini VertexAiGeminiChatModelIT.java

内置 JSON 模式支持

部分 AI 模型提供专用配置选项生成结构化(通常为 JSON)输出:

模型 配置项示例 功能描述
OpenAI spring.ai.openai.chat.options.responseFormat=JSON_OBJECT 强制生成符合 JSON Schema 的响应
Azure OpenAI spring.ai.azure.openai.chat.options.responseFormat={"type":"json_object"} 启用 JSON 模式
Ollama spring.ai.ollama.chat.options.format=json 指定返回 JSON 格式
Mistral AI spring.ai.mistralai.chat.options.responseFormat={"type":"json_object"} 启用 JSON 模式

关键变更说明

  • 弃用类迁移:旧版 *Parser 类需替换为对应的 *Converter 类。
  • JSON Schema 支持BeanOutputConverter 自动生成基于目标类的 JSON 模式,通过 @JsonPropertyOrder 注解可自定义属性顺序。
  • 泛型支持:使用 ParameterizedTypeReference 处理复杂泛型结构(如 List<ActorsFilms>)。
相关文章
|
17天前
|
人工智能 JavaScript 前端开发
实战使用 Qwen3-coder 低代码开发 HTML 个人网站
阿里巴巴开源的Qwen3-coder模型,凭借强大性能和低代码能力,助力用户快速搭建个人网站。本文详解环境配置、提示词设计与部署流程,适合编程新手快速上手,掌握AI辅助开发技能。
1111 8
|
2月前
|
人工智能 数据可视化 前端开发
5 分钟搞定系统架构图!魔搭社区免费工具,小白也能轻松上手
本文介绍了如何在魔搭社区创空间中免费创建一个基于代码上传生成系统架构图的应用。通过使用 Gradio 搭建前端界面,并结合后端 API 实现 Mermaid 图表转换,开发者可快速将代码转化为流程图、类图、时序图等多种架构图。该工具支持多语言、多格式输出,极大提升了技术文档编写的效率,适合不擅长绘图的小白开发者使用。文末附有完整操作教程与项目体验链接,方便读者上手实践。
455 68
5 分钟搞定系统架构图!魔搭社区免费工具,小白也能轻松上手
|
7天前
|
开发者 Python
Python中的f-string:更简洁的字符串格式化
Python中的f-string:更简洁的字符串格式化
178 93
|
7天前
|
人工智能 算法 测试技术
轻量高效,8B 性能强劲书生科学多模态模型Intern-S1-mini开源
继 7 月 26 日开源『书生』科学多模态大模型 Intern-S1 之后,上海人工智能实验室(上海AI实验室)在8月23日推出了轻量化版本 Intern-S1-mini。
261 42
|
4天前
|
编解码 自然语言处理
通义万相开源14B数字人Wan2.2-S2V!影视级音频驱动视频生成,助力专业内容创作
今天,通义万相的视频生成模型又开源了!本次开源Wan2.2-S2V-14B,是一款音频驱动的视频生成模型,可生成影视级质感的高质量视频。
98 10
|
4天前
|
机器学习/深度学习 编解码 人工智能
面壁开源多模态新旗舰MiniCPM-V 4.5,8B 性能超越 72B,高刷视频理解又准又快
今天,面壁智能正式开源 8B 参数的面壁小钢炮 MiniCPM-V 4.5 多模态旗舰模型,成为行业首个具备“高刷”视频理解能力的多模态模型,看得准、看得快,看得长!高刷视频理解、长视频理解、OCR、文档解析能力同级 SOTA,且性能超过 Qwen2.5-VL 72B,堪称最强端侧多模态模型。
93 9
|
2天前
|
编解码 区块链 Python
CERES 云层和辐射带水 FM3 MODIS 版本 2C
CER_CRS_Aqua-FM3-MODIS_Edition2C 是 NASA CERES 项目的数据产品,基于 Aqua 卫星上的 FM3 仪器,提供高精度云与辐射通量数据,涵盖 2006 年。数据包含全天空与晴空条件下四层大气通量廓线,适用于地球辐射能量系统研究。
25 3
|
13天前
|
Web App开发 存储 人工智能
iflow低代码门户网站AI生成
iflow.cn 是一个以 AI 技术为核心的多功能平台,专注于教育、研究及职场效率提升。主要功能包括 AI 辅助内容生成、知识管理、教育资源整合及跨平台使用体验。网站还提供 AI 搜索、个性化内容生成、考试辅导及效率工具,服务于学生、职场人士、研究人员等群体。需注意浏览器兼容性及内容准确性。
|
2天前
|
缓存 自然语言处理 数据可视化
知识图谱与RAG融合实战:用LightRAG极速构建智能问答系统
本文介绍了LightRAG——一种融合知识图谱与RAG技术的轻量级框架,通过三重检索机制(向量、关键词与图检索)提升问答系统的准确性与全面性,并提供快速构建、可视化、性能优化及多领域应用方案。

热门文章

最新文章