提示词和提示词模板

提示词和提示词模板

  • [一、 核心概念详解](#一、 核心概念详解)
    • [1. 提示词 (Prompt)](#1. 提示词 (Prompt))
    • [2. 提示词中的四大角色 (Message Roles)](#2. 提示词中的四大角色 (Message Roles))
    • [3. 提示词模板 (Prompt Template)](#3. 提示词模板 (Prompt Template))
  • [二、 代码实战示例](#二、 代码实战示例)
    • [1. 基础 Prompt 构建(手动组装消息)](#1. 基础 Prompt 构建(手动组装消息))
    • [2. 使用 PromptTemplate 动态生成提示词](#2. 使用 PromptTemplate 动态生成提示词)
    • [3. 在 ChatClient 中使用系统提示词模板](#3. 在 ChatClient 中使用系统提示词模板)
  • [三、 高级特性:提示词动态管理 (Nacos 集成)](#三、 高级特性:提示词动态管理 (Nacos 集成))
    • [1. 引入依赖](#1. 引入依赖)
    • [2. 配置 Nacos](#2. 配置 Nacos)
    • [3. 动态调用](#3. 动态调用)
  • [四、 最佳实践建议](#四、 最佳实践建议)

在 Spring AI Alibaba 中,提示词(Prompt)是与大模型(交互的核心载体,而提示词模板(Prompt Template)则是实现动态化、结构化提示词工程的关键工具。以下是对这两者的详细解析及代码实现。

一、 核心概念详解

1. 提示词 (Prompt)

Prompt 是发送给大模型的完整指令集合。在 Spring AI 中,它不仅仅是一段文本,而是一个包含消息列表(Messages)和配置选项(ChatOptions)的结构化对象。

  • 构成要素:
    • Messages:由不同角色的消息组成,包括 System(系统指令)、User(用户输入)、Assistant(历史回复)和 Tool(工具调用结果)。
    • ChatOptions:控制模型行为的参数,如温度(temperature)、最大令牌数(max_tokens)、模型名称(model)等。

2. 提示词中的四大角色 (Message Roles)

Spring AI 通过 Message 接口及其子类来区分对话中的不同角色,模型会根据角色理解上下文逻辑:

角色类型 类名 作用与优先级 示例场景
系统消息 SystemMessage 优先级最高。设定 AI 的全局行为准则、人设、语气约束。通常放在对话最前面。 "你是一个专业的 Java 专家,回答要简洁严谨。"
用户消息 UserMessage代表当前用户的真实提问或指令。 "请解释一下 Spring Boot 的自动装配原理。"
助手消息 AssistantMessage 代表模型的历史回复。用于多轮对话中让模型"记住"之前的上下文。 "Spring Boot 通过 @EnableAutoConfiguration..."
工具消息 ToolMessage 代表外部工具或函数调用的返回结果。用于增强模型获取实时信息的能力。 "查询到的北京天气是:晴,25℃。"

3. 提示词模板 (Prompt Template)

硬编码字符串作为提示词难以维护且缺乏灵活性。Prompt Template 允许开发者定义带有占位符的模板,并在运行时动态替换变量。

  • 核心机制:
    • 占位符语法:默认使用 {variableName} 格式。
    • 渲染引擎:底层默认使用 StTemplateRenderer(基于 StringTemplate 引擎),支持复杂的逻辑处理;也可配置为 NoOpTemplateRenderer(仅做简单替换)。
    • 动态性:通过 Map<String, Object> 传入变量值,生成最终的 PromptString

二、 代码实战示例

以下代码展示了如何构建基础 Prompt、使用模板动态生成 Prompt,以及在 ChatClient 中应用模板。

1. 基础 Prompt 构建(手动组装消息)

java 复制代码
import org.springframework.ai.chat.messages.SystemMessage;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class BasicPromptController {

    @Autowired
    private ChatModel chatModel;

    @GetMapping("/chat/basic")
    public String basicChat() {
        // 1. 构建系统消息:设定人设
        SystemMessage systemMessage = new SystemMessage("你是一个幽默的编程导师,擅长用比喻解释复杂概念。");
        
        // 2. 构建用户消息:具体提问
        UserMessage userMessage = new UserMessage("什么是递归?");
        
        // 3. 组装 Prompt
        Prompt prompt = new Prompt(List.of(systemMessage, userMessage));
        
        // 4. 调用模型并获取响应
        return chatModel.call(prompt).getResult().getOutput().getContent();
    }
}

2. 使用 PromptTemplate 动态生成提示词

这是企业级开发中最常用的方式,实现了提示词与业务逻辑的解偶。

java 复制代码
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.chat.prompt.PromptTemplate;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.Map;

@RestController
public class TemplatePromptController {

    @Autowired
    private ChatModel chatModel;

    @GetMapping("/chat/template")
    public String templateChat(@RequestParam String topic, @RequestParam String language) {
        // 1. 定义提示词模板,使用 {topic} 和 {language} 作为占位符
        String templateText = """
            你是一个精通 {language} 的技术专家。
            请用通俗易懂的语言解释以下概念:{topic}。
            要求:
            1. 给出一个生活中的类比。
            2. 提供一段简单的代码示例。
            """;
        
        // 2. 创建 PromptTemplate 实例
        PromptTemplate promptTemplate = new PromptTemplate(templateText);
        
        // 3. 准备动态变量
        Map<String, Object> variables = Map.of(
            "topic", topic,
            "language", language
        );
        
        // 4. 渲染并创建 Prompt 对象
        // create(variables) 方法会自动替换占位符并封装成 Prompt
        Prompt prompt = promptTemplate.create(variables);
        
        // 5. 调用模型
        return chatModel.call(prompt).getResult().getOutput().getContent();
    }
}

3. 在 ChatClient 中使用系统提示词模板

ChatClient 提供了更流畅的 API 来集成系统提示词。

java 复制代码
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ChatClientTemplateController {

    private final ChatClient chatClient;

    @Autowired
    public ChatClientTemplateController(ChatClient.Builder builder) {
        this.chatClient = builder.build();
    }

    @GetMapping("/chat/client-template")
    public String clientTemplateChat(@RequestParam String userName) {
        // 使用链式调用,动态设置 System Message
        return chatClient
            .prompt()
            // 动态设置系统指令,这里可以直接传入字符串,也可以结合 PromptTemplate 预处理后传入
            .system("你好,{name}!我是你的专属AI助手。", Map.of("name", userName)) 
            .user("今天有什么新闻?")
            .call()
            .content();
    }
}

三、 高级特性:提示词动态管理 (Nacos 集成)

在生产环境中,频繁修改提示词并重新打包部署效率极低。Spring AI Alibaba 提供了 Nacos Prompt 管理 功能,支持从 Nacos 配置中心动态加载和更新提示词模板。

1. 引入依赖

xml 复制代码
<dependency>
    <groupId>com.alibaba.cloud.ai</groupId>
    <artifactId>spring-ai-alibaba-starter-nacos-prompt</artifactId>
</dependency>

2. 配置 Nacos

application.yml 中启用 Nacos Prompt 模板支持:

yaml 复制代码
spring:
  ai:
    nacos:
      prompt:
        template:
          enabled: true
  cloud:
    nacos:
      config:
        server-addr: your-nacos-address:8848

3. 动态调用

java 复制代码
import org.springframework.ai.chat.prompt.ConfigurablePromptTemplate;
import org.springframework.ai.chat.prompt.ConfigurablePromptTemplateFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Map;

@RestController
public class NacosPromptController {

    @Autowired
    private ConfigurablePromptTemplateFactory promptTemplateFactory;

    @GetMapping("/chat/nacos")
    public String nacosChat() {
        // 从 Nacos 获取名为 "greeting_template" 的提示词模板
        // 如果 Nacos 中未配置,则使用默认的 fallback 逻辑(需自行处理或配置默认值)
        ConfigurablePromptTemplate template = promptTemplateFactory.create("greeting_template");
        
        // 渲染模板
        String renderedPrompt = template.render(Map.of("user", "张三"));
        
        // 此时 renderedPrompt 即为从云端动态获取并替换变量后的最终提示词
        return renderedPrompt;
    }
}

四、 最佳实践建议

  1. 分离关注点:不要将提示词硬编码在 Java 字符串中。对于简单的静态提示词,可以使用常量;对于复杂或经常变化的提示词,务必使用 PromptTemplate 或外部配置(如 Nacos/数据库)。
  2. 善用 System Message:将角色设定、输出格式约束(如"只返回 JSON")、安全限制等放在 SystemMessage 中,这比放在 UserMessage 中更有效且稳定。
  3. 变量校验:在使用 PromptTemplate 时,确保传入的 Map 中包含所有占位符对应的键,否则可能会抛出异常或保留原始占位符(取决于渲染器配置)。
  4. 结构化输出配合:当需要模型返回特定格式(如 JSON)时,应在 Prompt 模板中明确说明格式要求,并结合 Spring AI 的 .entity() 方法进行自动反序列化。
相关推荐
wuqingshun3141591 小时前
重写equals而不重写hashCode,会出什么问题?
java·开发语言
阿里云大数据AI技术1 小时前
DataWorks Data Agent 实战课堂(一):解锁你的7×24h全能“数据搭子”DataWorks AI助理!
大数据·人工智能·agent
得一录2 小时前
大模型中Temperature的解释
人工智能
Database_Cool_2 小时前
阿里云RDS主从延迟解决方案_只读实例半同步复制最佳实践
数据库·人工智能
我今晚不熬夜2 小时前
Java语言实现Modbus协议通过用串口读取数据(以RTU为例)
java·网络协议
XMan_Liu2 小时前
AI聊天机器人架构学习
人工智能·架构·机器人
喝拿铁写前端2 小时前
AI 时代,ESLint 应该怎么做得更好
前端·人工智能·代码规范
派叔2 小时前
老字号数字化转型的困境与路径:一个系统架构视角下的观察
大数据·人工智能·系统架构·产品运营·流量运营
阿里-于怀2 小时前
阿里云刚发布的 AgentLoop 是什么?
人工智能·阿里云·云计算