訪客直接打「幫我查一下」時發生了什麼
手打一句請求,應該和從選單裡點同一項得到一樣的結果。用詞表做這件事,七種語言裡必然漏;每則訊息都問一次模型,又慢又貴。我們量到了什麼、為什麼路由分成兩步,以及為什麼同一句話在文件開著時會走到另一條路上。
輸入框旁邊那個 + 是能力選單:深入查一下、幫我寫一份文件、轉真人。絕大多數人從來不點開它,他們直接把請求打出來——"research it"、「查查看」、"もっと深く調べて"。如果手打和點選單得到的結果不一樣,這個選單就成了擺設。
所以平台會把手打的訊息路由到同樣的能力上。這一頁講它怎麼做到——因為兩種最直覺的做法都不成立,而這兩次失敗值得在你動手做類似的東西之前先知道。
詞表為什麼會輸
一份觸發詞清單,要在你支援的每一種語言裡都寫對,還要扛得住人真正打字的樣子:
reserach it please——拼錯了,詞表一條都對不上。- 「研究一下唄」——一種沒人想到要加進去的說法。
go deeper on that one——清單裡的詞一個都沒出現。
你可以一直往裡加。你做不到的是加完。每多一種語言,清單就翻一倍,而漏掉的那些是無聲的:訪客打了一句請求,得到一個普通回答,他沒有任何辦法知道原本有個功能能接住這件事。
每則訊息都問模型,一樣會輸
另一個直覺做法——每則訊息都問一次小模型「這個人是不是在觸發某項能力」——準確度夠,但它把一次模型呼叫擺在了每一則訊息前面,包括那些擺明只是普通提問的絕大多數。那是訪客感覺得到的延遲,也是你在答案本來就沒有懸念的訊息上白花的錢。
兩步:便宜的一步守門,準的一步定奪
路由器是嵌入守門 + 模型定奪。
第一步,嵌入。 每項能力有幾條錨點短語;另有一份共用的反例錨點——語意上離觸發語很近的日常回話。訊息同時和兩邊比。嵌入模型是多語的,所以一套錨點管七種語言:「深入查一下」和 research it 落在同一片空間裡。哪邊都不像,路由就到此為止,一次模型呼叫都不花。
第二步,模型。 像是在按按鈕,就讓一個小模型在候選裡挑一項,或者說都不是。
順序是要緊的,而且和我們最初試的那版正好相反。嵌入擅長回答「這句話像不像一個請求」,不擅長回答「這個人是要用這項能力,還是在問這項能力」——How does your deep research feature work? 和一句真的觸發語長得一模一樣。而後面這件事恰恰是模型擅長的。所以便宜的那一步守門,準的那一步定奪。
反例錨點是做什麼用的
光有正例錨點分不開 tell me more 和 dig deeper——它們在語意上本來就近。分開它們靠的是讓 tell me more 也待在反例集裡,於是最近鄰是一句日常回話而不是一條觸發語。有兩類反例是在實測翻車之後才補進去的:
| 這一類 | 例子 | 少了它會怎樣 |
|---|---|---|
| 短追問 | and in Tokyo? | 被判成深入查 |
| 問一個陌生的專名 | what is ANVISA | 被讀成「去查這個詞」 |
| 同話題的長提問 | 「我這個產品在當地屬於哪一類」 | 直接開工寫了一份沒人要的文件 |
| 「把剛才那段整理一下」 | 「把剛才說的整理一下寄給我」 | 被讀成「寫一份新文件」 |
第三條最說明問題。寫一份文件 那一項的錨點必須是長句(短錨點對長請求的相似度太低),而只要是長句,它就不可避免地帶上這個代理程式的話題;於是一句同話題的長提問會順著話題爬上去——實測到過 0.711,比真正在要一份文件的句子還高。
數字
在 110 條獨立寫出來的樣本上量的(60 條該觸發、50 條不該),七種語言,說法故意寫得和錨點不一樣:
| 路由做法 | 正確率 |
|---|---|
| 只用嵌入 | 84.5% |
| 嵌入守門 + 模型定奪 | 95.5% |
守門的門檻不是挑出來的,是拿同一批樣本逐檔掃出來的:
| 守門門檻 | 模型呼叫次數 | 認出的真請求(共 60) | 誤觸發(共 50) |
|---|---|---|---|
| 0.00 | 110 | 60 | 9 |
| 0.45 | 100 | 60 | 7 |
| 0.55 | 88 | 60 | 5 |
| 0.60 | 77 | 59 | 4 |
| 0.70 | 71 | 59 | 3 |
0.55 是「一條真請求都還沒丟」的最後一檔。再往上,每擋掉一個誤觸發就要賠一條真請求——而在這個樣本量下,一兩條的差是雜訊,我們不拿召回去換雜訊。
同一句話,兩種意思
「再加一節講巴西的路徑。」
沒有文件開著時,這是在要你寫點東西。右邊開著一份文件時,這是在改那一份。同樣的字,兩種答案——而判錯的代價比看上去大:一位正在改報告的訪客說了「加一節」,結果被建出了另一份新文件。
第一版的修法是加一條規矩——文件開著時,永遠不路由到寫文件。bug 是止住了,同時也弄壞了另一件事:真想再要一份新文件的人,從此說不出口了。第二條規矩(畫圖請求必須字面上帶「圖」字)形狀一樣,代價也一樣:它認不出「這幾個數字換個樣子看看」。
規矩疊規矩,說明做判斷的不是該做判斷的那個元件。現在語境進了定奪那一步——模型被告知有一份文件開著,並且多拿到一個選項:改這一份。它什麼都不路由,因為改文件的那組工具本來就掛在這一輪上,它們才是做這件事的。兩個原來的 bug 仍然是修好的,兩件被誤傷的真請求也回來了。
有一處不對稱是刻意的:模型不可用、路由只能退回嵌入猜測時,文件開著的門檻更高。那邊判錯一次是整輪被劫持——正在討論 21 天審查窗口的訪客,收到的是一句「我沒辦法為 21 天審查窗口畫一張圖」;而同樣的錯在普通對話裡,最多多出一張沒人要的圖。
這對你的代理程式意味著什麼
- 只有上了選單的能力才能被手打觸發。 你沒開深入查,訪客說了也只會得到一個普通回答,而不是一項你沒買的功能。
- 觸發詞不用你寫。 沒有租戶級的關鍵詞清單要維護,任何語言都沒有。
- 一個需要受詞、而這句話裡又沒有的請求,會以「填回輸入框」的形式回來,而不是替你猜一個。有人打了一句「研究一下唄」,題目會被填進輸入框裡,他送出前可以改——猜錯的代價從白等一分鐘降到改兩個字。