
GraphRAG:基于PolarDB+通義千問api+LangChain的知識圖譜定制實踐
阿里巴巴和 Spring 官方一直保持著非常成功的合作,在微服務時代共同合作打造了 SpringCloud Alibaba 微服務框架與整體解決方案,該框架已經是國內使用最廣泛的開源微服務框架之一,整體生態 star 數超過 10w。
關于 Spring AI Alibaba,我們期望保持同樣的深度合作模式,其中 Spring 社區主要負責綠色部分,即智能體應用開發原子能力與API的抽象,Spring AI Alibaba 社區負責與阿里云通義模型、云原生基礎設施的深度集成,同時包括與智能體業務落地更密切的一些核心能力如流程編排、開發工具集、應用評測、可觀測、配置管理、流量管控等的抽象和實現。背靠 Spring 與阿里巴巴兩大開源社區支撐,相信 Spring AI Alibaba 項目將會長期保持一個持續且健康的發展態勢。
以下是 Spring AI Alibaba 框架的核心特性,可以幫我們加速和簡化 Java 智能體應用的開發。
第一點,Spring AI Alibaba是專門為Spring和Java開發者設計的智能體開發框架,使用它開發應用就如同開發一個普通的Spring Boot應用,理解成本非常低。
第二點,框架對AI智能體應用的通用開發范式做了很好的抽象,從原子能力層次如對話模型接入、提示詞模板到函數調用,再到高層次抽象如智能體編排、對話記憶等。
第三點,框架默認與通義系列模型做了深度適配,除此之外,還提供了應用從部署到運維的最佳實踐,包括網關、配置管理、部署、可觀測等。
接下來,我們一起看一下 Spring AI Alibaba 框架中的一些具體概念與 API 定義
首先,是 SpringAI 對模型基本交互的抽象與適配,其實智能體應用開發本質就是一個與大模型服務不停交互的過程,應用為模型提供語義化的輸入,模型推理后反饋給我們輸出。
與模型交互的輸入輸出可以是文本,比如最早期的 ChatGPT,現在我們不止有文本型模型、還有支持圖像、視頻、語音等的模型,因此輸入輸出對應的可能是各種類型的。包括一些模型開始支持多模態輸入,也就是圖形、文本的混合輸入。
Spring AI 對于這種類似聊天式的大模型交互模式提供了完整的抽象,包括文本、圖像、語音等,對于應用開發者來說,可以直接調用 Spring AI 提供的 API,以方法入參做模型輸入,返回值作模型輸出,同時還支持同步、異步、流式等通信模式。如果開發者要切換底層的模型服務,也是完全透明無感的。
Prompt 提示詞是與模型交互的一種輸入數據組織方式,本質上是一種復合結構的輸入,在 prompt 我們是可以包含多組不同角色(System、User、Aissistant等)的信息。如何管理好 Prompt 是簡化 AI 應用開發的關鍵環節。
Spring AI 提供了 Prompt Template 提示詞模板管理抽象,開發者可以預先定義好模板,并在運行時替換模板中的關鍵詞。
SpringAI 還支持從資源文件中直接加載提示詞模板:
大模型返回的數據通常是非格式化的,而應用上下游需要傳遞格式化的、確定的數據結構。因此 SpringAI 提供了結構化輸出轉換的能力,它可以自動化的幫我們在 Prompt 中加入數據格式信息,輔助模型理解我們要求的結果數據格式,同時在拿到模型數據后完成到 JavaBean 的轉換。
以上圖為例,Spring AI 框架幫我們簡化了整個格式化輸出轉換的過程,包括格式信息輸入與結果轉換。
函數調用是AI應用與模型交互中一個非常典型的范式,它可以輔助模型更好的回答用戶問題。我們在給模型輸入的過程中,附帶上可用的函數列表(包含函數名、函數描述等),模型在收到問題和函數列表后,根據對問題的推理在必要的時候發起對函數的調用。
SpringAI 幫我們規范了函數定義、注冊等過程,并在發起模型請求之前自動將函數注入到 Prompt 中,而當模型決策在合適的時候去調用某個函數時,Spring AI 完成函數調用動作,最終將函數執行結果與原始問題再一并發送給模型,模型根據新的輸入決策下一步動作。這其中涉及與大模型的多次交互過程,一次函數調用就是一次完成的交互過程。
這里是函數調用過程中具體的模型交互過程分析。
以上是沒有函數計算時應用和模型的交互過程,應用給模型的輸入是求一個數的平方根,模型根據自己的理解算出了一個結果,但并不準確。
為了解決這個問題,我們定義了一個求平方根的函數,并通過 Spring AI 提供的注解將這個函數注冊為一個可與模型交互的特殊函數,如下圖代碼段所示:
下圖是有了函數調用之后應用與模型的交互,可以看到為了得到最終答案,應用總共有兩輪與模型的交互過程。第一次是發起求平方根提問,與之前的不同是請求 prompt 中攜帶了 “tools” 信息(包含我們定義的函數),此時模型返回了 “ToolExecutionRequest” 的特殊結果,要求 Spring AI 通過調用函數來輔助完成求平方根的動作;隨后是第二輪模型交互,Spring AI 把原始問題和函數執行結果發送給模型,模型最終生成回答。
RAG 是另外一個常用的智能體應用開發范式,它本質上和函數調用類似,也是應用程序輔助模型推理與回答問題的一種方式,只不過在交互流程上和函數調用略有區別。
如上圖所示,總體上 RAG 是分為離線和運行時兩部分。離線部分是將一些領域特有數據進行向量化的過程,將向量化的數據存入向量數據庫。圖中后半部分體現的運行時流程,Spring AI 框架在組裝 prompt 時,會額外檢索向量數據庫,最終生成一個比用戶原始問題具有更多輔助上下文的 prompt,然后將這個具備上下文的 prompt 給到模型,模型根據用戶問題、上下文以及自己的推理生成響應。
Spring AI 提供了從離線數據加載、分析到向量化存儲的抽象,也提供了運行時檢索、prompt 增強的抽象。
Hello World 示例
可參考 官網文檔快速開始 詳細了解如何使用 Spring AI Alibaba 快速開發生成式 AI 應用。https://sca.aliyun.com/ai/get-started/
使用 Spring AI Alibaba 開發應用與使用普通 Spring Boot 沒有什么區別,只需要增加 spring-ai-alibaba-starter 依賴,將 ChatClient Bean 注入就可以實現與模型聊天了。
<dependency>
<groupId>com.alibaba.ai</groupId>
<artifactId>spring-ai-alibaba-starter</artifactId>
<version>1.0.0-M2</version>
</dependency>
注意:由于 spring-ai 相關依賴包還沒有發布到中央倉庫,如出現 spring-ai-core 等相關依賴解析問題,請在您項目的 pom.xml 依賴中加入如下倉庫配置。
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
spring:
ai:
dashscope:
api-key: ${AI_DASHSCOPE_API_KEY}
@RestController
public class ChatController {
private final ChatClient chatClient;
public ChatController(ChatClient.Builder builder) {
this.chatClient = builder.build();
}
@GetMapping("/chat")
public String chat(String input) {
return this.chatClient.prompt()
.user(input)
.call()
.content();
}
}
接下來,我們通過一個更貼近實際使用場景的示例,來展示 Spring AIAlibaba 在構建智能體應用方面的強大能力。
示例目標是使用 Spring AI Alibaba 框架開發一個智能機票助手,它可以幫助消費者完成機票預定、問題解答、機票改簽、取消等動作,具體要求為:
基于這樣一個智能機票助手目標,我們繪制了一個如下圖所示的架構圖:
接下來,我們結合架構圖對示例進行詳細分析。
本質上來說,我們是要用 Spring Boot 開發一個普通的 Java 應用,這個應用能夠持續的接收用戶的提問,為用戶解決機票相關的問題,之所以叫它為智能體應用是因為我們這個應用可以與 AI 交互,由 AI 幫助應用理解用戶問題并為用戶做決策。
機票助手應用簡化后的架構圖如下所示:
基于以上架構圖,用戶的機票業務請求都是由 AI 模型理解并決策,確定下一步動作、驅動業務流程。但任何一個通用的大模型都能幫我們準確無誤的解決機票相關的問題嗎?依賴模型的決策是可靠的嗎?比如有用戶提出了機票改簽的訴求后,模型一定是能夠很好的理解用戶的意圖的,這點沒有疑問。但它怎么知道當前用戶符不符合退票規則呢?要知道每個航空公司的改簽規則可能都是不一樣的;它怎么知道改簽手續費的規定呢?在這樣一個可能帶來經濟糾紛、法律風險的應用場景下,AI模型必須要知道改簽規則的所有細節,并逐條確認用戶信息復合規則后,才能最終作出是否改簽的決策。
很顯然,單純依賴 AI 模型本身并不能替我們完成上面的要求,這個時候就要用到 RAG(檢索增強)模式了。通過 RAG 我們可以把機票退改簽相關的領域知識輸入給應用和 AI 模型,讓 AI 結合這些規則與要求輔助決策。
增加 RAG 后的架構如下圖所示:
有了 RAG 之后,我們的應用真正的成為了一個智能化的機票問題專家,就像一個經過公司業務培訓的客服代表,既能人性化的與用戶對話,又能根據規則引導用戶行為。
AI 智能體可以幫助應用理解用戶需求并作出決策,但是它沒法代替應用完成決策的執行,決策的執行還是要由應用自己完成,這一點和傳統應用并沒有區別,不論是智能化的還是預先編排好的應用,都是要由應用本身去調用函數修改數據庫記錄實現數據持久化。
通過 Spring AI 框架,我們可以將模型的決策轉換為對某個具體函數的調用,從而完成機票的最終改簽或者退票動作,將用戶數據寫入數據庫,這就是我們前面提到的 Function Calling 模式。
增加 Function Calling 后的架構圖如下所示:
最后一點是關于多輪連續對話的支持,我們要記住一點,大模型是無狀態的,它看到的只有當前這一輪對話的內容。因此如果要支持多輪對話效果,需要應用每次都要把之前的對話上下文保留下來,并與最新的問題一并作為 prompt 發送給模型。這時,我們可以利用 Spring AI Alibaba 提供的內置 Conversation Memory 支持,方便的維護對話上下文。
總結起來,我們在這個智能機票助手應用中用到了 Spring AI Alibaba 的核心如下能力:
Spring AI Alibaba 不止提供了以上原子能力抽象,還提供了高階 “智能體” API 抽象 ChatClient
,讓我們可以非常方便的使用流式 Fluent API 把多個組件組裝起來,成為一個智能體 Agent。
對于智能機票助手與 AI 模型交互的所有能力(Prompt、RAG、Chat Memory、Function Calling 等),我們可以直接使用ChatClient 進行聲明,最終實例化一個可以智能體代理對象。示例代碼如下:
this.chatClient = modelBuilder
.defaultSystem("""
您是“Funnair”航空公司的客戶聊天支持代理。請以友好、樂于助人且愉快的方式來回復。
您正在通過在線聊天系統與客戶互動。
在提供有關預訂或取消預訂的信息之前,您必須始終
從用戶處獲取以下信息:預訂號、客戶姓名。
在詢問用戶之前,請檢查消息歷史記錄以獲取此信息。
在更改預訂之前,您必須確保條款允許這樣做。
如果更改需要收費,您必須在繼續之前征得用戶同意。
使用提供的功能獲取預訂詳細信息、更改預訂和取消預訂。
如果需要,可以調用相應函數調用完成輔助動作。
請講中文。
今天的日期是 {current_date}.
""")
.defaultAdvisors(
new PromptChatMemoryAdvisor(chatMemory), // Chat Memory
new VectorStoreChatMemoryAdvisor(vectorStore)),
new QuestionAnswerAdvisor(vectorStore, SearchRequest.defaults()), // RAG
new LoggingAdvisor())
.defaultFunctions("getBookingDetails", "changeBooking", "cancelBooking") // FUNCTION CALLING
.build();
這樣,ChatClient就為我們屏蔽了所有與大模型交互的細節,只需要把 ChatClient注入常規的 Spring Bean 就可以為我們的機票應用加入智能化能力了。
最終,我們開發的示例運行效果如下所示:
本示例項目的源碼請參見文章最后 Github 倉庫地址。
Spring AI Alibaba 的目標是提供 AI 開源框架以及與阿里巴巴整體開源生態的深度適配,以幫助 Java 開發者快速構建 AI Native 應用架構。
文章轉自微信公眾號@阿里云開發者