深入理解并掌握 Spring AI 与 Open AI 的使用方法( 二 )

通过使用提示词模板,我们可以隐藏创建提示词的复杂性 , 并为用户提供一个简单的接口 。
在上述示例中,我们创建了代表用户消息的提示词 。我们可以使用 SystemMessage 来表示 LLM 在对话中的角色 。
@Serviceclass JokeService {private final ChatClient chatClient;JokeService(ChatClient chatClient) {this.chatClient = chatClient;}String getJoke(String subject) {SystemMessage systemMessage = new SystemMessage("你是一个有用又风趣的聊天机器人");UserMessage userMessage = new UserMessage("告诉我一个关于 " + subject +" 的笑话");Prompt prompt = new Prompt(List.of(systemMessage, userMessage));ChatResponse response = chatClient.call(prompt);return response.getResult().getOutput().getContent();}}在上述示例中,我们创建了一个系统消息和用户消息 , 以代表用户和 LLM 之间的对话 。通过使用系统消息,我们可以定义角色并向 LLM 提供额外的上下文 。

深入理解并掌握 Spring AI 与 Open AI 的使用方法

文章插图
使用输出解析器
在前面的例子中,我们将 LLM 的回应作为字符串获取 。我们可以使用输出解析器来解析回应并以所需格式提取所需信息 。
目前,Spring AI 提供了以下类型的输出解析器:
BeanOutputParser - 用于解析回应并转换成Java Bean 。
MapOutputParser - 用于解析回应并转换成Map 。
ListOutputParser - 用于解析回应并转换成List 。
我们创建了一个新的 MovieController 控制器,用来获取某位导演导演的电影列表 。
@RestControllerclass MovieController {private final ChatClient chatClient;MovieController(ChatClient chatClient) {this.chatClient = chatClient;}private static final String PROMPT_TEMPLATE = """What are the best movies directed by {director}?{format}""";//...}现在,让我们来看一下如何使用 BeanOutputParser 来解析响应并将其转换为 Java Bean 。
record DirectorResponse(String director, List<String> movies) {}@RestControllerclass MovieController {//...@GetMapping("/ai/chat/movies")DirectorResponse chat(@RequestParam String director) {var outputParser = new BeanOutputParser<>(DirectorResponse.class);var userPromptTemplate = new PromptTemplate(PROMPT_TEMPLATE);Map<String, Object> model = Map.of("director", director, "format", outputParser.getFormat());var prompt = userPromptTemplate.create(model);var response = chatClient.call(prompt);return outputParser.parse(response.getResult().getOutput().getContent());}}在上述示例中,我们创建了一个名为 DirectorResponse 的 Java Bean,用于表示 LLM 的响应 。BeanOutputParser 将解析响应并将其转为 DirectorResponse 对象 。
同样,我们可以使用 MapOutputParser 和 ListOutputParser 来解析响应并分别将其转换为 Map 和 List 。
@RestControllerclass MovieController {//...@GetMapping("/ai/chat/movies-as-map")Map<String, Object> chatWithMapOutput(@RequestParam String director) {var outputParser = new MapOutputParser();var userPromptTemplate = new PromptTemplate(PROMPT_TEMPLATE);Map<String, Object> model = Map.of("director", director, "format", outputParser.getFormat());var prompt = userPromptTemplate.create(model);var response = chatClient.call(prompt);return outputParser.parse(response.getResult().getOutput().getContent());}@GetMapping("/ai/chat/movies-as-list")List<String> chatWithListOutput(@RequestParam String director) {var outputParser = new ListOutputParser(new DefaultConversionService());var userPromptTemplate = new PromptTemplate(PROMPT_TEMPLATE);Map<String, Object> model = Map.of("director", director, "format", outputParser.getFormat());var prompt = userPromptTemplate.create(model);var response = chatClient.call(prompt);return outputParser.parse(response.getResult().getOutput().getContent());}}我们可以按照以下方式测试API:
curl --location 'http://localhost:8080/ai/chat/movies?director=Quentin%20Tarantino'//OUTPUT:{"director":"Quentin Tarantino","movies":["Pulp Fiction","Inglourious Basterds","Django Unchained","Kill Bill: Volume 1","Kill Bill: Volume 2"]}curl --location 'http://localhost:8080/ai/chat/movies-as-map?director=Quentin%20Tarantino'//OUTPUT:{"best_movies":[{"title":"Pulp Fiction","year":1994},{"title":"Inglourious Basterds","year":2009},{"title":"Kill Bill: Volume 1","year":2003},{"title":"Kill Bill: Volume 2","year":2004},{"title":"Django Unchained","year":2012}]}curl --location 'http://localhost:8080/ai/chat/movies-as-list?director=Quentin%20Tarantino'//OUTPUT:["Pulp Fiction","Kill Bill: Volume 1","Inglourious Basterds","Django Unchained","Once Upon a Time in Hollywood"]


推荐阅读