AI-Learning

AI-Learning

AI的应用方面

image-20250403170412746

Agent+Function Calling

image-20250403170521257

Rag Embeddings

image-20250403171111482

开发框架选择

image-20250403171652098

image-20250403172303742

image-20250403172549434

对话机器人

基本调用

  1. 引入依赖
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-openai-spring-boot-starter</artifactId>
</dependency>

<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-bom</artifactId>
<version>${spring-ai.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
  1. 配置Client
1
2
3
4
5
6
7
8
9
10
11
@Configuration
public class CommonConfiguration {
@Bean
public ChatClient chatClient(OpenAiChatModel model){
return ChatClient
.builder(model)
.defaultSystem("你是一个AI助手,名字叫帆帆,你要热心回答用户的问题")
.build();
}
}

  1. 生成会话
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class AiController {

private final ChatClient chatClient;

// 指定字符编码否则无法正确展示
@RequestMapping(value = "/chat",produces = "text/html;charset=utf-8")
public Flux<String> chat(String prompt){
return chatClient.prompt()
.user(prompt)
.stream()
.content();
}
}

会话日志/记忆

  • SimpleLoggerAdvisor:会话日志控制台记录

    需要配置日志记录级别

    1
    2
    3
    logging:
    level:
    org.springframework.ai.chat.client.advisor: debug
  • MessageChatMemoryAdvisor:会话记录

image-20250403220227214

  1. 配置Advisor
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@Configuration
public class CommonConfiguration {

// 配置会话记录advisor
@Bean
public ChatMemory chatMemory(){
// 基于map的内存会话保存
return new InMemoryChatMemory();
}


@Bean
public ChatClient chatClient(OpenAiChatModel model, ChatMemory chatMemory){
return ChatClient
.builder(model)
.defaultAdvisors(
new MessageChatMemoryAdvisor(chatMemory),
new SimpleLoggerAdvisor()
)
.defaultSystem("你是一个可爱的AI助手,名字叫帆帆,你要热心回答用户的问题")
.build();
}
}

  1. 在对话回复API中加入会话ID
1
2
3
4
5
6
7
8
9
// 指定字符编码否则无法正确展示
@RequestMapping(value = "/chat",produces = "text/html;charset=utf-8")
public Flux<String> chat(String prompt,String chatId){
return chatClient.prompt()
.user(prompt)
.advisors(a -> a.param(CHAT_MEMORY_CONVERSATION_ID_KEY,chatId)) // 加入会话id
.stream()
.content();
}

会话历史

会话历史其实保存在InMemoryChatMemory,但是他包含其他不需要的消息类型,需要过滤处理

image-20250404214042495

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Data
public class MessageVo {
private String role;
private String content;

// 构造器
public MessageVo(Message message) {
switch (message.getMessageType()) {
case USER:
this.role = "user";break;
case ASSISTANT:
this.role = "assistant";break;
default:
this.role = "";break;
}
this.content = message.getText();
}
}

1
2
3
4
5
@GetMapping("/{type}/{chatId}")
public List<MessageVo> getHistoryChat(@PathVariable String type, @PathVariable String chatId){
List<Message> messages = chatMemory.get(chatId, Integer.MAX_VALUE);
return messages.stream().map(MessageVo::new).toList();
}

SDK

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
44
45
46
47
48
49
50
51
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversation;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationParam;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationResult;
import com.alibaba.dashscope.common.MultiModalMessage;
import com.alibaba.dashscope.common.Role;
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.alibaba.dashscope.exception.UploadFileException;
import com.alibaba.dashscope.utils.JsonUtils;

public class Main {
private static final String modelName = "qwen-audio-turbo-latest";
public static void MultiRoundConversationCall() throws ApiException, NoApiKeyException, UploadFileException {
MultiModalConversation conv = new MultiModalConversation();
MultiModalMessage systemMessage = MultiModalMessage.builder().role(Role.SYSTEM.getValue())
.content(Arrays.asList(Collections.singletonMap("text", "You are a helpful assistant."))).build();
MultiModalMessage userMessage = MultiModalMessage.builder().role(Role.USER.getValue())
.content(Arrays.asList(Collections.singletonMap("audio", "https://dashscope.oss-cn-beijing.aliyuncs.com/audios/welcome.mp3"),
Collections.singletonMap("text", "这段音频在说什么?"))).build();
List<MultiModalMessage> messages = new ArrayList<>();
messages.add(systemMessage);
messages.add(userMessage);
MultiModalConversationParam param = MultiModalConversationParam.builder()
.model(modelName)
.messages(messages)
.build();
MultiModalConversationResult result = conv.call(param);
System.out.println("第一轮回复:"+JsonUtils.toJson(result));
// add the result to conversation
messages.add(result.getOutput().getChoices().get(0).getMessage());
MultiModalMessage msg = MultiModalMessage.builder().role(Role.USER.getValue())
.content(Arrays.asList(Collections.singletonMap("text", "简单介绍这家公司。"))).build();
messages.add(msg);
// new messages
param.setMessages((List)messages);
result = conv.call(param);
System.out.println("第二轮回复:"+JsonUtils.toJson(result));
}
public static void main(String[] args) {
try {
MultiRoundConversationCall();
} catch (ApiException | NoApiKeyException | UploadFileException e) {
System.out.println(e.getMessage());
}
System.exit(0);
}
}

FuctionCall

image-20250408203835841

Tool 主要用于:

  • 信息检索。此类别中的工具可用于从外部源(如数据库、Web 服务、文件系统或 Web 搜索引擎)检索信息。目标是增强模型的知识,使其能够回答其他方式无法回答的问题。因此,它们可用于检索增强生成 (RAG) 方案。例如,工具可用于检索给定位置的当前天气、检索最新的新闻文章或查询数据库以获取特定记录。
  • 采取行动。此类别中的工具可用于在软件系统中执行作,例如发送电子邮件、在数据库中创建新记录、提交表单或触发工作流。目标是自动执行原本需要人工干预或显式编程的任务。例如,可以使用工具为与聊天机器人交互的客户预订航班,在网页上填写表单,或在代码生成场景中实现基于自动测试 (TDD) 的 Java 类。

重要参数

  • returnDirect:默认为false,开启时AI Model识别调用tool的结果将直接返回给客户端,而不是给AI Model进行处理返回

return-direct

MCP

核心特点

image-20250408204701599

五大功能

image-20250408205147978

image-20250408211635871