这里写目录标题
LangChain4j入门
LangChain4j 是一个用于构建基于大型语言模型(LLM)应用的 Java 框架,它简化了与 OpenAI、Hugging Face 等 LLM 服务的集成,并提供了工具链来构建复杂的 LLM 应用。
配置
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-open-ai-spring-boot-starter</artifactId>
<version>1.0.0-beta3</version>
</dependency>
在yml配置api_key,base_ur,model_name必需项
一般将APIKEY保存在系统环境变量中,用System.getenv()
获取
测试
@Autowired
private OpenAiChatModel openAiChatModel;
@Test
public void testChat() {
String question = "java的特性";
String ans = openAiChatModel.chat(question);
System.out.println(ans);
}
Ollama
Ollama是一个允许开发者在本地计算环境中运行模型的工具。
- 选择模型:
- 输入命令行 ollama run deepseek-r1:1.5b
- 本地项目配置
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-ollama</artifactId>
<version>1.0.0-beta3</version>
</dependency>
阿里云百炼平台
在线集成了阿里的通义系列大模型和第三方大模型,涵盖文本、
图像、音视频等不同模态。
依赖
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-community-dashscope-spring-boot-starter</artifactId>
</dependency>
在官网申请API-Key
langchain4j:
community:
dashscope:
chat-model:
api-key: sk-66xxxxxxx
model-name: qwen-max
AIService
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-spring-boot-starter</artifactId>
</dependency>
AIService用于格式化输入,解析输出,记忆聊天等功能。
- 创建接口
package com.atguigu.java.ai.langchain4j.assistant;
public interface Assistant {
String chat(String userMessage);
}
- 创建类测试
@Autowired
private QwenChatModel qwenChatModel;
@Test
public void testChat() {
//创建AIService
Assistant assistant = AiServices.create(Assistant.class, qwenChatModel);
//调用service的接口
String answer = assistant.chat("Hello");
System.out.println(answer);
}
更方便的方式是使用@AIService注解,然后通过@Autowired使用
package com.atguigu.java.ai.langchain4j.assistant;
@AiService(wiringMode = EXPLICIT, chatModel =
"qwenChatModel")
public interface Assistant {
String chat(String userMessage);
}
聊天记忆
我们来测试每次聊天是否有记忆
@Autowired
private Assistant assistant;
@Test
public void testAssistant() {
String question1 = "我是赵铁柱";
String question2 = "我是谁?";
String ans1 = assistant.chat(question1);
String ans2 = assistant.chat(question2);
System.out.println(ans1);
System.out.println(ans2);
}
目前是没记忆的,需要使用chatMemory
- 注解
@AiService(wiringMode = EXPLICIT,chatMemory = "chatMemory" chatMemoryProvider="chatMemoryProvider")
- 配置类
package com.atguigu.java.ai.langchain4j.config;
@Configuration
public class MemoryChatAssistantConfig {
@Bean
ChatMemory chatMemory() {
//设置聊天记忆记录的message数量
return MessageWindowChatMemory.withMaxMessages(10);
}
}
- 注入测试
@Autowired
private MemoryChatAssistant memoryChatAssistant;
@Test
public void testChatMemory4() {
String answer1 = memoryChatAssistant.chat("我是环环");
System.out.println(answer1);
String answer2 = memoryChatAssistant.chat("我是谁");
System.out.println(answer2);
}
隔离聊天
- 在AIService中添加chatMemoryProvider
@AiService(
wiringMode = WiringMode.EXPLICIT,
chatModel = "qwenChatModel",
chatMemory = "chatMemory"
chatMemoryProvider="chatMemoryProvider"
)
public interface SeparateChatAssistant {
/**
* 处理用户消息并维护独立的对话上下文
* @param memoryId 对话内存 ID(区分不同用户)
* @param userMessage 用户输入的消息
* @return AI 回复
*/
String chat(@MemoryId int memoryId, @UserMessage String userMessage);
}
- 配置chatMemoryProvider类
MongoDB
- 引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
- 配置项:
spring.data.mongodb.uri = mongodb://localhost:27017/chat_memory_db
- 实现Entity
@Data
@AllArgsConstructor
@NoArgsConstructor
@Document("chat_message")
public class ChatMessages {
@Id //对应数据库的id字段
private ObjectId messageId; //MongoDB自动生成id为ObjectId类型
private String content;
}
- 使用MongoTemplate测试
@Autowired
private MongoTemplate mongoTemplate;
@Test
public void testInsert(){
ChatMessages chatMessages = new ChatMessages();
chatMessages.setContent("哈哈哈哈");
// 数据库自动生成id
mongoTemplate.insert(chatMessages);
}
接下来可以在IDEA中连接数据库在线查看。
操作 | 代码 | 具体代码 |
---|---|---|
插入 | insert(object) | |
查找 | findbyId(‘id’,Class)、findAll(Class) | |
更新 | upsert(query,update,Class) | Query query = Query.query(Criteria.where(“id”).is(id)); Update update = new Update().set(“age”, newAge); |
删除 | remove(query,Class) |
持久化存储
- 配置chatMemoryProvider
@AiService(chatMemoryProvider = "chatMemoryProvider")
和实体类 - 配置MongoChatMemoryStore,重写getMessages等三大方法
@Component
public class MongoChatMemoryStore implements ChatMemoryStore {
@Autowired
private MongoTemplate mongoTemplate;
@Override
public List<ChatMessage> getMessages(Object memoryId) {
Query query = new Query(Criteria.where("memoryId").is(memoryId));
ChatMessages chatMessages = mongoTemplate.findOne(query,ChatMessages.class);
// 将String转成反序列化 转出List<ChatMessage>
if (chatMessages==null){
return new ArrayList<ChatMessage>();
}
List<ChatMessage> chatMessage = ChatMessageDeserializer.messagesFromJson(chatMessages.getContent());
System.out.println("反序列化:"+chatMessage);
return chatMessage;
}
@Override
public void updateMessages(Object memoryId, List<ChatMessage> list) {
// 查询条件
Criteria criteria = Criteria.where("memoryId").is(memoryId);
Query query = new Query(criteria);
Update update = new Update();
// 插入更新消息列表
update.set("content", ChatMessageSerializer.messagesToJson(list));
mongoTemplate.upsert(query,update,ChatMessages.class);
}
@Override
public void deleteMessages(Object memoryId) {
// 查询条件
Criteria criteria = Criteria.where("memoryId").is(memoryId);
// 构建查询对象
Query query = new Query(criteria);
mongoTemplate.remove(query,ChatMessages.class);
}
}
- 测试
@Autowired
private Assistant assistant;
@Test
public void testAssistant() {
String question1 = "我是赵铁柱";
String question2 = "我是谁?";
String ans1 = assistant.chat(1,question1);
String ans2 = assistant.chat(1,question2);
String ans3 = assistant.chat(2,question2);
}
Prompt
@SystemMessage 设定角色,塑造AI助手的专业身份,明确助手的能力范围
- 配置@SystemMessage
@SystemMessage("你是我的好朋友,请用东北话回答问题。")//系统消息提示词
String chat(@MemoryId int memoryId, @UserMessage String userMessage);
- 配置用户输入@UserMessage
@UserMessage("你是我的好朋友,请用东北话回答问题。")//系统消息提示词
String chat(@UserMessage String userMessage);
- 配置@V传递参数
@UserMessage("你是我的好朋友,请用上海话回答问题,并且添加一些表情符号。{{message}}")
String chat(@V("message") String userMessage);
*创建小智医疗助手
- 创建XiaoZhiAssistant
- 提示词模版:xiaozhi-prompt-template.txt
- 配置chatMemoryProvider持久化和记忆回话隔离
- 创建实体类
- 创建Controller方法
Function Calling(Tools)
大语言模型的缺陷是数学能力不擅长。
- @Tool注解提供数学工具
@Component
public class CalculatorTools {
@Tool
double sum(double a, double b) {
System.out.println("调用加法运算");
return a + b;
}
@Tool
double squareRoot(double x) {
System.out.println("调用平方根运算");
return Math.sqrt(x);
}
}
- 在@AiService配置
tools ="calculatorTools"
根据工具的不同,即使没有任何描述,大语言模型可能也能很好地理解它,例如add(a, b) 。
实战小智医疗智能体
- 实现业务,在tools中提示大模型预约流程和结果
加载Mysql等
@Component
public class AppointmentTool {
@Autowired
private AppointmentService appointmentService;
@Tool(name="预约挂号",value="根据参数,先查询是否当天是否预约过,如果没有预约过,则进行预约,返回预约结果")
public String appointment(Appointment appointment) {
// 先查询是否当天是否预约过
if (appointmentService.isAppointment(appointment)) {
return "您今天已经预约过了,请勿重复预约";
}
// 进行预约
boolean result = appointmentService.appointment(appointment);
if (result) {
return "预约成功";
} else {
return "预约失败";
}
}
}
RAG
LLM的知识仅限于它所训练的数据。如果你想让LLM了解特定领域的知识或转专有数据,需要微调。
RAG通过检索外部知识库(如文档、数据库),将检索到的相关信息作为上下文输入给生成模型,辅助生成更准确的回答。
1. 全文搜索
2. **向量搜索**(向量余弦相似度,独立的向量数据库)
3. 混合搜索
RAG的过程
- 索引阶段
xx - 检索阶段
xxx - 文档加载器,文档解析器,文档分割器
//文档加载器,文档解析器,文档分割器
PathMatcher pathMatcher = FileSystems.getDefault().getPathMatcher("glob:*.txt");
List<Document> documents = FileSystemDocumentLoader.loadDocuments(folder, pathMatcher,new TextDocumentParser());
//
Token分词器
向量存储
之前我们使用的是InMemoryEmbeddingStore作为向量存储,但是不建议在生产中使用基于内存的向量存储。因此这里我们使用Pinecone作为向量数据库。
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-pinecone</artifactId>
</dependency>
#集成阿里通义千问-通用文本向量-v3,注入EmbeddingModel
langchain4j.community.dashscope.embedding-model.api-key=${DASH_SCOPE_API_KEY}
langchain4j.community.dashscope.embedding-model.model-name=text-embedding-v3
- 配置EmbeddingStoreConfig
- //相似度匹配embeddingSearch
- 上传知识库到Pinecone
- 在AssistantConfig中添加contentRetrieverXiaozhiPincone
- AiService注解加contentRetriever=“contentRetrieverXiaozhiPincone”
流式输出
大模型的流式输出是指大模型在生成文本或其他类型的数据时,不是等到整个生成过程完成后再一次性返回所有内容,而是生成一部分就立即发送一部分给用户或下游系统,以逐步、逐块的方式返回结果。
<!--流式输出-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-reactor</artifactId>
</dependency>
1.配置
#集成阿里通义千问-流式输出
langchain4j.community.dashscope.streaming-chat-model.api-key=${DASH_SCOPE_API_KEY}
langchain4j.community.dashscope.streaming-chat-model.model-name=qwen-plus
- AIService添加
streamingChatModel = "qwenStreamingChatModel"
- 修改chat方法返回类型为Flux,也别忘了修改Controller中的返回类型
总结
整个框架流程如下
完结撒花!