Spring AI源码解读(五):PromptTemplate

该文章已生成可运行项目,

一、简介

Spring AI中提示模板化的关键组件是PromptTemplate类,旨在简化结构化提示的创建,这些提示随后会被发送至AI模型进行处理。

PromptTemplate 最基本的功能是支持变量替换。你可以在模板中定义占位符,然后在运行时提供这些变量的值:

// 定义带‍有变量的模板
Strin‍g template ="你好,{name}。今天是{day},天气{⁡weather}。";

// 创建模板‍对象
PromptTemp‍late promptTemplate = new PromptTemplat⁡e(template);

// 准备变量映射
Map<String, Object> variables = new HashMap<>();
variables.put("name", "小火汁");
variables.put("day", "星期一");
variables.put("weather", "晴朗");

// 生成最终提示文本
String prompt = promptTemplate.render(variables);
// 结果: "你好,小火汁。今天是星期一,天气晴朗。"

Spring AI中提示模板化的一个关键组件是PromptTemplate类,旨在简化结构化提示的创建,随后将其发送至AI模型进行处理。PromptTemplate 底层使用了OSS StringTemplate 引擎,这是一个强大的模板引擎,专注于文本生成。在Spring AI中,PromptTemplate 类实现了以下接口:

public class PromptTemplate implements PromptTemplateActions, PromptTemplateMessageActions {

    // Other methods to be discussed later
}

二、类图

可以看出,这些接口提供了不同类型的模板操作功能,使其既能生成普通文本,也能生成结构化的消息。

三、专用模板类

模板引擎的代码如下所示:

主要代码为:this.st = new ST(this.template, '{', '}');,创建一个新的 StringTemplate (ST) 实例,用于解析和渲染模板。指定模板变量的 起始符结束符(默认是 $...$,这里显式设置为 {}

public PromptTemplate(String template) {
    this.template = template;
    // If the template string is not valid, an exception will be thrown
    try {
        this.st = new ST(this.template, '{', '}');
    }
    catch (Exception ex) {
        throw new IllegalArgumentException("The template string is not valid.", ex);
    }
}

Spring AI提供了几种专用的模板类,对应不同角色的消息:

  1. SystemPromptTemplate: 用于系统消息,设置AI的行为和背景
  2. AssistantPromptTemplate: 用于助手消息,用于设置AI回复的结构
  3. FunctionPromptTemplate: 里面就一个空的构造方法,感觉还未实现,目前没有任何作用

下面我们拿SystemMessage来举例,SystemMessage的官方定义如下,其实就是系统提示词,让模型知道自己扮演着什么角色。

// A message of the type 'system' passed as input. 
// The system message gives high level instructions for the conversation. 
// This role typically provides high-level instructions for the conversation. 
// For example, you might use a system message to instruct the generative 
// to behave like a certain character or to provide answers in a specific format.

SystemPromptTemplate的代码如下所示:

public class SystemPromptTemplate extends PromptTemplate {

    public SystemPromptTemplate(String template) {
        super(template);
    }

    public SystemPromptTemplate(Resource resource) {
        super(resource);
    }

    @Override
    public Message createMessage() {
        return new SystemMessage(render());
    }

    @Override
    public Message createMessage(Map<String, Object> model) {
        return new SystemMessage(render(model));
    }

    @Override
    public Prompt create() {
        return new Prompt(new SystemMessage(render()));
    }

    @Override
    public Prompt create(Map<String, Object> model) {
        return new Prompt(new SystemMessage(render(model)));
    }

}

可以看到,除了构造方法,SystemPromptTemplate其实就是实现了Message()方法和create()方法,可以快速构造系统prompt,如下所示:

String userText = """
    Tell me about three famous pirates from the Golden Age of Piracy and why they did.
    Write at least a sentence for each pirate.
    """;

Message userMessage = new UserMessage(userText);

String systemText = """
  You are a helpful AI assistant that helps people find information.
  Your name is {name}
  You should reply to the user's request with your name and also in the style of a {voice}.
  """;

SystemPromptTemplate systemPromptTemplate = new SystemPromptTemplate(systemText);
Message systemMessage = systemPromptTemplate.createMessage(Map.of("name", name, "voice", voice));

Prompt prompt = new Prompt(List.of(userMessage, systemMessage));

List<Generation> response = chatModel.call(prompt).getResults();

四、从文件加载模板

PromptTemplate 支持从外部文件加载模板内容,很适合管理复杂的提示词。Spring AI 利用 Spring 的 Resource 对象来从指定路径加载模板文件:

// 从类路径资源加载系统提示模板
@Value("classpath:/prompts/system-message.st")
priva‍te Resour‍ce systemResource;

// 直接使用资源‍创建模板
SystemPromptT‍emplate systemPromptTemplate = new SystemPromptTemplat⁡e(systemResource);

完整用法如下:

@Value("classpath:/prompts/TestPrompt.st")
private org.springframework.core.io.Resource systemResource;

chatClient = ChatClient.builder(dashscopeChatModel)
                .defaultSystem(SYSTEM_PROMPT)
                .build();


public String doChatWithPrompt(String message, String chatId) {
    SystemPromptTemplate systemPromptTemplate = new SystemPromptTemplate(systemResource);
    Prompt systemPrompt = systemPromptTemplate.create(Map.of("name", "whliu", "voice", "幽默风趣的中文"));

    ChatResponse chatResponse = chatClient
            .prompt(systemPrompt)
            .user(message)
            .advisors(spec -> spec.param(CHAT_MEMORY_CONVERSATION_ID_KEY, chatId)
                    .param(CHAT_MEMORY_RETRIEVE_SIZE_KEY, 10))
            .call()
            .chatResponse();
    String content = chatResponse.getResult().getOutput().getText();
    return content;
}

值得注意的是,.defaultSystem(SYSTEM_PROMPT)是在创建ChatClient的时候传入的,而需要从模板动态配置的prompt是在调用的时候传入的,这两者并不冲突,是可以叠加的。

本文章已经生成可运行项目
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小火汁猛猛

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值