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 系列之七 - 结构化输出

相关推荐
NAGNIP7 小时前
一文搞懂深度学习中的通用逼近定理!
人工智能·算法·面试
冬奇Lab9 小时前
一天一个开源项目(第36篇):EverMemOS - 跨 LLM 与平台的长时记忆 OS,让 Agent 会记忆更会推理
人工智能·开源·资讯
冬奇Lab9 小时前
OpenClaw 源码深度解析(一):Gateway——为什么需要一个"中枢"
人工智能·开源·源码阅读
AngelPP12 小时前
OpenClaw 架构深度解析:如何把 AI 助手搬到你的个人设备上
人工智能
宅小年12 小时前
Claude Code 换成了Kimi K2.5后,我再也回不去了
人工智能·ai编程·claude
九狼13 小时前
Flutter URL Scheme 跨平台跳转
人工智能·flutter·github
ZFSS13 小时前
Kimi Chat Completion API 申请及使用
前端·人工智能
天翼云开发者社区14 小时前
春节复工福利就位!天翼云息壤2500万Tokens免费送,全品类大模型一键畅玩!
人工智能·算力服务·息壤
知识浅谈14 小时前
教你如何用 Gemini 将课本图片一键转为精美 PPT
人工智能
Ray Liang14 小时前
被低估的量化版模型,小身材也能干大事
人工智能·ai·ai助手·mindx