設(shè)計:分層模型與工程落地)
開頭做了一段時間大模型應(yīng)用開發(fā)我發(fā)現(xiàn)一個特別有意思的現(xiàn)象同樣是調(diào)用同一個模型有的產(chǎn)品用下來像冷冰冰的問答機有的卻像相處很久的老朋友。差別往往不在模型本身而在產(chǎn)品有沒有給這個模型配上“記憶”。最近我們團隊在做一款名叫“小度想想”的智能體產(chǎn)品核心目標(biāo)就是讓智能體記住每個用戶的偏好、習(xí)慣和對話上下文真正實現(xiàn)千人千面的個性化體驗。這篇文章把我們在設(shè)計記憶系統(tǒng)時踩過的坑、理清的思路、落地的實現(xiàn)方式整理出來希望能給正在做智能體、AI助手或個性化對話系統(tǒng)的朋友一些參考。記憶的分層、寫入策略、召回調(diào)優(yōu)、隱私邊界這些我們都會展開聊內(nèi)容偏工程落地不堆概念看完可以直接照著搭一版。1. 為什么智能體需要記憶產(chǎn)品痛點與設(shè)計原點1.1 “失憶”的智能體有多讓人抓狂先講個真實場景。早期我們上線了一版沒有記憶能力的對話Demo用戶每天進來都是陌生感拉滿。有用戶連續(xù)一周跟智能體說“我膽固醇偏高早餐不要推薦油膩的”智能體每次都像第一次聽到一樣下一條推薦還是煎餅果子配油條。用戶后來在反饋里寫了一句很扎心的話“它還不如一個記事本?!边@句話直接推動我們把記憶系統(tǒng)提上了排期。失憶帶來的問題不只是體驗差還會讓用戶對產(chǎn)品的信任感快速流失。試想用戶花了十分鐘告訴智能體自己的作息、飲食禁忌、健身目標(biāo)轉(zhuǎn)頭再問一句“我今天適合練什么”智能體完全接不上那一刻用戶就會覺得之前的信息全白給了。更現(xiàn)實的是很多智能體產(chǎn)品的核心價值并不是單輪問答的正確率而是長期陪伴中形成的連貫服務(wù)。沒有記憶就等于每次對話都是初次見面產(chǎn)品永遠(yuǎn)停留在工具層面做不出情感黏性和個性化價值。1.2 從“會聊天”到“懂你”記憶的分層模型想清楚記憶要解決什么問題后我們一開始也犯過“什么都想存”的毛病。對話記錄、用戶點擊、停留時長、頁面瀏覽全部塞進一張表里結(jié)果又亂又沒法用。后來參考認(rèn)知科學(xué)里關(guān)于人類記憶的分層方式把智能體記憶拆成四類短時工作記憶、長期情景記憶、語義知識記憶和用戶畫像記憶。短時工作記憶對應(yīng)當(dāng)前會話里的上下文比如用戶前一句提到“周末去杭州”后一句問“幫我查高鐵”智能體得知道“杭州”就是它要查的目的地。長期情景記憶則是跨會話的關(guān)鍵事件比如“上個月用戶說過在準(zhǔn)備省考”“去年年底換了新工作”。語義知識記憶更偏通用常識比如城市地圖、菜系分類、履歷常識這部分可以直接從外部知識庫掛載不一定要從對話里學(xué)。用戶畫像記憶是最高抽象層把用戶明確表達(dá)或行為推斷出的偏好沉淀成標(biāo)簽比如“偏愛清淡”“工作時間上午九點到下午六點”“家里有一只五歲的柯基”。這四類記憶不是并列關(guān)系而是層層匯總的關(guān)系。會話上下文經(jīng)過提煉變成情景記憶情景記憶再經(jīng)過歸納和校驗沉淀為用戶畫像。分清楚層級之后后面設(shè)置存儲策略和更新邏輯都會省力很多。1.3 千人千面不是玄學(xué)記憶如何支撐個性化“千人千面”這個詞在產(chǎn)品文檔里出現(xiàn)頻率很高但落到智能體身上本質(zhì)就一句話讓系統(tǒng)在面對不同用戶時能夠調(diào)取不同的背景信息生成不同的回答策略和表達(dá)風(fēng)格。舉個例子同一個“晚上吃什么”的問題面對一位高血糖用戶和一位正在減肥的健身用戶智能體給出的答案完全不同。前者側(cè)重推薦的含糖量提示后者側(cè)重蛋白質(zhì)和熱量控制。如果不用記憶做區(qū)分模型只能給出一份模板化的“均衡飲食建議”看起來沒錯但誰都覺得沒說透。記憶支撐個性化還有一層遞進它讓模型越用越懂用戶的表達(dá)習(xí)慣。有人喜歡簡潔答案有人希望先解釋原理再給結(jié)論有人習(xí)慣用短句提問。這些風(fēng)格特征完全可以被記憶系統(tǒng)捕獲然后在生成提示詞里作為顯性指令傳給模型。我們實測下來加了風(fēng)格記憶之后用戶的對話滿意度評分提升非常明顯比單純調(diào)模型參數(shù)還管用。這也是為什么我一直認(rèn)為大模型應(yīng)用拼到最后拼的不是模型本身而是模型外面的這套數(shù)據(jù)與記憶架構(gòu)。2. 記憶系統(tǒng)整體架構(gòu)與技術(shù)選型2.1 四層架構(gòu)采集、存儲、召回、應(yīng)用記憶系統(tǒng)在我們項目里并不是一個單獨的服務(wù)而是嵌在智能體主流程中的中間層。整體分成四層采集層、存儲層、召回層和應(yīng)用層。采集層負(fù)責(zé)從交互過程中提取原始線索包括用戶輸入、用戶反饋、主動點擊行為、系統(tǒng)觸發(fā)的埋點等。這里有一個容易被忽略的點不是所有對話內(nèi)容都值得進存儲層采集層需要先做一輪預(yù)過濾把噪音話題、閑聊寒暄、重復(fù)試探性內(nèi)容篩掉。存儲層負(fù)責(zé)把采集到的線索變成結(jié)構(gòu)化記錄寫入對應(yīng)的存儲介質(zhì)。召回層是記憶系統(tǒng)的核心它的任務(wù)是當(dāng)用戶發(fā)起新一輪對話時從海量記憶里快速找到與當(dāng)前問題相關(guān)的片段。應(yīng)用層再把召回結(jié)果轉(zhuǎn)成提示詞中的上下文塊交給大模型生成最終回答。四層之間的接口要盡量保持簡單我們一開始設(shè)計時還加了消息隊列做異步解耦后面發(fā)現(xiàn)對話場景下的記憶寫入延遲其實沒那么敏感反而是同步寫入更容易排查問題。最后簡化成了“采集層寫一份、存儲層存一份、召回層查一份、應(yīng)用層拼一份”的直線流水代碼清晰很多。這個經(jīng)歷也讓我意識到架構(gòu)是為場景服務(wù)的不要為了所謂的解耦而過度設(shè)計。2.2 技術(shù)選型向量庫、緩存庫和關(guān)系庫怎么搭配存儲層的選型是記憶系統(tǒng)設(shè)計里最花時間的環(huán)節(jié)。我們考慮過全用向量數(shù)據(jù)庫也考慮過全用關(guān)系型數(shù)據(jù)庫最后定下來的是“關(guān)系庫 向量庫 緩存庫”的組合方案。關(guān)系型數(shù)據(jù)庫用來存用戶畫像這類強結(jié)構(gòu)數(shù)據(jù)。它字段明確、支持復(fù)雜條件查詢、事務(wù)能力強標(biāo)簽體系變動的時候也好做遷移。向量數(shù)據(jù)庫用來存文本類的記憶片段比如用戶說過的一段話、事件摘要、偏好描述這類信息沒有固定結(jié)構(gòu)只能靠語義相似度來檢索。緩存庫用來存當(dāng)前會話內(nèi)的短時上下文需要低延遲讀寫所以對速度要求最高一般用鍵值型存儲就能滿足。三者的邊界其實和前面說的記憶分層是對應(yīng)的畫像層偏結(jié)構(gòu)化情景層偏向量化會話層偏緩存化。選型時還有個容易被忽視的細(xì)節(jié)向量數(shù)據(jù)庫的索引類型和距離度量方式。如果記憶片段數(shù)量不大幾萬條以內(nèi)用暴力檢索都能滿足需求一旦上了百萬級就得考慮HNSW這類近似最近鄰索引同時要根據(jù)文本長度選擇合適的歸一化方式。我們早期在評估階段用默認(rèn)配置跑了一版結(jié)果中文長文本的召回結(jié)果非常不穩(wěn)定后來發(fā)現(xiàn)距離度量選成了不適合文本向量的方式換成適用的度量之后效果立刻改善。這個坑后面細(xì)說。2.3 記憶類型與生命周期管理不同記憶類型的生命周期差異很大不能一視同仁。會話內(nèi)的短時記憶只在當(dāng)前對話中有效對話結(jié)束就可以清理最多保留到用戶關(guān)閉頁面后十分鐘。用戶畫像層的記憶則需要長期保存通常情況下只增不刪除非用戶主動修改或要求清除。情景記憶和語義記憶處于中間狀態(tài)需要做時間衰減和定期歸檔。生命周期管理的核心是防止兩件事一是記憶無限膨脹導(dǎo)致召回時噪聲變大二是陳舊記憶誤導(dǎo)模型比如用戶兩年前喜歡某個品牌現(xiàn)在可能早就換口味了。我們的處理方式是給每條記憶打上時間戳和置信度字段召回時按時間衰減系數(shù)做加權(quán)同時后臺跑定期任務(wù)把超過半年的低置信度記憶降級超過一年且從未被命中的記憶直接歸檔。表格里可以看到我們對四類記憶的生命周期約定記憶類型存儲介質(zhì)默認(rèn)保存時長更新策略召回優(yōu)先級短時工作記憶緩存庫會話結(jié)束 10分鐘每輪對話全量覆蓋最高長期情景記憶向量庫180天事件抽取后追加中語義知識記憶向量庫/知識掛載持久定期同步外部知識低用戶畫像記憶關(guān)系庫持久顯式確認(rèn)后更新高這套生命周期管理規(guī)則上線之后最直觀的變化是召回精度的穩(wěn)定性變好了。之前出現(xiàn)過用戶上一秒說“想去重慶”下一秒智能體突然引用他半年前說過的“不喜歡火鍋”嚴(yán)重割裂。加了時間加權(quán)后近期的記憶天然占更大權(quán)重這種跨時空打架的情況明顯減少。3. 核心細(xì)節(jié)解析從用戶畫像到記憶槽位設(shè)計3.1 用戶畫像字段設(shè)計與標(biāo)簽體系用戶畫像不是簡單堆字段而是要具備可擴展性。我們把畫像表設(shè)計成三塊基礎(chǔ)屬性、動態(tài)偏好、行為統(tǒng)計。基礎(chǔ)屬性包括稱呼、所在城市、年齡范圍等這類信息通常由用戶主動提供或?qū)υ捴酗@式說出。動態(tài)偏好包括飲食口味、溝通風(fēng)格、興趣話題、常用時間段等這類信息會隨著對話持續(xù)更新。行為統(tǒng)計則記錄統(tǒng)計類的指標(biāo)比如最近七天對話次數(shù)、平均對話輪數(shù)、主動點擊次數(shù)。畫像字段里我們特別設(shè)計了一個“標(biāo)簽來源”字段記錄每個標(biāo)簽是被用戶明確說出來的還是被系統(tǒng)推斷出來的。比如用戶直接說“我不吃香菜”這就是顯式標(biāo)簽置信度直接拉滿如果是通過用戶多次提到“香菜好難吃”推斷出來的就是隱式標(biāo)簽置信度低一些。這個設(shè)計非常關(guān)鍵因為在后續(xù)的記憶更新沖突中我們要靠置信度來決定聽誰的。JSON示例可以這樣表示{ user_id: u_10001, base_info: { nickname: A同學(xué), city: 杭州, age_range: 25-30 }, preferences: [ { tag: 飲食偏好:清淡, source: explicit, confidence: 0.95, updated_at: 2025-06-01 20:13:00 }, { tag: 溝通風(fēng)格:喜歡短答案, source: inferred, confidence: 0.72, updated_at: 2025-05-30 09:12:00 } ], behavior_stats: { recent_days_active: 12, avg_dialogue_rounds: 6.5, preferred_hour: 22:00-23:00 } }3.2 記憶寫入策略什么時候記、怎么記、記多少記憶寫入是整個系統(tǒng)里最需要克制的地方。我們的經(jīng)驗是寧缺毋濫。寫入過多低質(zhì)量的記憶會讓系統(tǒng)變得“自作聰明”甚至產(chǎn)生錯誤的個性化。寫入時機主要看三類信號。第一類是用戶顯式表達(dá)比如“我喜歡”“我不吃”“我住在”這類明確句這是最高優(yōu)級的寫入信號。第二類是重復(fù)行為同一個偏好在多輪對話或多次會話中反復(fù)出現(xiàn)系統(tǒng)可以自動打上隱式標(biāo)簽。第三類是外部行為反饋比如用戶對某類推薦頻繁點擊或者對某類回答頻繁點踩這些行為也能反映偏好。記多少的問題同樣值得琢磨。我們嘗試過把用戶原話完整存進向量庫后來發(fā)現(xiàn)效率極低且原話里的情緒化表達(dá)會干擾語義檢索。最終方案是讓大模型先做一次結(jié)構(gòu)化抽取每條記憶只保留“主體 屬性 偏好對象 時間上下文”的格式比如“用戶不喜歡吃香菜”而不是“我記得用戶上次吃飯的時候說香菜好難吃”。這樣做至少帶來兩個好處一是記憶片段更干凈向量檢索的語義距離更準(zhǔn)確二是后續(xù)做用戶可讀的記憶管理界面時可以直接把這些結(jié)構(gòu)化描述展示給用戶體驗更友好。提示記憶寫入要做冪等控制同一個標(biāo)簽如果已經(jīng)被寫入再次寫入時不要生成新記錄而是更新原記錄的置信度和時間戳否則畫像表很快就會堆滿重復(fù)數(shù)據(jù)。3.3 記憶召回相似度計算與閾值調(diào)優(yōu)召回模塊直接決定了記憶能不能被“用起來”。我們采用的是多路召回策略每一路單獨輸出一批候選再做融合排序。第一路是根據(jù)用戶當(dāng)前問題文本向量與向量庫中的記憶片段算相似度找語義上最接近的記憶。第二路是直接拉取當(dāng)前用戶的畫像標(biāo)簽把置信度高的畫像記錄全量取出。第三路是查最近幾輪會話的短時上下文。第四路是可選的根據(jù)當(dāng)前場景和時間段做規(guī)則召回比如用戶在晚間提問就把“晚間提問偏好”這一維度的記憶優(yōu)先提出來。多路召回的難點在融合排序。不同路的打分口徑不一樣不能直接相加。我們的做法是給每一路設(shè)一個基礎(chǔ)權(quán)重再用時間衰減因子加權(quán)。時間衰減采用指數(shù)衰減公式最終權(quán)重 基礎(chǔ)權(quán)重 × exp(-λ × 天數(shù)間隔)。λ取值我們調(diào)到0.02表示一條記憶經(jīng)過35天權(quán)重會衰減到原來的一半。這個參數(shù)可以根據(jù)產(chǎn)品節(jié)奏調(diào)整如果用戶活躍周期是周級λ可以適當(dāng)調(diào)大。閾值也不是拍腦袋定的。我們先拿了一批人工標(biāo)注的測試數(shù)據(jù)跑索引方式下的相似度分布發(fā)現(xiàn)相關(guān)記憶的相似度集中在0.78以上不相關(guān)記憶大多在0.65以下。所以初始閾值設(shè)為0.76然后再根據(jù)線上召回日志微調(diào)。調(diào)閾值的核心指標(biāo)是“召回命中率”也就是召回來的記憶里有多少條真正對回答有幫助。如果命中率低于40%說明閾值偏低或排序有問題需要收緊。3.4 個性化生成提示詞組裝與沖突消解召回的最終目的是給大模型提供一份干凈的“記憶簡報”。我們在提示詞組裝上迭代過很多版本總結(jié)出一個比較穩(wěn)的思路system提示詞中先固定角色人設(shè)然后放“用戶畫像”接著放“近期重要記憶”最后放“當(dāng)前會話上下文”。畫像是高置信度標(biāo)簽語氣肯定近期記憶用“據(jù)用戶最近提到”這類弱表述避免模型把過期信息當(dāng)硬事實。示例模板大致如下【角色設(shè)定】 你是“小度想想”一位溫暖、細(xì)心的個人智能助手。 【用戶畫像】 用戶偏好清淡飲食喜歡200字以內(nèi)的短答案常在工作日晚十點后提問。 【近期記憶】 用戶在本周二提到周末想爬山用戶在上次對話中反饋不喜歡氛圍嘈雜的餐廳。 【當(dāng)前上下文】 用戶現(xiàn)在問這周六有什么合適的戶外活動推薦注意這里的措辭控制。如果記憶置信度偏低我們在生成提示詞時會把“用戶偏好清淡飲食”改成“用戶近期似乎比較關(guān)注清淡飲食”給模型留出懷疑和追問的空間。這個細(xì)節(jié)很重要它避免了模型過度自信地依據(jù)錯誤記憶生成答案。沖突消解是另一個大坑。最典型的情況是用戶今天說“我要開始吃辣了”但歷史畫像里還寫著“不吃辣”。我們的策略是當(dāng)用戶在當(dāng)前對話中給出了與畫像相反的信息時以當(dāng)前對話為準(zhǔn)同時把畫像標(biāo)簽的置信度降低并且更新為“近期偏好可能改變”。但更新不是立刻覆蓋而是進入一個“待確認(rèn)”狀態(tài)只有當(dāng)下一次對話再次驗證后才算徹底覆蓋。這樣設(shè)計是為了防止用戶只是隨口說了句違背習(xí)慣的話系統(tǒng)就永久修改畫像反而矯枉過正。4. 實操過程與核心環(huán)節(jié)實現(xiàn)4.1 環(huán)境準(zhǔn)備與工程目錄設(shè)計這套記憶系統(tǒng)我們用的是Python實現(xiàn)依賴并不多。下面是基礎(chǔ)的環(huán)境清單主要用到關(guān)系型數(shù)據(jù)庫做畫像存儲、向量索引庫做記憶片段檢索以及一個嵌入式向量構(gòu)建模塊。如果你想快速復(fù)現(xiàn)建議先把基礎(chǔ)環(huán)境跑通pip install numpy sqlalchemy redis工程目錄我們按功能模塊拆分核心就三個文件畫像存儲模塊、向量召回模塊、記憶組裝模塊。后期維護起來非常方便每個新同學(xué)接手后基本一天能看懂結(jié)構(gòu)。目錄設(shè)計如下memory_system/ ├── profile_store.py # 用戶畫像讀寫與沖突更新 ├── vector_memory.py # 記憶向量化、寫入、召回 ├── memory_composer.py # 提示詞組裝與記憶簡報生成 ├── tests/ # 單元測試與回歸用例 └── config.py # 閾值、衰減系數(shù)等全局配置4.2 畫像存儲與記憶管理核心代碼實現(xiàn)先說畫像存儲模塊。這一層最核心的是寫入時要判斷該更新還是該新建我們用一個簡單的按標(biāo)簽名查重再更新的邏輯實現(xiàn)。核心代碼如下class ProfileStore: def __init__(self, db_connection): self.conn db_connection def upsert_tag(self, user_id, tag, source, confidence): sql SELECT id, confidence FROM user_tags WHERE user_id? AND tag? row self.conn.execute(sql, (user_id, tag)).fetchone() if row: new_conf max(confidence, row[confidence] * 0.9) update_sql (UPDATE user_tags SET confidence?, updated_atCURRENT_TIMESTAMP WHERE id?) self.conn.execute(update_sql, (new_conf, row[id])) else: insert_sql (INSERT INTO user_tags(user_id, tag, source, confidence, created_at) VALUES(?, ?, ?, ?, CURRENT_TIMESTAMP)) self.conn.execute(insert_sql, (user_id, tag, source, confidence)) self.conn.commit()這個實現(xiàn)里有一個小細(xì)節(jié)對于已存在的標(biāo)簽新置信度不是直接替換而是取原先置信度的九折和當(dāng)前置信度之間的較大值。這么寫是為了防止某次誤判導(dǎo)致標(biāo)簽被瞬間拉得過高給系統(tǒng)留一點“猶豫空間”。記憶向量模塊就更直接了。寫入時把文本丟給Embedding模型轉(zhuǎn)成向量隨向量一起存上原文、類型和時間戳召回時用當(dāng)前query向量去索引里做相似度搜索。核心代碼片段如下class VectorMemory: def __init__(self, index, embed_func, top_k5): self.index index self.embed embed_func self.top_k top_k def add_memory(self, memory_id, text, memory_type): vec self.embed(text) metadata {id: memory_id, text: text, type: memory_type} self.index.upsert(memory_id, vec, metadata) def recall(self, query_text, user_idNone, top_kNone): k top_k or self.top_k query_vec self.embed(query_text) hits self.index.query(query_vec, kk) return [{text: h.metadata[text], score: h.score, type: h.metadata[type]} for h in hits]這里我刻意沒有綁定具體向量庫的API因為不同方案接口差異不大。實際工程里你需要把index.upsert和index.query替換成所用庫對應(yīng)的方法即可。4.3 完整示例模擬一次“千人千面”的對話做一個完整的走查。假設(shè)用戶A同學(xué)第一次使用“小度想想”在周二晚上說了句“周末想去人少一點的山里走走”。采集層識別到“人少”“山里”“周末”三個關(guān)鍵偏好寫入情景記憶同時把“偏好安靜的自然環(huán)境”作為隱式畫像標(biāo)簽置信度設(shè)為0.6。第二天用戶再問“這周六有什么推薦的地方嗎”系統(tǒng)進入召回流程第一步把用戶問題向量化在向量庫里做語義檢索召回“周末想去人少一點的山里走走”這條記憶相似度約0.83超過了我們設(shè)定的0.76閾值。 第二步從畫像表拉取用戶標(biāo)簽看到“偏好安靜的自然環(huán)境”和“喜歡短答案”。 第三步組裝記憶簡報得到類似下面的文本用戶畫像喜歡安靜的自然環(huán)境答案偏好簡潔。 近期記憶用戶提到周末想去人少一點的山里走走。 生成要求請圍繞江浙滬周邊、人少、適合徒步的景點給出推薦控制在150字以內(nèi)。模型依據(jù)這段簡報生成答案給出的推薦自然就避開了熱門景區(qū)而傾向那些徒步路線相對冷門、風(fēng)景更自然的地點。用戶如果覺得推薦滿意點了贊這個點贊行為又會作為信號反饋給采集層再次提高“偏好安靜的自然環(huán)境”這個標(biāo)簽的置信度。這條閉環(huán)跑通之后產(chǎn)品就具備了一個最基礎(chǔ)的“越用越懂你”能力。4.4 效果評估別只盯著模型指標(biāo)記憶系統(tǒng)上線后怎么評估效果我們分成了離線指標(biāo)和在線指標(biāo)兩部分。離線階段跑了三組測試召回命中率、記憶標(biāo)簽準(zhǔn)確率、上下文沖突率。召回命中率看的是召回片段和當(dāng)前問題是否相關(guān)標(biāo)簽準(zhǔn)確率靠人工抽檢來打標(biāo)上下文沖突率是看提示詞里是否出現(xiàn)互相矛盾的信息。這三項在開發(fā)階段用回歸測試集持續(xù)盯著就夠用。在線階段則更關(guān)注業(yè)務(wù)指標(biāo)。我們重點看了四個用戶次日留存、平均對話輪數(shù)、回答采納率、差評率。記憶系統(tǒng)的上線會讓對話輪數(shù)和使用時長明顯上升如果一段時間內(nèi)這些指標(biāo)沒有變化說明記憶沒有形成正向體驗。還有一類比較隱蔽的評估方式是“可解釋性回訪”隨機抽選用戶對照他們的記憶畫像讓用戶自己判斷畫像準(zhǔn)不準(zhǔn)。我們做了一輪訪談發(fā)現(xiàn)用戶對于“智能體記得我上次說過什么”的正面感知特別強烈哪怕只對了一條也會提升對整個產(chǎn)品的信任。這比任何算法指標(biāo)都更能說明問題。5. 常見問題與排查技巧實錄5.1 記憶污染聊錯一次永久帶偏記憶污染是我們上線后遇到最頭疼的問題。典型癥狀是用戶某次閑聊時隨口說了句氣話“我再也不喝咖啡了”系統(tǒng)立刻把“不喝咖啡”寫入畫像之后半個月的推薦全都避開咖啡用戶無奈地說“我不是那個意思啊”。排查下來發(fā)現(xiàn)根因是寫入策略太激進把低置信度的情緒化表達(dá)直接當(dāng)成了偏好。解決方案從三個層面入手。第一層在采集層加情緒識別帶有明顯負(fù)面情緒的句子不直接入畫像只進情景記憶存檔。第二層對隱式標(biāo)簽設(shè)置“冷靜期”新標(biāo)簽先以低置信度寫入至少需要在三天內(nèi)的兩次對話中重復(fù)出現(xiàn)才會升級為正式標(biāo)簽。第三層提供用戶可見的“記憶管理面板”讓用戶能直接對每條記憶做刪除和修改。這個過程在智能體產(chǎn)品里不是額外功能而是必須項因為自動記憶一定會犯錯要給用戶一個糾錯的出口。5.2 上下文爆炸長對話下的記憶裁剪記憶系統(tǒng)上線后另一個高頻問題是上下文長度。用戶的記憶越積越多提示詞里的記憶簡報越拼越長最終吃掉大量上下文配額甚至影響模型響應(yīng)速度。我們遇到一個極端案例某位高頻用戶對話三個月后畫像標(biāo)簽和記憶片段加起來接近8000字每次請求的延遲都比其他人高出近一倍。解決思路是給記憶簡報設(shè)“總字?jǐn)?shù)值”通常控制在600字以內(nèi)。超出的部分通過優(yōu)先級截斷先保留高置信度畫像再保留近期記憶最后才放中長期的情景記憶。與此同時后臺做一個記憶摘要任務(wù)把三個月前的事件摘要合并壓縮成一條全局摘要只保留“發(fā)生了什么、結(jié)果如何、涉及什么偏好”三要素。這個處理在實踐里非常管用記憶簡報的平均長度從1500字降到了500字左右模型生成質(zhì)量和響應(yīng)速度雙雙提升屬于少見的“減法優(yōu)化”。5.3 冷啟動與召回不準(zhǔn)數(shù)據(jù)稀疏怎么辦新用戶沒有任何畫像和情景記憶時記憶系統(tǒng)基本是空轉(zhuǎn)的這個問題叫冷啟動。我們嘗試的方案有兩個。第一是在第一次交互時主動提問采集信息但不是生硬地讓用戶填問卷而是把問題融進對話里比如用戶問天氣時順手問一句“您在南方還是北方換季的時候我會留意提醒您”。第二是為新用戶加載一套“通用常識包”把城市信息、季節(jié)信息、常見場景模板掛載到記憶上下文里雖然不是個性化內(nèi)容但至少能讓首輪回答不那么空洞。召回不準(zhǔn)的問題更多出現(xiàn)在向量索引的調(diào)參不當(dāng)。我們踩過的典型坑是文本長度差異太大造成的匹配偏差。長文本向量和短文本向量如果不做長度截斷或歸一化語義距離的計算結(jié)果會偏向長度相近的文本而不是含義相近的文本。解決方法是寫入前把所有記憶片段做長度歸一化統(tǒng)一截成256字符以內(nèi)的摘要再進行向量化。這個改動看似不起眼卻讓召回命中率提升了差不多十個百分點。5.4 隱私與合規(guī)底線哪些記憶不能碰記憶系統(tǒng)天然會觸碰個人信息這是逃不開的課題。我們的原則是能少存就少存能脫敏就脫敏能給用戶控制權(quán)就給控制權(quán)。身份證號、銀行卡、詳細(xì)住址這類強敏感信息一律不寫入記憶甚至在采集層就要做識別攔截。健康信息、政務(wù)信息等敏感類別只在用戶主動提供且明確授權(quán)時才允許進入情景記憶并且使用時只保留必要描述不保留原始隱私細(xì)節(jié)。我們還在產(chǎn)品里加入了“記憶透明度”設(shè)計。用戶在對話中隨時可以問智能體“你記得關(guān)于我的哪些信息”系統(tǒng)會把已存儲的記憶清單以通俗語言展示出來。用戶也可以一鍵清空某類記憶或全部記憶。這個設(shè)計雖然不能帶來直接的業(yè)務(wù)指標(biāo)但對用戶信任度和合規(guī)風(fēng)險控制的價值非常大。很多從業(yè)者會忽略這一點我強烈建議把記憶可視化放到需求優(yōu)先級前列。一個連自己記住了什么都不愿意展示給用戶的智能體很難真正獲得用戶信賴。結(jié)尾最后再分享一點個人體會。在做“小度想想”這套記憶系統(tǒng)之前我一直以為最難的是算法和存儲架構(gòu)真正落地之后才發(fā)現(xiàn)難點其實是“克制”??酥茖懭?、克制召回數(shù)量、克制對用戶隱私的過度挖掘每一條克制都在為更好的長期體驗讓路。我們曾經(jīng)因為召回命中率不夠高而盲目加規(guī)則結(jié)果系統(tǒng)變得格外“自以為是”后來砍掉一半規(guī)則效果反而好了。所以給正在做類似項目的朋友一個建議先搭一個最簡單的“畫像 情景記憶”的閉環(huán)跑通核心體驗再逐步加復(fù)雜策略。另外一個小技巧給每一類記憶都留一個“用戶可解釋入口”用戶能看見的系統(tǒng)才更可信。這個領(lǐng)域還在快速演進今天單條記憶的存取邏輯說不定未來就會變成智能體之間協(xié)作的通用語言。