Langchain4j 系列之六 - 提示词

上一个系列讲了Spring AI得到反馈效果不错,有人私信我说这个和Langchain4j有什么区别。如果站在使用方面,都是基于Java的大模型应用研发的工具,本质上没太大区别。但是从细节层面来说还是有很多不同之处,所以索性借此机会,给大家分享一下Langchain4j框架。在本系列中会按照Spring AI系列的顺序来写Langchain4j,这样的好处是可以对比两者不同的细节。

注意由于框架不同版本改造会有些使用的不同,因此本次系列中使用基本框架是langchain4j-1.9.1,JDK版本使用的是19。另外本系列尽量使用Java原生态,尽量不依赖于Spring和Spring Boot。虽然langchain4j也支持Spring Boot集成,但是如果是使用Spring Boot框架,那为何不索性使用Spring AI
本系列的所有代码地址: https://github.com/forever1986/langchain4j-study

目录

  • [1 提示词](#1 提示词)
    • [1.1 ChatModel方式演示提示词](#1.1 ChatModel方式演示提示词)
    • [1.2 AiServices方式演示提示词](#1.2 AiServices方式演示提示词)
  • [2 提示词模板](#2 提示词模板)
    • [2.1 ChatModel方式演示提示词](#2.1 ChatModel方式演示提示词)
    • [2.2 AiServices方式演示提示词](#2.2 AiServices方式演示提示词)
  • [3 与Spring AI的比较](#3 与Spring AI的比较)

上一章讲了大语言模型有哪些参数可以进行设置,以及一些常用配置。这一章开始讲解一些大语言模型常见的应用功能,包括提示词、聊天记忆、工具、MCP等等。本章就从提示词开始。

1 提示词

提示词对于大模型来说有多重要就不要再次累赘,而大模型关于提示词以及角色的内容,在之前《Spring AI 系列之二 - 提示词》中也讲过system 角色、user 角色和assistant 角色,另外还说了提示词模板。如果真的是零基础的话,可以先看看或者自己网上搜索一下。这里主要讲Langchain4j 的使用方式,不在对提示词基础进行说明。

在Langchain4j 中定义了ChatMessage接口,从该接口实现了五种不同的提示词,如下图

1)UserMessage:就是user 角色提出来的问题

2)SystemMessage:对话开始前设置,对整个对话过程都有效。一般用于规范大模型的回答的准则。

3)AiMessage:大模型回复的内容

4)ToolExecutionResultMessage:工具执行请求时所返回的结果

5)CustomMessage:表示一条自定义消息。仅能与支持此类消息的聊天模型实现一起使用

下面通过ChatModel和AiServices两种不同方式进行演示

1.1 ChatModel方式演示提示词

代码参考lesson03子模块

1)在lesson03子模块下,新增PromptChatModelTest类

java 复制代码
package com.langchain.lesson03.prompt.lowlevel;

import dev.langchain4j.data.message.ChatMessage;
import dev.langchain4j.data.message.SystemMessage;
import dev.langchain4j.data.message.UserMessage;
import dev.langchain4j.model.chat.ChatModel;
import dev.langchain4j.model.chat.response.ChatResponse;
import dev.langchain4j.model.openai.OpenAiChatModel;

import java.util.ArrayList;
import java.util.List;

public class PromptChatModelTest {

    public static void main(String[] args) {
        String apiKey = System.getenv("ZHIPU_API_KEY");
        ChatModel model = OpenAiChatModel.builder()
                .apiKey(apiKey)
                .baseUrl("https://open.bigmodel.cn/api/paas/v4")
                .modelName("glm-4-flash-250414")
                .build();
        SystemMessage systemMessage = SystemMessage.from("你现在的身份是一个精通Java的专家,专门解决Java遇到的问题。");
        UserMessage userMessage = UserMessage.from("你是谁?");
        List<ChatMessage> list = new ArrayList<>();
        list.add(systemMessage);
        list.add(userMessage);
        ChatResponse response = model.chat(list);
        System.out.println(response.aiMessage().text());
    }
}

2)运行PromptChatModelTest类,结果如下

1.2 AiServices方式演示提示词

代码参考lesson03子模块

1)在lesson03子模块下,其pom引入如下配置:

xml 复制代码
<dependencies>
    <dependency>
        <groupId>dev.langchain4j</groupId>
        <artifactId>langchain4j-open-ai</artifactId>
    </dependency>
    <dependency>
        <groupId>dev.langchain4j</groupId>
        <artifactId>langchain4j</artifactId>
    </dependency>
</dependencies>

2)在lesson03子模块下,创建Assistant接口(注意:接口的入参是一个List<ChatMessage

java 复制代码
package com.langchain.lesson03.prompt.highlevel.service;

import dev.langchain4j.data.message.ChatMessage;

import java.util.List;

public interface Assistant {

    // 注意接口的入参是一个List<ChatMessage
    String chat(List<ChatMessage> list);

}

3)在lesson03子模块下,新建PromptAiServicesTest类

java 复制代码
package com.langchain.lesson03.prompt.highlevel;

import com.langchain.lesson03.prompt.highlevel.service.Assistant;
import dev.langchain4j.data.message.ChatMessage;
import dev.langchain4j.data.message.SystemMessage;
import dev.langchain4j.data.message.UserMessage;
import dev.langchain4j.model.chat.ChatModel;
import dev.langchain4j.model.openai.OpenAiChatModel;
import dev.langchain4j.service.AiServices;

import java.util.ArrayList;
import java.util.List;

public class PromptAiServicesTest {

    public static void main(String[] args) {
        String apiKey = System.getenv("ZHIPU_API_KEY");
        ChatModel model = OpenAiChatModel.builder()
                .apiKey(apiKey)
                .baseUrl("https://open.bigmodel.cn/api/paas/v4")
                .modelName("glm-4-flash-250414")
                .build();
        // 这条SystemMessage,你可以将其放到Assistant接口的chat方法@SystemMessage注解中
        SystemMessage systemMessage = SystemMessage.from("你现在的身份是一个精通Java的专家,专门解决Java遇到的问题。");
        UserMessage userMessage = UserMessage.from("你是谁?");
        List<ChatMessage> list = new ArrayList<>();
        list.add(systemMessage);
        list.add(userMessage);
        Assistant assistant = AiServices.create(Assistant.class, model);
        String response = assistant.chat(list);
        System.out.println(response);
    }
}

4)运行PromptAiServicesTest类,结果如下:

2 提示词模板

除了设定角色,提示词模版是另外一种与大模型交互的更高效编程方式。在业务场景下,一般会使用命令型、描述型、问题型或者情景型等提示词,对大模型生成的效果有着显著的不同。某些提示词在不同场景下其实都能启到同样的效果,只需要将部分词语替换为相关的内容即可,这时候就需要提示词模版,只需要替换其中占位符的部分,则可以让同一个提示词在不同场景下有相同的效果。比如以下示例:

text 复制代码
你是一个{type}博主,你非常擅长给他人推荐{type}的内容。

上面的示例就是一个提示词模版,其中{type}是一个占位符,让用户可以填入旅游、美食等词语,让大模型适应不同场景。在Langchain4j 中提供PromptTemplate类,可以让用户很简单就能使用提示词模版,并将模版生成实际的Message。

2.1 ChatModel方式演示提示词

代码参考lesson03子模块

1)在lesson03子模块下,新建PromptTemplateChatModelTest类

java 复制代码
package com.langchain.lesson03.prompt.lowlevel;

import dev.langchain4j.data.message.ChatMessage;
import dev.langchain4j.data.message.SystemMessage;
import dev.langchain4j.data.message.UserMessage;
import dev.langchain4j.model.chat.ChatModel;
import dev.langchain4j.model.chat.response.ChatResponse;
import dev.langchain4j.model.input.Prompt;
import dev.langchain4j.model.input.PromptTemplate;
import dev.langchain4j.model.openai.OpenAiChatModel;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class PromptTemplateChatModelTest {

    public static void main(String[] args) {
        // 1.获取API KEY
        String apiKey = System.getenv("ZHIPU_API_KEY");
        // 2. 定义模型
        ChatModel model = OpenAiChatModel.builder()
                .apiKey(apiKey)
                .baseUrl("https://open.bigmodel.cn/api/paas/v4")
                .modelName("glm-4-flash-250414")
                .build();
        // 3. 提示词模板
        PromptTemplate promptTemplate = PromptTemplate.from("你的名字叫{{name}},你是一个{{type}}风格的旅游博主,专门介绍和推荐{{type}}风格相关的旅游内容。在每次回答用户的问题之前先说:'你好,我叫{{name}},今天是{{current_date}},很高兴回答你的问题',再回答用户的问题");
        // 4. 设置模版中的参数
        Prompt prompt = promptTemplate.apply(Map.of("name","周星驰","type","小众"));
        SystemMessage systemMessage = prompt.toSystemMessage();
        UserMessage userMessage = UserMessage.from("你是谁?");
        List<ChatMessage> list = new ArrayList<>();
        list.add(systemMessage);
        list.add(userMessage);
        // 5. 访问大模型
        ChatResponse response = model.chat(list);
        System.out.println(response.aiMessage().text());

    }
}

2)运行PromptTemplateChatModelTest类,结果如下:

注意:这里有一个参数是{current_date},在设置参数时并没有传入,而模型是自动匹配今天的时间。这里可以看看源码PromptTemplate,可以看到其会自动注入current_date、current_time和current_date_time三个参数,是为了自动获取当前时间。

2.2 AiServices方式演示提示词

代码参考lesson03子模块

1)在lesson03子模块下,新建PromptTemplateAiServicesTest 类

java 复制代码
package com.langchain.lesson03.prompt.highlevel;

import com.langchain.lesson03.prompt.highlevel.service.Assistant;
import dev.langchain4j.data.message.ChatMessage;
import dev.langchain4j.data.message.SystemMessage;
import dev.langchain4j.data.message.UserMessage;
import dev.langchain4j.model.chat.ChatModel;
import dev.langchain4j.model.input.Prompt;
import dev.langchain4j.model.input.PromptTemplate;
import dev.langchain4j.model.openai.OpenAiChatModel;
import dev.langchain4j.service.AiServices;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class PromptTemplateAiServicesTest {

    public static void main(String[] args) {
        // 1.获取API KEY
        String apiKey = System.getenv("ZHIPU_API_KEY");
        // 2. 定义模型
        ChatModel model = OpenAiChatModel.builder()
                .apiKey(apiKey)
                .baseUrl("https://open.bigmodel.cn/api/paas/v4")
                .modelName("glm-4-flash-250414")
                .build();
        // 3. 提示词模板
        PromptTemplate promptTemplate = PromptTemplate.from("你的名字叫{{name}},你是一个{{type}}风格的旅游博主,专门介绍和推荐{{type}}风格相关的旅游内容。在每次回答用户的问题之前先说:'你好,我叫{{name}},今天是{{current_date}},很高兴回答你的问题',再回答用户的问题");
        // 4. 设置模版中的参数
        Prompt prompt = promptTemplate.apply(Map.of("name","周星驰","type","小众"));
        SystemMessage systemMessage = prompt.toSystemMessage();
        UserMessage userMessage = UserMessage.from("你是谁?");
        List<ChatMessage> list = new ArrayList<>();
        list.add(systemMessage);
        list.add(userMessage);
        // 5. 访问大模型
        Assistant assistant = AiServices.create(Assistant.class, model);
        String response = assistant.chat(list);
        System.out.println(response);

    }
}

2)运行PromptTemplateAiServicesTest 类,结果如下:

3 与Spring AI的比较

这里也可以跟前面的Spring AI系列《Spring AI 系列之二 - 提示词》中的提示词作比较。

  • 提示词:这方面Spring AI和Langchain4j 实现方式几乎一样,都是通过一个基础接口,通过实现不同角色的message
  • 提示词模版:在PromptTemplate中实现方式略微不同,Spring AI通过接口集成方式,而Langchain4j 使用类似工厂模式方式,都是实现了模版生成不同角色的提示词,最终效果是一样的,因此也没有多大区别。
  • 使用方面:在使用上Spring AI的ChatClient提供了更多入口,比如defaultSystem、defaultUser、user等方法,而Langchain4j 则没有这样快捷的入口设置。

结语:本章讲述了提示词以及提示词模版的使用,分别展现ChatModel和AiServices两种使用方式。这里还是看不出ChatModel和AiServices之间的不同。不过越后面就会知道Langchain4j 为用户基于AiServices提供很多内置方便应用功能。下一章继续

Langchain4j 系列上一章:《Langchain4j 系列之五 - 大模型参数和常用配置

Langchain4j 系列下一章:《Langchain4j 系列之七 - 结构化输出

相关推荐
心态与习惯4 小时前
深度学习中的 seq2seq 模型
人工智能·深度学习·seq2seq
Coder_Boy_5 小时前
基于SpringAI的在线考试系统-0到1全流程研发:DDD、TDD与CICD协同实践
java·人工智能·spring boot·架构·ddd·tdd
北京耐用通信5 小时前
耐达讯自动化Profibus总线光纤中继器:光伏逆变器通讯的“稳定纽带”
人工智能·物联网·网络协议·自动化·信息与通信
啊阿狸不会拉杆5 小时前
《数字图像处理》第 7 章 - 小波与多分辨率处理
图像处理·人工智能·算法·计算机视觉·数字图像处理
AI即插即用5 小时前
即插即用系列 | CVPR 2025 AmbiSSL:首个注释模糊感知的半监督医学图像分割框架
图像处理·人工智能·深度学习·计算机视觉·视觉检测
数说星榆1815 小时前
脑启发计算与类神经形态芯片的协同
人工智能
m0_650108245 小时前
AD-GS:面向自监督自动驾驶场景的目标感知 B 样条高斯 splatting 技术
论文阅读·人工智能·自动驾驶·基于高斯泼溅的自监督框架·高质量场景渲染
王锋(oxwangfeng)5 小时前
自动驾驶领域OCC标注
人工智能·机器学习·自动驾驶
cxr8285 小时前
从NP-hard到梯度下降:神经-符号架构如何破解因果发现的“计算魔咒”
人工智能·重构·认知框架
老陈聊架构5 小时前
『AI辅助Skill』掌握三大AI设计Skill:前端独立完成产品设计全流程
前端·人工智能·claude·skill