langchain4j自用学习笔记

参考鱼皮老师教学视频

基本依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-community-dashscope-spring-boot-starter</artifactId>
<version>1.1.0-beta7</version>
</dependency>

<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-spring-boot-starter</artifactId>
<version>1.1.0-beta7</version>
</dependency>

<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j</artifactId>
<version>1.1.0</version>
</dependency>


<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-easy-rag</artifactId>
<version>1.1.0-beta7</version>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>

<!--网页爬取-->
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.20.1</version>
</dependency>

<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-mcp</artifactId>
<version>1.1.0-beta7</version>
</dependency>

Service类

在resources下添加system-prompt.txt文件,里面填写角色预设

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public interface AiCodeHelperService {

@SystemMessage(fromResource = "system-prompt.txt")
String chat(@UserMessage String message, @MemoryId String chatId);

@SystemMessage(fromResource = "system-prompt.txt")
Report report(@UserMessage String message, @MemoryId String chatId);

record Report(String name, List<String> suggestionList){}

@SystemMessage(fromResource = "system-prompt.txt")
Flux<String> chatStream(@UserMessage String message, @MemoryId String chatId);

}

Config类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
@Configuration
public class AiCodeHelperServiceFactory {

@Resource
private ChatModel qwenChatModel;

@Resource
private ContentRetriever contentRetriever;

@Bean
public AiCodeHelperService aiCodeHelperService() {
ChatMemory chatMemory = MessageWindowChatMemory.withMaxMessages(10);
//ai service
AiCodeHelperService aiCodeHelperService = AiServices.builder(AiCodeHelperService.class)
.chatMemory(chatMemory)
.chatModel(qwenChatModel)
.tools(new InterviewQuestionTool())
.contentRetriever(contentRetriever)
.chatMemoryProvider(chatId -> MessageWindowChatMemory.withMaxMessages(10))
.build();
return aiCodeHelperService;
}



}

Rag知识库

在resources创建docs文件夹,里面放知识库文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
@Configuration
public class AiConfiguration {

@Resource
private ChatModel qwenChatModel;

@Resource
private ContentRetriever contentRetriever;

@Resource
private StreamingChatModel streamingChatModel;

@Bean
public AiCodeHelperService aiCodeHelperService() {
ChatMemory chatMemory = MessageWindowChatMemory.withMaxMessages(10);
//ai service
AiCodeHelperService aiCodeHelperService = AiServices.builder(AiCodeHelperService.class)
.chatMemory(chatMemory)
.chatModel(qwenChatModel)
.streamingChatModel(streamingChatModel)
.contentRetriever(contentRetriever)
.chatMemoryProvider(chatId -> MessageWindowChatMemory.withMaxMessages(10))
.build();
return aiCodeHelperService;
}
}

Tools 调用实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
@Slf4j
public class InterviewQuestionTool {

/**
* 从面试鸭网站获取关键词相关的面试题列表
*
* @param keyword 搜索关键词(如"redis"、"java多线程")
* @return 面试题列表,若失败则返回错误信息
*/
@Tool(name = "interviewQuestionSearch", value = """
Retrieves relevant interview questions from mianshiya.com based on a keyword.
Use this tool when the user asks for interview questions about specific technologies,
programming concepts, or job-related topics. The input should be a clear search term.
"""
)
public String searchInterviewQuestions(@P(value = "the keyword to search") String keyword) {
List<String> questions = new ArrayList<>();
// 构建搜索URL(编码关键词以支持中文)
String encodedKeyword = URLEncoder.encode(keyword, StandardCharsets.UTF_8);
String url = "https://www.mianshiya.com/search/all?searchText=" + encodedKeyword;
// 发送请求并解析页面
Document doc;
try {
doc = Jsoup.connect(url)
.userAgent("Mozilla/5.0")
.timeout(5000)
.get();
} catch (IOException e) {
log.error("get web error", e);
return e.getMessage();
}
// 提取面试题
Elements questionElements = doc.select(".ant-table-cell > a");
questionElements.forEach(el -> questions.add(el.text().trim()));
return String.join("\n", questions);
}
}

配置yml:

1
2
3
4
5
6
7
8
9
langchain4j:
community:
dashscope:
chat-model:
model-name: qwen-max
api-key: sk-xxxxx
embedding-model:
model-name: text-embedding-v4
api-key: sk-xxxxx