令長時間嘅代理回合保持喺上下文視窗之內
模型一次只能讀取有限嘅內容,即係佢嘅上下文視窗。Mythex 嘅代理會做長時間嘅工作:讀取大量檔案、執行指令、將有界限嘅工作交俾子代理。我哋發現長時間工作有三種出錯方式:子代理不斷增長,直到模型拒絕每一個請求;子代理以為自己冇位,所以提早停止;而我哋嘅 token 計算方法,對俄文、中文同日文嚟講錯得好離譜。以下係我哋改動嘅內容。
先講幾個術語
- Token 係模型讀取嘅細件。限制同費用都係以 token 計算,唔係字元或字詞。
- 上下文視窗係模型一次請求最多能夠讀取嘅量。我哋亦會為每次請求設定自己更低嘅預算,令成本同速度維持合理。
- 工具結果係代理從工具取回嘅內容:佢讀取嘅檔案內容,或者佢執行指令嘅輸出。喺長時間工作入面,佢哋佔咗大部分被傳送嘅內容。
- 子代理係主代理為一個自成一體嘅任務而啟動嘅幫手,例如「對照筆記檢查呢幾章」。佢會得到一個指令,然後自己透過多次工具呼叫去完成工作。
問題一:子代理不斷增長,直到模型拒絕
代理每一步都會將到目前為止嘅對話傳送俾模型。當內容變得太大,我哋嘅程式碼會修剪佢,但只會喺用戶訊息嘅開頭修剪,所以工具呼叫同佢嘅結果永遠唔會被切開。佢會保留第一則訊息,加一個註明早前對話已被修剪嘅備註,然後保留能夠容納嘅最新完整回合。
子代理只有一則用戶訊息,就係佢嘅指令。咁樣就冇地方可以切。所以佢每一步都會傳送完整嘅歷史,不斷增長,直到請求大過模型可以接受嘅上限,大約一百萬個 token。喺一個有 8 個子代理嘅測試入面,8 個全部都被拒絕。
修正:先清除舊嘅工具結果
而家請求會分三步符合預算,只有前一步不夠時先試下一步:
- 清除最舊嘅工具結果。 佢哋嘅內容會被換成一段簡短註解:該結果為咗令對話維持喺模型嘅上下文之內而被清除,代理如有需要可以重新執行該工具。一個一小時前讀取嘅檔案,通常係請求入面最大、最冇用嘅嘢,而且檔案仍然可以再讀。最新嘅結果會完整保留。
- 保留完整嘅用戶回合。 同以前一樣:第一則訊息、一段註解,以及能夠容納嘅最新完整回合。
- 保留完整嘅工具輪次。 喺一個長回合入面(子代理只有呢一種),保留第一則訊息、一段註解,以及最新完整嘅「呼叫一個工具,取得其結果」輪次。
呢個只會改變傳送嘅內容,代理已儲存嘅歷史仍然保留所有嘢。喺同一個測試入面,8 個之中 0 個被拒絕,全部 8 個都完成咗。
分批清除,令快取仍然有效
模型供應商可以重用請求開頭部分嘅工作,只要佢同上一次請求完全一樣,呢個叫做前綴快取。如果我哋每次呼叫都多清除一個結果,請求嘅開頭每次都會改變,快取就永遠幫唔到手。
所以最舊嘅結果係一次清除四個,而唔係一個。咁樣被清除嘅部分,會喺多次呼叫之間保持不變。如果一個結果只係比備註大少少,我哋就唔會去動佢:清除佢幾乎唔會省到位,但仍然會改變請求嘅開頭。保留幾多完整內容,係按大小決定,而唔係按數量:最新而又能夠放入預算四分之一嘅結果會保留,而且至少保留一個。早期版本固定保留最新六個,對短嘅指令輸出係合適嘅,但喺長檔案讀取嘅情況下,會令大部分預算都被舊結果佔用。
拒絕而家會講清楚
模型判定為無效嘅請求,唔會再被重試;重新送出同一個請求,只會得到同一個答案。如果對話對模型嚟講太長,用戶會見到:「呢段對話太長,模型無法一次過讀完。請為下一步開一個新對話:目前已建構嘅嘢都會保留。」呢個係用戶需要自己處理嘅情況,而唔係服務中斷,所以唔會通知我哋嘅值班人員。
問題二:代理為咗「省位」而停止
一個子代理被要求讀取 40 章長篇章節,佢讀咗 2 章之後就停咗,話想省位。佢當時已用咗大約 100,000 個 token,預算則係 400,000 個。
佢無從得知,舊嘅結果其實會為佢被清除。所以我哋講俾佢聽。代理嘅指令而家寫明:當對話超出模型可以處理嘅範圍時,最舊嘅工具結果會被清除,而最新嘅會保持完整,所以唔好為咗省位而停止長時間任務,繼續做就得,如果需要已被清除嘅內容,就重新讀取該檔案。
從模型嘅角度睇,一個模型睇唔到嘅修正,其實唔算修正。呢個機制只有在代理信任佢嗰陣先會有幫助。
問題三:當所有嘢都係英文咁計算 token
我哋估算 token 時唔會執行 tokenizer,而係用字元數除以四。以英文嚟講,呢個係合理嘅經驗法則。但對其他文字就唔係:俄文大約每個 token 2.2 個字元,中文或日文則大約每個 token 一個字元。
所以一個子代理讀取俄文章節時,傳送咗一個大約 640,000 個 token 嘅請求,而我哋嘅估算卻話佢低於 400,000 嘅預算。呢個估算同樣有可能令請求超出模型嘅硬性上限。
而家估算會按文字系統計算:純 ASCII 每 4 個字元一個 token,中文、日文同韓文每 1 個字元一個 token,其他所有嘢(包括西里爾字母、希臘字母、阿拉伯字母、帶重音符號嘅字母、表情符號)則每 2 個字元一個 token。目標係寧願估高。以一章俄文章節為例,而家估算為 43,423 個 token,實際量度約為 44,600;以前則估算為 25,023。由於一則訊息寫好之後永遠唔會改變,佢嘅估算只會計算一次然後記住,而唔係每一步都重新計算。
我哋學到嘅嘢
- 喺真正佔空間嘅地方修剪。 喺代理工作入面,就係工具結果,而唔係用戶訊息。
- 告訴代理佢自己嘅安全網。 否則代理會按照已經唔再適用嘅限制去計劃。
- 「字元數除以四」係英文嘅假設。 任何為多語言用戶計算 token 嘅功能,都需要按文字系統計算,或者使用真正嘅 tokenizer。
- 留意快取。 如果請求開頭每次呼叫都會改變,成本會增加,速度亦會變慢。
如果你想喺自己嘅 app 入面加入 AI 功能,我哋嘅指南 LLM 係乜嘢 同 點樣使用 LLM API 從一開始就會講上下文視窗同 token。更多關於子代理點樣喺 Mythex 運作,可以睇子代理文件。