当前位置: 首页 > news >正文

SpringBoot 整合 Langchain4j 系统提示词与用户提示词实战详解

目录

一、前言

二、LangChain4j 提示词介绍

2.1 什么是提示词

2.2 提示词核心要素

2.3 LangChain4j 中提示词类型

2.3.1 系统提示词

2.3.2 用户提示词

2.3.3 两种提示词差异

2.4 LangChain4j 提示词优势

三、LangChain4j 提示词案例详解

3.1 环境准备

3.1.1 导入依赖

3.1.2 添加配置文件

3.2 系统提示词使用

3.2.1 增加自定义ChatMemoryProvider

3.2.2 自定义Assistant

3.2.3 添加测试接口

3.2.4 系统提示词添加占位符

3.2.4 从外部配置文件添加系统提示词

3.3 用户提示词使用

3.3.1 单参数占位符使用

3.3.2 置@V 注解使用

3.3.3 @V 注解多参数搭配使用

3.3.4 多种类型注解参数搭配使用

四、写在文末


一、前言

提示词(Prompt),是指用户输入给AI 大模型的一段文字或指令,用于引导模型生成特定类型的内容。通过提示词,用户可以告诉AI “做什么”、 “如何做” 以及明确最后的 “输出格式”,从而在满足用户需求的同时,最大程度减少无关信息的生成。有效的提示词本质上是一种“注入式指令”,它引导AI按照预设思路思考并输出结果。

在最早学习ChatGPT的时候,要是能够用好ChatGPT,首先要学习的技能就是提示词,精准的提示词可以让大模型的回复更贴合用户的需求,答案也更加专业,质量也就更好。

比如在下面的这个问题中,我们简单遵循了提示词编写的几个原则,这样的话,可以让大模型给出的回答更专业

二、LangChain4j 提示词介绍

2.1 什么是提示词

提示词是用户输入给AI模型的一段文字或指令,用于引导模型生成特定类型的内容。通过提示词,用户可以告诉AI"做什么"、"如何做"以及"输出格式",从而在满足需求的同时最大程度减少无关信息的生成。有效的提示词本质上是一种"注入式指令",它引导AI按照预设思路思考并输出结果。比如下面的提示词。

写一篇关于新能源汽车的发展趋势的文章,风格简单,通俗易懂,有数据支撑,字数不超过1000字

2.2 提示词核心要素

一个完整的提示词通常包含以下关键要素:

  • 指令:明确告诉AI"做什么",比如"撰写一份产品介绍文案"

  • 上下文:提供必要的背景信息,如项目背景、目标受众等

  • 目标:确定核心任务,对于复杂项目可拆解为子任务

  • 风格与语调:指定"正式"、"幽默"等风格

  • 目标受众:说明主要针对的群体,如"行业专家"或"普通消费者"

  • 输出格式:如"输出需为Markdown格式"

  • 约束条件:如"禁止虚构数据"等要求

在早期编写提示词的时候,需要尽可能的遵循各种规范和技巧,才能让大模型给出的回答更加的精准,比如为提示词设置角色身份,还要给出一些参考示例等等,到现在的阶段,随着大模型的完善和升级,只需要你的提示词通俗易懂,能够被大模型识别即可。

2.3 LangChain4j 中提示词类型

LangChain4j 中提示词主要分2类,也是很多大模型本身支持的提示词类型,包括:系统提示词和用户提示词,下面分别说明。官方文档地址:Tutorials | LangChain4j

2.3.1 系统提示词

系统提示词,也叫SystemMessage,系统提示词是开发者在模型启动或会话初始化阶段注入给AI的初始指令,用以规定AI的角色、语气、价值观及行为框架。它具有以下特点:

  • 高优先级:系统提示词通常具有最高优先级,能有效指导模型的整体行为;

  • 持久性:在一次部署或会话开启后不轻易更改;

  • 全局框架:用于统一AI整体输出的风格、语义与规范;

系统提示词通常包含以下核心要素:

  • 角色设定:定义AI应扮演的角色

  • 行为约束:设定AI必须遵循的规范

  • 语气与风格:规定对话中应保持的总体语气

  • 高层上下文:提供必要的背景信息

比如在LangChain4j 代码中,系统提示词代码的设置通常像下面这样:

@SystemMessage("你是一位专业的中国法律顾问,只回答与中国法律相关的问题。输出限制:对于其他领域的问题禁止回答,直接返回'抱歉,我只能回答中国法律相关的问题。'")

2.3.2 用户提示词

用户提示词是最终使用者与AI交互时所输入的具体指令或问题,用户提示词通常具备如下特点:

  • 动态性:每次对话时针对当前需求而发

  • 任务细化:通常包含更具体的需求细节

  • 可覆盖性:在同一会话中可以不断迭代或替换

比如在LangChain4j 代码中,用户提示词代码的编写通常像下面这样:

@UserMessage("请回答以下法律问题:{{question}}")
String answerLegalQuestion(@V("question") String question);

2.3.3 两种提示词差异

下面是两种提示词的差异对比

特性

系统提示词

用户提示词

设定主体

开发者/技术团队

最终用户

优先级

高(会覆盖冲突的用户提示词)

作用目标

全局框架

具体任务

持续时间

静态持久

动态一次性

典型应用

角色设定、安全策略

具体问题、单次任务

2.4 LangChain4j 提示词优势

合理使用LangChain4j 的提示词,可以简化代码编写,提升开发效率的目的,下面是在LangChain4j 中使用提示词的优势总结:

  1. 强类型安全:Java的强类型特性使提示词模板更安全可靠

  2. 灵活组合:可以灵活组合系统提示、用户提示和少量示例

  3. 易于维护:注解方式使提示词与业务代码解耦,便于维护

  4. 企业级支持:适合中大型企业构建自主可控的AI中台

  5. 丰富集成:内置30+主流大模型支持,提供全栈式AI工程化解决方案

通过合理使用LangChain4j的提示词功能,开发者可以构建出专注于特定领域、行为可控、输出可靠的AI助手,为用户提供准确、专业的服务。

三、LangChain4j 提示词案例详解

接下来,通过案例代码详细演示LangChain4j的提示词的使用。

3.1 环境准备

提前搭建一个springboot 工程

3.1.1 导入依赖

pom中导入下面的核心依赖

<properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><spring-boot.version>3.2.6</spring-boot.version><langchain4j.version>1.0.0-beta3</langchain4j.version></properties><dependencies><!-- web应用程序核心依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- 编写和运行测试用例 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!-- 基于openai系列整合的springboot-starter --><dependency><groupId>dev.langchain4j</groupId><artifactId>langchain4j-open-ai-spring-boot-starter</artifactId></dependency><!-- 接入阿里云百炼平台 --><dependency><groupId>dev.langchain4j</groupId><artifactId>langchain4j-community-dashscope-spring-boot-starter</artifactId></dependency><!--langchain4j高级功能--><dependency><groupId>dev.langchain4j</groupId><artifactId>langchain4j-spring-boot-starter</artifactId></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>2.0.39</version> <!-- 使用最新安全版本 --></dependency></dependencies><dependencyManagement><dependencies><!--引入SpringBoot依赖管理清单--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>${spring-boot.version}</version><type>pom</type><scope>import</scope></dependency><!--引入langchain4j依赖管理清单--><dependency><groupId>dev.langchain4j</groupId><artifactId>langchain4j-bom</artifactId><version>${langchain4j.version}</version><type>pom</type><scope>import</scope></dependency><!--引入百炼依赖管理清单--><dependency><groupId>dev.langchain4j</groupId><artifactId>langchain4j-community-bom</artifactId><version>${langchain4j.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement>

3.1.2 添加配置文件

在工程配置文件中添加下面的配置信息

server:port: 8082#直接对接的是deepseek官网的的大模型
langchain4j:#阿里百炼平台的模型community:dashscope:chat-model:api-key: 你的apikey #这个是白炼平台的apikeymodel-name: qwen-maxlogging:level:root: debug

3.2 系统提示词使用

在使用Langchain4j进行代码编写中,系统提示词使用 @SystemMessage 这个注解,在上文中我们谈到了系统提示词的作用,简单来说,在实际开发中,使用系统提示词,用于设定角色,塑造AI助手的专业身份,明确助手的能力范围,从而得到更专业的回复。

3.2.1 增加自定义ChatMemoryProvider

这个主要是为了后续能够在本地存储会话记忆

package com.congge.config;import dev.langchain4j.memory.chat.ChatMemoryProvider;
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class SystemChatAssistantConfig {@Bean("sysChatMemoryProvider")public ChatMemoryProvider sysChatMemoryProvider() {return memoryId -> MessageWindowChatMemory.builder().id(memoryId).maxMessages(20).build();}}

3.2.2 自定义Assistant

在下面的自定义Assistant接口中,添加一个chat方法,使用系统提示词很简单,只需要在方法上面添加@SystemMessage注解,然后在注解的属性中定义提示词内容即可,比如这里我们设定大模型的回答内容使用东北话的风格回复

package com.congge.assistant;import dev.langchain4j.service.MemoryId;
import dev.langchain4j.service.SystemMessage;
import dev.langchain4j.service.UserMessage;
import dev.langchain4j.service.spring.AiService;
import dev.langchain4j.service.spring.AiServiceWiringMode;@AiService(wiringMode = AiServiceWiringMode.EXPLICIT,chatModel = "qwenChatModel",chatMemoryProvider = "sysChatMemoryProvider"
)
public interface SystemAssistant {//设置系统消息提示词@SystemMessage("你是我的好朋友,请用东北话回答问题。")String chat(@MemoryId int memoryId, @UserMessage String userMessage);
}

3.2.3 添加测试接口

为了方便看效果,添加如下的测试接口

@RestController
public class SystemChatController {@Resourceprivate SystemAssistant systemAssistant;//localhost:8082/chat/system/v1?userId=1&userMessage=我是小王//localhost:8082/chat/system/v1?userId=1&userMessage=你知道我是谁吗?//localhost:8082/chat/system/v1?userId=2&userMessage=我是小李//localhost:8082/chat/system/v1?userId=2&userMessage=你知道我是谁吗?@GetMapping("/chat/system/v1")public String chatSystemV1(@RequestParam("userId") Integer userId,@RequestParam("userMessage") String userMessage) {String answer1 = systemAssistant.chat(userId,userMessage);return answer1;}}

启动工程后,测试一下接口,第一次调用

第二次调用

从两次的调用效果来看,由于设置了大模型的系统提示词风格为东北话的口气,所以给出的回答是符合预期的效果。

补充说明:

  • @SystemMessage 的内容将在后台转换为 SystemMessage 对象,并与 UserMessage 一起发送给大语言模型(LLM)。

  • SystemMessaged的内容只会发送给大模型一次。如果你修改了SystemMessage的内容,新的SystemMessage会被发送给大模型,之前的聊天记忆会失效。

3.2.4 系统提示词添加占位符

假如在编码的时候,不仅设置了系统提示词,还希望系统提示词中能够传递动态参数,这该怎么做呢,只需要在系统提示词设置的地方添加一个占位符即可,如下:

启动工程后,再次调用接口,可以看到下面的效果

3.2.4 从外部配置文件添加系统提示词

如果你的系统提示词比较长,而且内容相对比较复杂的情况下,直接在注解中编写看起来不那么优雅,此时可以考虑将系统提示词放在一个外部的资源模板文件中编写,然后进行引用即可,如下,在工程配置文件目录中增加一个txt的提示词模板,提示词的内容相同

然后在代码中做如下调整

@SystemMessage(fromResource = "prompt.txt")
String chat(@MemoryId int memoryId, @UserMessage String userMessage);

使用上面的接口再次测试一下,仍然能够达到相同的效果

3.3 用户提示词使用

用户提示词,即使用 @UserMessage这个注解,用户获取用户的输入问题或接收用户的输入参数,用户提示词是最终使用者与AI交互时所输入的具体指令或问题,指的是每一次用户每次对话时针对当前需求而发出的。

3.3.1 单参数占位符使用

如下的自定义Assistant中,对于chat方法使用了@UserMessage注解,当前的方法只有一个参数的情况

  • {{it}} 标识对唯一的参数的占位符 , 写法是固定的格式

package com.congge.assistant;import dev.langchain4j.service.UserMessage;
import dev.langchain4j.service.spring.AiService;
import dev.langchain4j.service.spring.AiServiceWiringMode;@AiService(wiringMode = AiServiceWiringMode.EXPLICIT,chatModel = "qwenChatModel",chatMemory = "chatMemory"
)
public interface ChatMemoryAssistant {@UserMessage("你是我的好朋友,请用东北话回答问题,并且回答的时候添加一些表情符号。 {{it}}")String chat(String userMessage);}

提供一个测试接口

@Resource
private ChatMemoryAssistant chatMemoryAssistant;//localhost:8082/chat/system/v2?userMessage=你知道我是谁吗?
@GetMapping("/chat/system/v2")
public String chatSystemV2(@RequestParam("userMessage") String userMessage) {String answer2 = chatMemoryAssistant.chat(userMessage);return answer2;
}

启动工程调用一下接口,可以看到返回结果中拼接了一些表情符号

3.3.2 置@V 注解使用

@V 这个注解明确指定传递的参数名称 , 有点像我们写rest接口的时候,使用requestParam这个注解绑定一个指定名称的参数类似

  • 在下面的接口中,使用@V注解来标注一下userMessage这个参数

  • @V 参数命名可以和方法的入参名称不一样,但是需要和占位符名称保持一致

调整测试接口,更换为chatV() 方法

@Resource
private ChatMemoryAssistant chatMemoryAssistant;//localhost:8082/chat/system/v2?userMessage=你知道我是谁吗?
@GetMapping("/chat/system/v2")
public String chatSystemV2(@RequestParam("userMessage") String userMessage) {String answer2 = chatMemoryAssistant.chatV(userMessage);return answer2;
}

调用接口,最终的效果是一致的

3.3.3 @V 注解多参数搭配使用

如果有两个或两个以上的参数时,必须要用 @V ,比如在下面的这个自定义Assistant中增加下面一个新的chat方法

@UserMessage("你是我的好朋友,请用粤语回答问题。{{userMessage}}")
String chatV2(@MemoryId int memoryId, @V("userMessage") String userMessage);

接口中调用一下

//localhost:8082/chat/system/v3?userId=1&userMessage=你知道我是谁吗?
@GetMapping("/chat/system/v3")
public String chatSystemV3(@RequestParam("userId") Integer userId,@RequestParam("userMessage") String userMessage) {String answer2 = systemAssistant.chatV2(userId,userMessage);return answer2;
}

调用接口

3.3.4 多种类型注解参数搭配使用

在实际应用开发中,可能是综合上面多个类型的注解参数一起搭配使用,从而更方便、更灵活的进行组合。首先在工程配置文件中添加一个提示词模板文件

  • 提示词模板中有几个占位符,其中username和age,与下面的chat方法里面的参数对应

  • current_date 表示的是系统方法,可用于获取当前系统时间

你是我的好朋友,我是{{username}},我的年龄是{{age}},请用东北话回答问题,回答问题时适当添加表情符号
今天是 {{current_date}}。

添加一个chat方法,如下

@SystemMessage(fromResource = "prompt_v2.txt")
String chatV3(@MemoryId int memoryId,@UserMessage String userMessage,@V("username") String username,@V("age") int age
);

添加一个测试接口

//localhost:8082/chat/system/v5?userId=1&userMessage=我是谁,你知道我多大了吗?
@GetMapping("/chat/system/v5")
public String chatSystemV5(@RequestParam("userId") Integer userId,@RequestParam("userMessage") String userMessage) {String response = systemAssistant.chatV3(userId,userMessage,"小王",28);return response;
}

调用一下接口

四、写在文末

本文通过案例操作详细分享了Langchain4j的系统提示词与用户提示词的使用,提示词的使用可以说在日常的大模型应用开发中使用非常普遍,有必要深入掌握,本篇到此结束,感谢观看。

http://www.lryc.cn/news/620331.html

相关文章:

  • JavaWeb(05)
  • TCP客户端Linux网络编程设计详解
  • 人工智能——CNN基础:卷积和池化
  • HiSmartPerf使用WIFI方式连接Android机显示当前设备0.0.0.0无法ping通!设备和电脑连接同一网络,将设备保持亮屏重新尝试
  • SAP Valuation Category在制造业成本核算中的使用场景与配置方案
  • 基于C语言基础对C++的进一步学习_C和C++编程范式、C与C++对比的一些补充知识、C++中的命名空间、文件分层
  • window显示驱动开发—多平面覆盖 VidPN 呈现
  • 看懂 Linux 硬件信息查看与故障排查
  • 力扣42:接雨水
  • 人工智能入门①:AI基础知识(上)
  • Python图像处理基础(十三)
  • 《工程封装》(Python)
  • 网络安全合规6--服务器安全检测和防御技术
  • 3.Ansible编写和运行playbook
  • 3DM游戏运行库合集离线安装包下载, msvcp140.dll丢失等问题修复
  • ESP32_STM32_DHT20
  • 三极管的基极为什么需要下拉电阻
  • Vue3从入门到精通:4.1 Vue Router 4深度解析与实战应用
  • vue实现模拟 ai 对话功能
  • JS的学习5
  • vue修改element的css属性
  • 决策树回归:用“分而治之”的智慧,搞定非线性回归难题(附3D可视化)
  • 北京JAVA基础面试30天打卡09
  • uniapp授权登录
  • 硬件工程师八月实战项目分享
  • 8.13迎来联动:PUBG布加迪,新版本37.1内容资讯!低配置也能飙车吃鸡!
  • 谈一些iOS组件化相关的东西
  • 【Golang】 Context.WithCancel 全面解析与实战指南
  • CAN仲裁机制的原理
  • 【CV 目标检测】③——目标检测方法