超實(shí)用!用FunctionCall實(shí)現(xiàn)快遞AI助手
昨天晚上直播,我們用 RAG(Retrieval-Augmented Generation,檢索增強(qiáng)生成)實(shí)現(xiàn)了數(shù)據(jù)庫(kù) AI 助手,今天我們準(zhǔn)備換一個(gè)技術(shù)使用 function call 來(lái)實(shí)現(xiàn)快遞 AI 助手。
執(zhí)行效果
快遞 AI 助手的業(yè)務(wù)邏輯很清晰,就是我通過(guò) LLM 大語(yǔ)言模型的對(duì)話來(lái)查詢我的快遞詳情,例如,我問(wèn) AI 我有幾個(gè)“運(yùn)送中”的快遞,他把這些快遞查詢并展示出來(lái),效果如下圖所示:
圖片
什么是 function call?
定義: Function Call(也稱(chēng)為 Tool Call)它允許大模型與一組 API 或工具進(jìn)行交互,從而增強(qiáng)其功能。
也就是說(shuō) Function Call 和 RAG、MCP 等類(lèi)似都是用于增強(qiáng) AI 能力邊界的。
function call 執(zhí)行流程
執(zhí)行流程如下:
圖片
“
其中,Tool 既為 Function Call。
當(dāng)然如果你上圖看的不是很懂的話,也可以參考阿里云提供的 function call 的工作流程:
快遞 AI 助手實(shí)現(xiàn)
具體實(shí)現(xiàn)步驟:
- 添加大模型依賴(lài)
- 配置大模型參數(shù)
- 創(chuàng)建 function call
- 調(diào)用 function call 實(shí)現(xiàn)快遞查詢
接下來(lái),我們一步步來(lái)看,我們以阿里云的百煉(通義千問(wèn))大模型對(duì)接為例。
1.添加大模型依賴(lài)
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-openai</artifactId>
</dependency>
2.配置大模型參數(shù)
spring:
ai:
openai:
base-url: https://dashscope.aliyuncs.com/compatible-mode/
api-key: ${ALIYUN-AK}
chat:
options:
model: deepseek-v3
3.創(chuàng)建 function call
這里就不連接數(shù)據(jù)庫(kù)查詢快遞信息了,生成級(jí)別需要連接數(shù)據(jù)庫(kù),這里演示效果,構(gòu)建測(cè)試數(shù)據(jù)即可,如下代碼所示:
import org.springframework.ai.tool.annotation.Tool;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
publicclass ExpressService {
@Tool(description = "用于查詢我的快遞")
public List<Express> getExpress(String state) {
// 生成測(cè)試數(shù)據(jù)
List<Express> data = getData();
// 根據(jù)狀態(tài)過(guò)濾(如果state為null或空則返回全部)
return state == null || state.isEmpty()
? data
: data.stream()
.filter(e -> e.state().equalsIgnoreCase(state))
.collect(Collectors.toList());
}
/**
* 生成測(cè)試快遞數(shù)據(jù)
*/
private List<Express> getData() {
List<Express> data = new ArrayList<>();
LocalDateTime now = LocalDateTime.now();
data.add(new Express(1001L, "北京", "西安", now.minusDays(12), "已簽收"));
data.add(new Express(1002L, "廣州", "西安", now.minusDays(12), "已簽收"));
data.add(new Express(1003L, "杭州", "西安", now.minusDays(3), "運(yùn)送中"));
data.add(new Express(1004L, "深圳", "西安", now.minusDays(3), "運(yùn)送中"));
data.add(new Express(1005L, "南京", "西安", now.minusDays(1), "待發(fā)貨"));
return data;
}
/**
* 快遞類(lèi)
*
* @param id
* @param from
* @param to
* @param createtime
* @param state
*/
record Express(long id, String from, String to,
LocalDateTime createtime, String state) {
}
}
4.調(diào)用 function call
調(diào)用大模型可以使用 ChatModel 和 ChatClient,這里使用 ChatClient 調(diào)用:
@RequestMapping("/tool")
public Flux<String> tool(@RequestParam("msg") String msg) {
return chatClient.prompt(msg)
.tools(new ExpressService(),
new DateTimeTools())
.stream().content();
}
最終執(zhí)行效果如下:
圖片
小結(jié)
大模型應(yīng)用開(kāi)發(fā)是以后程序開(kāi)發(fā)的主流方向,他也會(huì)巔峰以往的開(kāi)發(fā)形式,早早掌握大模型的開(kāi)發(fā)知識(shí),對(duì)于后期漲薪或找工作都有巨大的幫助。程序員群體注定是一個(gè)活到老學(xué)到老的群體,因?yàn)?/span>學(xué)習(xí)的本質(zhì)在于擴(kuò)展自己的能力邊界,讓自己變得更值錢(qián),所以各位動(dòng)起來(lái),讓我們一起擁抱這場(chǎng) AI 盛宴吧。