← 共識引擎

第 2 章:第 2 章

哲維決定先按照正常流程走。

他是個外包工程師,不是偵探。他的工作是修 bug,不是調查陰謀。如果決策迴圈是推薦權重衰減造成的,那他找到衰減的來源、修正參數、提交修復,結案。

他花了兩天做這件事。

第一步,檢查推薦引擎 7.2 持續整合模組的權重更新邏輯。理論上,每次新數據進來,推薦權重應該根據使用者的最新行為重新計算,確保推薦結果跟得上使用者的偏好變化。如果權重更新出了問題——比如更新頻率太低、或者衰減函數的參數設錯——就會造成 filter bubble。

他看了程式碼。權重更新的邏輯沒有問題。衰減函數的參數也在正常範圍內。

第二步,檢查這些「迴圈」使用者的推薦輸出日誌。如果權重沒有正常更新,那他們收到的推薦排序應該會逐漸固定。他看了日誌——推薦排序有在變,但使用者選擇的排序位置沒有跟著變。

這不是 filter bubble。Filter bubble 是推薦變窄導致使用者選擇變窄。這裡的推薦沒有變窄,是使用者自己固定了選擇。

他坐在螢幕前,把這個結論寫在備忘錄裡。然後他盯著那行字看了很久。

如果推薦沒有變窄,但使用者選擇了固定——那代表使用者的決策在某個時間點被「鎖定」了。不是被推薦系統被動收窄的,是被某種機制主動固定住的。

他需要看更多的數據。

他打開了推薦引擎的 A/B 測試框架。和盟的每一個功能上線前都會跑 A/B test,把使用者隨機分成對照組和實驗組,比較數據差異。如果決策迴圈是某個 A/B test 的副作用,那測試框架裡應該有紀錄。

他搜尋了過去三個月內所有跟「推薦排序」「權重」「決策路徑」相關的測試項目。

找到了一個。

測試名稱:RD-7203-DPV。描述寫著「決策路徑驗證測試——增強型推薦一致性優化」。開始時間是八十二天前。狀態:進行中。

他點進去看測試配置。

實驗組佔比 0.3%。隨機抽樣。測試內容:對實驗組使用者施加「決策路徑微調」,目標是提升推薦接受率。

哲維把「決策路徑微調」這幾個字讀了三遍。

他繼續往下看。測試配置裡有一個參數表,其中一個欄位叫做「lock_threshold」——鎖定閾值。當使用者的決策一致性超過這個閾值時,系統會「維持當前推薦輸出」,不再根據新數據更新。

這就是決策迴圈。

不是 bug。是一個被設計出來的功能。當一個人做決定的規律性高到某個程度,系統就會停止更新推薦,讓他的選擇固定在現有模式裡。

他靠回椅背。

天花板上那條裂紋還在。

他繼續看。測試配置的最下面有一個核准紀錄。核准人是「S.W.」——蘇薇。核准日期是八十三天前。備註欄寫著:「B 級測試,影響範圍 0.3%,風險可控。」

哲維把視窗關上。

他現在知道這不是 bug 了。但他還不知道這個測試的目的是什麼。提升推薦接受率——這是配置裡寫的。但為什麼要鎖定使用者的決策?如果一個人已經固定選擇了,推薦接受率本來就高,不需要特別「優化」。

他打開了另一個數據視圖:RD-7203-DPV 實驗組的 KPI 追蹤。

數據很漂亮。實驗組的推薦接受率比對照組高出 12%。使用者停留時間增加 8%。轉換率提升 6%。

從產品的角度來看,這是一個成功的測試。

哲維把這些數據截圖存了下來。然後他做了一件他知道自己不應該做的事——他打開了數據庫的底層表格。

他的權限是「唯讀 access,log and metrics dashboard」。但和盟的權限管理有一個設計上的盲點:dashboard 的唯讀權限跟數據庫的唯讀權限是分開的。他之前在做其他案子的時候無意間發現,他的外包帳號可以直接查詢某些底層表格。

他查了使用者決策路徑的原始數據。

表格裡的欄位比 dashboard 看到的多了很多。除了基本的行為數據之外,還有「決策情境標記」——每一個決策被標記了場景類型:消費、資訊獲取、社交互動、路線選擇。

他過濾了實驗組的使用者,把他們的決策情境標記按照時間排序。

然後他看到了。

這些使用者的決策被標記了不只一種情境。消費、資訊、社交、路線——全部都有。而且不同情境的決策模式是連動的。一個在消費上出現迴圈的使用者,通常在同一個時間點,他的資訊獲取行為也開始固定了。

這不是在優化推薦。

這是在測試系統能在多大程度上,全面影響一個人的決策模式。

哲維把查詢關掉。他的手有一點冷。

房間裡很安靜。冰箱的嗡嗡聲、巷子裡不知道哪一戶的電視聲、他自己的呼吸。

他拿起手機。時間是凌晨三點四十分。

他打開備忘錄,打了一行字:「RD-7203-DPV 不是 bug。是 A/B test。測試內容:決策鎖定。影響範圍 0.3% 全球使用者。核准人:蘇薇。」

然後他加了一行:「我的程式碼被用在這個測試裡。三個月前提交的推薦權重優化模組,被整合進了 RD-7203-DPV 的決策路徑微調邏輯。」

他存檔。

他沒有把這些寫進要交給蘇薇的報告裡。

他蓋上筆電,躺在床上。天花板上那條裂紋在黑暗中看不清楚,但他知道它在哪裡。

他沒有睡著。

哲維第二天沒有打開那個數據 dashboard。

他接了另一個案子的小型電商搜尋功能,花了整個上午寫了一個基礎的全文搜尋架構。工作的时候他的腦子可以清空,只剩下邏輯和語法。這是他喜歡寫程式的原因之一——程式碼的世界是確定的,不是對就是錯,跑得動就跑得動,不會有灰色地帶。

中午他吃了一個便利商店的飯糰,站在店門口吃完的。陽光很大,他瞇著眼睛看巷子裡的人走過去。一個穿西裝的男人、一個推嬰兒車的媽媽、一個看起來跟他差不多大的女生背著筆電包走過去,腳步很快。

他回到房間,打開筆電。

他知道他應該繼續做那個電商搜尋的案子。但他打開了和盟的數據 dashboard。

他這次不是來看決策迴圈的。他來看自己的程式碼。

三個月前他接了一個和盟的外包案——推薦權重優化模組。合約上寫的功能是「優化推薦系統權重更新效率,減少計算冗餘」。他寫了一個模組,可以減少權重更新時的數據處理量,同時保持推薦品質。技術上不複雜,但需要跟和盟的推薦引擎核心整合。

他當時被告知這個模組會被用在「推薦引擎 7.1 的效能優化」上。

他現在要確認這件事。

他打開了和盟的程式碼倉庫——他的外包帳號有唯讀權限,可以看到他提交過的程式碼以及相關的 commit 記錄。他找到了三個月前的那次提交:commit hash 開頭是 a3f7c2,訊息寫著「推薦權重優化模組 v1.2 — 效率提升 23%」。

然後他看了這個 commit 被 merge 進哪些分支。

他被告知的是 merge 進 7.1 效能優化分支。但實際上,這個 commit 被 merge 進了三個分支:7.1 效能優化、7.2 持續整合模組、還有一個叫做「RD-experimental」的分支。

RD-experimental。

他沒有這個分支的讀取權限。

他盯著那個分支名稱看了很久。然後他打開了 commit 的詳細內容,看他寫的程式碼被怎麼修改過。

他提交的原始碼是純粹的權重更新效率優化——減少不必要的數據讀取、快取中間結果、平行化部分計算。但在 RD-experimental 分支裡,他的程式碼被加上了額外的邏輯。

有人在他的權重更新模組裡,插入了一個「決策一致性追蹤」的函數。這個函數會計算每個使用者的決策規律性,當規律性超過某個閾值時,觸發一個標記。

這個標記就是 RD-7203-DPV 測試的觸發條件。

他寫的程式碼——那個他以為只是在做效能優化的程式碼——被拿來當作決策鎖定的偵測器。

哲維把筆電推開了一點。

他想到一件事。他打開了合約附件裡的技術規格文件,找到他當時接的案子的工作範圍描述。上面寫著:「推薦權重優化模組,目標為提升推薦引擎 7.1 的權重更新效率。範圍:數據預處理層、快取層。不涉及推薦決策邏輯。」

不涉及推薦決策邏輯。

但有人把他的程式碼拿去改了,加上了決策追蹤的功能,然後用在他的外包合約沒有授權的測試裡。

他不知道這是誰做的。他只知道核准 RD-7203-DPV 的人是蘇薇。

他打開了 commit 記錄裡的修改者欄位。決策一致性追蹤函數的提交者是一個叫做「cyq_analyst」的內部帳號。

cyq。

他想到了一個名字。但他告訴自己想太多了。cyq 可以是任何人。和盟有幾千個員工。

他繼續看。cyq_analyst 的那次提交是在他的原始 commit 之後五天。提交訊息寫著:「在權重優化模組中整合決策路徑追蹤功能,供 RD-7203 測試使用。」

供 RD-7203 使用。

所以這不是偷用的。這是刻意整合的。有人——cyq_analyst——在他的程式碼裡加了功能,然後用在蘇薇核准的測試裡。

他需要知道 cyq_analyst 是誰。

他打開了和盟的內部通訊工具——他的外包帳號有基本的搜尋功能。他搜尋了「cyq_analyst」。

跳出來的是一個員工檔案。名字:陳若晴。職稱:數據分析師。部門:推薦引擎產品部。

哲維把通訊工具關掉了。

他坐在那裡,聽著冰箱的嗡嗡聲。窗外的陽光從早上六點就開始曬他的房間,現在已經移到了桌子的另一邊。

陳若晴。

他三個月前提交的那個模組,被陳若晴的團隊拿去改了,加上了決策追蹤功能,然後用在他不知道的測試裡。

他不確定她知不知道這個測試在做什麼。數據分析師的工作是分析數據,不是決定測試方向。但也許她知道。也許她參與了她被分配參與的一切。

他不知道。

他打開了跟若晴的對話視窗。最後一篇訊息停在四個月前。她問他最近好不好,他回了還好,她回了也不錯。

他的光標在對話框裡閃了很久。

他打了一行字:「你還在和盟嗎?」

然後他刪掉了。重新打:「我需要問你一件事。跟一個數據分析有關。」

刪掉了。

他不知道要怎麼問。他不知道她會不會回答。他不知道她站在哪一邊——如果真的有「邊」的話。

他把手機放下。

然後他做了一件事。他打開了數據庫,查詢了 cyq_analyst 在 RD-7203-DPV 測試中的所有操作記錄。

記錄顯示:陳若晴在八十三天前提交了決策追蹤函數的修改。在七十天前,她查詢過實驗組的決策路徑數據。在四十五天前,她跑了一份分析報告。在二十天前,她查詢過實驗組跟對照組的 KPI 比較。

她一直在追蹤這個測試。

哲維把這些記錄截圖存了下來。然後他做了一件更進一步的事——他查了陳若晴的部門架構。

她的直屬主管是推薦引擎產品部的總監。但 RD-7203-DPV 的核准人是蘇薇,蘇薇的部門是商務中心。兩個不同的部門。

這代表這個測試是跨部門的。蘇薇核准、陳若晴提供數據分析、哲維的程式碼被當作底層工具。

他們都是這個測試的一部分。

哲維把所有截圖整理好,存在一個加密的資料夾裡。然後他打開了要交給蘇薇的進度報告,寫了目前為止的「正常」發現:決策迴圈的成因是推薦權重更新邏輯的邊界條件問題,建議調整衰減函數參數。

他沒有提到 RD-7203-DPV。沒有提到決策鎖定。沒有提到陳若晴。

他把報告存檔,沒有寄出。

他需要想一下。

他關上筆電,躺在床上。天花板上那條裂紋在下午的陽光裡很清楚,像一條河流的分岔。

他想到若晴。想到她穿著整齊的衣服、說話有條理、問「為什麼」的時候是真的想知道為什麼。想到她相信系統可以被信任。

他不知道她知不知道她的名字出現在一個他沒有授權的測試裡。

他拿起手機,打開了對話視窗。

這一次他沒有刪掉。他打了一行字:「若晴,我需要跟你談一件事。不是私事。跟和盟的一個測試有關。」

他看了三遍,然後按了送出。

訊息變成已讀。

然後他等了很久。

若晴的回覆在二十分鐘後才來。

「什麼測試?」

哲維看著這三個字,想了一下要怎麼回。他不能把全部東西都寫在訊息裡——他不知道和盟有沒有監控外包工程師的通訊。他的 NDA 裡有一條是「不得透過未授權管道傳輸合作相關資訊」。

他回:「電話方便嗎?」

過了五分鐘,他的手機響了。

「喂。」若晴的聲音聽起來跟四個月前一樣。穩定、清晰、不疾不徐。

「你還在和盟?」他問。

「在。怎麼了?」

「你聽過 RD-7203-DPV 這個測試嗎?」

電話那頭安靜了兩秒。「你怎麼知道這個代號?」

「我在做和盟的外包案。推薦系統異常修復。排查的時候看到這個測試。」

「你的外包案怎麼會看到 RD-7203?那是內部測試,不在外包範圍內。」

「我知道。但數據是連動的。我追蹤異常的來源,追到了這個測試。」

若晴沒有說話。哲維聽到她那邊的鍵盤聲——她還在辦公室。

「你看到了什麼?」她問。

「決策迴圈。0.3% 的使用者出現高度一致的行為模式。測試配置裡有一個 lock_threshold 參數,當使用者的決策一致性超過這個值,系統就停止更新推薦。」

「那是決策路徑驗證測試。」若晴的語速比平常快了一點。「目的是提升推薦一致性。我們跑過風險評估,影響範圍可控——」

「若晴。」他打斷她。「這不是推薦一致性優化。這是決策鎖定。」

電話那頭又安靜了。

「你在說什麼?」

「我在說,這個測試在測試系統能不能讓一個人在不知不覺中,反覆做同一個決定。不只是消費。我看了數據——交通路線、資訊獲取、社交互動,全部都有。這不是推薦優化,這是行為操控。」

「哲維,你聽起來——」

「我知道我聽起來怎樣。但數據不會說謊。妳自己跑過這個測試的分析,妳看到了什麼?」

若晴沉默了很久。哲維聽到她那邊有人走過去的聲音、門關上的聲音。

「我看到的是推薦接受率提升 12%。」她最後說。「使用者停留時間增加。轉換率提升。從產品角度來看,這是一個成功的測試。」

「妳沒有覺得不對嗎?」

「什麼不對?」

「0.3% 的使用者,他們的決策被系統鎖定了。他們以為自己在選擇,其實他們的選擇是被設計過的。妳沒有覺得這有問題嗎?」

「他們還是有選擇權的。」若晴的聲音變低了,但還是穩定的。「系統沒有強迫他們做任何事。它只是⋯⋯優化了推薦輸出,讓他們的體驗更順暢。」

「優化到讓他們每天做同一個決定?」

「哲維,你現在在做的是一個 B 級外包案。你的工作是修復推薦系統的異常,不是調查內部測試。RD-7203 是經過核准的測試,風險評估也通過了。如果你在排查過程中看到了超出你工作範圍的東西,你應該聯絡你的聯絡人,而不是來問我。」

「妳的團隊在我的程式碼裡加了東西。」

這句話說出來之後,電話那頭完全安靜了。

「什麼?」

「三個月前我提交的那個推薦權重優化模組。妳的團隊——cyq_analyst——在我的程式碼裡加了決策追蹤函數。然後用在那個測試裡。我的合約範圍是效能優化,不涉及推薦決策邏輯。」

若晴沒有說話。

「妳知道這件事嗎?」他問。

「⋯⋯我知道你的模組被整合進了 7.2。」她的聲音變了。不是不穩,是變得更小心了。「但我不清楚 RD-7203 的具體整合細節。那個測試的核准流程是蘇薇那邊負責的。」

「但決策追蹤函數是妳的團隊加的。」

「我需要查一下。」

「好。」

電話兩端都安靜了。哲維聽到自己房間裡冰箱的嗡嗡聲。若晴那邊的辦公室背景音很遠,像隔了一層玻璃。

「哲維。」她最後說。「你把這個留在你的外包案裡。不要繼續挖了。」

「為什麼?」

「因為這不是你的範圍。而且——」她停了一下。「和盟的 NDA 裡有保密條款。如果你把內部測試的細節外洩,他們可以告你。」

「我沒有要外洩。我只是——」

「只是什麼?你只是一個外包工程師。你修你的 bug,交你的報告,收你的錢。這不是你的事情。」

這句話很理性。完全理性。理性到哲維不知道怎麼反駁。

「好。」他說。

「你答應我?」

「我說好。」

若晴掛了電話。

哲維把手機放在床上,看著天花板。

他沒有答應任何事。他只是說好。


隔天下午,蘇薇打來了。

不是視訊,是語音通話。哲維接起來的時候,她的聲音聽起來跟之前一樣——專業、不浪費時間。

「哲維,我收到你的初步分析報告了。」

他沒有寄出任何報告。但他之前存了一份草稿,內容是「正常」版本的發現。他不知道蘇薇是怎麼收到的——也許是他存檔的時候系統自動同步了。

「你說決策迴圈是權重衰減的邊界條件問題。」蘇薇說。「這個結論跟內部初步分析一致。你那邊有建議的修復方案嗎?」

「還在調。」他說。「需要再看一些數據。」

「好。但我想先跟你確認一件事。」她的語氣沒有變,但內容變了。「你在排查過程中,有沒有接觸到 RD-7203-DPV 的相關數據?」

哲維握著手機的手緊了一下。

「有。」他說。「異常的來源追蹤到了這個測試。」

「RD-7203 是內部測試,不在你的外包範圍內。」

「我知道。但數據是連動的。我不看這個測試的數據,沒辦法確認異常的成因。」

蘇薇沉默了兩秒。「我理解。但我想提醒你,你的外包合約附件三第二條,合作過程中接觸到的未公開產品資訊,屬於保密範圍。包括內部測試的詳細內容。」

「我沒有要把任何東西外洩。」

「我相信你。」她說。但她的語氣聽起來不像是在相信他,像是在記錄她說過這句話。「我只是想確保我們在同一頁上。你的工作是修復決策迴圈的異常。RD-7203 的細節不是你需要關心的。」

「好。」

「那我們保持聯絡。修復方案確定了隨時告訴我。」

她掛了電話。

哲維把手機放下,看著螢幕。

他想到蘇薇說的「同一頁上」。他想到若晴說的「這不是你的事情」。他想到合約附件三第二條。

他們都在說同一件事:閉嘴,修你的 bug,收你的錢。

他打開了那個加密資料夾,看著裡面的截圖。RD-7203 的測試配置、決策鎖定的數據、陳若晴的操作記錄、他自己的程式碼被修改的 commit 歷史。

他想到天花板上那條裂紋。

他想到巷子裡那個壞掉的招牌,「米七」。

他想到若晴最後說的那句話:「你只是一個外包工程師。」

他確實只是一個外包工程師。

他把資料夾關上,打開了電商搜尋功能的案子,繼續寫程式碼。

那天晚上他沒有打開和盟的任何東西。他寫電商搜尋的程式碼寫到凌晨一點,然後去廚房煮了一碗泡麵。站在陽台旁邊吃的時候,他看了一眼巷子。雜貨店的招牌亮著,還是「米七」。

他回到房間,躺在床上,沒有蓋被子。六月的台北已經很熱了,但他覺得有點冷。

他拿起手機,看到若晴在十分鐘前傳來一則訊息。

「我查了。cyq_analyst 是我。決策追蹤函數是我加的。但當時被告知的用途是推薦一致性分析,不是決策鎖定。我不知道它被用在 RD-7203 的 lock_threshold 邏輯裡。」

哲維看了三遍。

他回:「妳現在知道了。」

若晴已讀了很久,沒有回覆。

哲維把手機翻身放在床上,看著天花板。

那條裂紋在黑暗中看不清楚。但他知道它在哪裡。

7323 字 •