用開發(fā)中的敏感數(shù)據(jù)脫敏:Agent Skills架構(gòu)設(shè)計實戰(zhàn))
干過幾年Web后端的人轉(zhuǎn)去做大模型應(yīng)用開發(fā)最先撞上的墻往往不是什么模型調(diào)優(yōu)、Prompt技巧而是數(shù)據(jù)安全。我之前接手過一個客服工單智能助手的需求說白了就是讓 Agent 去讀工單數(shù)據(jù)庫然后自動幫客戶查進度、解答疑問。剛開始覺得這事兒不難查詢結(jié)果拼進 Prompt 給大模型就完事了。結(jié)果聯(lián)調(diào)的時候翻車了——大模型在回復(fù)里把客戶的完整手機號、家庭住址一字不差地復(fù)述了出來。那一刻我才意識到過去我們在 Web 應(yīng)用里攢下的那套數(shù)據(jù)防護經(jīng)驗放在 Agent Skills 面前幾乎全部失效。這篇文章就想聊聊我做 Agent Skills 敏感數(shù)據(jù)脫敏架構(gòu)設(shè)計的全過程。從 Web 開發(fā)者的視角出發(fā)講清楚 Agent 場景下數(shù)據(jù)鏈路到底發(fā)生了什么變化、敏感數(shù)據(jù)暴露在哪幾個環(huán)節(jié)、脫敏架構(gòu)怎么分層落地以及我在這個過程中踩過的坑和最終的排查經(jīng)驗。如果你也是從 Web 開發(fā)轉(zhuǎn)向 AI 應(yīng)用開發(fā)正在做 Agent、做 Skill 封裝、做 RAG 這類方向這篇文章應(yīng)該對你有用。1. 轉(zhuǎn)型視角下的Agent數(shù)據(jù)鏈路和我們熟悉的Web鏈路到底差在哪1.1 Web開發(fā)者心里那套“祖?zhèn)鳌钡臄?shù)據(jù)安全打法老一代 Web 后端對數(shù)據(jù)安全的直覺基本圍繞“接口鑒權(quán)、字段過濾、前端展示控制”這幾板斧。比如查詢客戶信息后端接口嚴格校驗登錄態(tài)返回 JSON 之前把敏感字段摘掉前端表格里手機號中間四位打星號數(shù)據(jù)庫查詢?nèi)繀?shù)化防注入。這套邏輯成立的前提是數(shù)據(jù)從后端到前端是一條單向、短命的傳輸鏈路。請求來了后端查庫把該給的字段給出去響應(yīng)結(jié)束這條數(shù)據(jù)路徑就斷開了。你只要保證接口不進黑名單字段、前端不顯示明文字段問題基本就控制住了。到了 Agent 場景這個前提直接崩了。Agent 不是簡單地“請求—響應(yīng)”而是會把外部數(shù)據(jù)取回來之后放進上下文Context里供模型推理、多輪對話、工具調(diào)用反復(fù)使用。數(shù)據(jù)在推理鏈路中的生命周期被拉長了好幾倍而模型必須真正“看懂”這些數(shù)據(jù)才能干活。這就意味著你不能簡單地把敏感字段藏起來——藏起來模型就看不懂了。1.2 Agent Skills把數(shù)據(jù)鏈路拉長成了什么樣子先解釋一下 Agent Skills 是什么。可以把 Skill 理解成 Agent 的一項專項能力封裝一個 Skill 內(nèi)部通常包含技能描述、參數(shù)定義、對應(yīng)的工具調(diào)用邏輯比如查數(shù)據(jù)庫、調(diào)外部 API以及返回數(shù)據(jù)的處理方式。Agent 會根據(jù)用戶意圖自主決定調(diào)用哪個 Skill然后把 Skill 返回的內(nèi)容拼進上下文繼續(xù)推理。問題就出在這個“拼進上下文”。我在做客服工單助手時Skill 返回的數(shù)據(jù)結(jié)構(gòu)大概是這樣的{ ticket_id: TK20250113002, customer_name: 張三, customer_phone: 13812345678, customer_address: 某某市某某區(qū)某某街道88號, issue_desc: 客戶反饋訂單未按時送達多次聯(lián)系客服未果, handler: 李四 }在 Web 時代這段 JSON 返回給前端之前我可以直接把customer_phone摘掉。前端不需要手機號頁面只顯示工單標題和狀態(tài)就行。但在 Agent 場景里模型需要根據(jù)工單內(nèi)容去判斷“這個客戶是不是在問物流問題”“要不要給他升級處理”甚至需要核對“這個手機號對應(yīng)的客戶是不是本人”。你如果直接把手機號碼干掉模型碰上復(fù)雜一點的對話就懵了。更麻煩的是上下文滯留。Agent 的對話是多輪的客戶先說“我要查訂單”然后又提供了自己的手機號模型把手機號記在上下文里。哪怕你 Skill 返回的數(shù)據(jù)做了脫敏只要對話歷史里曾經(jīng)出現(xiàn)過明文后續(xù)某輪模型就可能把明文回憶出來。1.3 敏感需要重新定義Web 時代對“敏感數(shù)據(jù)”的理解基本是靜態(tài)的身份證、手機號、銀行卡、住址這些字段打上標簽統(tǒng)一加密脫敏。到了 Agent 場景敏感數(shù)據(jù)的口徑必須做動態(tài)擴展。因為模型可以結(jié)合多條信息推斷出敏感結(jié)論。舉個例子工單里沒有客戶的完整姓名只有“張先生”三個字加上地址“某某小區(qū) 12 棟”再結(jié)合客戶自述“我住 12 棟 3 樓”模型可能直接推算出門牌號。這個時候單純對字段脫敏是不夠的你得有一套內(nèi)容級識別和分級策略讓模型在推理過程中用到的數(shù)據(jù)“夠用但不過分”。提示轉(zhuǎn)型 AI 應(yīng)用開發(fā)后請把“敏感數(shù)據(jù)”從字段清單升級為“識別—分級—改寫—審計”一條鏈路的架構(gòu)設(shè)計。這不是過度設(shè)計是 Agent 推理特性決定的底線要求。2. 設(shè)計脫敏架構(gòu)前先盯住Agent Skills的四個暴露點脫敏架構(gòu)設(shè)計的第一步不是寫代碼而是把 Agent 調(diào)用 Skill 時數(shù)據(jù)可能經(jīng)過的所有路徑盤一遍。我梳理下來Agent Skills 的敏感數(shù)據(jù)暴露點主要有四個。2.1 暴露點一入站參數(shù)Agent 調(diào)用 Skill 時需要在參數(shù)里帶上用戶信息??蛻粽f“幫我查一下我 13812345678 這個號碼的訂單”Agent 就會把手機號作為入?yún)鹘o查詢 Skill。如果 Skill 內(nèi)部直接拿這個參數(shù)查庫那么明文手機號至少會出現(xiàn)在Agent 的對話上下文里Skill 的請求日志里底層數(shù)據(jù)庫查詢?nèi)罩纠?。這個環(huán)節(jié)一般容易被忽略因為大家關(guān)注點都在“返回數(shù)據(jù)的脫敏”但入站參數(shù)同樣會泄露敏感信息。2.2 暴露點二上下文滯留這是 Agent 場景和 Web 場景最大的差異。Web 后端處理完請求響應(yīng)結(jié)束數(shù)據(jù)生命周期就結(jié)束了。但 Agent 的上下文是多輪累積的明文數(shù)據(jù)一旦進入上下文除非你主動清理否則它會一直待在那兒。我在測試中發(fā)現(xiàn)模型在第三輪對話時復(fù)述了第一輪出現(xiàn)過的完整身份證號而整個過程中我并沒有把身份證號當作任何 Skill 的返回值。原因就是第一輪用戶在咨詢時自己發(fā)了一段文字里面有身份證號模型把它存進了上下文后面又被“調(diào)用”了出來。2.3 暴露點三第三方工具返回結(jié)果Agent 通常不會只調(diào)自己的 Skill還會調(diào)用搜索工具、天氣工具、地圖工具甚至外部知識庫。這類第三方返回的內(nèi)容不受你控制里面很可能夾帶個人隱私。比如搜索結(jié)果里出現(xiàn)某用戶的社交賬號主頁里面就有手機號地圖工具返回某個地址詳情附帶聯(lián)系人電話。這些數(shù)據(jù)進入上下文后同樣面臨泄漏風險。2.4 暴露點四模型出站復(fù)述模型有一種讓人頭疼的能力就是一字不差地復(fù)述輸入中的字符串。明明 Skill 只需要返回“密碼重置鏈接已發(fā)送”但模型在給用戶解釋時可能會把短信驗證碼、銀行卡號、家庭住址這些原文完整說出來。這個暴露點可以說是整個鏈路里最容易被忽略但后果最直接的。針對這四個暴露點我最終把脫敏架構(gòu)拆成了四層識別層、策略層、改寫層、審計層。每一層解決一個特定方向的問題下面詳細展開。3. 分層脫敏架構(gòu)落地識別、分級、改寫、審計3.1 第一層敏感數(shù)據(jù)識別器脫敏的前提是知道哪些內(nèi)容是敏感的。Web 時代常用的做法是配置黑名單字段Agent 場景下這個粒度遠遠不夠。我的方案是多渠道識別規(guī)則識別用正則識別手機號、身份證號、銀行卡號、郵箱等模式固定的數(shù)據(jù)實體識別用命名實體識別NER模型識別姓名、地址、組織名等無固定格式的實體字段標注對于自研 Skill 的返回結(jié)果在字段定義階段就給敏感字段打標簽。代碼層面一個輕量識別器的做法大概是這樣的import re SENSITIVE_PATTERNS { phone: r\b1[3-9]\d{9}\b, id_card: r\b\d{17}[\dXx]\b, bank_card: r\b\d{16,19}\b, email: r\b[\w.-][\w-]\.[\w.-]\b, } def scan_sensitive(text: str): hits [] for name, pattern in SENSITIVE_PATTERNS.items(): for match in re.finditer(pattern, text): hits.append({ type: name, value: match.group(), start: match.start(), end: match.end(), }) return hits在實際項目里我建議不要只依賴正則。因為客戶地址這種信息格式極其自由“某某市某某區(qū)某某路 88 號 3 棟 201”這種長串正則寫不出來。我當時接了一個 NER 服務(wù)專門識別PER人名、LOC地點、ORG機構(gòu)名識別精度八九成配合規(guī)則識別基本夠用。3.2 第二層分級與策略引擎識別出敏感內(nèi)容之后不能一刀切全脫敏。不同場景下模型對數(shù)據(jù)的需求強度不一樣。我習慣把敏感數(shù)據(jù)分成三級級別定義示例處理方式L1模型推理必須的、不構(gòu)成隱私風險的內(nèi)容工單狀態(tài)、物流節(jié)點、商品名稱原樣保留L2非必要但模型偶爾會引用的個人信息姓名、城市級別地址變形脫敏保留語義L3一旦泄露后果嚴重的強隱私數(shù)據(jù)手機號、身份證號、銀行卡號、詳細門牌地址可逆加密/完全隱藏分級策略要外置成配置不要寫死在代碼里。我當時用了一個 JSON 配置文件業(yè)務(wù)方可以隨時調(diào)整{ field_policy: { customer_name: MASK_KEEP_LAST, customer_phone: REPLACE_RANDOM, customer_address: MASK_RETAIN_CITY, issue_desc: KEEP_ALL }, type_policy: { phone: REPLACE_RANDOM, id_card: REPLACE_ENCRYPTED, email: MASK_KEEP_PREFIX } }策略引擎根據(jù)這個配置決定對某一類型/字段的數(shù)據(jù)執(zhí)行哪種脫敏策略。常見策略包括MASK_KEEP_LAST保留后幾位其余打碼比如張*;MASK_RETAIN_CITY保留城市名隱藏詳細門牌地址REPLACE_RANDOM替換成隨機生成的假數(shù)據(jù)保持格式一致性REPLACE_ENCRYPTED用格式保留加密生成可逆的密文。這里特別說一下格式保留可逆加密。它是脫敏方案里一個比較優(yōu)雅的工具——加密后的結(jié)果在格式上和原文保持一致。比如身份證號加密后還是一串 18 位的數(shù)字從“長得像身份證號”這個角度模型完全可以正常理解這個字段的含義。但密文無法還原出真實內(nèi)容只有持有密鑰的后端服務(wù)才具備解密的權(quán)限。這樣既保證了模型對數(shù)據(jù)結(jié)構(gòu)的理解又實現(xiàn)了強隱私保護。日常做客服工單場景時后臺人工審計如果需要看真實數(shù)據(jù)可以通過安全網(wǎng)關(guān)單獨解密查看而 Agent 推理鏈路里拿到的永遠是密文。3.3 第三層上下文改寫器識別和分級完成之后接下來是核心環(huán)節(jié)在數(shù)據(jù)從 Skill 返回準備進入上下文之前插入一個改寫器。改寫器的作用是對即將進入模型上下文的內(nèi)容做清洗和替換。改寫器要處理的不僅是 Skill 返回的 JSON還包括用戶自己發(fā)來的文本消息里的敏感內(nèi)容。我實現(xiàn)的上下文改寫器核心邏輯是先對文本做敏感掃描再按策略執(zhí)行脫敏最后把脫敏后的文本放進上下文。class MaskingRewrite: def __init__(self, policy_engine): self.policy_engine policy_engine def rewrite_text(self, text: str) - str: hits scan_sensitive(text) if not hits: return text # 按命中位置倒序替換避免破壞索引 result list(text) for hit in sorted(hits, keylambda x: x[start], reverseTrue): policy self.policy_engine.get_policy(hit[type]) masked_value self.policy_engine.mask(hit[value], policy) result[hit[start]:hit[end]] masked_value return .join(result)這里有一個關(guān)鍵設(shè)計缺省禁止。也就是說如果一段文本里出現(xiàn)了敏感內(nèi)容但策略引擎沒有明確配置對應(yīng)的脫敏策略默認行為是攔截而不是放行。寧可讓模型多問一輪“請?zhí)峁┍匾畔ⅰ币膊荒茏屆魑牧镞M上下文。再展開說一個實操細節(jié)替換算法不能破壞索引位置。我第一次實現(xiàn)時用的是str.replace()結(jié)果出現(xiàn)了問題——當一段文本里有兩個完全相同的手機號時replace會把兩個都替換掉但我的代碼邏輯只期望替換第一個導致后續(xù)位置偏移。后來我才改成“倒序切片重建法”先把文本轉(zhuǎn)成字符數(shù)組從后往前替換索引永遠不亂。3.4 第四層輸出審計脫敏架構(gòu)還有一個容易被遺漏的出口Agent 的最終回復(fù)。模型在生成回復(fù)時可能會把上下文里被脫敏的內(nèi)容“重新生成”出來。比如脫敏后的手機號是138****1234模型看多了這個格式回復(fù)時有可能編一個類似的號碼出來更危險的是如果某一輪操作失誤導致明文進了上下文模型可能在回復(fù)中原樣復(fù)述。輸出審計層要做的事情是在 Agent 回復(fù)發(fā)給用戶之前再掃描一遍發(fā)現(xiàn)任何符合敏感模式的內(nèi)容就用統(tǒng)一的脫敏模板替換掉或者直接攔截回復(fù)要求重新生成。我在輸出審計層還做了一個輕量級的泄露檢測功能把所有命中敏感模式的文本片段記錄到審計日志里附帶上命中的信息來源是哪一輪對話、哪個 Skill 返回的。這樣一旦出現(xiàn)問題排查鏈路會容易很多。4. 一套可抄作業(yè)的參考實現(xiàn)從識別到審計的完整編排前面把分層架構(gòu)講完了這一節(jié)我直接給出一套能夠跑通的核心編排代碼大家可以按這個結(jié)構(gòu)快速在自己項目里搭一個雛形。class DataMaskingPipeline: def __init__(self, policy_engine, rewriter, auditor): self.policy_engine policy_engine self.rewriter rewriter self.auditor auditor def process_skill_response(self, skill_name: str, raw_data: str, user_id: str) - str: # 第一步識別 hits scan_sensitive(raw_data) if not hits: return raw_data # 第二步分級與改寫 rewritten self.rewriter.rewrite_text(raw_data) # 第三步記錄審計信息 self.auditor.log( skill_nameskill_name, user_iduser_id, hit_countlen(hits), hit_types[h[type] for h in hits], timestampdatetime.now(), ) return rewritten實際項目中這個 Pipeline 會被掛在 Skill 調(diào)用鏈的外層。我推薦的做法是做一個統(tǒng)一的數(shù)據(jù)安全網(wǎng)關(guān)所有 Skill 的對外 API 都通過這個網(wǎng)關(guān)進出。網(wǎng)關(guān)負責入站參數(shù)清洗、出站響應(yīng)改寫、日志審計三件事。從執(zhí)行順序上看Agent 每調(diào)用一次 Skill數(shù)據(jù)流的完整鏈路是用戶消息進入 Agent 編排層編排層決定調(diào)用某個 SkillSkill 請求先過安全網(wǎng)關(guān)入站參數(shù)里的敏感信息被脫敏/標記Skill 執(zhí)行業(yè)務(wù)邏輯返回原始結(jié)果原始結(jié)果再過安全網(wǎng)關(guān)敏感識別器掃描改寫器執(zhí)行脫敏脫敏后的結(jié)果進入模型上下文模型生成回復(fù)前輸出審計層掃描回復(fù)返回給用戶。不要小看中間多出來的幾層調(diào)用它們帶來的性能損耗在可接受范圍內(nèi)。我實測下來一次正則掃描加脫敏改寫大約在 5 到 10 毫秒對一個對話交互來說這個開銷完全可以接受。注意的是Skill 返回的數(shù)據(jù)如果是結(jié)構(gòu)化的 JSON不能簡單地把 JSON 轉(zhuǎn)成字符串再做脫敏。那樣做會讓字段和策略的映射關(guān)系丟失。正確做法是遍歷 JSON 的每個字段依據(jù)字段名匹配策略。def process_json(obj, field_policy): if isinstance(obj, dict): clean {} for k, v in obj.items(): if k in field_policy: clean[k] mask_value(v, field_policy[k]) else: clean[k] process_json(v, field_policy) return clean elif isinstance(obj, list): return [process_json(item, field_policy) for item in obj] else: return obj這里還要提醒一個容易踩坑的地方字段策略要盡量用“字段名 內(nèi)容類型”雙重匹配。因為有些字段雖然叫note但里面的內(nèi)容可能是用戶留言包含手機號有些字段叫name但可能存的是公司全稱不含個人隱私。所以不管是字段策略還是內(nèi)容掃描建議都過一遍識別器寧可多掃一次不要漏一次。5. 常見問題與排查技巧實錄脫敏架構(gòu)上線之后問題并不會消失只會換個姿勢出現(xiàn)。我整理了幾個在模擬項目X和實際客服工單助手開發(fā)中反復(fù)遇到的問題和對應(yīng)的排查思路希望對你有參考價值。5.1 脫敏后模型答非所問現(xiàn)象把客戶姓名替換成張*之后模型在回復(fù)里開始頻繁出現(xiàn)“關(guān)于您的姓名信息系統(tǒng)暫時無法識別”這樣的傻話。原因脫敏粒度過大把模型做語義理解所需的關(guān)鍵信息也抹掉了。排查思路先確認模型回答的質(zhì)量問題是不是只出現(xiàn)在含有敏感字段的對話中。如果是把策略從MASK_KEEP_LAST換成REPLACE_RANDOM也就是用假名替代真名比如“張三”變成“李四”。模型只需要知道“這是一個人的名字”并不需要知道具體的真實姓名隨機替換比打星號更能保留語義。這個技巧在客服工單場景中非常實用。5.2 明文從檢索結(jié)果里繞過脫敏層現(xiàn)象某輪對話里出現(xiàn)了明文手機號但我明明已經(jīng)在 Skill 返回的數(shù)據(jù)上掛了脫敏組件。原因這個手機號不是來自 Skill 的返回值而是來自 RAG 檢索召回的文檔內(nèi)容。RAG 鏈路里的文檔片段走的是另一條數(shù)據(jù)通道沒有經(jīng)過安全網(wǎng)關(guān)。排查思路把安全網(wǎng)關(guān)從“Skill 專用”升級為“所有數(shù)據(jù)出口強制走網(wǎng)關(guān)”包括 RAG 檢索器、外部知識庫調(diào)用、甚至系統(tǒng)提示詞里動態(tài)拼接的用戶資料都必須統(tǒng)一過一遍識別和改寫。我用了一個很笨但有效的辦法把數(shù)據(jù)安全網(wǎng)關(guān)做成了項目里所有外部數(shù)據(jù)源的唯一出口任何數(shù)據(jù)要進入模型上下文必須經(jīng)過這個出口。這樣至少不會出現(xiàn)旁路繞過。5.3 日志里出現(xiàn)明文現(xiàn)象安全掃描顯示對話記錄和模型輸出都沒有明文但運維查日志時發(fā)現(xiàn)Skill 的調(diào)用日志里完整記錄了入?yún)⑹謾C號。原因脫敏只作用在“上下文數(shù)據(jù)鏈路”上但調(diào)試日志、監(jiān)控日志記錄的是原始 API 請求是獨立的一條數(shù)據(jù)通道。排查思路日志脫敏必須作為一個獨立組件來對待。所有日志輸出之前統(tǒng)一走日志脫敏過濾器對手機號、身份證、地址這類字段打碼。我建議在日志框架層面全局掛一個過濾器而不是每個業(yè)務(wù)模塊手動打碼。因為人工手動打碼必然會有遺漏公共組件處理才能做到全覆蓋。5.4 明明脫敏了模型還是猜出原始號碼現(xiàn)象手機號已經(jīng)被替換成隨機號碼模型對話中也沒有出現(xiàn)過明文但有一次模型在回復(fù)中對客戶說“這個手機號是上次和您核對的那個號碼吧”而客戶上次并沒有報過號。原因模型基于對話上下文做了推理。前一輪客戶說了“我是 138 開頭的號”脫敏后的號碼恰好也以 138 開頭模型就自行串起來了。排查思路對高敏感字段脫敏后的格式要與原數(shù)據(jù)保持足夠距離。比如手機號這種強隱私信息在條件允許的情況下不要用“保留前三位、后四位”這種模式脫敏而是直接生成一個完全隨機的新號碼。寧可讓模型少一點“熟悉感”也不能讓它有推斷空間。5.5 常見問題速查表現(xiàn)象可能原因排查方向脫敏后模型答非所問脫敏粒度過大將打碼策略改為隨機替換對話中出現(xiàn)明文數(shù)據(jù)走了旁路RAG/外部工具所有數(shù)據(jù)出口統(tǒng)一走安全網(wǎng)關(guān)日志出現(xiàn)明文日志鏈路獨立于脫敏鏈路日志框架掛全局脫敏過濾器模型猜出原始敏感信息脫敏保留了可推斷片段高敏字段用完全隨機替換脫敏后數(shù)據(jù)格式錯亂替換算法破壞索引改用倒序切片重建法6. 從Web轉(zhuǎn)Agent安全思維上必須做出的三個轉(zhuǎn)變6.1 從攔截到改寫Web 時代防數(shù)據(jù)泄露的主流思路是“不返回、不展示”。敏感字段對前端就是不給對日志就是不記。到了 Agent 時代這個思路失靈了因為模型需要數(shù)據(jù)來完成推理。你不可能把一個沒有地址的工單給模型卻期望它準確判斷“客戶是不是因為配送地址有誤才投訴”。所以安全手段從“攔截刪除”變成了“智能改寫”——給你必要的信息但給的不是真實信息。6.2 從單點防護到全鏈路審計Web 場景下前端展示、后端存儲、日志記錄各管一攤每一攤都有單獨的防護措施。Agent 場景下數(shù)據(jù)要經(jīng)過入站參數(shù)、Skill 返回、上下文滯留、模型輸出、日志記錄五六個環(huán)節(jié)任何一個環(huán)節(jié)漏了整個防線就破了。所以脫敏架構(gòu)必須覆蓋全鏈路任何一條數(shù)據(jù)路徑都不能繞過安全網(wǎng)關(guān)。6.3 從靜態(tài)清單到動態(tài)策略Web 時代的敏感字段清單很穩(wěn)定基本是上線時配置好就不用動了。Agent 場景下的敏感內(nèi)容識別會隨著業(yè)務(wù)變化而漂移。比如某天業(yè)務(wù)方在工單里新增了“客戶偏好”字段里面的內(nèi)容可能是客戶自述的健康狀況、家庭情況這種東西靠正則識別不了靠字段清單也需要同步更新。所以策略引擎必須做得足夠靈活配置化、可視化讓業(yè)務(wù)方能隨時調(diào)整而不是每次改策略都要發(fā)布一次代碼。個人體會是Web 開發(fā)者轉(zhuǎn) AI 應(yīng)用開發(fā)最大的優(yōu)勢在于數(shù)據(jù)庫模型、API 設(shè)計、系統(tǒng)架構(gòu)這些基本功扎實最大的短板是容易把“數(shù)據(jù)安全”想簡單了。Agent 的數(shù)據(jù)鏈路遠比我們熟悉的 Web 鏈路復(fù)雜敏感數(shù)據(jù)脫敏也不只是寫幾個工具函數(shù)而是要當成一個獨立的架構(gòu)組件來設(shè)計。如果讓我重新來過我會在項目啟動的第一天就把數(shù)據(jù)安全網(wǎng)關(guān)的骨架搭好而不是等到聯(lián)調(diào)發(fā)現(xiàn)模型開始“復(fù)讀”客戶手機號了才來補窟窿。希望這篇文章能給同樣在做 Agent Skills 開發(fā)的同行們一些參考少走一些我走過的彎路。