一、Spring AI 結構化輸出的定義與核心概念
Spring AI 提供了一種強大的功能,允許開發者將大型語言模型(LLM)的輸出從字符串轉換為結構化格式,如 JSON、XML 或 Java 對象。這種結構化輸出能力對于依賴可靠解析輸出值的下游應用程序至關重要。
通過 Spring AI 的結構化輸出轉換器,開發者可以快速將 AI 模型的結果轉換為可以傳遞給其他應用程序函數和方法的數據類型。轉換器在 LLM 調用之前將期望的輸出格式附加到 prompt 中,為模型提供生成所需輸出結構的明確指導。在 LLM 調用之后,轉換器獲取模型的輸出文本并將其轉換為結構化類型的實例。
二、結構化輸出的技術原理
結構化輸出的技術原理可以分為以下幾個關鍵步驟:
-
附加格式說明
在 LLM 調用之前,轉換器會將期望的輸出格式(output format instruction)附加到 prompt 中。這些指令充當藍圖,塑造模型的響應以符合指定的格式。例如:Your response should be in JSON format. The data structure for the JSON should match this Java class: java.util.HashMap Do not include any explanations, only provide a RFC8259 compliant JSON response following this format without deviation.
-
模型生成響應
LLM 根據 prompt 中的格式說明生成符合要求的輸出。 -
解析與轉換
轉換器獲取模型的輸出文本,并將其解析為結構化類型的實例。此過程涉及將原始文本輸出映射到相應的結構化數據表示,如 JSON、XML 或特定于域的數據結構。
三、Spring AI 提供的轉換器實現
Spring AI 提供了多種轉換器實現,以滿足不同的結構化輸出需求:
-
BeanOutputConverter
- 使用指定的 Java 類(例如 Bean)或
ParameterizedTypeReference
配置。 - 指示 AI 模型生成符合 JSON 模式的響應,隨后利用
ObjectMapper
將 JSON 輸出反序列化為目標類的 Java 對象實例。
- 使用指定的 Java 類(例如 Bean)或
-
MapOutputConverter
- 指導 AI 模型生成符合 RFC8259 的 JSON 響應。
- 包含一個轉換器實現,利用提供的
MessageConverter
將 JSON 負載轉換為java.util.Map<String, Object>
實例。
-
ListOutputConverter
- 指導 AI 模型生成逗號分隔的格式化輸出。
- 最終轉換器將模型文本輸出轉換為
java.util.List
。
四、結構化輸出的應用場景
結構化輸出技術廣泛應用于以下場景:
-
智能助手
將模型輸出轉換為結構化數據,用于驅動智能助手的應用邏輯。 -
數據分析
將模型生成的分析結果轉換為結構化格式,便于后續的數據處理和可視化。 -
內容生成
將模型生成的內容轉換為特定的結構化格式,用于內容管理系統或自動化生成報告。
五、結構化輸出的實現方式
以下是一些使用 Spring AI 結構化輸出的代碼示例:
1. 使用 BeanOutputConverter
import com.alibaba.cloud.ai.client.ChatClient;
import com.alibaba.cloud.ai.client.model.ChatModel;
import com.alibaba.cloud.ai.client.output.BeanOutputConverter;public class StructuredOutputExample {public static void main(String[] args) {ChatModel chatModel = ChatModel.create("your-model-id");// 定義目標類record ActorsFilms(String actor, List<String> movies) {}// 創建 BeanOutputConverterBeanOutputConverter<ActorsFilms> beanOutputConverter = new BeanOutputConverter<>(ActorsFilms.class);// 獲取格式說明String format = beanOutputConverter.getFormat();// 構建 promptString actor = "Tom Hanks";String template = """Generate the filmography of 5 movies for {actor}.{format}""";// 調用模型Generation generation = chatModel.call(new PromptTemplate(template, Map.of("actor", actor, "format", format)).create()).getResult();// 轉換為目標類ActorsFilms actorsFilms = beanOutputConverter.convert(generation.getOutput().getContent());System.out.println("Actor: " + actorsFilms.actor());System.out.println("Movies: " + actorsFilms.movies());}
}
2. 使用 MapOutputConverter
import com.alibaba.cloud.ai.client.ChatClient;
import com.alibaba.cloud.ai.client.model.ChatModel;
import com.alibaba.cloud.ai.client.output.MapOutputConverter;import java.util.Map;public class MapOutputExample {public static void main(String[] args) {ChatModel chatModel = ChatModel.create("your-model-id");// 創建 MapOutputConverterMapOutputConverter mapOutputConverter = new MapOutputConverter();// 構建 promptString subject = "an array of numbers from 1 to 9 under their key name 'numbers'";String prompt = "Provide me a List of " + subject;// 調用模型Generation generation = chatModel.call(new Prompt(prompt)).getResult();// 轉換為 MapMap<String, Object> result = mapOutputConverter.convert(generation.getOutput().getContent());System.out.println("Result: " + result);}
}
3. 使用 ListOutputConverter
import com.alibaba.cloud.ai.client.ChatClient;
import com.alibaba.cloud.ai.client.model.ChatModel;
import com.alibaba.cloud.ai.client.output.ListOutputConverter;import java.util.List;public class ListOutputExample {public static void main(String[] args) {ChatModel chatModel = ChatModel.create("your-model-id");// 創建 ListOutputConverterListOutputConverter listOutputConverter = new ListOutputConverter(new DefaultConversionService());// 構建 promptString subject = "ice cream flavors";String prompt = "List five " + subject;// 調用模型Generation generation = chatModel.call(new Prompt(prompt)).getResult();// 轉換為 ListList<String> flavors = listOutputConverter.convert(generation.getOutput().getContent());System.out.println("Flavors: " + flavors);}
}
4. 使用 ChatClient
進行結構化輸出
import com.alibaba.cloud.ai.client.ChatClient;
import com.alibaba.cloud.ai.client.model.ChatModel;public class ChatClientExample {public static void main(String[] args) {ChatModel chatModel = ChatModel.create("your-model-id");// 定義目標類record ActorsFilms(String actor, List<String> movies) {}// 使用 ChatClient 轉換為 ActorsFilms 對象ActorsFilms actorsFilms = ChatClient.create(chatModel).prompt().user(u -> u.text("Generate the filmography of 5 movies for {actor}.").param("actor", "Tom Hanks")).call().entity(ActorsFilms.class);System.out.println("Actor: " + actorsFilms.actor());System.out.println("Movies: " + actorsFilms.movies());}
}
六、結構化輸出的未來發展方向
-
多模態輸出
結合文本、圖像、音頻等多種模態數據,提升輸出的多樣性和準確性。 -
實時轉換
提高轉換器的實時性,支持更快速的輸出解析和轉換。 -
領域特定轉換
針對特定領域(如醫療、法律)提供定制化的結構化輸出轉換器。 -
自動化優化
通過機器學習技術自動優化轉換器的性能和準確性。
七、總結
Spring AI 的結構化輸出功能為開發者提供了一種強大的工具,可以將 LLM 的輸出轉換為結構化格式,從而滿足下游應用程序的需求。通過使用 Spring AI 提供的轉換器實現,開發者可以輕松地將模型輸出轉換為 JSON、XML 或 Java 對象,提高開發效率和應用可靠性。隨著技術的不斷發展,結構化輸出將在更多領域發揮重要作用,為開發者提供更多智能化的解決方案。