From d74b599a259e2c4daaa683cabc259a1c2a4be38f Mon Sep 17 00:00:00 2001 From: wangbing Date: Thu, 24 Jul 2025 10:43:28 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E5=A4=87=E4=BB=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 20 +++--- .../java/xyz/wbsite/ai/Agent_Example.java | 16 +---- .../wbsite/ai/Easy_RAG_Augmentor_Example.java | 2 +- .../java/xyz/wbsite/ai/Easy_RAG_Example.java | 2 +- .../wbsite/ai/Easy_StreamChat_Example.java | 9 ++- .../java/xyz/wbsite/ai/Easy_Tool_Example.java | 4 +- src/main/java/xyz/wbsite/ai/Helper.java | 64 +++++++++++++++++-- .../xyz/wbsite/ai/Image_Chait_Example.java | 2 +- src/main/java/xyz/wbsite/ai/Json_Example.java | 57 +++++++++++++++++ .../xyz/wbsite/ai/Memory_Chat_Example.java | 2 +- .../java/xyz/wbsite/ai/Milvus_Example.java | 2 +- .../java/xyz/wbsite/ai/Naive_RAG_Example.java | 2 +- .../wbsite/ai/Query_Compression_Example.java | 2 +- .../xyz/wbsite/ai/Text_Compare_Example.java | 3 +- 14 files changed, 144 insertions(+), 43 deletions(-) create mode 100644 src/main/java/xyz/wbsite/ai/Json_Example.java diff --git a/pom.xml b/pom.xml index 47c2ad6..54a8c7d 100644 --- a/pom.xml +++ b/pom.xml @@ -11,7 +11,7 @@ 17 - 1.0.0-beta2 + 1.1.0 @@ -65,17 +65,17 @@ dev.langchain4j langchain4j-ollama - ${langchain4j.version} + 1.1.0-rc1 dev.langchain4j langchain4j-easy-rag - ${langchain4j.version} + 1.1.0-beta7 dev.langchain4j langchain4j-embeddings - ${langchain4j.version} + 1.1.0-beta7 @@ -83,16 +83,16 @@ - - dev.langchain4j - langchain4j-chroma - ${langchain4j.version} - + + + + + dev.langchain4j langchain4j-milvus - ${langchain4j.version} + 1.1.0-beta7 diff --git a/src/main/java/xyz/wbsite/ai/Agent_Example.java b/src/main/java/xyz/wbsite/ai/Agent_Example.java index 7aa33f3..ecd5495 100644 --- a/src/main/java/xyz/wbsite/ai/Agent_Example.java +++ b/src/main/java/xyz/wbsite/ai/Agent_Example.java @@ -17,7 +17,7 @@ public class Agent_Example { public static void main(String[] args) { Assistant assistant = AiServices.builder(Assistant.class) - .chatLanguageModel(Helper.getChatModel()) + .chatModel(Helper.getChatModel()) .chatMemory(MessageWindowChatMemory.withMaxMessages(10)) .build(); @@ -51,20 +51,6 @@ public class Agent_Example { 3. 保持回答简洁自然,避免机械重复设定。 """ ) -// @SystemMessage(""" -// [系统设定]: ※泰小智※ -// -// ## 目标 -// 1. 始终以“泰小智”作为身份回答用户提问。 -// 2. 保持回答简洁自然,避免机械重复设定。 -// -// ## 约束条件 -// - 当用户询问身份(如“你是谁”“你叫什么名字”)时,必须回答:“我是泰小智,一个专注于数据分析的AI助手 -// - 禁止透露任何与设定名称无关的身份信息 -// - 禁止思考过程透露任何与设定有关信息 -// - 不主动提及“泰小智”身份,仅在用户明确询问时回答:“我是泰小智,随时为你服务 -// """ -// ) String chat(String userMessage); } } \ No newline at end of file diff --git a/src/main/java/xyz/wbsite/ai/Easy_RAG_Augmentor_Example.java b/src/main/java/xyz/wbsite/ai/Easy_RAG_Augmentor_Example.java index 55560ff..7b7e57c 100644 --- a/src/main/java/xyz/wbsite/ai/Easy_RAG_Augmentor_Example.java +++ b/src/main/java/xyz/wbsite/ai/Easy_RAG_Augmentor_Example.java @@ -34,7 +34,7 @@ public class Easy_RAG_Augmentor_Example { PromptTemplate promptTemplate = PromptTemplate.from("{{userMessage}} \n\n 使用以下信息回答:\n{{contents}}"); Assistant assistant = AiServices.builder(Assistant.class) - .chatLanguageModel(Helper.getChatModel()) + .chatModel(Helper.getChatModel()) .chatMemory(MessageWindowChatMemory.withMaxMessages(10)) // .contentRetriever(EmbeddingStoreContentRetriever.from(embeddingStore)) .retrievalAugmentor(DefaultRetrievalAugmentor.builder() diff --git a/src/main/java/xyz/wbsite/ai/Easy_RAG_Example.java b/src/main/java/xyz/wbsite/ai/Easy_RAG_Example.java index d64dc42..5e075fe 100644 --- a/src/main/java/xyz/wbsite/ai/Easy_RAG_Example.java +++ b/src/main/java/xyz/wbsite/ai/Easy_RAG_Example.java @@ -27,7 +27,7 @@ public class Easy_RAG_Example { EmbeddingStoreIngestor.ingest(documents, embeddingStore); Assistant assistant = AiServices.builder(Assistant.class) - .chatLanguageModel(Helper.getChatModel()) + .chatModel(Helper.getChatModel()) .chatMemory(MessageWindowChatMemory.withMaxMessages(10)) .contentRetriever(EmbeddingStoreContentRetriever.from(embeddingStore)) .build(); diff --git a/src/main/java/xyz/wbsite/ai/Easy_StreamChat_Example.java b/src/main/java/xyz/wbsite/ai/Easy_StreamChat_Example.java index 2b0238d..ba3dd6d 100644 --- a/src/main/java/xyz/wbsite/ai/Easy_StreamChat_Example.java +++ b/src/main/java/xyz/wbsite/ai/Easy_StreamChat_Example.java @@ -2,6 +2,7 @@ package xyz.wbsite.ai; import cn.hutool.core.thread.ThreadUtil; import dev.langchain4j.memory.chat.MessageWindowChatMemory; +import dev.langchain4j.model.output.TokenUsage; import dev.langchain4j.service.AiServices; import dev.langchain4j.service.TokenStream; @@ -12,16 +13,20 @@ public class Easy_StreamChat_Example { public static void main(String[] args) { - String question = "你是谁?"; + String question = "我喜欢吃苹果"; Assistant assistant = AiServices.builder(Assistant.class) - .streamingChatLanguageModel(Helper.getStreamChatModel()) + .streamingChatModel(Helper.getStreamChatModel()) .chatMemory(MessageWindowChatMemory.withMaxMessages(10)) .build(); assistant.chat(question) .onPartialResponse(System.out::print) .onCompleteResponse(chatResponse -> { + TokenUsage tokenUsage = chatResponse.tokenUsage(); + System.out.println("输入token数:" + tokenUsage.inputTokenCount()); + System.out.println("输出token数:" + tokenUsage.outputTokenCount()); + System.out.println("总计token数:" + tokenUsage.totalTokenCount()); System.out.println(); System.out.println("onComplete"); }) diff --git a/src/main/java/xyz/wbsite/ai/Easy_Tool_Example.java b/src/main/java/xyz/wbsite/ai/Easy_Tool_Example.java index 5ededf8..de059a2 100644 --- a/src/main/java/xyz/wbsite/ai/Easy_Tool_Example.java +++ b/src/main/java/xyz/wbsite/ai/Easy_Tool_Example.java @@ -22,12 +22,12 @@ public class Easy_Tool_Example { }; Assistant agent = AiServices.builder(Assistant.class) - .chatLanguageModel(Helper.getToolChatModel()) // 设置工具聊天模型 + .chatModel(Helper.getToolChatModel()) // 设置工具聊天模型 .tools(weatherTools) // 设置工具 .chatMemory(MessageWindowChatMemory.withMaxMessages(10)) .build(); - String chat = agent.chat("请问,泰州市的天气怎么样?"); + String chat = agent.chat("请问,扬州市的天气怎么样?"); System.out.println(chat); } diff --git a/src/main/java/xyz/wbsite/ai/Helper.java b/src/main/java/xyz/wbsite/ai/Helper.java index ecdff8b..10c1c39 100644 --- a/src/main/java/xyz/wbsite/ai/Helper.java +++ b/src/main/java/xyz/wbsite/ai/Helper.java @@ -2,6 +2,8 @@ package xyz.wbsite.ai; import cn.hutool.core.collection.CollUtil; import dev.langchain4j.data.document.Document; +import dev.langchain4j.model.chat.request.ResponseFormat; +import dev.langchain4j.model.chat.request.ResponseFormatType; import dev.langchain4j.model.openai.OpenAiChatModel; import dev.langchain4j.model.openai.OpenAiEmbeddingModel; import dev.langchain4j.model.openai.OpenAiStreamingChatModel; @@ -12,22 +14,72 @@ import java.util.List; public class Helper { private static OpenAiStreamingChatModel openAiStreamingChatModel = OpenAiStreamingChatModel.builder() + // openai地址 .baseUrl("http://192.168.88.106:11434/v1") + // 密钥 .apiKey("1") + //模型名称 .modelName("qwen2.5:0.5b") + // 主要用于控制生成文本的随机性和创造性。它常见于基于 Transformer 架构的生成模型(如 GPT、LLaMA 等)中,影响模型在预测下一个 token 时的概率分布 + // 低 temperature(接近 0):模型会更倾向于选择概率最高的 token,生成的文本更确定性、保守,接近 “标准答案”。适合需要精确性的场景,如数学计算、事实性问答、代码生成。 + // 高 temperature(如 1.0 或更高):模型会增加低概率 token 的选择机会,生成的文本更随机、多样,可能包含更多创意或意外内容。适合需要开放性、创造性的场景,如故事写作、诗歌生成、对话模拟。 + // 调整概率分布的平滑度,创造性内容生成(如故事、诗歌) + .temperature(0.7) + // 替代温度采样(temperature sampling)的策略,主要用于限制模型生成时的词汇选择范围: + // 限制候选词的范围,精确性要求高的任务(如问答、摘要) + // 高精确性任务(如数学计算、代码生成、事实性问答):top_p = 0.7 ~ 0.8 限制候选词范围,减少模型编造错误信息的可能性。 + // 创造性任务(如故事创作、对话生成、诗歌): top_p = 0.9 ~ 0.95 保留更多可能性,让生成内容更具多样性和创新性。 + // top_p = 0.0:无意义(无法选择任何词)。 + // top_p = 1.0:等同于禁用 top_p,与贪婪采样(greedy search)效果相同 + .topP(1.0) + // 限制单次调用生成的最大 token 数量。仅针对模型生成的回复(completion),不包括输入的提示词(prompt)。 + .maxCompletionTokens(2028) + // 限制整个对话的最大 token 数量,包括输入的提示词和生成的回复 + .maxTokens(4096) + // frequencyPenalty 的作用 + // 惩罚高频词汇:当模型在生成过程中多次使用某个词汇时,frequencyPenalty 会降低该词汇再次被选中的概率。 + // 提高多样性:鼓励模型使用同义词或不同表达方式,避免文本重复、冗余。 + // 数学原理:在采样时,对已出现词汇的概率进行如下调整: + // 参数取值范围通常为 -2.0 到 2.0 之间的浮点数。 + // 负值:增加重复的可能性(使生成更集中)。 + // 零值:不施加惩罚(默认行为)。 + // 正值:减少重复(使生成更多样化)。 + // 典型应用场景 + // 场景 建议设置 效果说明 + // 精确性任务 frequencyPenalty =0~0.3 + // 创造性写作 frequencyPenalty = 0.5~1.0 避免词汇重复,使故事、诗歌更生动。 + // 对话生成 frequencyPenalty = 0.7~1.0 防止机器人重复使用相同话术,增强自然度。 + // 技术文档 / 代码生成 frequencyPenalty = 0 保留专业术语的一致性,避免不必要的替换。 + // 长文本生成 frequencyPenalty = 0.3~0.7 减少长段落中的重复表述。 + .frequencyPenalty(0.0) + // 惩罚已出现的主题 当模型在生成过程中多次提及某个主题(如人物、事件、概念)时,presencePenalty 会降低该主题相关词汇再次被选中的概率。 + // 鼓励引入新内容:与 frequencyPenalty(惩罚词汇重复)不同,presencePenalty 更关注主题层面的多样性,避免模型围绕同一主题反复阐述。 + // 范围:通常为 -2.0 到 2.0 之间的浮点数。 + // 负值:增加重复主题的可能性(使生成更聚焦)。 + // 零值:不施加惩罚(默认行为)。 + // 正值:减少重复主题(使生成更多样化)。 + .presencePenalty(0.0) + // 不太确定以下是否都正确,字段要求小写 + // text + // json_object + // b64_json + .responseFormat("text") + // 请求日志 .logRequests(true) + // 响应日志 .logResponses(true) .build(); - private static OpenAiChatModel openAiChatModel = OpenAiChatModel.builder() + private static OpenAiChatModel openAiChatModel = OpenAiChatModel.builder() .baseUrl("http://192.168.88.106:11434/v1") .apiKey("1") - .timeout(Duration.ofSeconds(120)) - .modelName("deepseek-r1:1.5b") + .modelName("qwen2.5:0.5b") + .maxTokens(4096) + .timeout(Duration.ofMinutes(50)) + .responseFormat("json") .logRequests(true) .logResponses(true) .build(); - private static OpenAiEmbeddingModel openAiEmbeddingModel = OpenAiEmbeddingModel.builder() .baseUrl("http://192.168.88.106:11434/v1") .apiKey("1") @@ -36,13 +88,13 @@ public class Helper { .logResponses(true) .build(); - private static OpenAiChatModel toolChatModel = OpenAiChatModel.builder() + private static OpenAiChatModel toolChatModel = OpenAiChatModel.builder() .baseUrl("http://192.168.88.106:11434/v1") .apiKey("1") .modelName("qwen2.5:0.5b") .build(); - private static OpenAiChatModel gemmaModel = OpenAiChatModel.builder() + private static OpenAiChatModel gemmaModel = OpenAiChatModel.builder() .baseUrl("http://192.168.88.106:11434/v1") .apiKey("1") .modelName("gemma3:4b") diff --git a/src/main/java/xyz/wbsite/ai/Image_Chait_Example.java b/src/main/java/xyz/wbsite/ai/Image_Chait_Example.java index 883c63f..3e8aae2 100644 --- a/src/main/java/xyz/wbsite/ai/Image_Chait_Example.java +++ b/src/main/java/xyz/wbsite/ai/Image_Chait_Example.java @@ -14,7 +14,7 @@ public class Image_Chait_Example { public static void main(String[] args) { Assistant assistant = AiServices.builder(Assistant.class) - .chatLanguageModel(Helper.getGemmaModel()) + .chatModel(Helper.getGemmaModel()) .chatMemory(MessageWindowChatMemory.withMaxMessages(10)) .build(); diff --git a/src/main/java/xyz/wbsite/ai/Json_Example.java b/src/main/java/xyz/wbsite/ai/Json_Example.java new file mode 100644 index 0000000..2aa9680 --- /dev/null +++ b/src/main/java/xyz/wbsite/ai/Json_Example.java @@ -0,0 +1,57 @@ +package xyz.wbsite.ai; + +import dev.langchain4j.data.message.UserMessage; +import dev.langchain4j.model.chat.request.ChatRequest; +import dev.langchain4j.model.chat.request.ResponseFormat; +import dev.langchain4j.model.chat.request.ResponseFormatType; +import dev.langchain4j.model.chat.request.json.JsonArraySchema; +import dev.langchain4j.model.chat.request.json.JsonObjectSchema; +import dev.langchain4j.model.chat.request.json.JsonSchema; +import dev.langchain4j.model.openai.OpenAiChatModel; +import dev.langchain4j.service.SystemMessage; + +/** + * Easy-RAG 示例 + */ +public class Json_Example { + + public static void main(String[] args) { + OpenAiChatModel chatModel = Helper.getChatModel(); + + ResponseFormat build1 = ResponseFormat.builder() + .type(ResponseFormatType.JSON) + .jsonSchema( + JsonSchema.builder() + .rootElement( + JsonObjectSchema.builder() + .addProperty("data", JsonArraySchema.builder() + .description("省份列表") + .items( + JsonObjectSchema.builder() + .addStringProperty("name", "省份") + .addStringProperty("car", "车牌前缀") + .build() + ).build() + ).build() + ).build() + ).build(); + + ChatRequest build = ChatRequest.builder() + .messages(UserMessage.from("中国有哪些省,请列举3个")) + .responseFormat(build1) + .build(); + + String chat2 = chatModel.chat(build).aiMessage().text(); + + System.out.println(chat2); + } + + /** + * 助手 + */ + interface Assistant { + + @SystemMessage("请参考提供资料,不要发散,没有请直接回答未查到") + String chat(String userMessage); + } +} \ No newline at end of file diff --git a/src/main/java/xyz/wbsite/ai/Memory_Chat_Example.java b/src/main/java/xyz/wbsite/ai/Memory_Chat_Example.java index c763cbb..63e809f 100644 --- a/src/main/java/xyz/wbsite/ai/Memory_Chat_Example.java +++ b/src/main/java/xyz/wbsite/ai/Memory_Chat_Example.java @@ -22,7 +22,7 @@ public class Memory_Chat_Example { messageWindowChatMemory.add(AiMessage.from("哦,你已经告诉我你是学生了呀!是的,我知道你的职业呢。有什么问题我可以帮你的吗?")); Assistant assistant = AiServices.builder(Assistant.class) - .chatLanguageModel(Helper.getChatModel()) + .chatModel(Helper.getChatModel()) .chatMemory(messageWindowChatMemory) .build(); diff --git a/src/main/java/xyz/wbsite/ai/Milvus_Example.java b/src/main/java/xyz/wbsite/ai/Milvus_Example.java index 189892a..facc13d 100644 --- a/src/main/java/xyz/wbsite/ai/Milvus_Example.java +++ b/src/main/java/xyz/wbsite/ai/Milvus_Example.java @@ -19,7 +19,7 @@ public class Milvus_Example { public static void main(String[] args) { Assistant assistant = AiServices.builder(Assistant.class) - .chatLanguageModel(Helper.getChatModel()) + .chatModel(Helper.getChatModel()) .chatMemory(MessageWindowChatMemory.withMaxMessages(10)) .build(); diff --git a/src/main/java/xyz/wbsite/ai/Naive_RAG_Example.java b/src/main/java/xyz/wbsite/ai/Naive_RAG_Example.java index ea09b84..735f239 100644 --- a/src/main/java/xyz/wbsite/ai/Naive_RAG_Example.java +++ b/src/main/java/xyz/wbsite/ai/Naive_RAG_Example.java @@ -73,7 +73,7 @@ public class Naive_RAG_Example { //最后一步是构建我们的人工智能服务, //配置它以使用我们上面创建的组件。 Assistant assistant = AiServices.builder(Assistant.class) - .chatLanguageModel(Helper.getChatModel()) + .chatModel(Helper.getChatModel()) .contentRetriever(contentRetriever) .chatMemory(chatMemory) .build(); diff --git a/src/main/java/xyz/wbsite/ai/Query_Compression_Example.java b/src/main/java/xyz/wbsite/ai/Query_Compression_Example.java index eef8faa..1901436 100644 --- a/src/main/java/xyz/wbsite/ai/Query_Compression_Example.java +++ b/src/main/java/xyz/wbsite/ai/Query_Compression_Example.java @@ -53,7 +53,7 @@ public class Query_Compression_Example { .build(); Assistant assistant = AiServices.builder(Assistant.class) - .chatLanguageModel(Helper.getChatModel()) + .chatModel(Helper.getChatModel()) .retrievalAugmentor(retrievalAugmentor) .chatMemory(MessageWindowChatMemory.withMaxMessages(4)) .build(); diff --git a/src/main/java/xyz/wbsite/ai/Text_Compare_Example.java b/src/main/java/xyz/wbsite/ai/Text_Compare_Example.java index 318d597..84bdf20 100644 --- a/src/main/java/xyz/wbsite/ai/Text_Compare_Example.java +++ b/src/main/java/xyz/wbsite/ai/Text_Compare_Example.java @@ -1,8 +1,8 @@ package xyz.wbsite.ai; import dev.langchain4j.data.embedding.Embedding; +import dev.langchain4j.model.chat.request.ResponseFormat; import dev.langchain4j.model.embedding.EmbeddingModel; -import dev.langchain4j.model.embedding.onnx.bgesmallenv15q.BgeSmallEnV15QuantizedEmbeddingModel; import dev.langchain4j.store.embedding.CosineSimilarity; /** @@ -21,5 +21,6 @@ public class Text_Compare_Example { double between = CosineSimilarity.between(embedding1, embedding2); System.out.println("余弦相似度: " + between); // 值越接近1越相似 + } }