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

38
.gitignore vendored Normal file
View File

@@ -0,0 +1,38 @@
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### IntelliJ IDEA ###
.idea/modules.xml
.idea/jarRepositories.xml
.idea/compiler.xml
.idea/libraries/
*.iws
*.iml
*.ipr
### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
### Mac OS ###
.DS_Store

10
.idea/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,10 @@
# 默认忽略的文件
/shelf/
/workspace.xml
# 基于编辑器的 HTTP 客户端请求
/httpRequests/
# 依赖于环境的 Maven 主目录路径
/mavenHomeManager.xml
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

17
.idea/dataSources.xml generated Normal file
View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DataSourceManagerImpl" format="xml" multifile-model="true">
<data-source source="LOCAL" name="langchain4j@localhost" uuid="f6ee985e-a235-49a0-a77a-ef4678f524a9">
<driver-ref>mysql.8</driver-ref>
<synchronize>true</synchronize>
<jdbc-driver>com.mysql.cj.jdbc.Driver</jdbc-driver>
<jdbc-url>jdbc:mysql://localhost:3306/langchain4j</jdbc-url>
<jdbc-additional-properties>
<property name="com.intellij.clouds.kubernetes.db.host.port" />
<property name="com.intellij.clouds.kubernetes.db.enabled" value="false" />
<property name="com.intellij.clouds.kubernetes.db.container.port" />
</jdbc-additional-properties>
<working-dir>$ProjectFileDir$</working-dir>
</data-source>
</component>
</project>

35
.idea/encodings.xml generated Normal file
View File

@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="file://$PROJECT_DIR$/langchain4j-ai-helloworld/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/langchain4j-ai-helloworld/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/langchain4j-ai-image/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/langchain4j-ai-image/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/langchain4j-ai-low-high-api/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/langchain4j-ai-low-high-api/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/langchain4j-ai-memory/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/langchain4j-ai-memory/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/langchain4j-ai-model-params/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/langchain4j-ai-model-params/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/langchain4j-ai-mongodb/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/langchain4j-ai-mongodb/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/langchain4j-ai-multimode/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/langchain4j-ai-multimode/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/langchain4j-ai-pinecone/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/langchain4j-ai-pinecone/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/langchain4j-ai-prompt/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/langchain4j-ai-prompt/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/langchain4j-ai-rag/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/langchain4j-ai-rag/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/langchain4j-ai-stream/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/langchain4j-ai-stream/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/langchain4j-ai-tools/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/langchain4j-ai-tools/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/langchain4j-ai-xiaoai-agent/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/langchain4j-ai-xiaoai-agent/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
<file url="file://$APPLICATION_HOME_DIR$/bin/src/main/java" charset="UTF-8" />
<file url="file://$APPLICATION_HOME_DIR$/bin/src/main/resources" charset="UTF-8" />
</component>
</project>

14
.idea/misc.xml generated Normal file
View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="MavenProjectsManager">
<option name="originalFiles">
<list>
<option value="$PROJECT_DIR$/pom.xml" />
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="17" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

View File

@@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.iwe3</groupId>
<artifactId>langchain4j-ai-java</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>langchain4j-ai-helloworld</artifactId>
<packaging>jar</packaging>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-open-ai</artifactId>
</dependency>
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!--test-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

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

View File

@@ -0,0 +1,19 @@
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 {
@Bean
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,26 @@
package com.iwe3.langchain4j.controller;
import dev.langchain4j.model.chat.ChatModel;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@Slf4j
public class LangChain4JController
{
// http://localhost:9001/langchain4j/hello?question=如何学习LangChain4J
@Resource
private ChatModel chatModel;
@GetMapping(value = "/langchain4j/hello")
public String hello(@RequestParam(value = "question",defaultValue = "你是谁") String question)
{
var result = chatModel.chat(question);
System.out.println("通过langchain4j调用模型返回结果\n"+result);
return result;
}
}

View File

@@ -0,0 +1,5 @@
server:
port: 9001
spring:
application:
name: langchain4j-ai-helloworld

View File

@@ -0,0 +1,49 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.iwe3</groupId>
<artifactId>langchain4j-ai-java</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>langchain4j-ai-image</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!--DashScope (Qwen)接入阿里云百炼平台
https://docs.langchain4j.dev/integrations/language-models/dashscope
-->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-community-dashscope-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--导入低阶依赖-->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-open-ai-spring-boot-starter</artifactId>
<version>1.9.1-beta17</version>
</dependency>
<!--导入高阶依赖-->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-spring-boot-starter</artifactId>
<version>1.9.1-beta17</version>
</dependency>
</dependencies>
</project>

View File

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

View File

@@ -0,0 +1,34 @@
package com.iwe3.langchain4j.config;
import dev.langchain4j.community.model.dashscope.WanxImageModel;
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
{
@Bean
public ChatModel ImageModel() {
return OpenAiChatModel.builder()
.apiKey(System.getenv("DASH_SCOPE_API_KEY"))
//qwen-vl-max 是一个多模态大模型,支持图片和文本的结合输入,适用于视觉-语言任务。
.modelName("qwen-vl-max")
.baseUrl("https://dashscope.aliyuncs.com/compatible-mode/v1")
.build();
}
/**
* @Description: 测试通义万象来实现图片生成,
* 知识出处https://help.aliyun.com/zh/model-studio/text-to-image
*/
@Bean
public WanxImageModel wanxImageModel()
{
return WanxImageModel.builder()
.apiKey(System.getenv("DASH_SCOPE_API_KEY"))
.modelName("wanx2.1-t2i-turbo") //图片生成 https://help.aliyun.com/zh/model-studio/text-to-image
.build();
}
}

View File

@@ -0,0 +1,62 @@
package com.iwe3.langchain4j.controller;
import dev.langchain4j.data.message.ImageContent;
import dev.langchain4j.data.message.TextContent;
import dev.langchain4j.data.message.UserMessage;
import dev.langchain4j.model.chat.ChatModel;
import dev.langchain4j.model.chat.response.ChatResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.IOException;
import java.util.Base64;
@RestController
@Slf4j
public class ImageModelController
{
@Autowired
private ChatModel ImageModel;
@Value("classpath:static/imgs/1.png")
private Resource resource;//import org.springframework.core.io.Resource;
/**
* @Description:
* 通过Base64编码将图片转化为字符串
* 结合ImageContent和TextContent形成UserMessage一起发送到模型进行处理。
*
*测试地址http://localhost:9005/lc4j/image/call
*/
@GetMapping(value = "/lc4j/image/call")
public String readImageContent() throws IOException
{
String result = null;
//第一步图片转码通过Base64编码将图片转化为字符串
byte[] byteArray = resource.getContentAsByteArray();
String base64Data = Base64.getEncoder().encodeToString(byteArray);
//第二步提示词指定结合ImageContent和TextContent一起发送到模型进行处理。
UserMessage userMessage = UserMessage.from(
TextContent.from("她是谁?"),
ImageContent.from(base64Data, "image/jpg")
);
//第三步API调用使用OpenAiChatModel来构建请求并通过chat()方法调用模型。
//请求内容包括文本提示和图片,模型会根据输入返回分析结果。
ChatResponse chatResponse = ImageModel.chat(userMessage);
//第四步解析与输出从ChatResponse中获取AI大模型的回复打印出处理后的结果。
result = chatResponse.aiMessage().text();
//后台打印
System.out.println(result);
//返回前台
return result;
}
}

View File

@@ -0,0 +1,71 @@
package com.iwe3.langchain4j.controller;
import com.alibaba.dashscope.aigc.imagesynthesis.ImageSynthesis;
import com.alibaba.dashscope.aigc.imagesynthesis.ImageSynthesisParam;
import com.alibaba.dashscope.aigc.imagesynthesis.ImageSynthesisResult;
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.alibaba.dashscope.utils.JsonUtils;
import dev.langchain4j.community.model.dashscope.WanxImageModel;
import dev.langchain4j.data.image.Image;
import dev.langchain4j.model.output.Response;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.IOException;
@RestController
@Slf4j
public class WanxImageModelController
{
@Autowired
private WanxImageModel wanxImageModel;
// http://localhost:9005/lc4j/image/create
@GetMapping(value = "/lc4j/image/create")
public String createImageContent() throws IOException
{
System.out.println(wanxImageModel);
var imageResponse = wanxImageModel.generate("美女");
System.out.println(imageResponse.content().url());
return imageResponse.content().url().toString();
}
// http://localhost:9005/lc4j/image/create2
@GetMapping(value = "/lc4j/image/create2")
public String createImageContent2() throws IOException
{
var prompt = "近景镜头18岁的中国女孩古代服饰圆脸正面看着镜头" +
"民族优雅的服装,商业摄影,室外,电影级光照,半身特写,精致的淡妆,锐利的边缘。";
var param =
ImageSynthesisParam.builder()
.apiKey(System.getenv("DASH_SCOPE_API_KEY"))
.model(ImageSynthesis.Models.WANX_V1)
.prompt(prompt)
.style("<watercolor>")
.n(1)
.size("1024*1024")
.build();
var imageSynthesis = new ImageSynthesis();
ImageSynthesisResult result = null;
try {
System.out.println("---sync call, please wait a moment----");
result = imageSynthesis.call(param);
} catch (ApiException | NoApiKeyException e){
throw new RuntimeException(e.getMessage());
}
System.out.println(JsonUtils.toJson(result));
return JsonUtils.toJson(result);
}
}

View File

@@ -0,0 +1,5 @@
server:
port: 9005
spring:
application:
name: langchain4j-ai-image

Binary file not shown.

After

Width:  |  Height:  |  Size: 250 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 492 KiB

View File

@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.iwe3</groupId>
<artifactId>langchain4j-ai-java</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>langchain4j-ai-low-high-api</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--导入低阶依赖-->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-open-ai-spring-boot-starter</artifactId>
<version>1.9.1-beta17</version>
</dependency>
<!--导入高阶依赖-->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-spring-boot-starter</artifactId>
<version>1.9.1-beta17</version>
</dependency>
</dependencies>
</project>

View File

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

View File

@@ -0,0 +1,37 @@
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 {
@Bean(name = "qwen")
public ChatModel chatModelQwen(){
/*大模型3件套apikey ,model-name,base-url */
return OpenAiChatModel.builder()
.apiKey(System.getenv("DASH_SCOPE_API_KEY"))
.modelName("qwen-plus")
.baseUrl("https://dashscope.aliyuncs.com/compatible-mode/v1")
.build();
}
/**
* @Description:
* 知识出处https://api-docs.deepseek.com/zh-cn/
*/
@Bean(name = "deepseek")
public ChatModel chatModelDeepSeek()
{
return
OpenAiChatModel.builder()
.apiKey(System.getenv("DEEP_SEEK_API_KEY"))
.modelName("deepseek-chat")
//.modelName("deepseek-reasoner")
.baseUrl("https://api.deepseek.com/v1")
.build();
}
}

View File

@@ -0,0 +1,21 @@
package com.iwe3.langchain4j.controller;
import com.iwe3.langchain4j.service.ChatAssistant;
import jakarta.annotation.Resource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HighLevelController {
@Resource
private ChatAssistant chatAssistant;
// http://localhost:9003/lc4j/boot/declarative?prompt=我是谁
@GetMapping(value = "/lc4j/boot/declarative")
public String declarative(@RequestParam(value = "prompt", defaultValue = "你是谁") String prompt)
{
return chatAssistant.chat(prompt);
}
}

View File

@@ -0,0 +1,41 @@
package com.iwe3.langchain4j.controller;
import dev.langchain4j.data.message.UserMessage;
import dev.langchain4j.model.chat.ChatModel;
import dev.langchain4j.model.chat.response.ChatResponse;
import dev.langchain4j.model.output.TokenUsage;
import jakarta.annotation.Resource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class LowLevelController {
@Resource(name = "qwen")
private ChatModel chatModel;
// http://localhost:9003/lc4j/lowapi/api01?prompt=我是谁
@GetMapping(value = "/lc4j/lowapi/api01")
public String api01(@RequestParam(value = "prompt", defaultValue = "你是谁") String prompt)
{
return chatModel.chat(prompt);
}
// http://localhost:9003/lc4j/lowapi/api02?prompt=我是谁
@GetMapping(value = "/lc4j/lowapi/api02")
public String api02(@RequestParam(value = "prompt", defaultValue = "你是谁") String prompt)
{
ChatResponse chatResponse = chatModel.chat(UserMessage.from(prompt));
String result = chatResponse.aiMessage().text();
System.out.println("通过调用大模型返回结果:"+result);
// Token 用量计算的底层api
TokenUsage tokenUsage = chatResponse.tokenUsage();
System.out.println("本次调用消耗的token"+tokenUsage);
result = result +"\t\n"+tokenUsage;
return result;
}
}

View File

@@ -0,0 +1,14 @@
package com.iwe3.langchain4j.service;
import dev.langchain4j.service.spring.AiService;
import dev.langchain4j.service.spring.AiServiceWiringMode;
/**
* 知识出处:
* https://docs.langchain4j.dev/tutorials/spring-boot-integration/#spring-boot-starter-for-declarative-ai-services
*/
@AiService(wiringMode = AiServiceWiringMode.EXPLICIT
,chatModel = "qwen")
public interface ChatAssistant {
String chat(String prompt);
}

View File

@@ -0,0 +1,5 @@
server:
port: 9003
spring:
application:
name: langchain4j-ai-low-level

View File

@@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.iwe3</groupId>
<artifactId>langchain4j-ai-java</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>langchain4j-ai-memory</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-reactor</artifactId>
<version>1.9.1-beta17</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--导入低阶依赖-->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-open-ai-spring-boot-starter</artifactId>
<version>1.9.1-beta17</version>
</dependency>
<!--导入高阶依赖-->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-spring-boot-starter</artifactId>
<version>1.9.1-beta17</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,12 @@
package com.iwe3.langchain4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MemoryApplication {
public static void main(String[] args) {
SpringApplication.run(MemoryApplication.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,19 @@
package com.iwe3.langchain4j.config;
import dev.langchain4j.memory.ChatMemory;
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MemoryChatAssistantConfig {
//@Bean -> 向IOC容器中注入 chatMemory 的实例
@Bean
ChatMemory windowChatMemory() {
// 设置聊天记忆记录的message数量
return MessageWindowChatMemory.withMaxMessages(10);
}
}

View File

@@ -0,0 +1,26 @@
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 org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SeparateChatAssistantConfig {
/**
* 聊天记忆提供器
* 配置采用memoryId来完成隔离
* @return
*/
@Bean
ChatMemoryProvider chatMemoryProvider() {
return memoryId -> MessageWindowChatMemory.builder()
.id(memoryId)
.maxMessages(10).chatMemoryStore(new InMemoryChatMemoryStore())
.build();
//如果未来想自定义 -> 则自己写一个类实现 ChatMemoryStore
}
}

View File

@@ -0,0 +1,20 @@
package com.iwe3.langchain4j.service;
import dev.langchain4j.service.spring.AiService;
import dev.langchain4j.service.spring.AiServiceWiringMode;
/**
* 知识出处:
* https://docs.langchain4j.dev/tutorials/spring-boot-integration/#spring-boot-starter-for-declarative-ai-services
* chatMemory = "chatMemory" 则表示使用ChatMemory来完成聊天记忆
*/
@AiService(wiringMode = AiServiceWiringMode.EXPLICIT
,chatModel = "qwen",chatMemory = "windowChatMemory")
public interface ChatAssistant {
/**
* 普通聊天
* @param prompt
* @return
*/
String chat(String prompt);
}

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,10 @@
server:
port: 9007
servlet:
encoding:
charset: utf-8
enabled: true
force: true # 设置响应的字符编码,避免流式返回输出乱码
spring:
application:
name: langchain4j-ai-memory

View File

@@ -0,0 +1,51 @@
package com.iwe3.langchain4j;
import com.iwe3.langchain4j.service.ChatAssistant;
import dev.langchain4j.data.message.UserMessage;
import dev.langchain4j.model.chat.ChatModel;
import jakarta.annotation.Resource;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class MemoryApplicationTest {
@Resource(name="qwen")
private ChatModel chatModel;
@Test
public void testLowerLevel(){
// 第一轮对话
var um01 = UserMessage.userMessage("我是蒲哥");
var res01 = chatModel.chat(um01);
var am01 = res01.aiMessage();
// 输出大语言模型的回复
System.out.println(am01.text());
// 第二轮对话
var um02 = UserMessage.userMessage("你知道我是谁吗");
//将第一轮对话记录,也一起发给 LLM
var res02 = chatModel.chat(um02);
var am02 = res02.aiMessage();
// 输出大语言模型的回复
System.out.println(am02.text());
}
@Autowired
private ChatAssistant chatAssistant;
@Test
public void testHighLevel(){
var res = chatAssistant.chat("我是蒲哥");
System.out.println("res = " + res);
res = chatAssistant.chat("我是谁?");
System.out.println("res = " + res);
}
}

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
public class SeparateChatTest {
@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);
}
}

View File

@@ -0,0 +1,51 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.iwe3</groupId>
<artifactId>langchain4j-ai-java</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>langchain4j-ai-model-params</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.39</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--导入低阶依赖-->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-open-ai-spring-boot-starter</artifactId>
<version>1.9.1-beta17</version>
</dependency>
<!--导入高阶依赖-->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-spring-boot-starter</artifactId>
<version>1.9.1-beta17</version>
</dependency>
</dependencies>
</project>

View File

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

View File

@@ -0,0 +1,45 @@
package com.iwe3.langchain4j.config;
import com.iwe3.langchain4j.listener.UserpuChatModelListener;
import dev.langchain4j.model.chat.ChatModel;
import dev.langchain4j.model.openai.OpenAiChatModel;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.time.Duration;
import java.util.List;
@Configuration
public class LLMConfig {
@Bean(name = "qwen")
public ChatModel chatModelQwen(){
/*模型3件套apikey - modelName - baseUrl */
return OpenAiChatModel.builder()
.apiKey(System.getenv("DASH_SCOPE_API_KEY"))
.modelName("qwen-plus")
.baseUrl("https://dashscope.aliyuncs.com/compatible-mode/v1")
.logRequests(true)
.logResponses(true)
.listeners(List.of(new UserpuChatModelListener()))
.maxRetries(3)
.timeout(Duration.ofSeconds(5))
.build();
}
/**
* @Description:
* 知识出处https://api-docs.deepseek.com/zh-cn/
*/
@Bean(name = "deepseek")
public ChatModel chatModelDeepSeek(){
return
OpenAiChatModel.builder()
.apiKey(System.getenv("DEEP_SEEK_API_KEY"))
.modelName("deepseek-chat")
//.modelName("deepseek-reasoner")
.baseUrl("https://api.deepseek.com/v1")
.build();
}
}

View File

@@ -0,0 +1,27 @@
package com.iwe3.langchain4j.controller;
import dev.langchain4j.model.chat.ChatModel;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@Slf4j
public class ModelParameterController
{
@Resource(name = "qwen")
private ChatModel chatModelQwen;
// http://localhost:9004/lc4j/modelparam/config?prompt=我是谁
@GetMapping(value = "/lc4j/modelparam/config")
public String config(@RequestParam(value = "prompt", defaultValue = "你是谁") String prompt)
{
var result = chatModelQwen.chat(prompt);
System.out.println("通过langchain4j调用模型返回结果"+result);
return result;
}
}

View File

@@ -0,0 +1,36 @@
package com.iwe3.langchain4j.listener;
import cn.hutool.core.util.IdUtil;
import dev.langchain4j.model.chat.listener.ChatModelErrorContext;
import dev.langchain4j.model.chat.listener.ChatModelListener;
import dev.langchain4j.model.chat.listener.ChatModelRequestContext;
import dev.langchain4j.model.chat.listener.ChatModelResponseContext;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class UserpuChatModelListener implements ChatModelListener
{
@Override
public void onRequest(ChatModelRequestContext requestContext)
{
// onRequest配置的k:v键值对在onResponse阶段可以获得上下文传递参数好用
String uuidValue = IdUtil.simpleUUID();
requestContext.attributes().put("TraceID",uuidValue);
log.info("请求参数requestContext:{}", requestContext+"\t"+uuidValue);
}
@Override
public void onResponse(ChatModelResponseContext responseContext)
{
Object object = responseContext.attributes().get("TraceID");
log.info("返回结果responseContext:{}", object);
}
@Override
public void onError(ChatModelErrorContext errorContext)
{
log.error("请求异常ChatModelErrorContext:{}", errorContext);
}
}

View File

@@ -0,0 +1,9 @@
server:
port: 9004
spring:
application:
name: langchain4j-ai-model-params
logging:
level:
dev:
langchain4j: debug

View File

@@ -0,0 +1,57 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.iwe3</groupId>
<artifactId>langchain4j-ai-java</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>langchain4j-ai-mongodb</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- Spring Boot Starter Data MongoDB -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-reactor</artifactId>
<version>1.9.1-beta17</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--导入低阶依赖-->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-open-ai-spring-boot-starter</artifactId>
<version>1.9.1-beta17</version>
</dependency>
<!--导入高阶依赖-->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-spring-boot-starter</artifactId>
<version>1.9.1-beta17</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
</dependencies>
</project>

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);
}
}

View File

@@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.iwe3</groupId>
<artifactId>langchain4j-ai-java</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>langchain4j-ai-multimode</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-open-ai</artifactId>
</dependency>
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!--test-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

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

View File

@@ -0,0 +1,37 @@
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 {
@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();
}
/**
* @Description:
* 知识出处https://api-docs.deepseek.com/zh-cn/
*/
@Bean(name = "deepseek")
public ChatModel chatModelDeepSeek()
{
return
OpenAiChatModel.builder()
.apiKey(System.getenv("DEEP_SEEK_API_KEY"))
.modelName("deepseek-chat")
//.modelName("deepseek-reasoner")
.baseUrl("https://api.deepseek.com/v1")
.build();
}
}

View File

@@ -0,0 +1,35 @@
package com.iwe3.langchain4j.controller;
import dev.langchain4j.model.chat.ChatModel;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@Slf4j
public class MultiModelController
{
@Resource(name = "qwen")
private ChatModel chatModelQwen;
@Resource(name = "deepseek")
private ChatModel chatModelDeepSeek;
// http://localhost:9002/multimodel/qwen?prompt=如何学习LangChain4J
@GetMapping(value = "/multimodel/qwen")
public String qwenCall(@RequestParam(value = "prompt", defaultValue = "你是谁") String prompt) {
var result = chatModelQwen.chat(prompt);
System.out.println("通过langchain4j调用模型返回结果\n"+result);
return result;
}
// http://localhost:9002/multimodel/deepseek?prompt=如何学习LangChain4J
@GetMapping(value = "/multimodel/deepseek")
public String deepseekCall(@RequestParam(value = "prompt", defaultValue = "你是谁") String prompt){
var result = chatModelDeepSeek.chat(prompt);
System.out.println("通过langchain4j调用模型返回结果\n"+result);
return result;
}
}

View File

@@ -0,0 +1,5 @@
server:
port: 9002
spring:
application:
name: langchain4j-ai-multimode

View File

@@ -0,0 +1,67 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.iwe3</groupId>
<artifactId>langchain4j-ai-java</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>langchain4j-ai-pinecone</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-pinecone</artifactId>
</dependency>
<!-- 接入阿里云百炼平台 -->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-community-dashscope-spring-boot-starter</artifactId>
</dependency>
<!-- 简单的rag实现 -->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-easy-rag</artifactId>
</dependency>
<!-- 解析pdf文档 -->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-document-parser-apache-pdfbox</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--导入低阶依赖-->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-open-ai-spring-boot-starter</artifactId>
<version>1.9.1-beta17</version>
</dependency>
<!--导入高阶依赖-->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-spring-boot-starter</artifactId>
<version>1.9.1-beta17</version>
</dependency>
</dependencies>
</project>

View File

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

View File

@@ -0,0 +1,32 @@
package com.iwe3.langchain4j.config;
import dev.langchain4j.data.segment.TextSegment;
import dev.langchain4j.model.embedding.EmbeddingModel;
import dev.langchain4j.store.embedding.EmbeddingStore;
import dev.langchain4j.store.embedding.pinecone.PineconeEmbeddingStore;
import dev.langchain4j.store.embedding.pinecone.PineconeServerlessIndexConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class EmbeddingStoreConfig {
@Autowired
private EmbeddingModel embeddingModel;
@Bean
public EmbeddingStore<TextSegment> embeddingStore() {
// 创建向量存储
return PineconeEmbeddingStore.builder()
.apiKey(System.getenv("PINECONE_API_KEY"))
.index("xiaoai-index") // 如果指定的索引不存在,将创建一个新的索引
.nameSpace("xiaoai-namespace") // 如果指定的名称空间不存在,将创建一个新的名称空间
.createIndex(PineconeServerlessIndexConfig.builder()
.cloud("AWS") // 指定索引部署在 AWS 云服务上。
.region("us-east-1") // 指定索引所在的 AWS 区域为 us-east-1。
.dimension(embeddingModel.dimension()) // 指定索引的向量维度,该维度与 embeddingModel 生成的向量维度相同。
.build())
.build();
}
}

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,11 @@
server:
port: 9011
spring:
application:
name: langchain4j-ai-pinecone
langchain4j:
community:
dashscope:
embedding-model:
model-name: text-embedding-v3
api-key: ${DASH_SCOPE_API_KEY}

View File

@@ -0,0 +1,79 @@
package com.iwe3.langchain4j;
import dev.langchain4j.data.segment.TextSegment;
import dev.langchain4j.model.embedding.EmbeddingModel;
import dev.langchain4j.store.embedding.EmbeddingMatch;
import dev.langchain4j.store.embedding.EmbeddingSearchRequest;
import dev.langchain4j.store.embedding.EmbeddingSearchResult;
import dev.langchain4j.store.embedding.EmbeddingStore;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class PineConeApplicationTest {
@Autowired
private EmbeddingModel embeddingModel;
@Autowired
private EmbeddingStore embeddingStore;
/**
* Pinecone - 相似度匹配
*/
@Test
public void embeddingSearch() {
// 提问,并将问题转成向量数据
var queryEmbedding = embeddingModel.embed("你最喜欢的运动是什么?").content();
// 创建搜索请求对象
var searchRequest = EmbeddingSearchRequest.builder()
.queryEmbedding(queryEmbedding)
.maxResults(1) // 匹配最相似的一条记录
.minScore(0.8)
.build();
// 根据搜索请求 searchRequest 在向量存储中进行相似度搜索
EmbeddingSearchResult<TextSegment> searchResult = embeddingStore.search(searchRequest);
// searchResult.matches(): 获取搜索结果中的匹配项列表。
// .get(0): 从匹配项列表中获取第一个匹配项
EmbeddingMatch<TextSegment> embeddingMatch = searchResult.matches().get(0);
// 获取匹配项的相似度得分
System.out.println(embeddingMatch.score()); // 输出0.8144288515898701
// 返回文本结果
System.out.println(embeddingMatch.embedded().text());
}
/**
* 将文本转换成向量,然后存储到 pinecone 中
*
* 参考:
* https://docs.langchain4j.dev/tutorials/embedding-stores
*/
@Test
public void testPineconeEmbedded() {
// 将文本转换成向量
var seg1 = TextSegment.from("我喜欢羽毛球");
var em1 = embeddingModel.embed(seg1).content();
embeddingStore.add(em1, seg1);// 存入向量数据库
var seg2 = TextSegment.from("今天天气很好");
var em2 = embeddingModel.embed(seg2).content();
embeddingStore.add(em2, seg2);// 存入向量数据库
}
@Test
public void testEmbeddingModel() {
var embed = embeddingModel.embed("你好");
System.out.println("向量维度:" + embed.content().vector().length);
System.out.println("向量输出:" + embed.toString());
}
}

View File

@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.iwe3</groupId>
<artifactId>langchain4j-ai-java</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>langchain4j-ai-prompt</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--导入低阶依赖-->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-open-ai-spring-boot-starter</artifactId>
<version>1.9.1-beta17</version>
</dependency>
<!--导入高阶依赖-->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-spring-boot-starter</artifactId>
<version>1.9.1-beta17</version>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,12 @@
package com.iwe3.langchain4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class PromptApplication {
public static void main(String[] args) {
SpringApplication.run(PromptApplication.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,104 @@
package com.iwe3.langchain4j.controller;
import com.iwe3.langchain4j.entity.LawPrompt;
import com.iwe3.langchain4j.service.LawExplainAssistant;
import dev.langchain4j.data.message.UserMessage;
import dev.langchain4j.model.chat.ChatModel;
import dev.langchain4j.model.chat.response.ChatResponse;
import dev.langchain4j.model.input.Prompt;
import dev.langchain4j.model.input.PromptTemplate;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.assertj.core.util.DateUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
@RestController
@Slf4j
public class ChatPromptController {
@Resource
private LawExplainAssistant lawExplainAssistant;
/**
* http://localhost:9008/lc4j/chatprompt/test2
* TRIPS协议与贸易有关的知识产权协议
* 世界贸易组织WTO成员间的一个重要协议
* 它规定了最低标准的知识产权保护要求并适用于所有WTO成员。
* @return
*/
@GetMapping(value = "/lc4j/chatprompt/test2")
public String test2()
{
var prompt = new LawPrompt();
prompt.setLegal("知识产权");
prompt.setQuestion("TRIPS协议?");
var chat = lawExplainAssistant.chat(prompt);
System.out.println(chat);
return "success : "+ DateUtil.now()+"<br> \n\n chat: "+chat;
}
/**
* 高阶API调用
* http://localhost:9008/lc4j/chatprompt/test1
* @return
*/
@GetMapping(value = "/lc4j/chatprompt/test1")
public String test1()
{
String chat = lawExplainAssistant.chat("什么是知识产权?",2000);
System.out.println(chat);
String chat2 = lawExplainAssistant.chat("什么是java",2000);
System.out.println(chat2);
return "success : "+ DateUtil.now()+"<br> \n\n chat: "+chat+"<br> \n\n chat2: "+chat2;
}
@Resource(name = "qwen")
private ChatModel chatModel;
/**
* 低阶API调用
* http://localhost:9008/lc4j/chatprompt/test
* @return
*/
@GetMapping(value = "/lc4j/chatprompt/test")
public String test(){
// 看看源码,默认 PromptTemplate 构造使用 it 属性作为默认占位符
/*String role = "外科医生";
String question = "牙疼";*/
String role = "财务会计";
String question = "人民币大写";
//1 构造PromptTemplate模板
PromptTemplate template = PromptTemplate.from("你是一个{{it}}助手,{{question}}怎么办");
//2 由PromptTemplate生成Prompt
Prompt prompt = template.apply(Map.of("it",role,"question",question));
//3 Prompt提示词变成UserMessage
UserMessage userMessage = prompt.toUserMessage();
//4 调用大模型
ChatResponse chatResponse = chatModel.chat(userMessage);
//4.1 后台打印
System.out.println(chatResponse.aiMessage().text());
//4.2 前台返回
return "success : "+ DateUtil.now()+"<br> \n\n chat: "+chatResponse.aiMessage().text();
}
}

View File

@@ -0,0 +1,12 @@
package com.iwe3.langchain4j.entity;
import dev.langchain4j.model.input.structured.StructuredPrompt;
import lombok.Data;
@Data
@StructuredPrompt("根据中国{{legal}}法律,解答以下问题:{{question}}")
public class LawPrompt
{
private String legal;//法律
private String question;//问题
}

View File

@@ -0,0 +1,38 @@
package com.iwe3.langchain4j.service;
import com.iwe3.langchain4j.entity.LawPrompt;
import dev.langchain4j.service.SystemMessage;
import dev.langchain4j.service.UserMessage;
import dev.langchain4j.service.V;
import dev.langchain4j.service.spring.AiService;
/**
* 一个法律解释助手
*/
@AiService(chatModel = "qwen")
public interface LawExplainAssistant {
//案例3 当提示词过多,也可以将从外部资源加载
@SystemMessage(fromResource = "prompt-template.txt")
String chat(LawPrompt lawPrompt);
//案例2 新建带着@StructuredPrompt的业务实体类比如LawPrompt
// @SystemMessage("你是一位专业的中国法律顾问,只回答与中国法律相关的问题。" +
// "输出限制:对于其他领域的问题禁止回答,直接返回'抱歉,我只能回答中国法律相关的问题。'")
// String chat(LawPrompt lawPrompt);
// @SystemMessage : 定AI-LLM 的角色,任务,风格,格式
// @UserMessage : 用户提示词
// @V : 超过1个以上参数需要起别名
//案例1 @SystemMessage + @UserMessage + @V
@SystemMessage("你是一位专业的中国法律顾问,只回答与中国法律相关的问题。" +
"输出限制:对于其他领域的问题禁止回答,直接返回'抱歉,我只能回答中国法律相关的问题。'")
@UserMessage("请回答以下法律问题:{{question}},字数控制在{{length}}以内")
String chat(@V("question") String question, @V("length") int length);
}

View File

@@ -0,0 +1,5 @@
server:
port: 9008
spring:
application:
name: langchain4j-ai-prompt

View File

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

View File

@@ -0,0 +1,58 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.iwe3</groupId>
<artifactId>langchain4j-ai-java</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>langchain4j-ai-rag</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- 简单的rag实现 -->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-easy-rag</artifactId>
</dependency>
<!-- 解析pdf文档 -->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-document-parser-apache-pdfbox</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--导入低阶依赖-->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-open-ai-spring-boot-starter</artifactId>
<version>1.9.1-beta17</version>
</dependency>
<!--导入高阶依赖-->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-spring-boot-starter</artifactId>
<version>1.9.1-beta17</version>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,12 @@
package com.iwe3.langchain4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class RagApplication {
public static void main(String[] args) {
SpringApplication.run(RagApplication.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,5 @@
server:
port: 9010
spring:
application:
name: langchain4j-ai-rag

View File

@@ -0,0 +1 @@
电子科技大学简称“成电”UESTC [12],位于四川成都,是中华人民共和国教育部直属全国重点大学 [127]国家首批“211工程”“985工程”重点建设大学首批国家“双一流”建设高校 [188]入选111计划 [140]、101计划 [141]、强基计划 [137]、珠峰计划 [138]、英才计划 [120]、卓越工程师教育培养计划 [139]、国家建设高水平大学公派研究生项目 [136];是一所以电子信息科学技术为核心,以工为主,理工渗透,理、工、管、文、医协调发展的多科性研究型大学,被誉为“中国民族电子工业摇篮”和“中国电子类院校排头兵”。

View File

@@ -0,0 +1,21 @@
电子科技大学University of Electronic Science and Technology of China简称 **UESTC****“成电”**是中国电子信息领域顶尖的高等学府也是国家“985工程”“211工程”和首批“双一流”A类建设高校。以下是其核心简介
------
### 📍 基本信息
- **所在地**:四川省成都市(主校区为清水河校区,另有沙河、九里堤校区)
- **创办时间**1956年
- **主管部门**:中华人民共和国教育部
- **校训**:求实求真,大气大为
------
### 🏛️ 历史沿革
- 由周恩来总理亲自部署,整合:
- 交通大学(现上海交大、西安交大)
- 南京工学院(现东南大学)
- 华南工学院(现华南理工大学) 的**电讯工程专业**,组建 **成都电讯工程学院**
- 1988年更名为 **电子科技大学**
- 1960年即被列为全国重点高校1961年成为“国防七子”之一。

View File

@@ -0,0 +1,83 @@
package com.iwe3.langchain4j;
import ai.djl.huggingface.tokenizers.HuggingFaceTokenizer;
import dev.langchain4j.data.document.Document;
import dev.langchain4j.data.document.loader.FileSystemDocumentLoader;
import dev.langchain4j.data.document.parser.apache.pdfbox.ApachePdfBoxDocumentParser;
import dev.langchain4j.data.document.splitter.DocumentByParagraphSplitter;
import dev.langchain4j.data.message.UserMessage;
import dev.langchain4j.data.segment.TextSegment;
import dev.langchain4j.model.chat.ChatModel;
import dev.langchain4j.model.chat.response.ChatResponse;
import dev.langchain4j.model.output.TokenUsage;
import dev.langchain4j.store.embedding.EmbeddingStoreIngestor;
import dev.langchain4j.store.embedding.inmemory.InMemoryEmbeddingStore;
import jakarta.annotation.Resource;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class RagApplicationTest {
@Resource
private ChatModel chatModel;
@Test
public void testCountToken(){
var res = chatModel.chat(UserMessage.from("你好,这是一段文字!"));
var result = res.aiMessage().text();
System.out.println("通过调用大模型返回结果:" + result);
/*Token用量计算底层API*/
var tu = res.tokenUsage();
System.out.println("本地调用销毁的TOKEN" + tu);
}
/**
* 加载文档并存入向量数据库
*/
@Test
public void testReadDocumentAndStore() {
// 使用FileSystemDocumentLoader读取指定目录下的知识库文档
// 并使用默认的文档解析器TextDocumentParser对文档进行解析
var document = FileSystemDocumentLoader.loadDocument("D:/files/电子科大.md");
// 为了简单起见,我们暂时使用基于内存的向量存储
InMemoryEmbeddingStore<TextSegment> db = new InMemoryEmbeddingStore<>();
// /ingest
// /1、分割文档默认使用递归分割器将文档分割为多个文本片段每个片段包含不超过 300个token并且有 30个token的重叠部分保证连贯性
// /2、文本向量化使用一个LangChain4j内置的轻量化向量模型对每个文本片段进行向量化
// /3、将原始文本和向量存储到向量数据库中(InMemoryEmbeddingStore)
EmbeddingStoreIngestor.ingest(document, db);
// 查看向量数据库内容
System.out.println(db);
}
/**
* 解析PDF
*/
@Test
public void testParsePDF() {
var document = FileSystemDocumentLoader.loadDocument(
"D:/files/电子科大.pdf",
new ApachePdfBoxDocumentParser()
);
System.out.println(document);
}
@Test
public void testReadDocument() {
// 使用FileSystemDocumentLoader读取指定目录下的知识库文档
// 并使用默认的文档解析器TextDocumentParser对文档进行解析
var document = FileSystemDocumentLoader
.loadDocument("D:/files/test.txt");
System.out.println(document.metadata());
System.out.println(document.text());
}
}

View File

@@ -0,0 +1,57 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.iwe3</groupId>
<artifactId>langchain4j-ai-java</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>langchain4j-ai-stream</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<!-- Spring Boot Starter Data MongoDB -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-reactor</artifactId>
<version>1.9.1-beta17</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--导入低阶依赖-->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-open-ai-spring-boot-starter</artifactId>
<version>1.9.1-beta17</version>
</dependency>
<!--导入高阶依赖-->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-spring-boot-starter</artifactId>
<version>1.9.1-beta17</version>
</dependency>
</dependencies>
</project>

View File

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

View File

@@ -0,0 +1,36 @@
package com.iweb.langchain4j.config;
import dev.langchain4j.model.chat.ChatModel;
import dev.langchain4j.model.chat.StreamingChatModel;
import dev.langchain4j.model.openai.OpenAiChatModel;
import dev.langchain4j.model.openai.OpenAiStreamingChatModel;
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();
}
/**
* @Description: 流式对话接口 StreamingChatModel
*/
@Bean
public StreamingChatModel streamingChatModel(){
return OpenAiStreamingChatModel.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,57 @@
package com.iweb.langchain4j.controller;
import com.iweb.langchain4j.service.ChatAssistant;
import dev.langchain4j.model.chat.StreamingChatModel;
import dev.langchain4j.model.chat.response.ChatResponse;
import dev.langchain4j.model.chat.response.StreamingChatResponseHandler;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;
@RestController
@Slf4j
public class StreamController {
@Resource //直接使用 low-level LLM API
private StreamingChatModel chatModelQwen;
@Resource //自己封装接口使用 high-level LLM API
private ChatAssistant chatAssistant;
// http://localhost:9006/lc4j/chatstream/chat2?prompt=我是谁?
@GetMapping(value = "/lc4j/chatstream/chat2")
public Flux<String> chat3(@RequestParam(value = "prompt", defaultValue = "你是谁?") String prompt) {
return chatAssistant.chatFlux(prompt);
}
// http://localhost:9006/lc4j/chatstream/chat?prompt=我是谁?
@GetMapping(value = "/lc4j/chatstream/chat")
public Flux<String> chat(@RequestParam("prompt") String prompt) {
return Flux.create(emitter -> {
chatModelQwen.chat(prompt, new StreamingChatResponseHandler()
{
@Override
public void onPartialResponse(String partialResponse)
{
emitter.next(partialResponse);
}
@Override
public void onCompleteResponse(ChatResponse completeResponse)
{
emitter.complete();
}
@Override
public void onError(Throwable throwable)
{
emitter.error(throwable);
}
});
});
}
}

View File

@@ -0,0 +1,27 @@
package com.iweb.langchain4j.service;
import dev.langchain4j.service.spring.AiService;
import dev.langchain4j.service.spring.AiServiceWiringMode;
import reactor.core.publisher.Flux;
/**
* 知识出处:
* https://docs.langchain4j.dev/tutorials/spring-boot-integration/#spring-boot-starter-for-declarative-ai-services
*/
@AiService(wiringMode = AiServiceWiringMode.EXPLICIT
,streamingChatModel = "streamingChatModel")
public interface ChatAssistant {
/**
* 普通聊天
* @param prompt
* @return
*/
String chat(String prompt);
/**
* 流式聊天
* @param prompt
* @return
*/
Flux<String> chatFlux(String prompt);
}

View File

@@ -0,0 +1,10 @@
server:
port: 9006
servlet:
encoding:
charset: utf-8
enabled: true
force: true # 设置响应的字符编码,避免流式返回输出乱码
spring:
application:
name: langchain4j-ai-stream

View File

@@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.iwe3</groupId>
<artifactId>langchain4j-ai-java</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>langchain4j-ai-tools</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--导入低阶依赖-->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-open-ai-spring-boot-starter</artifactId>
<version>1.9.1-beta17</version>
</dependency>
<!--导入高阶依赖-->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-spring-boot-starter</artifactId>
<version>1.9.1-beta17</version>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,22 @@
package com.iwe3.langchain4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
public class ToolsApplication {
/**
* 创建RestTemplate的实例
* @return
*/
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(ToolsApplication.class,args);
}
}

View File

@@ -0,0 +1,20 @@
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 {
@Bean(name = "qwen")
public ChatModel chatModelQwen(){
/*大模型3件套apikey ,model-name,base-url */
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,25 @@
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 org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SeparateChatAssistantConfig {
/**
* 聊天记忆提供器
* 配置采用memoryId来完成隔离
* @return
*/
@Bean
ChatMemoryProvider chatMemoryProvider() {
return memoryId -> MessageWindowChatMemory.builder()
.id(memoryId)
.maxMessages(10).chatMemoryStore(new InMemoryChatMemoryStore())
.build();
//如果未来想自定义 -> 则自己写一个类实现 ChatMemoryStore
}
}

View File

@@ -0,0 +1,32 @@
package com.iwe3.langchain4j.service;
import dev.langchain4j.service.MemoryId;
import dev.langchain4j.service.UserMessage;
import dev.langchain4j.service.V;
import dev.langchain4j.service.spring.AiService;
import dev.langchain4j.service.spring.AiServiceWiringMode;
/**
* 知识出处:
* https://docs.langchain4j.dev/tutorials/spring-boot-integration/#spring-boot-starter-for-declarative-ai-services
*/
@AiService(wiringMode = AiServiceWiringMode.EXPLICIT
,chatModel = "qwen",
tools = {"weatherTools"},
chatMemoryProvider = "chatMemoryProvider")
public interface ChatAssistant {
/**
* 聊天
* @param memoryId
* @param userMessage
* @return
*/
@UserMessage("请用粤语回答问题,并且添加一些表情符号。 {{msg}}")
String chat(@MemoryId int memoryId, @V("msg") String userMessage);
/**
* 普通聊天
* @param prompt
* @return
*/
String chat(String prompt);
}

View File

@@ -0,0 +1,27 @@
package com.iwe3.langchain4j.tools;
import dev.langchain4j.agent.tool.P;
import dev.langchain4j.agent.tool.Tool;
import dev.langchain4j.agent.tool.ToolMemoryId;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
@Component
public class WeatherTools {
@Resource
private RestTemplate restTemplate;
//name 是工具描述 value是工具补充信息
@Tool(name = "查询天气",value = "根据城市编码调用高德开发平台,返回对应城市的天气情况")
public String queryWeather(@ToolMemoryId int memoryId,
@P(value = "城市编码",required = true) String citycode){
System.out.println("查询天气情况---> 开始 ---> memoryId=" + memoryId);
//高德地图:查询天气
//https://lbs.amap.com/api/webservice/guide/api-advanced/weatherinfo
var key = "cf6cb4245c630692d2f13c1cd1ad1632";
var url = "https://restapi.amap.com/v3/weather/weatherInfo?key="+key+"&city="+citycode+"&extensions=all";
return restTemplate.getForObject(url, String.class);
}
}

View File

@@ -0,0 +1,5 @@
server:
port: 9009
spring:
application:
name: langchain4j-ai-tools

View File

@@ -0,0 +1,26 @@
package com.iwe3.langchain4j;
import com.iwe3.langchain4j.service.ChatAssistant;
import jakarta.annotation.Resource;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class ToolsApplicationTest {
@Resource
private ChatAssistant chatAssistant;
@Test
public void getWeatherByMemoryId(){
var res = chatAssistant.chat(1,"成都今天天气如何城市编码510100");
System.out.println("res = " + res);
}
@Test
public void getWeather(){
var res = chatAssistant.chat("成都今天天气如何城市编码510100");
System.out.println("res = " + res);
}
}

View File

@@ -0,0 +1,96 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.iwe3</groupId>
<artifactId>langchain4j-ai-java</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>langchain4j-ai-xiaoai-agent</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<knife4j.version>4.3.0</knife4j.version>
</properties>
<dependencies>
<!-- 接入阿里云百炼平台 -->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-community-dashscope-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-pinecone</artifactId>
</dependency>
<!-- 简单的rag实现 -->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-easy-rag</artifactId>
</dependency>
<!-- 引入德鲁伊数据源连接池的启动器 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-3-starter</artifactId>
<version>1.2.27</version>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>3.0.5</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<!-- Spring Boot Starter Data MongoDB -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-reactor</artifactId>
<version>1.9.1-beta17</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--导入低阶依赖-->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-open-ai-spring-boot-starter</artifactId>
<version>1.9.1-beta17</version>
</dependency>
<!--导入高阶依赖-->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-spring-boot-starter</artifactId>
<version>1.9.1-beta17</version>
</dependency>
<!-- 前后端分离中的后端接口测试工具 -->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
<version>${knife4j.version}</version>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,13 @@
package com.iwe3.langchain4j;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@MapperScan("com.iwe3.langchain4j.mapper")
@SpringBootApplication
public class XiaoAIAgentApplication {
public static void main(String[] args) {
SpringApplication.run(XiaoAIAgentApplication.class,args);
}
}

View File

@@ -0,0 +1,32 @@
package com.iwe3.langchain4j.config;
import dev.langchain4j.data.segment.TextSegment;
import dev.langchain4j.model.embedding.EmbeddingModel;
import dev.langchain4j.store.embedding.EmbeddingStore;
import dev.langchain4j.store.embedding.pinecone.PineconeEmbeddingStore;
import dev.langchain4j.store.embedding.pinecone.PineconeServerlessIndexConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class EmbeddingStoreConfig {
@Autowired
private EmbeddingModel embeddingModel;
@Bean
public EmbeddingStore<TextSegment> embeddingStore() {
// 创建向量存储
return PineconeEmbeddingStore.builder()
.apiKey(System.getenv("PINECONE_API_KEY"))
.index("xiaoai-index") // 如果指定的索引不存在,将创建一个新的索引
.nameSpace("xiaoai-namespace") // 如果指定的名称空间不存在,将创建一个新的名称空间
.createIndex(PineconeServerlessIndexConfig.builder()
.cloud("AWS") // 指定索引部署在 AWS 云服务上。
.region("us-east-1") // 指定索引所在的 AWS 区域为 us-east-1。
.dimension(embeddingModel.dimension()) // 指定索引的向量维度,该维度与 embeddingModel 生成的向量维度相同。
.build())
.build();
}
}

View File

@@ -0,0 +1,23 @@
package com.iwe3.langchain4j.config;
import dev.langchain4j.model.chat.StreamingChatModel;
import dev.langchain4j.model.openai.OpenAiStreamingChatModel;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class LLMConfig {
/**
* @Description: 流式对话接口 StreamingChatModel
*/
@Bean
public StreamingChatModel streamingChatModel(){
return OpenAiStreamingChatModel.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,65 @@
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;
/**
* 根据聊天ID查询所有消息
* @param memoryId
* @return
*/
@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());
}
/**
* 根据聊天id修改聊天消息
* @param memoryId
* @param messages
*/
@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);
}
/**
* 根据聊天ID删除聊天消息
* @param memoryId
*/
@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,27 @@
package com.iwe3.langchain4j.config;
import dev.langchain4j.memory.chat.ChatMemoryProvider;
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import jakarta.annotation.Resource;
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(30).
chatMemoryStore(mongoChatMemoryStore)
.build();
}
}

View File

@@ -0,0 +1,63 @@
package com.iwe3.langchain4j.config;
import dev.langchain4j.data.document.loader.FileSystemDocumentLoader;
import dev.langchain4j.data.document.parser.TextDocumentParser;
import dev.langchain4j.data.segment.TextSegment;
import dev.langchain4j.model.embedding.EmbeddingModel;
import dev.langchain4j.rag.content.retriever.ContentRetriever;
import dev.langchain4j.rag.content.retriever.EmbeddingStoreContentRetriever;
import dev.langchain4j.store.embedding.EmbeddingStore;
import dev.langchain4j.store.embedding.EmbeddingStoreIngestor;
import dev.langchain4j.store.embedding.inmemory.InMemoryEmbeddingStore;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.nio.file.FileSystems;
@Configuration
public class XiaoAiAgentConfig {
@Autowired
private EmbeddingStore embeddingStore;
@Autowired
private EmbeddingModel embeddingModel;
@Bean
ContentRetriever contentRetrieverInPinecone() {
// 创建一个 EmbeddingStoreContentRetriever 对象,用于从嵌入存储中检索内容
return EmbeddingStoreContentRetriever
.builder()
// 设置用于生成嵌入向量的嵌入模型
.embeddingModel(embeddingModel)
// 指定要使用的嵌入存储
.embeddingStore(embeddingStore)
// 设置最大检索结果数量,这里表示最多返回 1 条匹配结果
.maxResults(1)
// 设置最小得分阈值,只有得分大于等于 0.8 的结果才会被返回
.minScore(0.8)
// 构建最终的 EmbeddingStoreContentRetriever 实例
.build();
}
/**
* 配置RAG检索增强 文档库
* @return
*/
@Bean
ContentRetriever contentRetrieverInMemory() {
// 使用FileSystemDocumentLoader读取指定目录下的知识库文档
var pathMatcher = FileSystems.getDefault()
.getPathMatcher("glob:*\\.md");
var documents = FileSystemDocumentLoader
.loadDocuments("D:/documents", pathMatcher, new TextDocumentParser());
// 使用内存向量存储
InMemoryEmbeddingStore<TextSegment> db = new InMemoryEmbeddingStore<>();
// 使用默认的文档分割器
EmbeddingStoreIngestor.ingest(documents, db);
// 从嵌入存储EmbeddingStore里检索和查询内容相关的信息
return EmbeddingStoreContentRetriever.from(db);
}
}

View File

@@ -0,0 +1,26 @@
package com.iwe3.langchain4j.controller;
import com.iwe3.langchain4j.record.ChatRecord;
import com.iwe3.langchain4j.service.XiaoAIChatAssistant;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
@Tag(name="小艾")
@RestController
@RequestMapping("/xiaoai")
public class XiaoAIController {
@Resource
private XiaoAIChatAssistant xiaoAIChatAssistant;
@Operation(summary = "对话")
@PostMapping("/chat")
public Flux<String> chat(@RequestBody ChatRecord record){
return xiaoAIChatAssistant.chat(record.memoryId(),record.message());
}
}

Some files were not shown because too many files have changed in this diff Show More