言到結(jié)論:搭建企業(yè)級(jí)數(shù)據(jù)分析智能體的關(guān)鍵實(shí)踐)
周四下午兩點(diǎn)業(yè)務(wù)同學(xué)在群里甩過(guò)來(lái)一句話“你看昨天華南區(qū)轉(zhuǎn)化率為什么掉了”擱在以前這個(gè)問(wèn)題的標(biāo)準(zhǔn)解法是先登數(shù)倉(cāng)查訂單表確認(rèn)轉(zhuǎn)化率確實(shí)在掉再懷疑渠道、懷疑活動(dòng)、懷疑機(jī)型一層層往下鉆最后做一張三折頁(yè)簡(jiǎn)報(bào)。整個(gè)流程通常是兩個(gè)小時(shí)起步而且大量時(shí)間不是花在“分析”上而是花在“取數(shù)、清洗、拼接、核對(duì)口徑”上。所以我搭了一個(gè)數(shù)據(jù)分析智能體目標(biāo)就一句話讓業(yè)務(wù)問(wèn)題直接變成數(shù)據(jù)和結(jié)論。它不是一個(gè)套著問(wèn)答外殼的報(bào)表工具而是一個(gè)能自主規(guī)劃查詢、執(zhí)行計(jì)算、生成解釋性文字、并基于上下文進(jìn)行多輪追問(wèn)的智能體。本文想把這個(gè)項(xiàng)目掰開(kāi)揉碎講一講為什么需要它、整體架構(gòu)怎么設(shè)計(jì)、文本轉(zhuǎn)查詢和歸因這些核心模塊怎么落地、以及真實(shí)環(huán)境中踩到的坑。如果你也在考慮給團(tuán)隊(duì)搭一個(gè)自助分析助手這篇文章應(yīng)該能幫你少走不少?gòu)澛贰?. 為什么折騰這個(gè)數(shù)據(jù)分析的“最后一公里”一直被卡在取數(shù)在講架構(gòu)之前我先把做這個(gè)項(xiàng)目的動(dòng)機(jī)說(shuō)清楚。我們團(tuán)隊(duì)的數(shù)據(jù)基建其實(shí)不差數(shù)倉(cāng)層有統(tǒng)一的表指標(biāo)也有定期的報(bào)表但業(yè)務(wù)側(cè)拿到這些數(shù)據(jù)之后還是經(jīng)?;剡^(guò)頭來(lái)找人“幫我看一下為什么這個(gè)數(shù)掉了”“能不能按渠道拆一下”“上周的留存是多少”。原因很簡(jiǎn)單報(bào)表是靜態(tài)的一旦問(wèn)題的角度變了就必須改查詢條件而改查詢條件這件事又回到了寫(xiě)SQL的人手上。這就形成了一個(gè)很常見(jiàn)的“取數(shù)工具人”局面分析師每天都在幫業(yè)務(wù)查數(shù)、導(dǎo)數(shù)據(jù)、補(bǔ)口徑真正深入業(yè)務(wù)去解釋“為什么”的時(shí)間反而很少。我統(tǒng)計(jì)過(guò)自己一個(gè)月的工時(shí)大概六成以上消耗在數(shù)據(jù)獲取和清洗上真正能做判斷、寫(xiě)結(jié)論的時(shí)間不到四成。這個(gè)比例放在任何團(tuán)隊(duì)里都是不健康的。1.1 我確定的三個(gè)核心使用場(chǎng)景動(dòng)手之前我先復(fù)盤(pán)了團(tuán)隊(duì)里高頻出現(xiàn)的分析訴求最后圈定了三類(lèi)必須由智能體承接的場(chǎng)景避免一上來(lái)就把范圍鋪得太大日常指標(biāo)問(wèn)答類(lèi)似“昨日新增用戶是多少”“最近兩周App上的平均訂單金額怎么變化”。這類(lèi)問(wèn)題占了需求量的五成以上本質(zhì)上是取數(shù)動(dòng)作完全可以自動(dòng)化。異常波動(dòng)歸因比如“轉(zhuǎn)化率為什么掉了”“華南區(qū)營(yíng)收為什么上升”。這類(lèi)問(wèn)題需要多層拆解至少要看趨勢(shì)、再看維度貢獻(xiàn)、最后找可能的原因。臨時(shí)數(shù)據(jù)分析業(yè)務(wù)偶爾會(huì)發(fā)來(lái)一個(gè)Excel或CSV文件里面是活動(dòng)數(shù)據(jù)、渠道明細(xì)或用戶標(biāo)簽要求“幫忙看一下有沒(méi)有規(guī)律”。這不是固定表結(jié)構(gòu)能滿足的需要智能體自己讀文件、做統(tǒng)計(jì)描述、生成圖表。確定范圍很重要。很多智能體項(xiàng)目做砸不是因?yàn)槟P湍芰Σ恍卸且驗(yàn)橄氚阉袉?wèn)題一把抓結(jié)果每個(gè)場(chǎng)景都只做到了半吊子。我后來(lái)把這三類(lèi)場(chǎng)景作為開(kāi)發(fā)的驗(yàn)收基線每做一個(gè)版本就先跑一輪跑不通就不往下加新功能。1.2 傳統(tǒng)BI工具和智能體的本質(zhì)區(qū)別我們?cè)谧鲞@個(gè)項(xiàng)目之前團(tuán)隊(duì)內(nèi)也有一套自助式BI平臺(tái)業(yè)務(wù)同學(xué)可以自己拖拽圖表、配置篩選條件。但實(shí)際用下來(lái)門(mén)檻依然很高。業(yè)務(wù)同學(xué)的訴求往往是“這個(gè)數(shù)為什么變高了”而B(niǎo)I工具只能告訴他“這個(gè)數(shù)變高了”至于為什么得自己去找對(duì)比、下鉆、換維度整套操作路徑太長(zhǎng)了。核心區(qū)別可以用一張表說(shuō)清對(duì)比維度傳統(tǒng)BI工具數(shù)據(jù)分析智能體交互方式拖拽組件、配置篩選自然語(yǔ)言對(duì)話、多輪追問(wèn)查詢組織用戶自己設(shè)計(jì)圖表和過(guò)濾模型自動(dòng)規(guī)劃查詢計(jì)劃數(shù)據(jù)分析只能展示指標(biāo)靠人判斷自動(dòng)生成趨勢(shì)對(duì)比、歸因候選口徑維護(hù)按圖表配置分散在報(bào)告里集中維護(hù)指標(biāo)字典復(fù)用性強(qiáng)出錯(cuò)恢復(fù)用戶自己排查配置系統(tǒng)記錄失敗并自動(dòng)修正我用一個(gè)生活化的類(lèi)比來(lái)說(shuō)傳統(tǒng)BI就像給你一本菜譜和一堆食材做法寫(xiě)得清清楚楚但你得自己掌勺智能體更像一個(gè)有經(jīng)驗(yàn)的幫廚你跟他說(shuō)“今天想吃得清淡點(diǎn)”他會(huì)自己判斷是清蒸還是燉湯然后把成品端上來(lái)再告訴你為什么選這道菜。2. 整體架構(gòu)大腦、手和記憶是怎么分工的這件項(xiàng)目真正開(kāi)始設(shè)計(jì)時(shí)我面臨的一個(gè)關(guān)鍵問(wèn)題是該把邏輯放在模型里還是放在代碼里很多人以為數(shù)據(jù)分析智能體就是“寫(xiě)一段提示詞把數(shù)據(jù)傳給大模型等它返回結(jié)果”但實(shí)際做下來(lái)就會(huì)發(fā)現(xiàn)這會(huì)導(dǎo)致兩個(gè)嚴(yán)重問(wèn)題第一模型對(duì)表格內(nèi)容不感知容易生成不存在的字段第二權(quán)限和口徑控制完全失控因?yàn)樗静恢滥男?shù)據(jù)能看、哪些不能看。我最后采用了“控制流在代碼里判斷流在模型里”的分層設(shè)計(jì)。所有必須保證正確的事情比如權(quán)限校驗(yàn)、超時(shí)熔斷、字段白名單、SQL參數(shù)化全部交給代碼而需要靈活判斷的事情比如用戶想表達(dá)什么指標(biāo)、怎么拆解歸因、用什么圖表呈現(xiàn)全部交給大模型。整個(gè)智能體分為四層。2.1 入口交互層入口層負(fù)責(zé)接收用戶的消息也負(fù)責(zé)維護(hù)每次會(huì)話的狀態(tài)。用戶可以在對(duì)話框里連續(xù)追問(wèn)比如先問(wèn)“昨日整體轉(zhuǎn)化率”再追問(wèn)“分渠道看看”系統(tǒng)要能理解“分渠道”是針對(duì)前一個(gè)問(wèn)題的補(bǔ)充條件而不是一個(gè)全新的獨(dú)立問(wèn)題。這里我通過(guò)會(huì)話ID關(guān)聯(lián)歷史消息并且會(huì)把最近兩輪問(wèn)答的摘要一并傳給模型避免上下文丟失。入口層還支持兩種輸入形態(tài)一種是文本問(wèn)題另一種是文件上傳。上傳的Excel和CSV會(huì)先被解析成臨時(shí)表再進(jìn)入后續(xù)執(zhí)行流程。這個(gè)設(shè)計(jì)看起來(lái)簡(jiǎn)單但后期頻繁用到因?yàn)闃I(yè)務(wù)臨時(shí)分析的數(shù)據(jù)很多都不在數(shù)倉(cāng)里。2.2 規(guī)劃大腦層這是整個(gè)智能體最核心的一層。大模型接收到用戶問(wèn)題后并不是直接去查數(shù)據(jù)庫(kù)而是先產(chǎn)出“查詢計(jì)劃”。查詢計(jì)劃類(lèi)似于傳統(tǒng)程序里的中間表示把自然語(yǔ)言問(wèn)題翻譯成一個(gè)結(jié)構(gòu)化的JSON里面包含指標(biāo)、時(shí)間范圍、分組維度、過(guò)濾條件等關(guān)鍵信息。模型再根據(jù)這個(gè)計(jì)劃決定調(diào)用哪些工具、按什么順序調(diào)用。每個(gè)工具都是一個(gè)獨(dú)立的函數(shù)比如query_dashboard、query_channel_detail、calc_weekly_ratio、generate_chart。這樣做的優(yōu)勢(shì)是模型不需要理解所有SQL細(xì)節(jié)只需要理解“工具A能查什么工具B能算什么”大大降低出錯(cuò)概率。2.3 執(zhí)行工作層執(zhí)行工作層負(fù)責(zé)真正落地。查詢執(zhí)行器連接數(shù)倉(cāng)時(shí)只有只讀權(quán)限每條SQL單獨(dú)設(shè)置執(zhí)行超時(shí)時(shí)間默認(rèn)15秒查詢返回行數(shù)也會(huì)做一個(gè)上限限制防止用戶問(wèn)一個(gè)不合理的全表掃描把數(shù)據(jù)庫(kù)拖垮。圖表生成器則只基于真實(shí)返回的數(shù)據(jù)集工作絕不允許模型憑空生成數(shù)值。執(zhí)行工作層里還有一個(gè)專(zhuān)門(mén)處理本地文件的工具底層用表格計(jì)算庫(kù)實(shí)現(xiàn)能對(duì)上傳的數(shù)據(jù)做字段統(tǒng)計(jì)、缺失值檢測(cè)、分組聚合和簡(jiǎn)單的相關(guān)性分析。它不是萬(wàn)能的但足以覆蓋大部分臨時(shí)分析場(chǎng)景。2.4 記憶與緩存層為了支撐多輪對(duì)話我加了一個(gè)輕量級(jí)的會(huì)話記憶層。它會(huì)保存每個(gè)會(huì)話的查詢計(jì)劃、執(zhí)行結(jié)果和前幾輪的關(guān)鍵結(jié)論最新的會(huì)話數(shù)據(jù)保存在內(nèi)存里超過(guò)一定時(shí)間自動(dòng)收進(jìn)日志庫(kù)。這樣用戶追問(wèn)“那環(huán)比呢”的時(shí)候系統(tǒng)不需要重新理解前面的所有上下文直接取上一輪的指標(biāo)和時(shí)間范圍就能完成計(jì)算。指標(biāo)結(jié)果緩存也很重要。同一個(gè)問(wèn)題在一小時(shí)內(nèi)被反復(fù)詢問(wèn)時(shí)系統(tǒng)會(huì)直接讀取緩存結(jié)果不需要重新跑SQL響應(yīng)速度能提到秒級(jí)。這看起來(lái)是個(gè)小優(yōu)化但實(shí)際使用中業(yè)務(wù)側(cè)非常吃這一套因?yàn)樗麄兊暮芏鄦?wèn)題本質(zhì)上是“同樣的數(shù)換著角度問(wèn)”。3. 核心模塊實(shí)現(xiàn)文本轉(zhuǎn)查詢、歸因引擎、自動(dòng)可視化第2節(jié)講的是骨架這一節(jié)是真正讓它“看起來(lái)聰明”的三塊核心模塊也是我在開(kāi)發(fā)過(guò)程中花時(shí)間最多的地方。3.1 文本轉(zhuǎn)查詢先產(chǎn)出查詢計(jì)劃再生成SQL文本轉(zhuǎn)查詢最直覺(jué)的做法是讓模型直接寫(xiě)SQL但實(shí)踐下來(lái)問(wèn)題非常多。最大的坑是模型對(duì)表結(jié)構(gòu)和字段含義不了解經(jīng)常把“平臺(tái)類(lèi)型”猜成“platform”把“客戶ID”猜成“customer_id”一旦猜錯(cuò)整個(gè)查詢就報(bào)錯(cuò)。更嚴(yán)重的是模型有時(shí)會(huì)把不存在的事實(shí)拼進(jìn)SQL里比如生成一個(gè)用戶表單里根本沒(méi)有的字段而數(shù)據(jù)庫(kù)不會(huì)報(bào)錯(cuò)只會(huì)返回空結(jié)果用戶看到的就是一個(gè)“沒(méi)數(shù)據(jù)”的假象。為了避免這個(gè)問(wèn)題我設(shè)計(jì)了一個(gè)結(jié)構(gòu)化查詢計(jì)劃的中間步驟。模型先根據(jù)指標(biāo)字典和用戶問(wèn)題輸出一個(gè)類(lèi)似這樣的JSON{ intent: trend_query, metrics: [ { field: order_amount, agg: sum } ], date_range: { start: 2024-03-01, end: 2024-03-31 }, group_by: [channel_name], filters: [ { field: region, operator: , value: 華南 } ], order_by: [ { field: order_amount, direction: desc } ] }這個(gè)查詢計(jì)劃有巨大的工程價(jià)值。首先它把“用戶意圖”和“具體SQL語(yǔ)法”解耦了如果字段名變了只需要改映射表不需要重寫(xiě)整個(gè)模型的邏輯。其次這個(gè)計(jì)劃可以非常方便地做字段白名單校驗(yàn)在計(jì)劃進(jìn)入下一階段之前程序會(huì)逐項(xiàng)檢查字段名是否是字典中注冊(cè)過(guò)的有效字段防止模型憑空創(chuàng)造字段。最后它還能被人類(lèi)審計(jì)出了問(wèn)題回放日志時(shí)只看到查詢計(jì)劃就能判斷是模型理解錯(cuò)了還是執(zhí)行層出了問(wèn)題。3.2 歸因引擎不只告訴你掉了還要給出候選原因歸因是我認(rèn)為最有價(jià)值、也最難做好的模塊。很多報(bào)表工具只能告訴你“轉(zhuǎn)化率從3.2%降到2.8%”但業(yè)務(wù)側(cè)真正想知道的是“為什么”。我設(shè)計(jì)的歸因引擎采用兩階段判斷。第一階段是異常預(yù)檢。系統(tǒng)會(huì)先計(jì)算當(dāng)前指標(biāo)的時(shí)間序列自動(dòng)做環(huán)比、同比和閾值判斷。只有確認(rèn)“這個(gè)變化確實(shí)異?!钡臅r(shí)候才會(huì)進(jìn)入歸因階段如果只是正常波動(dòng)系統(tǒng)會(huì)直接說(shuō)明“變化幅度在正常波動(dòng)范圍內(nèi)”避免過(guò)度解讀。這個(gè)設(shè)計(jì)我在早期版本里沒(méi)有做好結(jié)果模型對(duì)每個(gè)波動(dòng)都強(qiáng)行找原因反而鬧了很多笑話。第二階段是維度下鉆與貢獻(xiàn)拆分。系統(tǒng)會(huì)按地區(qū)、渠道、品類(lèi)等維度分別計(jì)算指標(biāo)的貢獻(xiàn)變化量把整體變化拆解成各個(gè)維度的加減關(guān)系。比如整體營(yíng)收下降了100萬(wàn)可能華南區(qū)貢獻(xiàn)了-70萬(wàn)渠道B貢獻(xiàn)了-50萬(wàn)其他渠道正向拉回20萬(wàn)。模型拿到這組數(shù)字后再結(jié)合業(yè)務(wù)知識(shí)生成候選原因并給出置信度排序。我舉個(gè)例子。某個(gè)工作日系統(tǒng)給出的歸因結(jié)論是“昨日整體轉(zhuǎn)化率下降的主要來(lái)源是華南區(qū)貢獻(xiàn)了整體降幅的68%其中渠道B的觸達(dá)量較前日下降約35%且客單價(jià)同步下滑。根據(jù)歷史數(shù)據(jù)渠道B的波動(dòng)與當(dāng)前城市區(qū)域的活動(dòng)投放節(jié)奏高度相關(guān)建議優(yōu)先核查渠道B近期投放預(yù)算和落地頁(yè)轉(zhuǎn)化情況?!边@個(gè)結(jié)論并不是模型拍腦袋寫(xiě)的而是基于真實(shí)拆分?jǐn)?shù)據(jù)生成的每一句話背后都對(duì)應(yīng)一個(gè)查詢步驟或一項(xiàng)統(tǒng)計(jì)結(jié)果。正因如此它才具備讓業(yè)務(wù)信任的基礎(chǔ)。3.3 自動(dòng)可視化按數(shù)據(jù)語(yǔ)義而不是按用戶指令選圖可視化模塊看起來(lái)最容易但實(shí)際做起來(lái)很講究。早期版本我直接讓模型從代碼庫(kù)里選擇圖表類(lèi)型結(jié)果模型經(jīng)常選錯(cuò)比如把時(shí)間趨勢(shì)畫(huà)成餅圖把占比關(guān)系畫(huà)成折線圖。后來(lái)我換了一個(gè)方案讓模型先輸出“數(shù)據(jù)關(guān)系類(lèi)型”再由代碼層映射到具體圖表類(lèi)型。模型只要判斷這是“趨勢(shì)”“占比”“對(duì)比”還是“分布”剩下的交給代碼決定。映射表大概是這樣的數(shù)據(jù)關(guān)系匹配的圖表類(lèi)型典型問(wèn)題趨勢(shì)變化折線圖這周營(yíng)收怎么變化占比構(gòu)成堆疊柱狀圖各渠道貢獻(xiàn)了多少分組對(duì)比柱狀圖各省轉(zhuǎn)化率排名相關(guān)性散點(diǎn)圖客單價(jià)和復(fù)購(gòu)率有關(guān)嗎分布形態(tài)直方圖/箱線圖訂單金額都集中在什么區(qū)間這套映射比直接讓模型寫(xiě)圖表代碼穩(wěn)定很多。因?yàn)閳D表選型本身是有明確規(guī)則的用代碼控制不容易出錯(cuò)模型只需要做最擅長(zhǎng)的語(yǔ)義判斷。此外所有圖表生成前都會(huì)檢查數(shù)據(jù)是否為空、是否為純數(shù)值避免出現(xiàn)“畫(huà)了一個(gè)空殼圖”的低級(jí)問(wèn)題。4. 關(guān)鍵技術(shù)決策指標(biāo)字典、權(quán)限隔離和可觀測(cè)性如果說(shuō)核心模塊決定智能體的“上限”那么有幾個(gè)支撐性設(shè)計(jì)決定它的“生死”。我專(zhuān)門(mén)把這三項(xiàng)單獨(dú)拿出來(lái)講因?yàn)樗鼈兌际瞧綍r(shí)看不到、但在生產(chǎn)環(huán)境中特別要命的東西。4.1 指標(biāo)字典是定海神針不能指望模型自學(xué)數(shù)據(jù)分析智能體最大的風(fēng)險(xiǎn)之一是模型對(duì)業(yè)務(wù)口徑的臆測(cè)。最典型的情況是“活躍用戶”這個(gè)指標(biāo)不同團(tuán)隊(duì)有不同的定義有的按“當(dāng)日有登錄行為”有的按“當(dāng)日有付費(fèi)行為”還有的按“七日內(nèi)有任意行為”。如果指標(biāo)字典里沒(méi)有一個(gè)明確的官方口徑模型就會(huì)隨機(jī)挑一個(gè)輸出的數(shù)字自然對(duì)不上。我在系統(tǒng)里建了一個(gè)指標(biāo)字典每個(gè)指標(biāo)包含以下字段標(biāo)準(zhǔn)名稱(chēng)、業(yè)務(wù)別名、計(jì)算口徑、來(lái)源表、可用維度、統(tǒng)計(jì)周期和注意事項(xiàng)。當(dāng)用戶提問(wèn)時(shí)系統(tǒng)會(huì)對(duì)問(wèn)題進(jìn)行向量化檢索從指標(biāo)字典中召回最相關(guān)的若干條目把它們作為上下文注入到模型推理中。這里有個(gè)細(xì)節(jié)不是把整個(gè)字典全部塞進(jìn)提示詞那樣既浪費(fèi)token又干擾判斷只召回與當(dāng)前問(wèn)題相關(guān)的部分就夠了。同時(shí)日常維護(hù)指標(biāo)字典成了我這個(gè)項(xiàng)目里最重要的工作。每發(fā)現(xiàn)一個(gè)新的口徑疑點(diǎn)我就去和對(duì)應(yīng)業(yè)務(wù)線的同學(xué)確認(rèn)然后寫(xiě)進(jìn)字典里。這個(gè)資產(chǎn)的價(jià)值不亞于智能體本身的模型代碼因?yàn)槟P偷拿恳淮握_判斷本質(zhì)上都建立在口徑清晰的地基上。4.2 權(quán)限隔離必須在查詢執(zhí)行之前完成檢查權(quán)限問(wèn)題在小規(guī)模Demo里容易被忽略但一旦這個(gè)智能體面向整個(gè)業(yè)務(wù)團(tuán)隊(duì)就變成了嚴(yán)肅的安全問(wèn)題。不同角色能看的數(shù)據(jù)不一樣財(cái)務(wù)數(shù)據(jù)、用戶隱私、渠道成本明細(xì)都不是全員可見(jiàn)的。我的做法是在查詢計(jì)劃進(jìn)入執(zhí)行器之前依次做三層校驗(yàn)。第一層是表權(quán)限檢查用戶是否有權(quán)限訪問(wèn)該表。第二層是行級(jí)過(guò)濾根據(jù)用戶所屬的組織或區(qū)域自動(dòng)在過(guò)濾條件里追加一條租戶條件比如華南區(qū)的人只能看到華南區(qū)的數(shù)據(jù)。第三層是列級(jí)脫敏敏感字段在執(zhí)行結(jié)果返回給模型之前直接丟棄保證模型永遠(yuǎn)看不到它不該看到的內(nèi)容。曾經(jīng)有同事建議直接讓模型在提示詞里做判斷我都否決了。原因是權(quán)限是安全底線不能依賴(lài)模型的自覺(jué)和臨場(chǎng)發(fā)揮必須由代碼強(qiáng)制保證。我在整個(gè)鏈路中都遵循一條原則凡是涉及“能不能”“該不該”的問(wèn)題都放在代碼層凡是涉及“怎么看”“怎么解”的問(wèn)題才交給模型。4.3 可觀測(cè)性每次推理過(guò)程都要留痕讓模型自主完成多步分析意味著系統(tǒng)內(nèi)部會(huì)發(fā)生很多我們預(yù)想不到的路徑。如果不記錄每一步發(fā)生了什么出了問(wèn)題就會(huì)非常難排查。我要求系統(tǒng)對(duì)每一次對(duì)話的全過(guò)程做日志落盤(pán)包括用戶原始問(wèn)題、查詢計(jì)劃、生成的SQL、實(shí)際執(zhí)行耗時(shí)、返回行數(shù)、模型回復(fù)、錯(cuò)誤信息、token用量等關(guān)鍵字段。這套日志不只是事后排查用的。我把積累的失敗樣例整理成了一個(gè)回歸評(píng)測(cè)集每次升級(jí)模型或者調(diào)整提示詞后先拿回歸集跑一遍觀察失敗率有沒(méi)有改善。這個(gè)動(dòng)作保證了系統(tǒng)可以持續(xù)演進(jìn)而不是改一處壞一處。后來(lái)我還做了一個(gè)簡(jiǎn)單的觀測(cè)面板把每日的查詢成功率、平均耗時(shí)、最常見(jiàn)的錯(cuò)誤類(lèi)型展示出來(lái)成了我判斷系統(tǒng)健康度的主要參考。5. 真實(shí)跑一輪三個(gè)高光場(chǎng)景與一次翻車(chē)復(fù)盤(pán)光講設(shè)計(jì)理念沒(méi)有說(shuō)服力我把開(kāi)發(fā)過(guò)程中印象最深的幾個(gè)真實(shí)場(chǎng)景放出來(lái)涵蓋成功案例和一次典型的翻車(chē)。5.1 場(chǎng)景一營(yíng)收下滑系統(tǒng)給出分層歸因業(yè)務(wù)負(fù)責(zé)人問(wèn)“為什么3月第一周整體營(yíng)收環(huán)比下滑了12%”系統(tǒng)執(zhí)行的步驟大致是第一指標(biāo)字典鎖定“整體營(yíng)收”的標(biāo)準(zhǔn)口徑確認(rèn)時(shí)間范圍為最近兩周第二查詢總營(yíng)收的日趨勢(shì)計(jì)算環(huán)比降幅確實(shí)達(dá)到12%第三按地區(qū)拆解找到華南區(qū)貢獻(xiàn)了整個(gè)降幅的六成以上第四在華南區(qū)內(nèi)再按渠道拆發(fā)現(xiàn)渠道B的投放量較上周近乎減半第五結(jié)合歷史數(shù)據(jù)中渠道B與營(yíng)收波動(dòng)的相關(guān)性給出候選歸因。整個(gè)過(guò)程耗時(shí)約40秒而如果人工來(lái)做我至少要花掉一天還要頻繁向業(yè)務(wù)確認(rèn)口徑。輸出結(jié)果也不是干巴巴的數(shù)字而是帶了解釋邏輯的文本業(yè)務(wù)負(fù)責(zé)人可以直接拿去做下一步?jīng)Q策。這個(gè)場(chǎng)景成功的關(guān)鍵在于指標(biāo)字典里提前登記了各渠道的統(tǒng)計(jì)口徑所以模型的查詢計(jì)劃能準(zhǔn)確命中不需要反復(fù)試錯(cuò)。5.2 場(chǎng)景二轉(zhuǎn)化率波動(dòng)模型先確認(rèn)再下鉆第二個(gè)場(chǎng)景是運(yùn)營(yíng)同學(xué)問(wèn)“最近兩天渠道A的轉(zhuǎn)化率怎么有點(diǎn)奇怪”系統(tǒng)先做了異常預(yù)檢發(fā)現(xiàn)渠道A的轉(zhuǎn)化率確實(shí)下降了約15%但整體轉(zhuǎn)化率只下降了3%。此時(shí)模型并沒(méi)有直接下結(jié)論說(shuō)“渠道A拖垮大盤(pán)”而是繼續(xù)下鉆發(fā)現(xiàn)渠道A的觸達(dá)量上升了40%而用戶結(jié)構(gòu)里新用戶占比明顯偏高新用戶的轉(zhuǎn)化率天然低于老用戶。這是一個(gè)很有意思的發(fā)現(xiàn)。同樣是“轉(zhuǎn)化率下降”原因可能不是渠道變差了而是觸達(dá)量擴(kuò)大導(dǎo)致的用戶結(jié)構(gòu)變化。系統(tǒng)把這條邏輯寫(xiě)成注釋建議運(yùn)營(yíng)關(guān)注新用戶群與目標(biāo)客群的重合度。這種“把問(wèn)題背后的機(jī)制解釋清楚”的能力正是我認(rèn)為智能體與普通報(bào)表工具有本質(zhì)區(qū)別的地方。5.3 場(chǎng)景三上傳一份活動(dòng)明細(xì)自動(dòng)完成初步探索有一次業(yè)務(wù)同學(xué)直接上傳了一個(gè)活動(dòng)報(bào)名明細(xì)的CSV文件問(wèn)“這個(gè)活動(dòng)上線后的用戶表現(xiàn)怎么樣”。系統(tǒng)先把文件解析成臨時(shí)表自動(dòng)輸出字段清單、非空率、基本統(tǒng)計(jì)分布再根據(jù)問(wèn)題生成一張報(bào)名趨勢(shì)圖和一張來(lái)源渠道占比圖最后總結(jié)了幾個(gè)關(guān)鍵信息晚間報(bào)名的占比最高、移動(dòng)端來(lái)源超過(guò)七成、二次報(bào)名用戶比例明顯高于新用戶。這個(gè)能力并不復(fù)雜底層就是調(diào)用表格計(jì)算工具做描述性統(tǒng)計(jì)。但它解決了一個(gè)非常現(xiàn)實(shí)的痛點(diǎn)以前業(yè)務(wù)發(fā)一個(gè)Excel過(guò)來(lái)你得先自己?jiǎn)査f(shuō)明文檔、猜字段含義、寫(xiě)清洗腳本現(xiàn)在系統(tǒng)能在幾分鐘內(nèi)給出第一版探索結(jié)果。對(duì)臨時(shí)性分析需求來(lái)說(shuō)它足夠?qū)嵱谩?.4 翻車(chē)復(fù)盤(pán)模型幻覺(jué)字段連續(xù)兩次修正失敗必須說(shuō)這個(gè)智能體也有翻車(chē)的時(shí)候。有一次用戶問(wèn)“平臺(tái)整體轉(zhuǎn)化率是否受新版本影響”系統(tǒng)生成的查詢計(jì)劃里出現(xiàn)了一個(gè)不存在的字段“platform”數(shù)據(jù)庫(kù)直接報(bào)錯(cuò)。系統(tǒng)自動(dòng)啟動(dòng)修正機(jī)制第一次修正把它改成了“app_version”但該字段在數(shù)據(jù)表中也不存在第二次修正嘗試查“channel_name”最終得到的是完全錯(cuò)誤的結(jié)果。事后回放日志我發(fā)現(xiàn)問(wèn)題出在兩處一是模型在生成查詢計(jì)劃時(shí)沒(méi)有嚴(yán)格按照指標(biāo)字典中的可用維度來(lái)填寫(xiě)字段二是修正循環(huán)缺少一個(gè)關(guān)鍵約束——修正方向沒(méi)有回到“查字典”這一步而是繼續(xù)用自己的猜想來(lái)覆蓋。這個(gè)案例讓我意識(shí)到任何依賴(lài)模型自主性的環(huán)節(jié)都必須有“不確定就停止并詢問(wèn)”的兜底規(guī)則。針對(duì)這個(gè)問(wèn)題我在提示詞和代碼兩層都做了修補(bǔ)。代碼層新增了字段白名單強(qiáng)校驗(yàn)不符合字典規(guī)則的字段直接拒絕提示詞層增加了一句硬性約束“當(dāng)你對(duì)目標(biāo)字段不確定時(shí)不要猜測(cè)請(qǐng)向用戶詢問(wèn)確認(rèn)?!边@之后模型胡亂編字段的次數(shù)大幅下降但完全杜絕是不可能的所以日志和人工復(fù)核仍然是最后一道防線。6. 提示詞和參數(shù)的取舍能交給代碼控制的絕不指望模型自覺(jué)很多技術(shù)同學(xué)看到數(shù)據(jù)分析智能體第一反應(yīng)是先琢磨提示詞。我的經(jīng)驗(yàn)恰好相反提示詞只是整個(gè)系統(tǒng)的一小塊而且真正好用的提示詞一定不長(zhǎng)。6.1 系統(tǒng)提示詞我只寫(xiě)三塊內(nèi)容系統(tǒng)提示詞越短越好。核心只保留角色定義、行為規(guī)則和輸出格式。角色定義告訴模型它是什么行為規(guī)則告訴它遇到不同情況該怎么做輸出格式保證它返回的結(jié)果能被程序穩(wěn)定解析。我舉一個(gè)簡(jiǎn)化版本你是企業(yè)內(nèi)部分析助手只基于給定的數(shù)據(jù)結(jié)果進(jìn)行回答。 行為規(guī)則 1. 先輸出你認(rèn)為需要執(zhí)行的查詢計(jì)劃不要跳過(guò)中間步驟。 2. 不確定字段時(shí)禁止猜測(cè)優(yōu)先查指標(biāo)字典。 3. 如果字典也無(wú)法確認(rèn)直接向用戶提問(wèn)。 4. 對(duì)異常數(shù)據(jù)要區(qū)分“真實(shí)異?!焙汀罢2▌?dòng)”不可強(qiáng)行歸因。 5. 回復(fù)包含結(jié)論、數(shù)據(jù)依據(jù)和可能的后續(xù)建議語(yǔ)氣簡(jiǎn)潔。 輸出格式 - 第一步輸出一個(gè)JSON查詢計(jì)劃 - 第二步輸出解釋性分析文本 - 第三步輸出可能需要的圖表描述字段我見(jiàn)過(guò)很多團(tuán)隊(duì)把提示詞寫(xiě)到兩三千字把各種業(yè)務(wù)規(guī)則往里塞。實(shí)際效果并不好因?yàn)槟P吞幚沓L(zhǎng)提示詞時(shí)注意力容易被稀釋真正關(guān)鍵的指令反而被淹沒(méi)了。更可靠的做法是把業(yè)務(wù)知識(shí)放到指標(biāo)字典和工具定義里讓模型在需要時(shí)通過(guò)“查詢字典”這個(gè)工具獲得信息而不是把字典內(nèi)容全部預(yù)埋在提示詞中。6.2 關(guān)鍵參數(shù)設(shè)置與使用效果這里給一組我實(shí)測(cè)下來(lái)比較穩(wěn)定的參數(shù)供初讀者參考參數(shù)推薦值說(shuō)明temperature0.1 - 0.2數(shù)據(jù)分析場(chǎng)景要低隨機(jī)性不追求發(fā)散輸出top_p0.8限制候選集范圍避免模型輸出過(guò)長(zhǎng)或漂移max_tokens1024留下足夠空間給分析文本但不過(guò)度消耗查詢超時(shí)15秒執(zhí)行SQL最長(zhǎng)時(shí)間防止拖垮數(shù)倉(cāng)修正循環(huán)最多3次連續(xù)失敗必須停止引導(dǎo)用戶補(bǔ)充信息會(huì)話上下文長(zhǎng)度最近2輪完整信息防止上下文過(guò)長(zhǎng)導(dǎo)致遺忘早期問(wèn)題其中temperature和修正循環(huán)這兩個(gè)參數(shù)是我踩坑最多的地方。早期我把temperature設(shè)置得偏高模型同樣的問(wèn)題在不同時(shí)刻給出的口徑會(huì)有偏差用戶很快就說(shuō)“這系統(tǒng)一會(huì)一個(gè)數(shù)”。后來(lái)我把temperature壓到0.2以下輸出穩(wěn)定多了。另外一個(gè)重要經(jīng)驗(yàn)是修正循環(huán)必須有上限否則模型會(huì)在錯(cuò)誤的路徑上越走越遠(yuǎn)浪費(fèi)大量時(shí)間最后還給出一個(gè)看起來(lái)言之鑿鑿的錯(cuò)誤結(jié)論。6.3 讓模型更穩(wěn)定的一些實(shí)操技巧除了參數(shù)我還積累了幾個(gè)提升穩(wěn)定性的小技巧。第一結(jié)構(gòu)化輸出盡量用JSON Schema約束而不是自由文本描述。強(qiáng)制讓模型返回規(guī)定格式的查詢計(jì)劃解析程序就不需要去猜測(cè)字段含義。第二每次生成查詢計(jì)劃后都要和指標(biāo)字典中的白名單做交叉校驗(yàn)這一步是硬代碼邏輯不依賴(lài)模型。第三典型查詢計(jì)劃的few-shot示例不需要太多三五個(gè)就夠了主要是為了給模型建立“復(fù)雜問(wèn)題也要拆成步驟”的示范。第四非常重要的一點(diǎn)凡是要把結(jié)果推向生產(chǎn)的操作比如發(fā)送推送消息、觸發(fā)告警都要經(jīng)過(guò)人工確認(rèn)不能讓智能體全自動(dòng)完成。7. 做完這個(gè)項(xiàng)目之后的一些真實(shí)體會(huì)講到這里這個(gè)項(xiàng)目的技術(shù)結(jié)構(gòu)基本就完整了。最后說(shuō)幾句我個(gè)人的真實(shí)感受不算是總結(jié)只是希望給想動(dòng)手的人一些心理準(zhǔn)備。首先數(shù)據(jù)分析智能體的價(jià)值不在于它“像人一樣說(shuō)話”而在于它能體系化地把“取數(shù)、清洗、計(jì)算、歸因、可視化”這一整條鏈路縮短。它不會(huì)替代分析師但一定會(huì)把分析師從繁瑣取數(shù)里解放出來(lái)讓分析師把精力放到真正需要業(yè)務(wù)判斷的地方。如果你們團(tuán)隊(duì)的痛點(diǎn)也是大量時(shí)間消耗在取數(shù)而不是分析上那這個(gè)方向值得投入。其次做這類(lèi)系統(tǒng)一定要盡早建設(shè)回歸評(píng)測(cè)集。我前期就是吃了沒(méi)有評(píng)測(cè)集的虧每次調(diào)整提示詞都感覺(jué)變好了但總有歷史問(wèn)題被改回來(lái)。后來(lái)把失敗案例、正常案例、邊界案例整理成一份固定測(cè)試集每次改動(dòng)都先跑一遍才真正做到可迭代。最后再分享一個(gè)小技巧先在指標(biāo)字典上花時(shí)間比在提示詞上花時(shí)間更值。模型的提示詞寫(xiě)得再好如果連“業(yè)績(jī)”和“銷(xiāo)售額”都分不清系統(tǒng)永遠(yuǎn)不會(huì)有可信度。把這個(gè)地基打扎實(shí)了整個(gè)智能體才會(huì)穩(wěn)你才有底氣把它展示給別人。