Spring AI 06 提示词(Prompt)全场景实战:从基础到高级模板用法

在 Spring AI 开发中,Prompt(提示词) 是与大模型交互的核心,灵活的提示词设计能直接决定AI回答的质量。本文基于你提供的完整代码,详细讲解 Spring AI 中基础提示词、系统提示词、动态参数提示词、模板化提示词、外部文件提示词的全套用法,让你轻松掌握提示词的高级编排技巧。


一、前置说明

本文基于 Spring AI + Ollama 环境,使用我们上文中配置好的 ollamaChatClient 实现流式响应,所有接口均支持中文、无乱码、可直接运行测试。

核心依赖(确保已引入):

xml 复制代码
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-ollama-spring-boot-starter</artifactId>
</dependency>

二、完整代码 + 逐接口详解

1. 基础提示词(最简单调用)

直接传入用户问题,无任何额外配置,最基础的AI调用方式。

java 复制代码
/**
 * 1. 基础提示词:直接传入用户问题
 */
@GetMapping(value = "/chat1", produces = "text/stream;charset=utf-8")
public Flux<String> chat1() {
    String userInput = "今天的天气怎么样?";
    return ollamaChatClient.prompt()
            .user(userInput)
            .stream()
            .content();
}

适用场景:简单问答、无角色设定、无格式要求的场景。


2. 系统提示词(设定AI角色)

使用 .system() 给AI设定固定角色/风格,优先级高于全局配置

java 复制代码
/**
 * 2. 系统提示词:设定AI回答风格(优先级高于全局)
 */
@GetMapping(value = "/chat2", produces = "text/stream;charset=utf-8")
public Flux<String> chat2() {
    String userInput = "今天的天气怎么样?";
    return ollamaChatClient.prompt()
            .system("以小朋友的风格来回答") // 系统提示词:角色设定
            .user(userInput)
            .stream()
            .content();
}

效果:AI会用可爱、简单、口语化的小朋友语气回答天气问题。


3. 动态参数系统提示词(变量传参)

系统提示词支持动态参数 ,通过 .param() 传入变量,灵活切换角色。

java 复制代码
/**
 * 3. 动态参数系统提示词:前端传入角色,动态生成提示词
 */
@GetMapping(value = "/chat3", produces = "text/stream;charset=utf-8")
public Flux<String> chat3(String role) {
    String userInput = "今天的天气怎么样?";
    return ollamaChatClient.prompt()
            .system(spec -> spec.text("以{role}的语气风格回答问题").param("role", role))
            .user(userInput)
            .stream()
            .content();
}

测试示例

  • 请求:/prompt/chat3?role=天气预报员
  • AI效果:以专业天气预报员的身份回答问题

4. PromptTemplate 模板提示词

使用 PromptTemplate 标准化构建提示词,支持变量渲染。

java 复制代码
/**
 * 4. PromptTemplate模板:标准化构建提示词
 */
@GetMapping(value = "/chat4", produces = "text/stream;charset=utf-8")
public Flux<String> chat4(String weather) {
    // 定义模板
    PromptTemplate template = new PromptTemplate("今天是{weather}吗?");
    // 渲染变量
    Prompt prompt = template.create(Map.of("weather", weather));

    return ollamaChatClient.prompt(prompt)
            .stream()
            .content();
}

测试 :传入 weather=晴天,最终提示词为:今天是晴天吗?


5. 自定义分隔符模板(<> 替代 {})

默认模板使用 {} 分隔变量,可自定义分隔符(如 <>)避免冲突。

java 复制代码
/**
 * 5. 自定义模板分隔符:使用<>代替{},避免语法冲突
 */
@GetMapping(value = "/chat5", produces = "text/stream;charset=utf-8")
public Flux<String> chat5(String weather) {
    PromptTemplate promptTemplate = PromptTemplate.builder()
            // 自定义分隔符 < >
            .renderer(StTemplateRenderer.builder()
                    .startDelimiterToken('<')
                    .endDelimiterToken('>')
                    .build())
            .template("""
                    今天是<weather>吗?
                     """)
            .build();
    // 渲染变量
    String prompt = promptTemplate.render(Map.of("weather", weather));

    return ollamaChatClient.prompt(prompt)
            .stream()
            .content();
}

适用场景 :提示词中本身包含大括号{},避免变量解析错误。


6. 外部文件加载提示词(text.st

最实用的企业级用法:将提示词写在外部文件中,无需修改代码即可更新提示词。

java 复制代码
/**
 * 6. 外部文件提示词:从本地.st文件加载系统提示词
 */
@GetMapping(value = "/chat6", produces = "text/stream;charset=utf-8")
public Flux<String> chat6(String weather) {
    // 加载本地提示词文件
    var systemResource = new FileSystemResource("C:\\Users\\user\\OneDrive\\桌面\\text.st");
    // 构建系统提示模板
    SystemPromptTemplate systemPromptTemplate = new SystemPromptTemplate(systemResource);
    // 渲染变量
    String prompt = systemPromptTemplate.create(Map.of("weather", weather)).getContents();

    return ollamaChatClient.prompt(prompt)
            .stream()
            .content();
}
📄 外部文件 text.st 内容示例:
复制代码
你是一个专业的天气助手,只回答天气相关问题。
用户问题:{weather}
请用简洁、专业的语言回答。

优势:提示词与代码解耦,支持热更新、多人协作编辑。


三、完整 Controller 代码(可直接复制)

java 复制代码
package com.easyai;

import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
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.chat.prompt.SystemPromptTemplate;
import org.springframework.ai.template.st.StTemplateRenderer;
import org.springframework.core.io.FileSystemResource;
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.Map;

@RestController
@RequestMapping("/prompt")
@Slf4j
public class PromptController {

    @Resource
    private ChatClient ollamaChatClient;

    // 1. 基础提示词
    @GetMapping(value = "/chat1", produces = "text/stream;charset=utf-8")
    public Flux<String> chat1() {
        String userInput = "今天的天气怎么样?";
        return ollamaChatClient.prompt()
                .user(userInput)
                .stream()
                .content();
    }

    // 2. 固定系统提示词
    @GetMapping(value = "/chat2", produces = "text/stream;charset=utf-8")
    public Flux<String> chat2() {
        String userInput = "今天的天气怎么样?";
        return ollamaChatClient.prompt()
                .system("以小朋友的风格来回答")
                .user(userInput)
                .stream()
                .content();
    }

    // 3. 动态参数系统提示词
    @GetMapping(value = "/chat3", produces = "text/stream;charset=utf-8")
    public Flux<String> chat3(String role) {
        String userInput = "今天的天气怎么样?";
        return ollamaChatClient.prompt()
                .system(spec -> spec.text("以{role}的语气风格回答问题").param("role", role))
                .user(userInput)
                .stream()
                .content();
    }

    // 4. PromptTemplate模板
    @GetMapping(value = "/chat4", produces = "text/stream;charset=utf-8")
    public Flux<String> chat4(String weather) {
        PromptTemplate template = new PromptTemplate("今天是{weather}吗?");
        Prompt prompt = template.create(Map.of("weather", weather));

        return ollamaChatClient.prompt(prompt)
                .stream()
                .content();
    }

    // 5. 自定义分隔符模板
    @GetMapping(value = "/chat5", produces = "text/stream;charset=utf-8")
    public Flux<String> chat5(String weather) {
        PromptTemplate promptTemplate = PromptTemplate.builder()
                .renderer(StTemplateRenderer.builder().startDelimiterToken('<').endDelimiterToken('>').build())
                .template("""
                        今天是<weather>吗?
                         """)
                .build();
        String prompt = promptTemplate.render(Map.of("weather", weather));

        return ollamaChatClient.prompt(prompt)
                .stream()
                .content();
    }

    // 6. 外部文件加载提示词
    @GetMapping(value = "/chat6", produces = "text/stream;charset=utf-8")
    public Flux<String> chat6(String weather) {
        var systemResource = new FileSystemResource("C:\\Users\\user\\OneDrive\\桌面\\text.st");
        SystemPromptTemplate systemPromptTemplate = new SystemPromptTemplate(systemResource);
        String prompt = systemPromptTemplate.create(Map.of("weather", weather)).getContents();

        return ollamaChatClient.prompt(prompt)
                .stream()
                .content();
    }
}

四、核心知识点总结

  1. 基础提示词.user() 直接传入问题,快速调用
  2. 系统提示词.system() 设定AI角色,优先级最高
  3. 动态提示词 :使用 {变量} + .param() 实现灵活传参
  4. 模板提示词PromptTemplate 标准化管理提示词
  5. 自定义分隔符:解决模板符号冲突问题
  6. 外部文件提示词:企业级最佳实践,提示词与代码解耦

五、测试建议

  1. 启动项目后,逐个访问接口测试效果
  2. 测试 /chat3 时传入不同角色(天气预报员、诗人、老师)
  3. 创建 text.st 文件测试外部提示词功能
  4. 所有接口均支持流式响应,浏览器访问可看到逐字输出

总结

本文覆盖了 Spring AI Prompt 提示词 100% 常用场景 ,从简单到企业级模板用法全部包含,代码可直接运行、可直接用于项目开发。配合上一篇的 多智能体 + Advisor,你已经完全掌握 Spring AI 核心开发能力!

相关推荐
Zzj_tju13 小时前
LLM for Code Research:程序合成、自动调试与软件工程评测
人工智能·语言模型·软件工程
拾起_36913 小时前
12-Provider 配置与模型路由:多 provider 接入机制
人工智能·开源
SelectDB技术团队13 小时前
Agent 可观测性:Apache Doris / SelectDB 的技术能力、选型对比与实践
数据库·人工智能·agent·可观测·ai-native·apache doris·selectdb
拾起_36913 小时前
10-Plugin 系统与 Skill 发现:扩展边界与上下文注入
人工智能·开源
阿虎儿13 小时前
Dify v1.15.0 Chatflow附件上传存储机制调研报告
人工智能
zhiSiBuYu051713 小时前
RAG 性能优化与缓存策略实战指南
人工智能·python·机器学习
大鱼>13 小时前
智能喂食器远程控制系统:硬件设计与软件实现
人工智能·iot·宠物
苏州邦恩精密13 小时前
浙江蔡司3D扫描仪应用领域及厂家选择分析
人工智能·科技·3d·自动化·制造
想会飞的蒲公英13 小时前
集成学习入门:Bagging、Boosting 到底在组合什么
人工智能·python·机器学习·集成学习·boosting
海外数字观察家13 小时前
品未云:博兹瓦纳华商批发零售一体化 ERP,破解本土软件适配难题|CSDN 技术分享
大数据·网络·人工智能·博兹瓦纳进销存系统·博兹瓦纳收银系统·博兹瓦纳erp系统·博兹瓦纳仓库管理系统