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. 语言本地化:根据用户语言偏好调整系统消息

相关推荐
kk哥889910 小时前
如何快速掌握JavaSE的核心语法?
java
我是一只小青蛙88810 小时前
AVL树:平衡二叉搜索树原理与C++实战
java·jvm·面试
浩瀚地学10 小时前
【Java】JDK8的一些新特性
java·开发语言·经验分享·笔记·学习
XXOOXRT11 小时前
基于SpringBoot的加法计算器
java·spring boot·后端·html5
阿崽meitoufa11 小时前
JVM虚拟机:垃圾收集器和判断对象是否存活的算法
java·jvm·算法
我是苏苏11 小时前
C#高级:使用ConcurrentQueue做一个简易进程内通信的消息队列
java·windows·c#
moxiaoran575312 小时前
Go语言的错误处理
开发语言·后端·golang
编程小风筝12 小时前
Spring 框架如何整合Redis缓存中间件?
redis·spring·缓存
heartbeat..13 小时前
数据库基础知识体系:概念、约束、范式与国产产品
java·数据库·学习笔记·国产数据库