当前位置: 首页 > news >正文

002-Spring AI Alibaba Prompt 能力完整案例

本案例将引导您一步步构建一个 Spring Boot 应用,演示如何利用 Spring AI Alibaba 的 Prompt 模板功能,实现角色扮演和基于上下文的智能问答。

1. 案例目标

我们将创建一个包含两个核心功能的 Web 应用:

  1. AI 角色扮演 (/example/ai/roles):通过系统提示词模板,让 AI 扮演一个具有特定名字和声音风格的角色,并以该角色的口吻回答问题。
  2. 上下文问答 (/prompt/ai/stuff):根据请求参数,决定是否将一篇关于"冰壶"的维基百科文档作为上下文"填充"到提示词中,让 AI 基于该文档内容回答相关问题。

2. 技术栈与核心依赖

  • Spring Boot 3.x
  • Spring AI Alibaba (用于对接阿里云 DashScope 通义大模型)
  • Maven (项目构建工具)

在 pom.xml 中,你需要引入以下核心依赖:

com.alibaba.cloud.aispring-ai-alibaba-starter-dashscope1.0.0-M2 org.springframework.bootspring-boot-starter-web
org.springframework.bootspring-boot-dependencies3.3.1pomimportcom.alibaba.cloudspring-cloud-alibaba-dependencies2023.0.1.2pomimport

3. 项目配置

在 src/main/resources/application.yml 文件中,配置你的 DashScope API Key。

spring:ai:dashscope:api-key: ${DASHSCOPE_API_KEY} # 建议使用环境变量,更安全# 可选:指定使用的模型,默认为 qwen-turbochat:options:model: qwen-plus

重要提示:请将 DASHSCOPE_API_KEY 环境变量设置为你从阿里云获取的有效 API Key。你也可以直接将其写在配置文件中,但这不推荐用于生产环境。

4. 准备 Prompt 模板文件

在 src/main/resources 目录下创建以下文件结构:

src/main/resources/
├── docs/
│   └── wikipedia-curling.md
└── prompts/├── system-message.st└── qa-prompt.st

4.1 docs/wikipedia-curling.md

这是我们将用作上下文的文档内容。

# Curling
Curling is a sport in which players slide stones on a sheet of ice toward a target area which is segmented into four concentric circles. It is related to bowls, boules and shuffleboard. Two teams, each with four players, take turns sliding heavy, polished granite stones, also called rocks, across the ice curling sheet toward the house, a circular target marked on the ice. Each team has eight stones. The purpose is to accumulate the highest score for a game; points are scored for the stones resting closest to the centre of the house at the conclusion of each end, which is completed when both teams have thrown all of their stones. A game usually consists of eight or ten ends.
The curler can induce a curved path by causing the stone to slowly turn as it slides, and the path of the rock may be further influenced by two sweepers with brooms who accompany it as it slides down the sheet, using the brooms to alter the state of the ice in front of the stone. A great deal of strategy and teamwork goes into choosing the ideal path and placement of a stone for each situation, and the skills of the curlers determine how close to the desired result the stone will achieve. This gives curling its nickname of "chess on ice".

4.2 prompts/system-message.st

系统提示词模板,用于定义 AI 的角色。

你是一个乐于助人的 AI 助手。你的名字是 {name},你的说话风格是 {voice}。
请始终保持这个角色设定与用户进行对话。

4.3 prompts/qa-prompt.st

问答提示词模板,用于注入上下文和问题。

请根据提供的上下文信息来回答用户的问题。如果上下文中没有相关信息,请说你不知道。
上下文信息:
---
{context}
---
用户问题: {question}

5. 编写 Java 代码

5.1 RoleController.java

实现 AI 角色扮演功能。

package com.example.demo.controller;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.chat.prompt.SystemPromptTemplate;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/example/ai")
public class RoleController {private final ChatClient chatClient;// 注入系统提示词模板文件@Value("classpath:/prompts/system-message.st")private Resource systemResource;// 构造函数注入 ChatClientpublic RoleController(ChatClient.Builder chatClientBuilder) {this.chatClient = chatClientBuilder.build();}/*** 生成角色扮演对话* @param message 用户消息* @param name AI 角色名字* @param voice AI 说话风格* @return 流式响应*/@GetMapping("/roles")public Flux generate(String message, String name, String voice) {// 1. 创建用户消息UserMessage userMessage = new UserMessage(message);// 2. 使用系统提示词模板并填充变量SystemPromptTemplate systemPromptTemplate = new SystemPromptTemplate(systemResource);Message systemMessage = systemPromptTemplate.createMessage(Map.of("name", name, "voice", voice));// 3. 调用大模型,传入系统消息和用户消息return chatClient.prompt(new Prompt(List.of(systemMessage, userMessage))).stream().content();}
}

5.2 StuffController.java

实现基于上下文的问答功能。

package com.example.demo.controller;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.chat.prompt.PromptTemplate;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;
import java.util.HashMap;
import java.util.Map;
@RestController
@RequestMapping("/prompt/ai")
public class StuffController {private final ChatClient chatClient;// 注入要填充的文档资源@Value("classpath:/docs/wikipedia-curling.md")private Resource docsToStuffResource;// 注入问答提示词模板@Value("classpath:/prompts/qa-prompt.st")private Resource qaPromptResource;public StuffController(ChatClient.Builder chatClientBuilder) {this.chatClient = chatClientBuilder.build();}/*** 根据上下文回答问题* @param message 用户问题* @param stuffit 是否填充上下文* @return 流式响应*/@GetMapping(value = "/stuff")public Flux completion(String message, boolean stuffit) {// 1. 创建提示词模板PromptTemplate promptTemplate = new PromptTemplate(qaPromptResource);Map map = new HashMap<>();map.put("question", message);// 2. 根据参数决定是否填充上下文信息if (stuffit) {map.put("context", docsToStuffResource);} else {map.put("context", ""); // 不填充时,传入空字符串}// 3. 创建最终的 Prompt 并调用模型return chatClient.prompt(promptTemplate.create(map)).stream().content();}
}

6. 运行与测试

  1. 启动应用:运行你的 Spring Boot 主程序。
  2. 使用浏览器或 API 工具(如 Postman, curl)进行测试

测试 1:AI 角色扮演

访问以下 URL,让 AI 扮演一个名叫"阿尔法"、声音"沉稳而富有磁性"的助手,询问它今天天气如何。

http://localhost:8080/example/ai/roles?message=今天天气怎么样?&name=阿尔法&voice=沉稳而富有磁性

预期响应(流式输出)

你好,我是阿尔法。关于今天的天气,我无法直接获取实时信息,建议您查看当地的天气预报应用。不过,无论天气如何,都希望您有愉快的一天。

测试 2:带上下文的问答

访问以下 URL,开启上下文填充,并提问"冰壶运动有几个队员?"。

http://localhost:8080/prompt/ai/stuff?message=冰壶运动有几个队员?&stuffit=true

预期响应(流式输出)

根据提供的上下文信息,冰壶运动有两支队伍,每支队伍有四名队员。

测试 3:不带上下文的问答

访问相同的 URL,但将 stuffit 设为 false,再问同样的问题。

http://localhost:8080/prompt/ai/stuff?message=冰壶运动有几个队员?&stuffit=false

预期响应(流式输出)

根据提供的上下文信息,我没有找到关于"冰壶运动有几个队员"的相关信息,所以我无法回答这个问题。

7. 实现思路与扩展建议

实现思路

本案例的核心思想是"模板与数据分离"。我们将固定的提示词结构(模板)与动态变化的变量(如角色名、上下文文档)分离开来。这使得:

  • 可维护性高:修改提示词风格只需编辑 .st 文件,无需改动 Java 代码。
  • 复用性强:同一个模板可以用于不同的数据填充场景。
  • 功能强大:通过动态注入上下文,为构建检索增强生成(RAG)应用奠定了基础。

扩展建议

  • 多模板管理:可以设计一个更复杂的模板管理器,根据业务场景动态选择不同的模板。
  • 模板缓存:对于频繁使用的模板,可以增加缓存层,避免每次请求都从磁盘加载,提升性能。
  • A/B 测试:通过配置或请求头,动态切换不同版本的提示词模板,用于效果对比和优化。
  • 集成向量数据库:将 StuffController 中的静态文档替换为从向量数据库(如 Milvus, Chroma)中检索到的相关文本片段,构建真正的 RAG 系统。
http://www.jsqmd.com/news/330151/

相关文章:

  • 2026年市场靠谱的管家婆软件管理系统排行榜单,财务云/人力云/好会计/税务云/制造云,管家婆软件管理系统推荐排行榜单
  • 强烈安利8个降AIGC网站,千笔AI帮你轻松应对论文AI检测
  • Python 基础语法
  • Java继承:成员变量访问(就近原则+this/super用法)
  • 【毕业设计】SpringBoot+Vue+MySQL Spring Boot企业员工薪酬关系系统平台源码+数据库+论文+部署文档
  • HR 视角曝光:为什么有些人的简历自带“高亮”提醒,而你的在后台显示为“不匹配”?
  • 英语学习网络
  • C语言中的运算符
  • 2026 招聘平台算法大改版!还在用去年的简历模板?小心被系统判定为“僵尸用户”直接屏蔽
  • 看完就会:9个AI论文工具测评!本科生毕业论文写作全攻略
  • 实测对比后!千笔·专业学术智能体,行业天花板级的AI论文平台
  • Ai术语
  • WAF在云原生环境下的部署实用的方案与性能优化策略
  • 探寻2026年优质控制台供应商,这些厂家上榜!,室外监控杆/横臂监控杆/八角监控杆/大屏幕控制台,控制台品牌排名
  • 2026曝气池清理厂家盘点,优质服务一目了然,曝气池清理公司聚焦技术实力与行业适配性
  • Product Hunt 每日热榜 | 2026-01-31
  • 深度解析 BQ7694003:12S BMS 前端 AFE 硬件设计与软件驱动全攻略 2
  • 毕业设计开题报告-宠物商店的设计与实现
  • 爱心捐助平台开题报告
  • Sora的最强对手来了?谷歌Veo震撼发布,影视圈要变天了
  • SynPDF下载安装
  • 计算机Java毕设实战-基于SpringBoot的二手交易系统电子二手交易系统【完整源码+LW+部署说明+演示视频,全bao一条龙等】
  • 安徽眼科机构怎么选?这些优质品牌值得了解
  • 告别模糊视界!2026高口碑眼科诊所建议:专业+温度双在线
  • 学习Modbus的第三天
  • 儿童验光配镜认准这3家医院 家长实测口碑推荐|近视防控干货
  • 青少年眼科检查怎么选?3家高性价比机构实测,家长必藏
  • 全网最全8个降AIGC工具 千笔AI帮你轻松降AI率
  • 告别工具割裂,一套系统打通门店数字化全链路
  • 4家口碑爆棚的眼科精细检查机构推荐,近视防控适用