Files
han-ai-robot-backend/src/main/java/com/hanserwei/airobot/controller/StructuredOutputController.java
Hanserwei 594adcc48d feat(ai): 新增多模态与结构化输出功能支持
- 引入 Cassandra作为聊天记忆存储后端
- 配置 DashScope 多模态模型支持图文输入- 新增结构化输出控制器,支持 Bean、Map、List 等格式转换
- 添加文生图接口,集成阿里百炼图像生成能力
- 更新应用配置以支持多模态及持久化聊天记录
- 升级依赖项,引入 DashScope SDK 和 Cassandra 支持库
- 创建 ActorFilmography 和 Book 数据模型用于结构化响应
- 调整 ChatClient 配置以适配新的多模态与记忆逻辑
2025-10-27 22:11:08 +08:00

127 lines
4.5 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.hanserwei.airobot.controller;
import com.hanserwei.airobot.model.ActorFilmography;
import com.hanserwei.airobot.model.Book;
import jakarta.annotation.Resource;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.chat.prompt.PromptTemplate;
import org.springframework.ai.converter.BeanOutputConverter;
import org.springframework.ai.converter.ListOutputConverter;
import org.springframework.ai.converter.MapOutputConverter;
import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/v8/ai")
public class StructuredOutputController {
@Resource
private ChatClient chatClient;
/**
* 示例1: BeanOutputConverter - 获取演员电影作品集
*
* @param name
* @return
*/
@GetMapping("/actor/films")
public ActorFilmography generate(@RequestParam(value = "name") String name) {
// 一次性返回结果
return chatClient.prompt()
.user(u -> u.text("""
请为演员 {actor} 生成包含5部代表作的电影作品集,
只包含 {actor} 担任主演的电影,不要包含任何解释说明。
""")
.param("actor", name))
.call()
.entity(ActorFilmography.class);
}
/**
* 示例2: MapOutputConverter - 获取编程语言信息
* @param language
* @return
*/
@GetMapping("/language-info")
public Map<String, Object> getLanguageInfo(@RequestParam(value = "lang") String language) {
String userText = """
请提供关于编程语言 {language} 的结构化信息,包含以下字段:"
name (语言名称), "
popularity (流行度排名,整数), "
features (主要特性,字符串数组), "
releaseYear (首次发布年份). "
不要包含任何解释说明,直接输出 JSON 格式数据。
""";
return chatClient.prompt()
.user(u -> u.text(userText).param("language", language))
.call()
.entity(new MapOutputConverter());
}
/**
* 示例3: ListOutputConverter - 获取城市列表
* @param country
* @return
*/
@GetMapping("/city-list")
public List<String> getCityList(@RequestParam(value = "country") String country) {
return chatClient.prompt()
.user(u -> u.text(
"""
列出 {country} 的8个主要城市名称。
不要包含任何编号、解释或其他文本,直接输出城市名称列表。
""")
.param("country", country))
.call()
.entity(new ListOutputConverter(new DefaultConversionService()));
}
/**
* 使用低级 API 的 BeanOutputConverter - 获取书籍信息
* @param bookTitle
* @return
*/
@GetMapping("/book-info")
public Book getBookInfo(@RequestParam(value = "name") String bookTitle) {
// 使用 BeanOutputConverter 定义输出格式
BeanOutputConverter<Book> converter = new BeanOutputConverter<>(Book.class);
// 提示词模板
String template = """
请提供关于书籍《{bookTitle}》的详细信息:
1. 作者姓名
2. 出版年份
3. 主要类型(数组)
4. 书籍描述不少于50字
不要包含任何解释说明,直接按指定格式输出。
{format}
""";
// 创建 Prompt
PromptTemplate promptTemplate = new PromptTemplate(template);
Prompt prompt = promptTemplate.create(Map.of(
"bookTitle", bookTitle,
"format", converter.getFormat()
));
// 调用模型并转换结果
String result = chatClient.prompt(prompt)
.call()
.content();
// 结构化转换
return converter.convert(result);
}
}