前言
看此篇的前置知識為langchain4j整合springboot,以及springboot集成langchain4j記憶對話。
Function-Calls介紹
- langchain4j 中的 Function Calls(函數調用)是一種讓大語言模型(LLM)與外部工具(如 API、代碼執行器等)交互的機制。通過這種機制,LLM 可以根據上下文動態調用開發者預定義的函數,從而擴展其能力邊界,解決純文本生成無法處理的復雜任務(如數學計算、實時數據查詢、業務邏輯處理等)。
- 對于基礎大模型來說,他只具備通用信息,他的參數都是拿公網進行訓練,并且有一定的時間延遲,無法得知一些具體業務數據和實時數據,這些數據往往被各軟件系統存儲在自己數據庫中:
- 比如我現在開發一個智能票務助手我現在跟AI說需要退票,AI怎么做到呢?就需要讓AI調用我們自己系統的退票業務方法,進行數據庫操作。
- 那這些都可以通過function-call進行完成,更多的用于實現類似智能客服場景,因為客服需要幫用戶解決業務問題(就需要調用業務方法)。
Function-Calls流程
比如: 現在當用戶問的是“kizzo頁面訪問量有多少”,大模型需要從程序內部獲取
1.問大模型 “頁面訪問量有多少”
2.大模型在識別到你的問題是:“kizzo頁面訪問量有多少”
3.大模型提取“訪問量”
4.調用 pageViewCount方法
5.通過返回的結果再結合上下文再次請求大模型
6.響應“Kizzo頁面的訪問量目前有1000次。”
Function-Calls代碼實現
- 加入回調
@Service
@Slf4j
public class ToolsService {@Tool("kizzo頁面訪問量有多少")public Integer pageViewCount(@P("訪問量") String pv){//todo 此處可以查詢數據庫或rpc方法log.info("pv:{}", pv);// 結果return 1000;}
}
ToolsService配置為了一個bean
@Tool 用于告訴AI什么對話調用這個方法
@P(“訪問量")用于告訴AI,調用方法的時候需要提取對話中的什么信息,這里提取的是訪問量
- 在AiConfig中的助手對象增加Function-Calls Tools
@Beanpublic Assistant assistant(ChatLanguageModel chatLanguageModel, StreamingChatLanguageModel streamingChatLanguageModel, ToolsService toolsService){// 最多存儲多少聊天記錄ChatMemory chatMemory = MessageWindowChatMemory.withMaxMessages(10);// 為Assistant動態代理對象chat ---> 對話內容存儲ChatMemoryi ---> 聊天記錄ChatMemory取出來 ---->放入到當前對話中Assistant assistant = AiServices.builder(Assistant.class).tools(toolsService).chatLanguageModel(chatLanguageModel).streamingChatLanguageModel(streamingChatLanguageModel).chatMemory(chatMemory).build();return assistant;}
再次調用后結果如下:
預設角色(系統消息SystemMessage)
基礎大模型是沒有目的性的,你聊什么給什么,但是如果我們開發的事一個智能票務助手,我需要他以一個票務助手的角色跟我對話, 并且在我跟他說”退票”的時候, 讓大模型一定要告訴我“車次”和“姓名"這樣我才能去調用業務方法(假設有一個業務方法,需要根據車子和姓名才能查詢具體車票),進行退票。
在langchain4j中實現也非常簡單
- @SystemMessage 系統消息,一般做一些預設角色的提示詞,設置大模型的基本職責
- 可以通過{{current date}} 傳入參數,因為預設詞中的文本可能需要實時變化
- @V(“current date”),通過@V傳入{{}中的參數
- 一旦參數不止一個,就需要通過@UserMessage設置用戶信息
代碼實現:
- 在AiConfig中的助手對象重載一個stream流輸出方法,用@SystemMessage預設提示詞角色
@SystemMessage("""您是“xx”航空公司的客戶聊天支持代理。請以友好、樂于助人且愉快的方式來回復。您正在通過在線聊天系統與客戶互動。在提供有關預訂或取消預訂的信息之前,您必須始終從用戶處獲取以下信息:預訂號、客戶姓名。請講中文。今天的日期是 {{current_date}}.""")TokenStream stream(@UserMessage String message, @V("current_date") String currentDate);
- 在ToolsService中新增一個tool
@Tool("退票")public String cancelBooking(@P("地區") String bookingNumber,@P("姓名") String name){//todo 業務方法,退票數據庫操作log.info("bookingNumber:{},name:{}", bookingNumber,name);// 結果return "退票成功";}
- Controller中新增一個接口調用
// 預設角色記憶流對話@RequestMapping(value = "/system_message_chat_stream",produces = "text/stream;charset=UTF8")public Flux<String> systemMessageStreamChat(@RequestParam(defaultValue="我是誰") String message) {TokenStream stream = assistant.stream(message, LocalDate.now().toString());return Flux.create(sink -> {stream.onPartialResponse(s -> sink.next(s)).onCompleteResponse(c -> sink.complete()).onError(sink::error).start();});}
結果如下: