Initial commit

This commit is contained in:
userpu
2025-12-17 19:47:14 +08:00
commit 0d15e20780
119 changed files with 3582 additions and 0 deletions

View File

@@ -0,0 +1,12 @@
package com.iwe3.langchain4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MongoDBApplication {
public static void main(String[] args) {
SpringApplication.run(MongoDBApplication.class,args);
}
}

View File

@@ -0,0 +1,23 @@
package com.iwe3.langchain4j.config;
import dev.langchain4j.model.chat.ChatModel;
import dev.langchain4j.model.openai.OpenAiChatModel;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class LLMConfig {
/**
* @Description: 普通对话接口 ChatModel
*/
@Bean(name = "qwen")
public ChatModel chatModelQwen()
{
return OpenAiChatModel.builder()
.apiKey(System.getenv("DASH_SCOPE_API_KEY"))
.modelName("qwen-plus")
.baseUrl("https://dashscope.aliyuncs.com/compatible-mode/v1")
.build();
}
}

View File

@@ -0,0 +1,51 @@
package com.iwe3.langchain4j.config;
import com.iwe3.langchain4j.entity.ChatMessages;
import dev.langchain4j.data.message.ChatMessage;
import dev.langchain4j.data.message.ChatMessageDeserializer;
import dev.langchain4j.data.message.ChatMessageSerializer;
import dev.langchain4j.store.memory.chat.ChatMemoryStore;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Component;
import java.util.LinkedList;
import java.util.List;
@Component
public class MongoChatMemoryStore implements ChatMemoryStore {
@Autowired
private MongoTemplate mongoTemplate;
@Override
public List<ChatMessage> getMessages(Object memoryId) {
Criteria criteria = Criteria.where("memoryId").is(memoryId);
Query query = new Query(criteria);
ChatMessages chatMessages = mongoTemplate.findOne(query, ChatMessages.class);
if (chatMessages == null) return new LinkedList<>();
return ChatMessageDeserializer.messagesFromJson(chatMessages.getContent());
}
@Override
public void updateMessages(Object memoryId, List<ChatMessage> messages) {
Criteria criteria = Criteria.where("memoryId").is(memoryId);
Query query = new Query(criteria);
Update update = new Update();
update.set("content", ChatMessageSerializer.messagesToJson(messages));
// 根据query条件能查询出文档则修改文档否则新增文档
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);
}
}

View File

@@ -0,0 +1,29 @@
package com.iwe3.langchain4j.config;
import dev.langchain4j.memory.chat.ChatMemoryProvider;
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import dev.langchain4j.store.memory.chat.InMemoryChatMemoryStore;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SeparateChatAssistantConfig {
@Resource
private MongoChatMemoryStore mongoChatMemoryStore;
/**
* 指定使用-> mongoChatMemoryStore 来存储
* @return
*/
@Bean
ChatMemoryProvider chatMemoryProvider() {
return memoryId -> MessageWindowChatMemory.builder()
.id(memoryId)
.maxMessages(10).
chatMemoryStore(mongoChatMemoryStore)
.build();
}
}

View File

@@ -0,0 +1,24 @@
package com.iwe3.langchain4j.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.bson.types.ObjectId;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Document("chat_messages")
public class ChatMessages {
//唯一标识,映射到 MongoDB 文档的 _id 字段
@Id
private ObjectId messageId; //利用数据库生成ID就用ObjectId
private String memoryId; //隔离聊天记录的ID
private String content; //存储当前聊天记录列表的json字符串
}

View File

@@ -0,0 +1,22 @@
package com.iwe3.langchain4j.service;
import dev.langchain4j.service.MemoryId;
import dev.langchain4j.service.UserMessage;
import dev.langchain4j.service.spring.AiService;
import dev.langchain4j.service.spring.AiServiceWiringMode;
@AiService(
wiringMode = AiServiceWiringMode.EXPLICIT,
chatModel = "qwen",
chatMemoryProvider = "chatMemoryProvider"
)
public interface SeparateChatAssistant {
/**
* 分离聊天记录
* @param memoryId 聊天id
* @param userMessage 用户消息
* @return
*/
String chat(@MemoryId int memoryId, @UserMessage String userMessage);
}

View File

@@ -0,0 +1,13 @@
server:
port: 9008
servlet:
encoding:
charset: utf-8
enabled: true
force: true # 设置响应的字符编码,避免流式返回输出乱码
spring:
application:
name: langchain4j-ai-mongodb
data:
mongodb:
uri: mongodb://localhost:27017/chat_memory_db # MongoDB连接配置,数据库 chat_memory_db 会自动创建

View File

@@ -0,0 +1,57 @@
package com.iwe3.langchain4j;
import com.iwe3.langchain4j.entity.ChatMessages;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
@SpringBootTest
public class MongoCrudTest {
@Autowired
private MongoTemplate mongoTemplate;
@Test
public void delete(){
var criteria = Criteria.where("_id").is("69420db67db051baab1b4873");
var query = new Query(criteria);
mongoTemplate.remove(query,ChatMessages.class);
}
@Test
public void update(){
//id不存在则会自动变成新增
var criteria = Criteria.where("_id").is("69420db67db051baab1b4873");
var query = new Query(criteria);
//创建一个修改对象
var update = new Update();
update.set("content","奥特之母");
//将查询条件, 修改的内容,文档的信息 -> mongodb
mongoTemplate.upsert(query,update,ChatMessages.class);
}
@Test
public void insert(){
// mongoTemplate.insert(new ChatMessages(1L,"迪迦")); //程序员自己管理ID就用Long
//利用数据库生成ID就用ObjectId
var msg = new ChatMessages();
msg.setContent("贝利亚");
mongoTemplate.insert(msg);
}
@Test
public void findById(){
var msg = mongoTemplate.
findById("69420db67db051baab1b4873",
ChatMessages.class);
System.out.println(msg);
}
}

View File

@@ -0,0 +1,30 @@
package com.iwe3.langchain4j;
import com.iwe3.langchain4j.service.SeparateChatAssistant;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class MongoDBApplicationTest {
@Autowired
private SeparateChatAssistant separateChatAssistant;
@Test
public void testSeparateChatMemory() {
// 用户1的对话
var res = separateChatAssistant.chat(1, "我是蒲哥");
System.out.println(res);
res = separateChatAssistant.chat(1, "你知道我是谁吗");
System.out.println(res);
// 用户2的对话
var res02 = separateChatAssistant.chat(2, "我是小明");
System.out.println(res02);
res02 = separateChatAssistant.chat(2, "我叫什么名字");
System.out.println(res02);
}
}