最近寫一個(gè)AgentCLI原型玩具的時(shí)候,發(fā)現(xiàn)一些比較有意思的點(diǎn).
因?yàn)橹饕钦罩鳧eepSeek API來寫的.
所以基本上也可以說是OpenAI Chat Completion API的一些點(diǎn).
不過,可能有些是DeepSeek特有的.
一個(gè)是請求的stop list.
大致就是遇到給定詞的時(shí)候,模型會(huì)停止生成.
這個(gè)某種程度上來說,提供了手動(dòng)接入模型context方向的能力.
之前翻Anthropic早年的幾篇博客的時(shí)候有提到一個(gè)理論.
大致就是llm不單單是predicate next token.
形式上,前面的token對后面token的走向是有某種差分關(guān)系的.
也就是說,intuition里,前面token的組織形式,影響著后面token的概率空間.
從而對context的概率空間有著同樣的影響.
通俗地說,就是理論上是有可能通過token的組織形式,讓后續(xù)的模型的attention能夠集中在某些特定的知識/context維度,從而提高對結(jié)果走向的確定性.
這個(gè)也是prompt/personality的理論基礎(chǔ).
一個(gè)比較實(shí)用場景可能就是最初DeepSeek R1的那個(gè) aha moment.
現(xiàn)在看Flash的thinking在發(fā)現(xiàn)錯(cuò)誤的時(shí)候經(jīng)常會(huì)有先導(dǎo)的hmm,或者but wait用詞習(xí)慣.
理論上來說,在這個(gè)時(shí)候停止生成,然后人工amend一個(gè)后續(xù)的矯正思路的,是有可能幫助CoT提早converge到解決問題的概率空間方向的.
另外一個(gè)則是response里的stop reason.
這個(gè)主要是sse/stream模式下的一個(gè)概念.
也是tool call的主要實(shí)現(xiàn)方式.
它也是在tool call的時(shí)候,會(huì)生成這個(gè)stop reason,然后停止sse/token的繼續(xù)生成.
因?yàn)檫@個(gè)時(shí)候需要client端去做實(shí)際的tool call,然后再把結(jié)果以role=tool的形式append回去繼續(xù)生成,直到真正的推理完成.
直覺上來說,它應(yīng)該跟請求的stop word是同類東西.
畢竟理論上,要讓模型能夠產(chǎn)生tool call,形式上也是只要讓它學(xué)會(huì)生成<tool_call>之類的特殊token/標(biāo)簽就行了.
不過這個(gè)stop帶來的是agent loop的一些思路.
從實(shí)現(xiàn)上來說,agent loop要多久,取決于要不要忽略這種stop generation,繼續(xù)程序上讓它loop下去就行了.
最簡單的就是在當(dāng)前turn stop之后,簡單追加一個(gè)anything else的user prompt就可以繼續(xù)持續(xù)讓它生成.
這個(gè)比復(fù)雜的prompt調(diào)教確定性高多了.
而且一般的harness思路也不過就是通過prompt的方式去構(gòu)建這種audit+retry的workflow.
這個(gè)不是說不行.
但是比較挑模型.
尤其像DeepSeek v4 Flash這種喜歡一條路走到黑,一般不遵循subagent指令,就喜歡硬扛,上下文越長能力越強(qiáng)的就不行了.
所以感覺還是要有一些類DSL的inner implement來做,會(huì)比單純的prompt來做更合適.
甚至直接面向tool call,把a(bǔ)gent model切換/調(diào)度/fork做成tool的話,比單純的單個(gè)task tool可能更flexible.
尤其考慮想opus系列那種看上去就是靠偷偷多路采樣提高最終接受度的方式.
原則上,對于同一conversation,可以fork多個(gè)agent不同model去并發(fā)執(zhí)行,然后采用類似的方式去audit各個(gè)返回結(jié)果,然后擇一作為main/base,繼續(xù)下一個(gè)prompt.
壞處可能就是費(fèi)token,以及對一些非可重入對tool調(diào)用會(huì)帶來一些反復(fù).
比如不同的model修改同一文件,導(dǎo)致各自的上下文中這個(gè)文件的狀態(tài)總是不對/跟預(yù)期不符.
一個(gè)折中的方式可能就是在各自stop reason的時(shí)候去仲裁,即使是reason是tool call.
還有一個(gè)另外可能比較有價(jià)值的就是fill in the middle和prefix這兩個(gè)API變種.
這兩個(gè)形式上都是實(shí)現(xiàn)一個(gè)事情,就是給定prefix和stop word,模型生成中間的部分.
這個(gè)看著像是某種RL過程的副產(chǎn)品.
因?yàn)檫@個(gè)明顯可以直接拿來生成各種evaluation.
一個(gè)更實(shí)用的方式可能就是根據(jù)這個(gè)做有限度的prompt適配調(diào)優(yōu)/benchmark.
因?yàn)樗峁┝饲爸煤秃笾貌糠?
當(dāng)用不同prompt的時(shí)候,前置除了假裝system prompt的部分外,其他都是一致的.
后綴也是.
那么中間實(shí)踐填充的就可以作為某種prompt優(yōu)劣的基線來源了.
畢竟這種至少后綴是某種確定不變的驗(yàn)收標(biāo)準(zhǔn).
不算徹底的盲測.
再一點(diǎn)比較有意思的是v4對thinking模式下的有tool call的reasoning內(nèi)容的處理.
非thinking模式下,reasoning的內(nèi)容在sse turn之間是可以不必要回傳的.
也就是說,非thinking模式下,client端在請求中可以不回傳部分內(nèi)容.也就是交互的input token可以是不一樣的.
從實(shí)現(xiàn)角度來說,在不考慮緩存的情況下,一樣不一樣沒區(qū)別,畢竟都是next token predication.
但是如果強(qiáng)調(diào)可以不回傳的話,也就是說這個(gè)非thinking模式下的reasoning可能不會(huì)影響kv cache的內(nèi)容.
換句話來說,就是這個(gè)reasoning可能跟上下文完全沒有關(guān)系/影響.
那很自然的一個(gè)想法就是,非thinking 模式下的reasoning內(nèi)容是怎么來說,以及到底有什么作用.
記得v4的technical report里提到的各種thinking模式的區(qū)別.
非thinking的response格式是</thinking> summary
high的是<thinking>thinking token</thinking>summary
max的是system prompt<thinking>thinking token</thinking>summary
看比較明顯的區(qū)別就是非thinking是個(gè)half close的標(biāo)簽.
能想到的可能就是thinking模式下的tool call生成可能主要是跟thinking的內(nèi)容有關(guān).
或者說,thinking決定的tool call的概率空間.
不過既然是關(guān)于有么有tool call的情況.
那么實(shí)際可能純粹就是thinking模式下,thinking block內(nèi)過程中也支持tool call.
而非thinking模式里,reasoning是純粹的CoT,不會(huì)生成任何tool call,完全沒有外部影響干擾的.
所以從sse層面來說,非thinking的assistant message不會(huì)被tool call stop分割.
而thinking的有可能會(huì).
如果不回傳的話,server端的拼接可能會(huì)有問題?
不過這也只能是猜測了.