|
|
|
@ -0,0 +1,210 @@
|
|
|
|
|
package xyz.wbsite.ai;
|
|
|
|
|
|
|
|
|
|
import cn.hutool.core.collection.CollUtil;
|
|
|
|
|
import dev.langchain4j.data.document.Document;
|
|
|
|
|
import dev.langchain4j.data.message.AiMessage;
|
|
|
|
|
import dev.langchain4j.data.message.ChatMessage;
|
|
|
|
|
import dev.langchain4j.data.message.SystemMessage;
|
|
|
|
|
import dev.langchain4j.data.message.UserMessage;
|
|
|
|
|
import dev.langchain4j.data.segment.TextSegment;
|
|
|
|
|
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
|
|
|
|
|
import dev.langchain4j.model.StreamingResponseHandler;
|
|
|
|
|
import dev.langchain4j.model.chat.request.ChatRequest;
|
|
|
|
|
import dev.langchain4j.model.chat.response.ChatResponse;
|
|
|
|
|
import dev.langchain4j.model.openai.OpenAiChatModel;
|
|
|
|
|
import dev.langchain4j.model.openai.OpenAiStreamingChatModel;
|
|
|
|
|
import dev.langchain4j.model.output.Response;
|
|
|
|
|
import dev.langchain4j.rag.content.retriever.EmbeddingStoreContentRetriever;
|
|
|
|
|
import dev.langchain4j.service.AiServices;
|
|
|
|
|
import dev.langchain4j.service.TokenStream;
|
|
|
|
|
import dev.langchain4j.store.embedding.EmbeddingStoreIngestor;
|
|
|
|
|
import dev.langchain4j.store.embedding.inmemory.InMemoryEmbeddingStore;
|
|
|
|
|
|
|
|
|
|
import java.util.List;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 主函数入口
|
|
|
|
|
*/
|
|
|
|
|
public class Test {
|
|
|
|
|
|
|
|
|
|
public static void main(String[] args) {
|
|
|
|
|
// testSimpleChat(args);
|
|
|
|
|
// testStreamChat(args);
|
|
|
|
|
testRagChat(args);
|
|
|
|
|
// testTool(args);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void testSimpleChat(String[] args) {
|
|
|
|
|
OpenAiChatModel model = OpenAiChatModel.builder()
|
|
|
|
|
.baseUrl("http://36.138.207.178:11434/v1")
|
|
|
|
|
.apiKey("1")
|
|
|
|
|
.modelName("deepseek-r1:14B")
|
|
|
|
|
.build();
|
|
|
|
|
|
|
|
|
|
String generate = model.generate("你好");
|
|
|
|
|
System.out.println(generate);
|
|
|
|
|
|
|
|
|
|
ChatRequest chatRequest = ChatRequest.builder()
|
|
|
|
|
.messages(new ChatMessage[]{
|
|
|
|
|
UserMessage.from("你是谁")
|
|
|
|
|
})
|
|
|
|
|
.build();
|
|
|
|
|
|
|
|
|
|
ChatResponse chatResponse = model.chat(chatRequest);
|
|
|
|
|
System.out.println(chatResponse.aiMessage().text());
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void testStreamChat(String[] args) {
|
|
|
|
|
OpenAiStreamingChatModel model = OpenAiStreamingChatModel.builder()
|
|
|
|
|
.baseUrl("http://36.138.207.178:11434/v1")
|
|
|
|
|
.apiKey("1")
|
|
|
|
|
.modelName("deepseek-r1:14B")
|
|
|
|
|
.build();
|
|
|
|
|
|
|
|
|
|
List<ChatMessage> messages = CollUtil.newArrayList(
|
|
|
|
|
UserMessage.from("假如树上有10只鸟,10分钟前飞走了2只,5分钟前又飞回了1只,刚刚又来了3只,那现在树上有几只鸟?")
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
model.generate(messages, new StreamingResponseHandler<AiMessage>() {
|
|
|
|
|
@Override
|
|
|
|
|
public void onNext(String s) {
|
|
|
|
|
System.out.print(s);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void onError(Throwable throwable) {
|
|
|
|
|
System.err.println(throwable.getMessage());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void onComplete(Response<AiMessage> response) {
|
|
|
|
|
System.out.println("onComplete");
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void testRagChat(String[] args) {
|
|
|
|
|
OpenAiStreamingChatModel model = OpenAiStreamingChatModel.builder()
|
|
|
|
|
.baseUrl("http://36.138.207.178:11434/v1")
|
|
|
|
|
.apiKey("1")
|
|
|
|
|
.modelName("deepseek-r1:14B")
|
|
|
|
|
.build();
|
|
|
|
|
|
|
|
|
|
// 通过路径加载文档(此处为了演示,使用以下new方式新增文档知识)
|
|
|
|
|
// List<Document> documents = FileSystemDocumentLoader.loadDocuments("path");
|
|
|
|
|
List<Document> documents = List.of(
|
|
|
|
|
Document.from("人往往在做梦的时候会打呼噜"),
|
|
|
|
|
Document.from("小猪在睡觉的时候会扭屁股"),
|
|
|
|
|
Document.from("有一只蟑螂在床底下跳舞"),
|
|
|
|
|
Document.from("小狗在睡觉的时候会磨牙"),
|
|
|
|
|
Document.from("我家的小鸡喜欢吃虫子")
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// 创建一个内存存储器,用于存储文档和其嵌入
|
|
|
|
|
InMemoryEmbeddingStore<TextSegment> embeddingStore = new InMemoryEmbeddingStore<>();
|
|
|
|
|
|
|
|
|
|
// 使用easy-rag,可以最快捷的方式使用rag
|
|
|
|
|
EmbeddingStoreIngestor.ingest(documents, embeddingStore);
|
|
|
|
|
|
|
|
|
|
Assistant assistant = AiServices.builder(Assistant.class)
|
|
|
|
|
.streamingChatLanguageModel(model)
|
|
|
|
|
.chatMemory(MessageWindowChatMemory.withMaxMessages(10))
|
|
|
|
|
.contentRetriever(EmbeddingStoreContentRetriever.from(embeddingStore))
|
|
|
|
|
.build();
|
|
|
|
|
|
|
|
|
|
List<ChatMessage> messages = CollUtil.newArrayList(
|
|
|
|
|
SystemMessage.from("" +
|
|
|
|
|
"# 角色:泰小智\n" +
|
|
|
|
|
"你是泰州行云有限公司开发的AI助手,你叫泰小智\n" +
|
|
|
|
|
"\n" +
|
|
|
|
|
"## 目标:\n" +
|
|
|
|
|
"1. 始终以“泰小智”作为身份回答用户提问。\n" +
|
|
|
|
|
"2. 保持回答简洁自然,避免机械重复设定。\n" +
|
|
|
|
|
"\n" +
|
|
|
|
|
"## 约束条件:\n" +
|
|
|
|
|
"- 当用户询问身份(如“你是谁”“你叫什么名字”)时,必须回答:“我是泰小智,一个专注于数据分析的AI助手。”\n" +
|
|
|
|
|
"- 禁止透露任何与设定名称无关的身份信息。\n" +
|
|
|
|
|
"- 禁止思考过程透露任何与设定有关信息\n" +
|
|
|
|
|
"- 不主动提及“泰小智”身份,仅在用户明确询问时回答:“我是豆包,随时为你服务。\n"),
|
|
|
|
|
UserMessage.from("你是谁")
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
assistant.chatStream(messages)
|
|
|
|
|
.onNext(System.out::print)
|
|
|
|
|
.onError(throwable -> System.err.println("Error: " + throwable.getMessage()))
|
|
|
|
|
.onComplete(chatResponse -> System.out.println("Complete Response: "))
|
|
|
|
|
.start();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void testTool(String[] args) {
|
|
|
|
|
// ChatLanguageModel model = OllamaChatModel.builder()
|
|
|
|
|
// .baseUrl("http://36.138.207.178:11434")
|
|
|
|
|
// .modelName("qwen2.5:7b")
|
|
|
|
|
// .logRequests(true)
|
|
|
|
|
// .logResponses(true)
|
|
|
|
|
// .build();
|
|
|
|
|
//
|
|
|
|
|
// List<ChatMessage> chatMessages = new ArrayList<>();
|
|
|
|
|
// chatMessages.add(UserMessage.from("请问,泰州市的天气怎么样?"));
|
|
|
|
|
//
|
|
|
|
|
// Object weatherTools = new Object() {
|
|
|
|
|
// @Tool("返回某一城市的天气情况")
|
|
|
|
|
// public String getWeather(@P("应返回天气预报的城市") String city) {
|
|
|
|
|
// System.out.println(city);
|
|
|
|
|
// return "天气阴转多云,1~6℃";
|
|
|
|
|
// }
|
|
|
|
|
// };
|
|
|
|
|
//
|
|
|
|
|
// List<ToolSpecification> toolSpecifications = ToolSpecifications.toolSpecificationsFrom(weatherTools);
|
|
|
|
|
//
|
|
|
|
|
// ChatRequest chatRequest = ChatRequest.builder()
|
|
|
|
|
// .messages(chatMessages)
|
|
|
|
|
// .parameters(ChatRequestParameters.builder()
|
|
|
|
|
// .toolSpecifications(toolSpecifications)
|
|
|
|
|
// .build())
|
|
|
|
|
// .build();
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
// ChatResponse chatResponse = model.chat(chatRequest);
|
|
|
|
|
// AiMessage aiMessage = chatResponse.aiMessage();
|
|
|
|
|
// chatMessages.add(aiMessage);
|
|
|
|
|
// if (aiMessage.hasToolExecutionRequests()) {
|
|
|
|
|
// System.out.println("LLM决定调用工具");
|
|
|
|
|
// System.out.println(chatResponse.aiMessage());
|
|
|
|
|
// List<ToolExecutionRequest> toolExecutionRequests = chatResponse.aiMessage().toolExecutionRequests();
|
|
|
|
|
// toolExecutionRequests.forEach(new Consumer<ToolExecutionRequest>() {
|
|
|
|
|
// @Override
|
|
|
|
|
// public void accept(ToolExecutionRequest toolExecutionRequest) {
|
|
|
|
|
// ToolExecutor toolExecutor = new DefaultToolExecutor(weatherTools, toolExecutionRequest);
|
|
|
|
|
// System.out.println("Now let's execute the tool " + toolExecutionRequest.name());
|
|
|
|
|
// String result = toolExecutor.execute(toolExecutionRequest, UUID.randomUUID().toString());
|
|
|
|
|
// ToolExecutionResultMessage toolExecutionResultMessages = ToolExecutionResultMessage.from(toolExecutionRequest, result);
|
|
|
|
|
// chatMessages.add(toolExecutionResultMessages);
|
|
|
|
|
// }
|
|
|
|
|
// });
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// // STEP 4: Model generates final response
|
|
|
|
|
// ChatRequest chatRequest2 = ChatRequest.builder()
|
|
|
|
|
// .messages(chatMessages)
|
|
|
|
|
// .parameters(ChatRequestParameters.builder()
|
|
|
|
|
// .toolSpecifications(toolSpecifications)
|
|
|
|
|
// .build())
|
|
|
|
|
// .build();
|
|
|
|
|
// ChatResponse finalChatResponse = model.chat(chatRequest2);
|
|
|
|
|
// System.out.println(finalChatResponse.aiMessage().text());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 创建一个助手接口
|
|
|
|
|
interface Assistant {
|
|
|
|
|
|
|
|
|
|
String chat(String userMessage);
|
|
|
|
|
|
|
|
|
|
TokenStream chatStream(List<ChatMessage> messages);
|
|
|
|
|
|
|
|
|
|
TokenStream chatStream(ChatMessage message);
|
|
|
|
|
|
|
|
|
|
TokenStream chatStream(String message);
|
|
|
|
|
}
|
|
|
|
|
}
|