
1. 當(dāng) Trace 多到人眼看不完聚類就成了剛需做 Agent 開(kāi)發(fā)的朋友大概率都經(jīng)歷過(guò)這個(gè)階段本地跑幾個(gè) case 的時(shí)候Trace 面板一拉每一步的輸入輸出、工具調(diào)用、耗時(shí)、token 消耗看得清清楚楚調(diào)試起來(lái)很舒服??梢坏┥暇€或者做一輪批量評(píng)測(cè)情況就完全變了——一天幾萬(wàn)甚至幾十萬(wàn)條 Session每條 Session 里又有幾十個(gè) Span你打開(kāi)可視化面板翻到第三頁(yè)就已經(jīng)不知道自己在看什么了。我最早做 Agent 可觀測(cè)性的時(shí)候踩的就是這個(gè)坑。當(dāng)時(shí)團(tuán)隊(duì)做了一個(gè)客服場(chǎng)景的 Agent上線第一周收集了大概 8 萬(wàn)條 Session。老板問(wèn)了一個(gè)特別樸素的問(wèn)題用戶到底在拿它干什么哪些場(chǎng)景表現(xiàn)好哪些場(chǎng)景翻車我盯著 Trace 列表看了整整一個(gè)下午最后只能給出幾個(gè)拍腦袋的個(gè)例完全沒(méi)有說(shuō)服力。問(wèn)題不在于數(shù)據(jù)不夠而在于數(shù)據(jù)太多、太碎、太異構(gòu)人眼根本沒(méi)法從海量 Trace 里抽象出行為模式。這就是智能聚類要解決的核心問(wèn)題把海量、零散、非結(jié)構(gòu)化的 Agent Trace通過(guò) Embedding 和聚類算法自動(dòng)歸并成若干類可解釋的行為模式讓你從看單條 Trace升級(jí)到看行為分布。它適合所有在做 Agent 開(kāi)發(fā)、評(píng)測(cè)、運(yùn)維、安全分析的人尤其是那些已經(jīng)過(guò)了 Demo 階段、開(kāi)始面對(duì)真實(shí)流量的人。這篇文章我會(huì)把整套思路拆開(kāi)講Trace 和 Session 的數(shù)據(jù)模型怎么設(shè)計(jì)、Embedding 到底該 embed 什么、聚類算法怎么選、聚類結(jié)果怎么解釋、以及我在實(shí)際項(xiàng)目里踩過(guò)的那些坑。不講空理論全部圍繞能落地來(lái)寫(xiě)。2. 先搞清楚要聚類的對(duì)象Trace、Session、Span 到底是什么關(guān)系2.1 三層數(shù)據(jù)模型別把 Session 和 Trace 混為一談很多人一開(kāi)始就搞混了這幾個(gè)概念導(dǎo)致后面 Embedding 的粒度選錯(cuò)聚類結(jié)果一塌糊涂。我先把它們理清楚。在典型的 Agent 可觀測(cè)體系里數(shù)據(jù)是分層的Session會(huì)話一次完整的用戶交互過(guò)程從用戶發(fā)起請(qǐng)求到 Agent 給出最終答復(fù)。一個(gè) Session 可能包含多輪對(duì)話。Trace追蹤一次請(qǐng)求鏈路的技術(shù)性記錄通常一個(gè) Session 對(duì)應(yīng)一個(gè)或多個(gè) Trace。Trace 是技術(shù)視角的容器。Span跨度Trace 里的最小單元一次 LLM 調(diào)用、一次工具調(diào)用、一次檢索都是一個(gè) Span。用生活化的類比Session 是你去醫(yī)院看了一次病Trace 是這次看病的完整病歷流水Span 是掛號(hào)、問(wèn)診、化驗(yàn)、開(kāi)藥每一個(gè)具體環(huán)節(jié)。為什么要強(qiáng)調(diào)這個(gè)因?yàn)榫垲惖牧6葲Q定了你能得到什么洞察聚類粒度聚合對(duì)象能回答的問(wèn)題適用場(chǎng)景Span 級(jí)單次工具/LLM 調(diào)用哪類工具調(diào)用容易失敗工具優(yōu)化Trace 級(jí)單次請(qǐng)求鏈路哪類任務(wù)鏈路最長(zhǎng)/最貴性能優(yōu)化Session 級(jí)完整多輪會(huì)話用戶到底想干什么產(chǎn)品/行為分析我個(gè)人的經(jīng)驗(yàn)是做理解 Agent 行為和表現(xiàn)Session 級(jí)聚類是主戰(zhàn)場(chǎng)Trace 級(jí)聚類是補(bǔ)充。因?yàn)橛脩粢鈭D往往要跨多輪才能體現(xiàn)只看單輪 Trace 會(huì)丟失上下文。2.2 一條 Session 里哪些字段值得被 Embedding確定了粒度接下來(lái)要決定把什么變成向量。這是整個(gè)流程里最關(guān)鍵的一步選錯(cuò)了后面全白搭。一條 Session 通常包含這些信息用戶的多輪輸入文本Agent 的多輪輸出文本調(diào)用的工具序列tool call sequence每步的耗時(shí)、token 數(shù)、狀態(tài)碼最終是否成功、是否有用戶負(fù)反饋元數(shù)據(jù)時(shí)間、渠道、用戶 ID、模型版本不是所有字段都適合 Embedding。文本類字段用戶輸入、Agent 輸出天然適合結(jié)構(gòu)化字段耗時(shí)、狀態(tài)碼更適合作為聚類后的分析維度而不是聚類輸入。我一般會(huì)構(gòu)造一個(gè)復(fù)合文本表示把一條 Session 壓縮成一段可 Embedding 的文本類似這樣def session_to_text(session): user_turns .join([t.content for t in session.turns if t.role user]) tool_seq - .join([s.tool_name for s in session.spans if s.type tool]) return f用戶意圖: {user_turns[:500]}\n工具鏈路: {tool_seq}注意這里我做了兩件事一是截?cái)嘤脩糨斎氡苊獬L(zhǎng)文本稀釋語(yǔ)義二是把工具序列也拼進(jìn)去。為什么因?yàn)楹芏?Agent 的行為差異不體現(xiàn)在文本上而體現(xiàn)在它調(diào)用了哪些工具、以什么順序調(diào)用。兩個(gè)用戶問(wèn)的問(wèn)題很像但一個(gè)觸發(fā)了檢索、一個(gè)直接回答這本身就是兩種行為模式。提示工具序列拼接時(shí)建議用固定的分隔符如-并且對(duì)工具名做歸一化避免同一個(gè)工具因?yàn)槊灰恢卤划?dāng)成兩個(gè)。2.3 為什么不能直接對(duì)原始 Trace JSON 做 Embedding我見(jiàn)過(guò)有人圖省事直接把整條 Trace 的 JSON 序列化后丟給 Embedding 模型。實(shí)測(cè)下來(lái)效果很差原因有三個(gè)第一JSON 里大量字段是技術(shù)噪音trace_id、時(shí)間戳、span_id這些對(duì)語(yǔ)義毫無(wú)貢獻(xiàn)反而會(huì)干擾向量表示。第二JSON 的結(jié)構(gòu)化符號(hào)括號(hào)、引號(hào)、冒號(hào)會(huì)占用大量 token稀釋真正有意義的文本。第三Embedding 模型是在自然語(yǔ)言上訓(xùn)練的對(duì) JSON 這種半結(jié)構(gòu)化文本的語(yǔ)義捕捉能力很弱。正確的做法是先做特征工程再 Embedding。把結(jié)構(gòu)化信息轉(zhuǎn)成自然語(yǔ)言描述或者干脆分成兩路文本走 Embedding結(jié)構(gòu)化特征走單獨(dú)的數(shù)值聚類最后做融合。這個(gè)思路后面第 4 節(jié)會(huì)詳細(xì)展開(kāi)。3. Embedding 選型不是越貴越好而是越懂你的領(lǐng)域越好3.1 通用 Embedding 模型在 Agent Trace 上的真實(shí)表現(xiàn)Embedding 模型排行網(wǎng)上到處都是但那些榜單基本都是在通用語(yǔ)義相似度任務(wù)上評(píng)的跟你的 Agent Trace 場(chǎng)景未必對(duì)得上。我實(shí)測(cè)過(guò)幾個(gè)主流方向說(shuō)說(shuō)真實(shí)感受。通用大模型 Embedding比如各家 API 提供的通用 embedding 接口開(kāi)箱即用語(yǔ)義理解能力強(qiáng)對(duì)用戶輸入這種自然語(yǔ)言處理得很好。缺點(diǎn)是貴而且對(duì) Agent 領(lǐng)域特有的術(shù)語(yǔ)工具名、內(nèi)部黑話理解一般。開(kāi)源中小模型比如 BGE 系列、GTE 系列可以本地部署成本低中文支持不錯(cuò)。缺點(diǎn)是維度固定長(zhǎng)文本處理能力有限需要自己做分塊。領(lǐng)域微調(diào)模型如果你有標(biāo)注數(shù)據(jù)比如人工標(biāo)過(guò)的 Session 分類可以拿通用模型做微調(diào)。效果最好但成本最高一般團(tuán)隊(duì)到不了這一步。我的建議是先用通用 API 模型跑通流程驗(yàn)證聚類有沒(méi)有價(jià)值再考慮降本或微調(diào)。別一上來(lái)就糾結(jié)模型選型流程跑不通模型再好也沒(méi)用。3.2 維度、成本、延遲的三角權(quán)衡選 Embedding 模型繞不開(kāi)三個(gè)指標(biāo)維度、成本、延遲。它們互相制約。維度方面常見(jiàn)的有 768、1024、1536、3072 等。維度越高表達(dá)能力越強(qiáng)但存儲(chǔ)和計(jì)算成本也越高。做 Session 聚類我實(shí)測(cè) 1024 維基本夠用1536 維是舒適區(qū)3072 維對(duì)聚類任務(wù)來(lái)說(shuō)邊際收益很低——因?yàn)榫垲惐旧砭褪窃诮稻S找結(jié)構(gòu)輸入維度太高反而容易受噪聲影響。成本方面按 token 計(jì)費(fèi)的 API 模型一條 Session 如果壓縮到 500 token10 萬(wàn)條 Session 就是 5000 萬(wàn) token這個(gè)量級(jí)要算清楚預(yù)算。本地模型雖然省 API 費(fèi)但要算 GPU 成本。延遲方面如果是離線批量聚類延遲不敏感如果要實(shí)時(shí)給每條新 Session 打標(biāo)簽?zāi)?Embedding 延遲就很重要了。我一般會(huì)做一個(gè)簡(jiǎn)單的成本估算表方案單條成本10萬(wàn)條成本延遲適用階段通用 API 大模型高高中驗(yàn)證期開(kāi)源本地模型低攤薄后低低規(guī)?;⒄{(diào)模型中中低成熟期3.3 一個(gè)容易被忽略的點(diǎn)Embedding 的歸一化這個(gè)坑我踩過(guò)。不同 Embedding 模型輸出的向量有的已經(jīng)做了 L2 歸一化有的沒(méi)有。如果你混用不同來(lái)源的向量或者沒(méi)注意歸一化聚類結(jié)果會(huì)嚴(yán)重偏移。判斷方法很簡(jiǎn)單算一下向量的模長(zhǎng)。如果模長(zhǎng)都接近 1說(shuō)明已歸一化如果差異很大就要手動(dòng)歸一化。做余弦相似度聚類時(shí)務(wù)必確保所有向量在同一尺度上。我一般會(huì)在入庫(kù)前統(tǒng)一做一次 L2 歸一化省得后面出問(wèn)題。import numpy as np def l2_normalize(vecs): norms np.linalg.norm(vecs, axis1, keepdimsTrue) norms[norms 0] 1e-10 return vecs / norms4. 聚類算法怎么選K-Means 不是萬(wàn)能藥4.1 先降維還是先聚類順序很重要拿到一堆高維向量第一反應(yīng)往往是先降維再聚類。但這里有個(gè)順序問(wèn)題降維是為了可視化還是為了聚類如果是為了可視化畫(huà)個(gè)散點(diǎn)圖給人看那 UMAP 或 t-SNE 都行降到 2 維或 3 維。但要注意降維后的距離關(guān)系已經(jīng)失真不能拿降維后的結(jié)果去做聚類否則聚類質(zhì)量會(huì)大打折扣。如果是為了聚類正確順序是先在高維空間聚類再降維可視化。因?yàn)榫垲愃惴ㄔ诟呔S空間能捕捉到更完整的結(jié)構(gòu)降維只是為了讓你看得見(jiàn)。我見(jiàn)過(guò)有人用 t-SNE 降到 2 維再跑 K-Means結(jié)果聚出來(lái)的類完全沒(méi)有業(yè)務(wù)意義。這就是順序搞反了。4.2 K-Means、HDBSCAN、層次聚類的適用邊界不同聚類算法適合不同場(chǎng)景我列個(gè)對(duì)比算法是否需要預(yù)設(shè)類數(shù)能否發(fā)現(xiàn)噪聲適合的類形狀A(yù)gent Trace 場(chǎng)景K-Means是否球形類數(shù)已知、分布均勻HDBSCAN否是任意類數(shù)未知、有離群點(diǎn)層次聚類否否任意小數(shù)據(jù)集、要層次結(jié)構(gòu)譜聚類是否任意圖結(jié)構(gòu)數(shù)據(jù)做 Agent Trace 聚類我最推薦HDBSCAN。原因很實(shí)際你事先根本不知道用戶有多少種行為模式而且總有一批四不像的 Session比如用戶亂輸、Agent 報(bào)錯(cuò)這些應(yīng)該被識(shí)別為噪聲而不是硬塞進(jìn)某個(gè)類。K-Means 會(huì)強(qiáng)行把每個(gè)點(diǎn)都分到某個(gè)類導(dǎo)致噪聲污染真實(shí)類。但 HDBSCAN 也有缺點(diǎn)參數(shù)敏感尤其是min_cluster_size調(diào)不好要么全是一個(gè)類要么全是噪聲。我的經(jīng)驗(yàn)是min_cluster_size從總樣本量的 1% 到 2% 開(kāi)始試然后根據(jù)結(jié)果調(diào)整。4.3 類數(shù)到底怎么定肘部法之外的實(shí)戰(zhàn)判斷如果你非要用 K-Means那類數(shù) K 怎么定就是繞不開(kāi)的問(wèn)題。教科書(shū)會(huì)告訴你用肘部法或輪廓系數(shù)但實(shí)戰(zhàn)中這兩個(gè)指標(biāo)經(jīng)常給出模棱兩可的答案。我的做法是指標(biāo) 業(yè)務(wù)雙驗(yàn)證。先用輪廓系數(shù)掃一遍 K 的范圍比如 5 到 50找出幾個(gè)候選值然后對(duì)每個(gè)候選 K 跑一次聚類人工看幾個(gè)類的代表樣本判斷這個(gè)類是不是有業(yè)務(wù)意義。指標(biāo)好但業(yè)務(wù)上說(shuō)不通的類直接否掉。舉個(gè)真實(shí)例子有一次輪廓系數(shù)告訴我 K12 最好但我看了聚類結(jié)果發(fā)現(xiàn)其中 4 個(gè)類其實(shí)是同一個(gè)業(yè)務(wù)場(chǎng)景的細(xì)分合并后 K8 反而更清晰。指標(biāo)是參考業(yè)務(wù)是裁判。5. 讓聚類結(jié)果說(shuō)人話從向量簇到行為標(biāo)簽5.1 每個(gè)簇的代表樣本怎么挑聚類跑完你得到一堆簇 ID但這對(duì)業(yè)務(wù)方毫無(wú)意義。下一步是給每個(gè)簇畫(huà)像。最直接的方法是挑代表樣本。怎么挑離簇中心最近的若干條。但要注意如果用的是 HDBSCAN簇中心的概念不直接適用可以用簇內(nèi)所有點(diǎn)的均值作為近似中心。def pick_representatives(embeddings, labels, cluster_id, top_n5): mask labels cluster_id cluster_vecs embeddings[mask] center cluster_vecs.mean(axis0) dists np.linalg.norm(cluster_vecs - center, axis1) idx np.argsort(dists)[:top_n] return np.where(mask)[0][idx]挑出代表樣本后人工讀一遍就能大致總結(jié)出這個(gè)簇在講什么。這一步目前還很難完全自動(dòng)化但可以用 LLM 輔助把代表樣本喂給大模型讓它生成一句行為描述。實(shí)測(cè)下來(lái)LLM 生成的描述有 70% 左右可以直接用剩下的需要人工修正。5.2 用 LLM 給簇自動(dòng)打標(biāo)簽的正確姿勢(shì)讓 LLM 打標(biāo)簽關(guān)鍵在于提示詞的設(shè)計(jì)。直接問(wèn)這些 Session 屬于什么類型效果一般因?yàn)?LLM 不知道你的業(yè)務(wù)分類體系。我的做法是分兩步第一步讓 LLM 從代表樣本里抽取共同特征用戶意圖、工具鏈路、結(jié)果狀態(tài)第二步基于這些特征生成一個(gè)簡(jiǎn)短標(biāo)簽。提示詞大概長(zhǎng)這樣以下是同一類 Agent 會(huì)話的代表樣本請(qǐng)總結(jié)它們的共同行為模式。 樣本1: ... 樣本2: ... 請(qǐng)輸出1) 用戶核心意圖 2) 典型工具鏈路 3) 一個(gè)不超過(guò)10字的標(biāo)簽這樣出來(lái)的標(biāo)簽質(zhì)量明顯更高。另外標(biāo)簽要可迭代第一輪生成的標(biāo)簽可能比較粗糙可以拿全部樣本再讓 LLM 精修一輪。5.3 標(biāo)簽體系要能掛上業(yè)務(wù)指標(biāo)光有標(biāo)簽還不夠標(biāo)簽必須能跟業(yè)務(wù)指標(biāo)掛鉤否則聚類就只是自嗨。我一般會(huì)做一張簇-指標(biāo)對(duì)照表把每個(gè)簇的樣本量、成功率、平均耗時(shí)、平均 token 消耗、負(fù)反饋率都算出來(lái)。這樣一眼就能看出哪個(gè)行為模式是高頻但低質(zhì)的哪個(gè)是低頻但高價(jià)值的。簇 ID行為標(biāo)簽樣本占比成功率平均耗時(shí)負(fù)反饋率0簡(jiǎn)單問(wèn)答35%96%1.2s2%1多輪檢索22%78%8.5s12%2工具鏈?zhǔn)?%31%15s45%3意圖不明15%60%3s20%有了這張表優(yōu)化方向就非常明確了簇 2 成功率只有 31%負(fù)反饋率 45%這就是重點(diǎn)排查對(duì)象。你可以進(jìn)一步下鉆看這個(gè)簇里工具調(diào)用失敗的具體原因。6. 我在實(shí)際項(xiàng)目里踩過(guò)的坑和對(duì)應(yīng)解法6.1 坑一Session 長(zhǎng)度差異巨大導(dǎo)致聚類偏移Agent 的 Session 長(zhǎng)度差異可以非??鋸堄械木鸵惠唵?wèn)答有的能聊幾十輪。如果直接把整條 Session 的文本拼起來(lái)做 Embedding長(zhǎng) Session 的向量會(huì)被大量?jī)?nèi)容平均掉短 Session 的向量則很集中導(dǎo)致聚類結(jié)果被長(zhǎng)度主導(dǎo)而不是被語(yǔ)義主導(dǎo)。我的解法是分層處理對(duì)超長(zhǎng) Session 做摘要后再 Embedding或者干脆按輪次切分對(duì)每一輪單獨(dú) Embedding 后再做 Session 級(jí)聚合比如取平均或加權(quán)平均。實(shí)測(cè)下來(lái)先摘要再 Embedding 的效果更穩(wěn)定。6.2 坑二工具名不統(tǒng)一同一個(gè)工具被聚成兩類這個(gè)坑特別隱蔽。比如你的 Agent 里有個(gè)搜索工具有時(shí)候叫web_search有時(shí)候叫search有時(shí)候叫g(shù)oogle_search。Embedding 時(shí)它們會(huì)被當(dāng)成不同的東西導(dǎo)致本該屬于同一類的 Session 被拆開(kāi)。解法是做工具名歸一化維護(hù)一張別名映射表把所有變體映射到統(tǒng)一名稱。這個(gè)表要定期維護(hù)因?yàn)楣ぞ邥?huì)不斷新增。6.3 坑三聚類結(jié)果不穩(wěn)定每次跑都不一樣K-Means 對(duì)初始中心敏感HDBSCAN 對(duì)參數(shù)敏感導(dǎo)致每次跑出來(lái)的聚類結(jié)果都不太一樣。這在需要追蹤行為變化趨勢(shì)的場(chǎng)景下是致命的——你沒(méi)法比較這周和上周的分布。解法有兩個(gè)一是固定隨機(jī)種子保證可復(fù)現(xiàn)二是用增量聚類把歷史簇中心保存下來(lái)新數(shù)據(jù)來(lái)了先分配到已有簇只有明顯偏離的才新建簇。這樣分布就是連續(xù)可比的。6.4 坑四把聚類當(dāng)成終點(diǎn)而不是起點(diǎn)最常見(jiàn)的誤區(qū)是聚類跑完、標(biāo)簽打完項(xiàng)目就結(jié)束了。但實(shí)際上聚類只是把海量數(shù)據(jù)壓縮成可理解的幾個(gè)類別真正的價(jià)值在于基于這些類別去做優(yōu)化。我一般會(huì)把聚類結(jié)果接入三個(gè)下游一是評(píng)測(cè)針對(duì)每個(gè)簇設(shè)計(jì)專門(mén)的測(cè)試用例二是告警某個(gè)簇的占比突然飆升就觸發(fā)預(yù)警三是產(chǎn)品迭代高頻低質(zhì)的簇就是優(yōu)化優(yōu)先級(jí)最高的地方。7. 從離線聚類到在線行為監(jiān)控的演進(jìn)思路離線聚類跑通之后很自然會(huì)想能不能實(shí)時(shí)監(jiān)控 Agent 的行為分布我的做法是離線建庫(kù)、在線匹配。離線階段把歷史 Session 聚成若干簇保存每個(gè)簇的中心向量和標(biāo)簽。在線階段每條新 Session 來(lái)了先做 Embedding然后計(jì)算它到各個(gè)簇中心的距離分配到最近的簇。如果距離超過(guò)閾值說(shuō)明這是一個(gè)新行為先標(biāo)記為待觀察積累到一定量后再觸發(fā)一次離線聚類。這樣既保證了實(shí)時(shí)性又能持續(xù)發(fā)現(xiàn)新行為模式。閾值怎么定我一般用歷史數(shù)據(jù)的距離分布取 95 分位數(shù)作為閾值這樣只有真正偏離的行為才會(huì)被標(biāo)記。這套機(jī)制跑起來(lái)之后你對(duì) Agent 的理解就從事后分析變成了實(shí)時(shí)感知。哪個(gè)行為模式在增長(zhǎng)、哪個(gè)在衰退、有沒(méi)有新行為冒出來(lái)一目了然。這才是智能聚類真正的價(jià)值所在——它不是一個(gè)分析工具而是一個(gè)持續(xù)理解 Agent 行為的感知系統(tǒng)。最后分享一個(gè)我個(gè)人的小習(xí)慣每次聚類結(jié)果出來(lái)后我都會(huì)隨機(jī)抽 20 條 Session 人工讀一遍看看聚類有沒(méi)有把明顯不同的東西混在一起。這個(gè)動(dòng)作花不了多少時(shí)間但能幫你及時(shí)發(fā)現(xiàn) Embedding 或聚類參數(shù)的問(wèn)題。機(jī)器再智能也需要人的眼睛做最后一道校驗(yàn)。