Spring AI ChatClient -Prompt 模板

模板化 Prompt 的重要性

ChatClient内置 Prompt 模板功能,支持运行时替换变量,避免硬编码 Prompt 文本。这种设计体现了模板方法模式(Template Method Pattern),通过定义算法骨架,将具体实现延迟到子类或运行时。

Prompt 的组成结构

Prompt是发送给AI模型的输入,由以下部分组成:

  • 用户消息 (User Messages)**:来自最终用户的直接输入。

  • 系统消息 (System Messages)**:系统生成的指导性消息,用于引导AI行为。

  • Prompt选项:模型配置参数,如模型名称、温度等控制参数。


方式一、基础模板使用(默认分隔符 {})

java 复制代码
import org.springframework.ai.chat.client.ChatClient;

/*
author: atg
*/ 
@Component
public class PromptTemplateDemo1 {

    private final ChatClient chatClient;

    public PromptTemplateDemo1(ChatClient.Builder chatClientBuilder) {
        this.chatClient = chatClientBuilder.build();
    }

    public String templateBasicDemo(String composer) {
        // 使用{composer}作为变量占位符
        return chatClient.prompt()
                .user(u -> u
                        .text("推荐5部由{composer}作曲的电影原声带")
                        .param("composer", composer)) // 替换变量
                .call()
                .content();
    }
}

模板参数的安全性

在使用模板参数时,需要注意:

  1. 参数验证:验证输入参数的有效性,防止注入攻击

  2. 转义处理:对特殊字符进行适当的转义

  3. 长度限制:限制参数长度,避免过长的输入

  4. 类型检查:确保参数类型符合预期


方式二、自定义模板分隔符(避免 JSON 冲突)

当 Prompt 包含 JSON 时,可自定义分隔符避免语法冲突:

java 复制代码
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.template.StTemplateRenderer;
import org.springframework.stereotype.Component;

@Component
class CustomTemplateDemo {

    private final ChatClient chatClient;

    public CustomTemplateDemo(ChatClient.Builder chatClientBuilder) {
        this.chatClient = chatClientBuilder.build();
    }

       public String customDelimiterDemo(String genre) {
        // 方法1:使用 PromptTemplate 单独处理
        PromptTemplate promptTemplate = new PromptTemplate(
                "推荐3部{genre}类型的经典电影,返回格式:{{\"title\":\"\",\"year\":\"\"}}",
                Map.of("genre", genre)
        );
        // 自定义模板分隔符为<<和>>
        return chatClient.prompt()
                .user((Resource) promptTemplate)// 配置自定义分隔符
                .call()
                .content();
    }
}

分隔符选择的考虑因素

选择自定义分隔符时,需要考虑:

  1. 冲突避免:分隔符不应在 Prompt 内容中出现

  2. 可读性:分隔符应该容易识别和理解

  3. 兼容性:确保分隔符不会引起解析问题

  4. 转义支持:支持分隔符的转义,以处理特殊情况


方式3、系统消息模板

系统消息模板允许为不同的应用场景定制 AI 行为:

java 复制代码
import org.springframework.ai.chat.client.ChatClient;

@Component
public class SystemTemplateDemo {
    private final ChatClient chatClient;

    public SystemTemplateDemo(ChatClient.Builder chatClientBuilder) {
        // 系统消息使用模板变量
        this.chatClient = chatClientBuilder
                .defaultSystem("你是一个{role}专家,专注于{domain}领域")
                .build();
    }
    
    public String domainSpecificQuery(String role, String domain, String question) {
        return chatClient.prompt()
                .system(s -> s
                    .param("role", role)
                    .param("domain", domain))
                .user(question)
                .call()
                .content();
    }
}

动态系统消息的应用场景

动态系统消息适用于:

  1. 多租户系统:为不同租户定制不同的 AI 行为

  2. 领域专家:根据问题领域切换专业角色

  3. 语言本地化:根据用户语言偏好调整系统消息

相关推荐
寻星探路21 小时前
【深度长文】万字攻克网络原理:从 HTTP 报文解构到 HTTPS 终极加密逻辑
java·开发语言·网络·python·http·ai·https
想用offer打牌1 天前
MCP (Model Context Protocol) 技术理解 - 第二篇
后端·aigc·mcp
曹牧1 天前
Spring Boot:如何测试Java Controller中的POST请求?
java·开发语言
KYGALYX1 天前
服务异步通信
开发语言·后端·微服务·ruby
掘了1 天前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
爬山算法1 天前
Hibernate(90)如何在故障注入测试中使用Hibernate?
java·后端·hibernate
kfyty7251 天前
集成 spring-ai 2.x 实践中遇到的一些问题及解决方案
java·人工智能·spring-ai
猫头虎1 天前
如何排查并解决项目启动时报错Error encountered while processing: java.io.IOException: closed 的问题
java·开发语言·jvm·spring boot·python·开源·maven
李少兄1 天前
在 IntelliJ IDEA 中修改 Git 远程仓库地址
java·git·intellij-idea