零代碼改造 + 全鏈路追蹤!Spring AI 最新可觀測性詳細(xì)解讀
前言:AI Agent 從 Demo到生產(chǎn)階段的挑戰(zhàn)
自 2022 年底 GPT-3.5 引爆大模型革命以來,AI 應(yīng)用經(jīng)歷了從技術(shù)探索到產(chǎn)業(yè)落地的快速演進。開源模型迭代與低代碼平臺的興起,推動了 AI Agent 開發(fā)效率的顯著提升。然而,行業(yè)普遍面臨一個核心矛盾:絕大多數(shù) AI 應(yīng)用仍停留在 demo 階段,很難在企業(yè)級生產(chǎn)環(huán)境中大規(guī)模落地。最終能形成一個線上服務(wù)產(chǎn)品的更是少之又少。
在總結(jié)了內(nèi)部和外部的 Agent 落地經(jīng)驗之后,我們發(fā)現(xiàn)在 demo 和生產(chǎn)階段,大家對 AI 應(yīng)用的要求會有一個非線性的提高。對于一個 demo 應(yīng)用來說,我們可能只需要基本功能達到 80 分,把這個應(yīng)用搓出來,最快地看到效果就夠了。但要把這個應(yīng)用部署到生產(chǎn),則要額外考慮的事情就非常多了:開發(fā)效率、業(yè)務(wù)能力、部署便捷性、問題診斷能力、成本控制、生成質(zhì)量、安全合規(guī)等方面,都是 AI 應(yīng)用落地前面的一道道“門檻”。
圖片
好在現(xiàn)在有一些相對成熟的方案來跨過這些“門檻”,以較低的成本保證 AI 應(yīng)用的生產(chǎn)可用。按照場景可以基本分為兩大類:
- 開發(fā)效率、業(yè)務(wù)能力、部署能力:這些能力與搭建 AI 應(yīng)用的技術(shù)棧強相關(guān),開發(fā)者所采用的語言、框架本身特性直接決定了上述能力的強弱。選擇一個相對成熟、開發(fā)&運維友好、擴展性好的 AI 應(yīng)用框架是保證這些能力的重要手段。一些如 AI 網(wǎng)關(guān) [1]、AI Runtime [2]、Agent market [3] 等產(chǎn)品或中間件也能一定程度上提高上述能力。
- 問題診斷、成本控制、生成質(zhì)量監(jiān)測、安全合規(guī):這些場景業(yè)務(wù)上看似發(fā)散,但本質(zhì)上都需要先回答“如何觀測 AI 應(yīng)用運行時狀態(tài)”的問題。目前 AI 應(yīng)用的可觀測性包括三種主要的實現(xiàn)路徑,按照無侵入性由弱到強可以分為:
通過手動添加埋點:一般需要在應(yīng)用中引入 metrics、trace、log 框架,通過在關(guān)鍵調(diào)用中顯示調(diào)用 API 來記錄數(shù)據(jù)。該方式最靈活,但實現(xiàn)起來也最繁瑣,需要專門的開發(fā)者進行開發(fā)和維護。
基于框架&基礎(chǔ)設(shè)施原生的可觀測性:不少比較成熟的 AI 框架本身內(nèi)置了一定的可觀測性,如 AgentScope [4]、Dify [5]、Spring AI [6] 等,一些中間件 [7] 和基礎(chǔ)設(shè)施 [8] 也提供開箱即用的可觀測數(shù)據(jù)透出。該集成方式相對最輕量,但可擴展性最差,且難以打通眾多框架與中間件之間的數(shù)據(jù)關(guān)聯(lián),使用起來并不方便。
基于專門的可觀測采集套件:對于那些較容易實現(xiàn)代碼增強的語言,如 Java、Python、Golang 等,存在一些像 OpenTelemetry [9] 和 LoongSuite [10] Instrumentation 這樣的自動插樁工具(一般也稱之為無侵入探針),可以在編譯時或運行時對業(yè)務(wù)代碼進行增強,從而自動化地完成一些可觀測性數(shù)據(jù)的采集。這些工具集成時不需要修改代碼與依賴,僅需要修改編譯或啟動命令,就可以啟用應(yīng)用的可觀測性。這種集成方式最簡單友好,可觀測數(shù)據(jù)也更加標(biāo)準(zhǔn)通用?;谔准峁┑臄U展機制,也能比較好地與手動埋點擴展兼容,是許多開發(fā)團隊的第一選擇。
AI Coding 與多語言 AI 框架的強勢發(fā)展,使得目前越來越多的內(nèi)部和外部開發(fā)團隊選擇使用 Python 以外的語言搭建 AI 應(yīng)用。本文將圍繞 Java + Spring AI (Alibaba) 的 AI 應(yīng)用為例,介紹框架原生及無侵入探針的集成方式的最佳實踐。
Java 開發(fā)者的 AI Agent 框架:Spring AI Alibaba
Spring AI 的局限與突破
Spring AI 作為 Spring 官方推出的 AI 開發(fā)框架,借鑒了 Python 語言中炙手可熱(至少曾是)的 Langchain 與 LlamaIndex 的實現(xiàn),通過封裝大模型調(diào)用、向量數(shù)據(jù)庫、工具調(diào)用等基礎(chǔ)能力,幫助開發(fā)者用幾行代碼即可構(gòu)建智能體原型。例如,以下代碼可快速實現(xiàn)一個帶工具調(diào)用的對話 Agent:
public Flux<String> streamChat(String chatId, String userMessageContent) {
return this.chatClient.prompt()
.system("你是一個提供預(yù)定服務(wù)的chatbot")
.user(userMessageContent)
.toolNames("getBookingDetails")
.stream()
.content();
}
然而,當(dāng)業(yè)務(wù)場景涉及多 Agent 協(xié)同、復(fù)雜工作流時,Spring AI 的單體化設(shè)計顯現(xiàn)出明顯短板:
- 缺乏工作流編排能力:難以實現(xiàn) Agent 間的任務(wù)流轉(zhuǎn)與狀態(tài)管理;
- 生態(tài)集成有限:未提供企業(yè)級所需的 RAG、模型評估等開箱功能。
Spring AI Alibaba 的增強能力
作為對 Spring AI 的企業(yè)級增強方案,Spring AI Alibaba 通過三大核心特性解決了上述問題:
- Graph 框架:基于有向無環(huán)圖實現(xiàn)多 Agent 協(xié)同編排,支持條件分支、并行執(zhí)行等復(fù)雜邏輯;
- DSL 轉(zhuǎn)換器:兼容 Dify 等低代碼平臺的 DSL 配置,實現(xiàn)“低代碼設(shè)計-高代碼部署”的無縫銜接;
- 阿里云生態(tài)集成:內(nèi)置 RAG、百煉平臺對接、可觀測性等企業(yè)級能力,加速智能體工業(yè)化落地。
以多 Agent 協(xié)同場景為例,開發(fā)者可通過 Spring AI Alibaba 多 Agent 框架定義如下工作流,并快速完成 Agent 編排:
// 定義 Agent 1
ReactAgent writerAgent = ReactAgent.builder()
.name("writer_agent")
.model(chatModel)
.description("可以寫文章。")
.instruction("你是一個知名的作家,擅長寫作和創(chuàng)作。請根據(jù)用戶的提問進行回答。")
.outputKey("article")
.build();
// 定義 Agent 2
ReactAgent reviewerAgent = ReactAgent.builder()
.name("reviewer_agent")
.model(chatModel)
.description("可以對文章進行評論和修改。")
.instruction("你是一個知名的評論家,擅長對文章進行評論和修改。對于散文類文章,請確保文章中必須包含對于西湖風(fēng)景的描述。")
.outputKey("reviewed_article")
.build();
// 定義順序的 AgentFlow
SequentialAgent blogAgent = SequentialAgent.builder()
.name("blog_agent")
.state(stateFactory)
.description("可以根據(jù)用戶給定的主題寫一篇文章,然后將文章交給評論員進行評論,必要時做出修改。")
.inputKey("input")
.outputKey("topic")
.subAgents(List.of(writerAgent,reviewerAgent))
.build();
Optional<OverAllState> result = blogAgent.invoke(Map.of("input", "幫我寫-個I00字左右的散文");
受限于篇幅,本篇不對框架本身過多介紹,更多 Spring AI Alibaba 框架的最佳實踐請移步:Spring AI Alibaba 官方網(wǎng)站[11]。
可觀測性集成:框架原生方式
基本原理
圖片
Spring AI Alibaba 的可觀測性體系基本基于 OpenTelemetry(OTel)標(biāo)準(zhǔn)構(gòu)建,通過分層架構(gòu)實現(xiàn)數(shù)據(jù)采集、處理與上報的全鏈路覆蓋:
- 埋點層:框架內(nèi)部通過 Micrometer(Spring 官方推薦的可觀測中間件)對關(guān)鍵調(diào)用(如模型推理、工具調(diào)用、外部調(diào)用)自動埋點;
- 數(shù)據(jù)導(dǎo)出層:Micrometer 在運行時提供可插拔的 Tracer 實現(xiàn),支持將埋點層產(chǎn)生的數(shù)據(jù)使用 OpenTelemetry SDK 導(dǎo)出為滿足 OTLP 協(xié)議的格式;
- 存儲層:兼容任何支持 OTLP 協(xié)議格式的可觀測存儲,如 Prometheus、Langfuse、Jaeger 等;
- 擴展層:Spring AI Alibaba 基于 Spring AI 原生實現(xiàn)提供了一些可觀測性擴展 [12],支持如輸入輸出采集、提示詞版本關(guān)聯(lián)采集等更多 Spring AI 暫不支持的數(shù)據(jù)格式與語義。
接入實踐
STEP 1:準(zhǔn)備 Agent 應(yīng)用
Spring AI Alibaba 示例項目中提供了非常多類型的實例項目,本次實踐采用的機票預(yù)定助手項目可以在該鏈接找到:https://github.com/spring-ai-alibaba/examples/tree/main/spring-ai-alibaba-agent-example/playground-flight-booking [13]。
STEP 2:引入相關(guān)依賴
<!-- 用于實現(xiàn)各種 OTel 相關(guān)組件,如 Tracer、Exporter 的自動裝載 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- 用于將 micrometer 產(chǎn)生的指標(biāo)數(shù)據(jù)對接到 otlp 格式 -->
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-otlp</artifactId>
</dependency>
<!-- 用于將 micrometer 底層的鏈路追蹤 tracer 替換為 OTel tracer -->
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-tracing-bridge-otel</artifactId>
</dependency>
<!-- 用于將 OTel tracer 產(chǎn)生的 span 按照 otlp 協(xié)議進行上報 -->
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-exporter-otlp</artifactId>
</dependency>
<!-- 引入 ARMS 可觀測性擴展 -->
<dependency>
<groupId>com.alibaba.cloud.ai</groupId>
<artifactId>spring-ai-alibaba-autoconfigure-arms-observation</artifactId>
</dependency>
以上依賴彼此之間的關(guān)系如下圖所示,實線為直接依賴,虛線為間接依賴:
圖片
STEP 3:修改 application.properties 相關(guān)配置,啟用可觀測性
# arms 擴展相關(guān)配置
spring.ai.alibaba.arms.enabled=true
spring.ai.alibaba.arms.tool.enabled=true
spring.ai.alibaba.arms.model.capture-input=true
spring.ai.alibaba.arms.model.capture-output=true
# otel 擴展相關(guān)配置
management.otlp.tracing.export.enabled=true
management.tracing.sampling.probability=1.0
management.otlp.tracing.endpoint={YOUR_TRACE_ENDPOINT}
management.otlp.metrics.export.enabled=true
management.otlp.metrics.export.url={YOUR_METRICS_ENDPOINT}
management.otlp.logging.export.enabled=false
management.opentelemetry.resource-attributes.service.name={YOUR_SERVICE_NAME}
management.opentelemetry.resource-attributes.service.version=1.0
management.opentelemetry.resource-attributes.deployment.environment=test
要獲取數(shù)據(jù)上報端點,你可以參考文檔通過OpenTelemetry上報Java應(yīng)用數(shù)據(jù)[14] 將數(shù)據(jù)上報到阿里云,你也可以將其替換為任何一個其他支持 OTLP 上報協(xié)議的上報端點,如 Spring AI Alibaba Admin [15]。
STEP 4:啟動應(yīng)用
啟動命令為:java -jar spring-ai-demo.jar。
STEP 5:登錄阿里云應(yīng)用監(jiān)控 OpenTelemetry 版,查看可觀測數(shù)據(jù)
訪問應(yīng)用后,能夠查看到大模型的部分調(diào)用鏈路。通過 span 名稱可以看到過程中發(fā)生了兩次大模型調(diào)用(chat qwen-max),中間還調(diào)用了一次工具(execute_tool get-booking-details),在每個 span 中都可以看到對應(yīng)的上下文信息,如模型輸入輸出、消耗 token 數(shù)、調(diào)用的工具名與入?yún)⒌鹊取?/span>
圖片
注:由于 Spring AI 目前提供的指標(biāo)與 OpenTelemetry 命名規(guī)范不一致,目前僅支持查看 tracing 數(shù)據(jù)。
可觀測性集成:無侵入探針方式
框架原生可觀測性的痛點
在前言中我們提到,框架原生的可觀測性雖然帶來了簡便的接入體驗,但往往存在各種局限性,主要包括以下幾個方面:
- 擴展性差:Spring AI 的內(nèi)置埋點與框架代碼是耦合在一起的,如果我們希望為某些 span 添加一些額外的 attributes,或者把部分 attributes 采用日志的形式打印,實現(xiàn)受制于框架埋點實現(xiàn)。一旦框架本身并沒有采集某些上下文,實現(xiàn)期望的擴展就會非常困難,往往需要向 Spring AI 倉庫提交 PR。
- 端到端實現(xiàn)困難:庫原生的可觀測實現(xiàn)與無侵入探針方案適配性較差(相關(guān)討論可以參見What are the Best Practices for Providing Instrumentation for Spring AI. [16])。一旦選用了庫原生的方案,又在 Agent 中需要發(fā)起消息隊列/中間件/RPC 等調(diào)用時,就必須選擇 Spring 原生支持的調(diào)用類型,或者基于 Micrometer 機制手動添加埋點透傳上下文,否則就會導(dǎo)致調(diào)用鏈斷鏈,影響問題定位和排查。
- 靈活度低:Spring AI 的可觀測性大量使用了 Spring Boot 的 Auto Configuration 機制,對手動管理的 Spring Bean 適配性較差。
- 運維復(fù)雜:接入需要引入大量不同發(fā)行商的依賴,這些依賴之間可能存在諸多版本限制,不利于項目依賴的升級和維護。
為了應(yīng)對這些問題,進一步簡化接入步驟,LoongSuite 商業(yè)版自 4.6.0 版本起面向 Spring AI (Alibaba) 提供了無侵入探針的解決方案。
LoongSuite 簡介
LoongSuite 是阿里云可觀測團隊維護的一個可觀測性開源品牌,統(tǒng)一管理多個數(shù)據(jù)采集產(chǎn)品。它包含 LoongCollector,用于主機級別的數(shù)據(jù)采集,支持日志、Prometheus 指標(biāo)及 eBPF 網(wǎng)絡(luò)與安全數(shù)據(jù)。同時,LoongSuite 提供多種語言的進程探針,如 Python、Go 和 Java 探針,用于無侵入式地采集 AI 應(yīng)用的運行數(shù)據(jù)。這些探針可以捕獲模型輸入輸出、工具調(diào)用情況及耗時等信息。LoongCollector 負(fù)責(zé)數(shù)據(jù)的統(tǒng)一處理與上報,支持 OTLP 協(xié)議,可對接開源系統(tǒng)如 Jaeger、Elasticsearch,也可連接云廠商的托管服務(wù)。此外,LoongSuite 與 OpenTelemetry 社區(qū)緊密合作,其 Python 探針基于社區(qū)版本擴展 AI 插件,Go Agent 源自阿里云貢獻項目,并參與推動 Go 插樁技術(shù)發(fā)展及 GenAI 語義規(guī)范的制定。[17]
圖片
技術(shù)原理
圖片
LoongSuite 多語言探針通過 Java、Golang、Python 等語言提供的代碼增強機制,在探針包中預(yù)定義好一系列的代碼增強邏輯。通過修改編譯或者啟動命令,探針包中的代碼增強邏輯會生效于目標(biāo)框架的關(guān)鍵方法中,在方法執(zhí)行前后分別執(zhí)行預(yù)定義好的一些步驟,如創(chuàng)建/關(guān)閉 span、記錄 metrics、傳遞上下文、捕獲異常等。使用者不需要修改業(yè)務(wù)代碼,就可以直接集成可觀測性。
相比框架原生方案,該實現(xiàn)有諸多優(yōu)勢:
圖片
接入實踐
STEP 1:準(zhǔn)備 Agent 應(yīng)用
同上一章 STEP 1,項目地址:https://github.com/spring-ai-alibaba/examples/tree/main/spring-ai-alibaba-agent-example/playground-flight-booking。
STEP 2:下載探針
目前僅 LoongSuite 商業(yè)版 4.6.0 版本支持 Spring AI (Alibaba) 的無侵入接入,該版本尚未完全發(fā)布,您可以通過以下鏈接獲取探針并解壓:http://arms-apm-cn-hangzhou.oss-cn-hangzhou.aliyuncs.com/4.6.0/AliyunJavaAgent.zip。
圖片
STEP 3:修改啟動命令,啟動應(yīng)用
您可以進入云監(jiān)控 2.0 控制臺[1],選擇一個工作空間后,按照接入中心 > 應(yīng)用監(jiān)控&鏈路追蹤 > 手動安裝 > 自研 Java Agent(通用環(huán)境手動接入)中的步驟來接入您的應(yīng)用。
原啟動命令為:
java -jar spring-ai-demo.jar
修改后啟動命令為:
java \
-javaagent:{PATH_TO_JAVA_AGENT} \
-Dprofiler.jdk21.async.context.propagation.enable=true \
-Darms.licenseKey={YOUR_LICENSE_KEY} \
-Darms.appName={YOUR_APP_NAME} \
-Darms.workspace={YOUR_WORKSPACE}
-Daliyun.javaagent.reginotallow={YOUR_REGION} \
-jar spring-ai-demo.jar
注:
- 請把 {PATH_TO_JAVA_AGENT} 替換為 STEP 2 中解壓后的探針地址絕對路徑
- 如果您使用的是 JDK 21 及以上版本,且未開啟虛擬線程,可以使用
-Dprofiler.jdk21.async.context.propagation.enable=true
來保證異步上下文自動透傳;如若開啟虛擬線程,則需謹(jǐn)慎使用,詳情參見:探針(Java Agent)版本說明[2] - 請把 {YOUR_LICENSE_KEY} 替換為您的 license key,把 {YOUR_WORKSPACE} 替換為您的工作空間名,您可以在 云監(jiān)控 2.0 控制臺選擇您的工作空間,并單擊接入中心獲取您的 license key
- 請把 {YOUR_APP_NAME} 替換為您的應(yīng)用名,把 {YOUR_REGION} 替換為您需要上報到的地域
STEP 4:登錄阿里云云監(jiān)控,查看可觀測數(shù)據(jù)
能看到包括微服務(wù)調(diào)用在內(nèi)的大模型調(diào)用,相比框架原生的接入方案,無侵入探針的可觀測數(shù)據(jù)遵循了最新的 OpenTelemetry 語義規(guī)范,前端適配更加完整、準(zhǔn)確。
圖片
也可以通過單擊選項卡僅過濾 AI 相關(guān)調(diào)用。
圖片
使用 K8S 部署,體驗更快捷的接入方式
如果您的 Spring AI 應(yīng)用部署在 K8S 環(huán)境中,您可以通過修改 pod label 的方式完成探針接入,免去探針下載與修改啟動命令的步驟,更加方便快捷,詳情請參見:監(jiān)控 ACK 集群下的 Java 應(yīng)用[19],調(diào)整探針版本為 4.6.0 的方式可以參考自主控制探針版本[20]。
未來展望:Spring AI 可觀測性的下一個里程碑
1. 可觀測插樁開源:當(dāng)前僅 LoongSuite 商業(yè)版探針(也即 AliyunJavaAgent)支持 Spring AI 的無侵入接入,我們計劃在短期內(nèi)將其貢獻到 LoongSuite 開源社區(qū)及 OpenTelemetry 社區(qū),為更廣大的開發(fā)者群體提供便利。歡迎在 issue 下面留言提出您的意見:https://github.com/open-telemetry/opentelemetry-java-instrumentation/issues/12878。
2. AgentScope Studio 融合:AgentScope Studio 后續(xù)將成為 LoongSuite 可觀測性的前端門戶,Spring AI 可觀測性相關(guān)能力也將整合進入 AgentScope 中:https://github.com/agentscope-ai/agentscope-studio。
3. 更加豐富的可觀測數(shù)據(jù):當(dāng)前無侵入探針在多 Agent 場景下的適配還稍顯不足,后續(xù)我們將面向 Spring AI Alibaba 的多 Agent 框架增加 Agent 粒度的調(diào)用統(tǒng)計,提供更加豐富、準(zhǔn)確、完整的可觀測性。