AI 智能體到底應(yīng)該如何構(gòu)建?分享 Github 上收獲 4k stars 的 12 條原則 原創(chuàng)
編者按: AI 智能體到底應(yīng)該如何構(gòu)建?是追求復(fù)雜的端到端解決方案,還是回歸軟件工程的本質(zhì)思維?
我們今天為大家?guī)?lái)的文章,作者的觀(guān)點(diǎn)是:智能體本質(zhì)上就是軟件,應(yīng)該用嚴(yán)謹(jǐn)?shù)能浖こ淘瓌t來(lái)構(gòu)建,而非盲目追求“黑箱式”的復(fù)雜框架。
文章從智能體的發(fā)展歷程出發(fā),深入剖析了從有向圖到 DAG 編排工具,再到今天 AI 智能體的技術(shù)演進(jìn)脈絡(luò)。隨后,作者系統(tǒng)性地提出了構(gòu)建可靠 LLM 應(yīng)用的12個(gè)核心原則。
這篇文章為正在構(gòu)建 AI 應(yīng)用的開(kāi)發(fā)者提供了一套完整而實(shí)用的方法論,特別適合那些希望擺脫框架束縛、追求技術(shù)本質(zhì)的工程師。相信通過(guò)這12個(gè)原則的指導(dǎo),我們能夠構(gòu)建出更加可靠、可控、可擴(kuò)展的智能體系統(tǒng)。
01 AI Agent 是如何走到今天的
1.1 我的觀(guān)點(diǎn)僅供參考
無(wú)論您是智能體領(lǐng)域的新手,還是像我這樣固執(zhí)的老兵,我都將試圖說(shuō)服您摒棄對(duì) AI Agent 的大部分固有認(rèn)知,退一步,從第一性原理(first principles)出發(fā)重新思考它們。(如果你錯(cuò)過(guò)了不久前 OpenAI 發(fā)布的內(nèi)容,這里有個(gè)劇透預(yù)警:把更多智能體邏輯塞進(jìn) API 后面并非正解)
02 智能體本質(zhì)上是軟件,讓我們簡(jiǎn)要追溯其發(fā)展歷程
讓我們回溯智能體的發(fā)展脈絡(luò)。
2.1 60 年前
這個(gè)階段重點(diǎn)探討的是有向圖(DGs)及其無(wú)環(huán)版本 —— 有向無(wú)環(huán)圖(DAGs)。首先要指出的是...軟件本質(zhì)上就是有向圖。這就是為什么我們過(guò)去常用流程圖表示程序的原因。
2.2 20 年前
約 20 年前,DAG 編排工具開(kāi)始流行。我們開(kāi)始談?wù)?Airflow[1]、Prefect[2] 等經(jīng)典工具,以及它們的前輩,還有 dagster[3]、inggest[4]、windmill[5] 等新秀。這些編排工具沿用了相同的圖模式,同時(shí)增加了可觀(guān)測(cè)性(observability)、模塊化(modularity)、重試機(jī)制(retries)、管理界面(administration)等功能優(yōu)勢(shì)。
2.3 10-15 年前
當(dāng)機(jī)器學(xué)習(xí)模型開(kāi)始展現(xiàn)出實(shí)用價(jià)值時(shí),我們開(kāi)始看到融入 ML 模型的 DAG 工作流。一些典型的步驟可能包括“將此列中的文本匯總到一個(gè)新列中”或“按嚴(yán)重程度/情感對(duì)支持工單進(jìn)行分類(lèi)”。
但歸根結(jié)底,這些軟件在很大程度上還是確定性軟件(deterministic software)。
2.4 智能體技術(shù)帶來(lái)的根本性變革
我并非第一個(gè)提出此觀(guān)點(diǎn)[6]的人,但當(dāng)我開(kāi)始研究智能體時(shí),最深刻的領(lǐng)悟是:你可以徹底摒棄 DAG 架構(gòu)。無(wú)需軟件工程師針對(duì)每個(gè)步驟和邊界條件進(jìn)行編碼,只需賦予智能體一個(gè)目標(biāo)和一組狀態(tài)轉(zhuǎn)移規(guī)則:
讓 LLM 實(shí)時(shí)做出決策,找出路徑。
這樣做的好處是可以減少代碼編寫(xiě)量。你只需為 LLM 定義圖的"邊",由其自主推導(dǎo)"節(jié)點(diǎn)"。借此,系統(tǒng)可具備錯(cuò)誤自恢復(fù)能力,大幅減少代碼量,甚至可能發(fā)現(xiàn) LLM 獨(dú)創(chuàng)的問(wèn)題解決方案。
2.5 智能體(Agents)的核心運(yùn)行機(jī)制是一個(gè)循環(huán)體系
換個(gè)角度看,這是一個(gè)包含 3 個(gè)步驟的循環(huán)體系:
1)LLM 通過(guò)結(jié)構(gòu)化 JSON 輸出確定工作流的下一步("工具調(diào)用")
2)由確定性代碼執(zhí)行工具調(diào)用
3)將工具運(yùn)行結(jié)果追加至上下文窗口
4)不斷循環(huán)直至判定下一步為"完成"狀態(tài)
初始上下文僅是起始事件(可能是用戶(hù)消息、定時(shí)觸發(fā)任務(wù)或 webhook 等),然后我們要求 LLM 選擇下一步(工具)或判斷任務(wù)是否完成。
下面是一個(gè)多步驟示例:
而生成的“materialized” DAG 結(jié)構(gòu)示例如下:
2.6 “循環(huán)往復(fù),直至問(wèn)題解決”模式的缺陷
該模式最顯著的弊端:
- 當(dāng)上下文窗口過(guò)長(zhǎng)時(shí),智能體會(huì)迷失方向,他們陷入反復(fù)嘗試同一種錯(cuò)誤方法的循環(huán)
- 字面意思就是這樣,僅此一項(xiàng)就足以使該方法失效
即使你沒(méi)有手動(dòng)構(gòu)建過(guò)智能體,在使用自動(dòng)化編程工具時(shí)也應(yīng)當(dāng)遭遇過(guò)這種長(zhǎng)上下文問(wèn)題。系統(tǒng)往往在多次交互后陷入混亂,迫使您重啟對(duì)話(huà)。
我還想提出一個(gè)我經(jīng)常聽(tīng)到的觀(guān)點(diǎn),你可能已深有體會(huì):
即使模型支持的上下文窗口越來(lái)越大,精準(zhǔn)、簡(jiǎn)潔的提示詞始終能獲得更優(yōu)的結(jié)果
與我交流過(guò)的多數(shù)開(kāi)發(fā)者都放棄了"工具調(diào)用循環(huán)(tool calling loop)"方案,皆因發(fā)現(xiàn)超過(guò) 10-20 次交互后,LLM 便無(wú)法恢復(fù)任務(wù)狀態(tài)。即便智能體準(zhǔn)確率達(dá) 90%,這仍與"可交付客戶(hù)使用"的標(biāo)準(zhǔn)相去甚遠(yuǎn)。試想一個(gè)網(wǎng)頁(yè)應(yīng)用若在 10% 的訪(fǎng)問(wèn)中崩潰,會(huì)是一種怎樣的用戶(hù)體驗(yàn)?
2.7 真正有效的方法 —— 微智能體(micro agents)
我在實(shí)際應(yīng)用中觀(guān)察到一種比較常見(jiàn)的方法,使用智能體架構(gòu)并將其嵌入到更宏觀(guān)的、更具確定性的有向無(wú)環(huán)圖(DAG)系統(tǒng)中。
您可能會(huì)問(wèn):"為什么在這種情況下還要使用智能體?"我們稍后會(huì)詳細(xì)解釋。簡(jiǎn)而言之,讓語(yǔ)言模型管理限定范圍明確的任務(wù)集合,可以輕松整合實(shí)時(shí)的人類(lèi)反饋,并將這些反饋轉(zhuǎn)化為工作流步驟,而不會(huì)陷入上下文錯(cuò)誤循環(huán)(即后文所提到的 factor 1、factor 3、factor 7)。
2.8 現(xiàn)實(shí)生活中的微智能體案例
下面這個(gè)示例展示了如何使用確定性代碼運(yùn)行微智能體,處理部署過(guò)程中的人工介入步驟:
- 人工將 PR 合并到 GitHub 主分支
- 使用確定性代碼將修改后的項(xiàng)目部署到預(yù)發(fā)布環(huán)境
- 使用確定性代碼運(yùn)行預(yù)發(fā)布環(huán)境的端到端(e2e)測(cè)試
- 使用確定性代碼將初始上下文"將 SHA 4af9ec0 部署到生產(chǎn)環(huán)境"移交智能體進(jìn)行生產(chǎn)環(huán)境的部署
- 智能體調(diào)用 deploy_frontend_to_prod(4af9ec0)
- 使用確定性代碼請(qǐng)求人工批準(zhǔn)此操作
- 人工拒絕操作并反饋"能否先部署后端部分?"
- 智能體調(diào)用 deploy_backend_to_prod(4af9ec0)
- 使用確定性代碼請(qǐng)求人工批準(zhǔn)此操作
- 人工批準(zhǔn)進(jìn)行操作
- 使用確定性代碼執(zhí)行后端部分的部署
- 智能體調(diào)用 deploy_frontend_to_prod(4af9ec0)
- 使用確定性代碼請(qǐng)求人工批準(zhǔn)此操作
- 人工批準(zhǔn)進(jìn)行操作
- 使用確定性代碼執(zhí)行前端部分的部署
- 智能體判定任務(wù)成功完成,流程結(jié)束!
- 使用確定性代碼運(yùn)行生產(chǎn)環(huán)境的端到端測(cè)試
- 確定性代碼任務(wù)完成后,若檢測(cè)到異常,則轉(zhuǎn)交回滾智能體進(jìn)行故障審查,必要時(shí)執(zhí)行版本回退
這個(gè)示例基于我們?yōu)楣芾?Humanlayer 的部署流程而部署的一個(gè)開(kāi)源智能體(OSS agent),以下是我上周與它的真實(shí)對(duì)話(huà)記錄:
我們沒(méi)有讓這個(gè)智能體擁有過(guò)多的功能或復(fù)雜的職責(zé)。LLM 的核心價(jià)值在于解析人類(lèi)的自然語(yǔ)言反饋,并提出更新的行動(dòng)方案。我們盡可能避免讓它同時(shí)處理過(guò)多無(wú)關(guān)的任務(wù)或記憶冗長(zhǎng)的歷史記錄,使 LLM 專(zhuān)注于 5-10 步的小型工作流。
這里有另一個(gè)更經(jīng)典的客戶(hù)支持/ chatbot 示例[7]。
2.9 那么,智能體的本質(zhì)究竟是什么?
- prompt - 告訴 LLM 如何行動(dòng),以及它可以使用哪些“工具”。prompt 的輸出是一個(gè) JSON 對(duì)象,用于描述工作流程中的下一步("工具調(diào)用"或"函數(shù)調(diào)用")。(factor 2)
- switch 語(yǔ)句 - 根據(jù) LLM 返回的 JSON 內(nèi)容決定后續(xù)操作。(factor 8 的一部分)
- 累積的上下文 - 記錄已執(zhí)行的操作步驟及其運(yùn)行結(jié)果(factor 3)
- for 循環(huán) - 循環(huán)執(zhí)行以下操作,直至大語(yǔ)言模型(LLM)返回終止信號(hào)(如標(biāo)記為"Terminal"的工具調(diào)用或自然語(yǔ)言響應(yīng)):將 switch 語(yǔ)句的執(zhí)行結(jié)果加入上下文窗口,并讓 LLM 決定下一步動(dòng)作。(factor 8)
以“deploybot”為例,我們通過(guò)自主掌控流程邏輯和上下文積累,獲得了以下優(yōu)勢(shì):
- 在 switch 語(yǔ)句和 for 循環(huán)中,我們可以隨時(shí)攔截控制流來(lái)暫停等待人工輸入,或等待長(zhǎng)時(shí)間運(yùn)行的任務(wù)完成
- 我們能將上下文窗口輕松序列化存儲(chǔ),實(shí)現(xiàn)「斷點(diǎn)續(xù)傳」式的任務(wù)暫停與恢復(fù)
- 在 prompt 的設(shè)計(jì)中,我們可以?xún)?yōu)化任務(wù)指令的傳遞方式和“當(dāng)前任務(wù)進(jìn)度”的說(shuō)明方式
03 factor 01:自然語(yǔ)言轉(zhuǎn)工具調(diào)用(Tool Calls)
智能體(agent)構(gòu)建最常見(jiàn)的模式之一就是將自然語(yǔ)言轉(zhuǎn)換為結(jié)構(gòu)化的工具調(diào)用。這是一種功能強(qiáng)大的模式,可以構(gòu)建能夠推理任務(wù)并執(zhí)行任務(wù)的智能體。
這種模式的核心原理,就是實(shí)現(xiàn)從自然語(yǔ)言到結(jié)構(gòu)化指令的精準(zhǔn)轉(zhuǎn)換:
請(qǐng)為 Terri 生成 750 美元的贊助支付鏈接,用于支付二月份 AI 創(chuàng)客大會(huì)的贊助費(fèi)用。
最終輸出一個(gè)結(jié)構(gòu)化對(duì)象,用于描述 Stripe API 的調(diào)用參數(shù),例如:
注:實(shí)際場(chǎng)景中 Stripe API 的調(diào)用更為復(fù)雜。一個(gè)成熟的智能體需要先獲取客戶(hù)列表、產(chǎn)品目錄和價(jià)目表等數(shù)據(jù),通過(guò)關(guān)聯(lián) ID 構(gòu)建有效請(qǐng)求參數(shù) —— 當(dāng)然,這些 ID 也可以直接預(yù)置在提示詞/上下文窗口中(本質(zhì)上這兩種方式是相通的,下文將具體說(shuō)明)。
后續(xù)可由確定性代碼接管該請(qǐng)求參數(shù),并執(zhí)行相應(yīng)的業(yè)務(wù)邏輯。(更多細(xì)節(jié)將在 factor 3 中說(shuō)明)
請(qǐng)注意:完整版的智能體在接收到 API 的調(diào)用結(jié)果后,會(huì)通過(guò)循環(huán)處理機(jī)制最終返回類(lèi)似這樣的信息:
已成功為 Terri 創(chuàng)建 750 美元的支付鏈接,用于贊助二月份 AI 創(chuàng)客見(jiàn)面會(huì)。鏈接如下:??https://buy.stripe.com/test_1234567890??
但本節(jié)將跳過(guò)該環(huán)節(jié),將其保留至后續(xù)章節(jié)實(shí)現(xiàn) —— 開(kāi)發(fā)者可根據(jù)實(shí)際需求決定是否集成該功能。
04 factor 02:自主掌控提示詞
不要直接套用框架自動(dòng)生成的提示詞。
某些框架會(huì)提供這種‘黑箱式’方案:
這種方案能幫你快速套用頂尖的提示詞模板上手,但后期很難精準(zhǔn)調(diào)整或?qū)嵤┠嫦蚬こ蹋y以確保模型接收的指令完全符合預(yù)期。
相反,你要像對(duì)待核心業(yè)務(wù)代碼一樣對(duì)待提示詞:
雖然上面這個(gè)示例是用 BAML 工具生成提示詞的,但其實(shí)你可以根據(jù)自己的需求選擇任何提示詞設(shè)計(jì)工具,甚至完全不需要借助工具,直接按照模板格式手動(dòng)編寫(xiě)提示詞也是可行的。
自主掌控提示詞的核心優(yōu)勢(shì):
- 完全的控制權(quán):可以精準(zhǔn)定制 AI Agent 所需的指令,徹底擺脫“黑箱操作”的束縛
- 可測(cè)試和可評(píng)估:像測(cè)試普通代碼一樣,為你的提示詞建立完整的測(cè)試評(píng)估體系
- 快速迭代:根據(jù)實(shí)際使用效果,隨時(shí)靈活調(diào)整優(yōu)化提示詞
- 透明可控:清楚掌握 AI Agent 執(zhí)行的具體指令內(nèi)容,沒(méi)有隱藏邏輯
- 角色突破:利用那些支持自定義用戶(hù)/助手角色設(shè)定的 API 接口 —— 比如 OpenAI 已棄用的舊版 'completions' 非對(duì)話(huà)型 API,甚至可以實(shí)現(xiàn)一些特殊的模型引導(dǎo)技巧
請(qǐng)記住:提示詞(prompts)是連接你的業(yè)務(wù)邏輯與大語(yǔ)言模型的主要接口。
完全掌控提示詞,才能提供生產(chǎn)級(jí) AI Agent 所需的靈活性和提示詞控制能力。
雖然沒(méi)人能斷言什么是最佳提示詞,但有一點(diǎn)很明確 —— 你需要的是能自由嘗試各種可能性。
05 factor 03:自主掌控上下文窗口
與大語(yǔ)言模型交互時(shí),上下文傳遞不必拘泥于標(biāo)準(zhǔn)消息格式。
在智能體(agent)中,每次向 LLM 提供輸入的實(shí)質(zhì)是:“這是目前情況,接下來(lái)該干嘛?”
一切皆上下文工程。大語(yǔ)言模型本質(zhì)上是無(wú)狀態(tài)函數(shù)(stateless functions)[8],只負(fù)責(zé)將輸入轉(zhuǎn)化為輸出。想要獲得優(yōu)質(zhì)輸出,就必須提供優(yōu)質(zhì)輸入。
構(gòu)建優(yōu)質(zhì)上下文需包含以下要素:
- 提示詞與指令:給模型的明確操作指引
- 外部數(shù)據(jù)源:檢索到的文檔或知識(shí)(例如使用 RAG 技術(shù))
- 歷史狀態(tài):過(guò)往的工具調(diào)用記錄、執(zhí)行結(jié)果等操作痕跡
- 記憶系統(tǒng):有關(guān)聯(lián)但獨(dú)立的對(duì)話(huà)/事件歷史記錄(Memory)
- 輸出結(jié)構(gòu)化指令:規(guī)定模型返回?cái)?shù)據(jù)的格式規(guī)范
本指南聚焦如何最大限度挖掘現(xiàn)有模型的潛力,以下內(nèi)容不在討論范圍內(nèi):
- 調(diào)整模型參數(shù)(如 temperature、top_p、frequency_penalty、presence_penalty 等)
- 訓(xùn)練自定義的生成模型(completion models)或嵌入模型
- 對(duì)現(xiàn)有模型進(jìn)行微調(diào)
在此重申:雖然無(wú)法斷言最佳的上下文傳遞方式,但我知道你希望能夠靈活地嘗試各種方式。
5.1 標(biāo)準(zhǔn)上下文格式與自定義上下文格式
大多數(shù) LLM 客戶(hù)端采用如下這種標(biāo)準(zhǔn)消息格式:
雖然這種格式適用于大多數(shù)場(chǎng)景,但若想極致壓榨現(xiàn)有 LLM 的性能,就必須以最高效的 token 利用率和注意力分配機(jī)制來(lái)傳遞上下文。
若希望突破基于消息的標(biāo)準(zhǔn)格式限制,您可以創(chuàng)建專(zhuān)為你個(gè)人的應(yīng)用場(chǎng)景優(yōu)化的上下文組織形式。例如,通過(guò)自定義數(shù)據(jù)結(jié)構(gòu)將相關(guān)內(nèi)容整合,根據(jù)實(shí)際需求打包或拆分到一個(gè)或多個(gè)用戶(hù)、系統(tǒng)、助手或工具消息中(具體組合視業(yè)務(wù)邏輯而定)。
以下示例演示了如何將完整的上下文信息封裝于單條用戶(hù)消息中:
雖然模型可能通過(guò)你提供的工具定義自動(dòng)推導(dǎo)后續(xù)操作步驟,但我們?nèi)越ㄗh在提示詞模板中明確聲明任務(wù)目標(biāo) —— 主動(dòng)說(shuō)明需求始終是更穩(wěn)妥的做法。
5.2 code example
我們可以采用如下方式構(gòu)建:
上下文窗口示例
下面是使用這種方法后上下文窗口的樣子:
初始的 Slack 請(qǐng)求:
列出 Git 標(biāo)簽后:
錯(cuò)誤發(fā)生與恢復(fù)后:
此時(shí)你的下一步可能是:
上文那些 XML 格式的內(nèi)容僅是一個(gè)參考示例 —— 您可以根據(jù)實(shí)際業(yè)務(wù)需求,自定義最合適的數(shù)據(jù)結(jié)構(gòu)。通過(guò)靈活嘗試不同的上下文組織形式、存儲(chǔ)內(nèi)容和輸入大模型的內(nèi)容,最終輸出質(zhì)量會(huì)顯著提升。
自主控制上下文窗口的好處:
- 信息密度:以最適配 LLM 認(rèn)知的方式組織信息
- 錯(cuò)誤處理:采用有助于 LLM 自主恢復(fù)的格式記錄錯(cuò)誤信息(已修復(fù)的錯(cuò)誤和失敗調(diào)用可從上下文中移除)
- 安全性:主動(dòng)過(guò)濾敏感數(shù)據(jù),精準(zhǔn)控制輸入內(nèi)容
- 靈活性:根據(jù)使用情況持續(xù)優(yōu)化調(diào)整上下文格式
- token 效率:優(yōu)化上下文格式,提高 token 效率與模型理解能力
上下文可包含: 提示詞(prompts)、指令(instructions)、RAG 文檔(RAG documents)、交互歷史(history)、工具調(diào)用記錄(tool calls)、記憶(memory)
請(qǐng)記住,上下文窗口是你與 LLM 交互的主要界面,其結(jié)構(gòu)設(shè)計(jì)與信息呈現(xiàn)方式將直接決定智能體的效能。
示例 - 信息密度優(yōu)化(相同的語(yǔ)義信息,更少的 token 消耗量):
雖然無(wú)法預(yù)知最優(yōu)方案,但必須確保系統(tǒng)具備無(wú)限試錯(cuò)的可能性——任何可能的嘗試路徑都應(yīng)向你開(kāi)放。
06 factor 04:「工具」本質(zhì)上只是 LLM 生成的結(jié)構(gòu)化輸出
「工具」無(wú)需進(jìn)行復(fù)雜設(shè)計(jì)。其本質(zhì)是大語(yǔ)言模型生成的結(jié)構(gòu)化輸出,用于觸發(fā)確定性代碼的執(zhí)行。
以 CreateIssue 和 SearchIssues 這兩個(gè)工具為例,讓大模型(LLM)“調(diào)用工具”,本質(zhì)上就是讓它輸出一個(gè)可解析的 JSON 對(duì)象,該對(duì)象對(duì)應(yīng)我們要執(zhí)行的具體工具操作。
這種模式很簡(jiǎn)單:
1)LLM 生成結(jié)構(gòu)化的 JSON 輸出
2)使用確定性代碼執(zhí)行對(duì)應(yīng)操作(如調(diào)用外部 API)
3)捕獲執(zhí)行結(jié)果并反饋到上下文中
這種設(shè)計(jì)實(shí)現(xiàn)了 LLM 決策邏輯與應(yīng)用程序執(zhí)行邏輯的清晰分離 —— LLM 負(fù)責(zé)決定『做什么』,而你的代碼掌控『怎么做』。即便 LLM 調(diào)用了某個(gè)工具,具體執(zhí)行方式也不必每次都嚴(yán)格對(duì)應(yīng)單一函數(shù)。
如果你還記得前文提及的 switch 語(yǔ)句
注:關(guān)于“plain prompting" vs. "tool calling" vs. "JSON mode”的性能權(quán)衡已有諸多討論。在此附上相關(guān)資源鏈接(參見(jiàn)《Prompting vs JSON Mode vs Function Calling vs Constrained Generation vs SAP》[9]、《When should I use function calling, structured outputs, or JSON mode?》[10]及《OpenAI JSON vs Function Calling》[11]),此處不展開(kāi)論述。
所謂的"下一步操作"未必只是簡(jiǎn)單地"運(yùn)行一個(gè)純函數(shù)并返回結(jié)果"。當(dāng)你把"工具調(diào)用"單純視為模型輸出的一段 JSON 指令(用于描述確定性代碼該執(zhí)行什么)時(shí),就能解鎖極大的靈活性。結(jié)合 factor 08 ,這種設(shè)計(jì)將帶來(lái)更強(qiáng)大的可能性。
07 factor 05:執(zhí)行狀態(tài)與業(yè)務(wù)狀態(tài)的統(tǒng)一
即便在 AI 領(lǐng)域之外,許多基礎(chǔ)設(shè)施系統(tǒng)也試圖將“執(zhí)行狀態(tài)”與“業(yè)務(wù)狀態(tài)”分離。對(duì) AI 應(yīng)用而言,這種分離可能涉及復(fù)雜的抽象機(jī)制來(lái)追蹤當(dāng)前步驟、下一步驟、等待狀態(tài)、重試次數(shù)等。這種分離帶來(lái)的復(fù)雜性可能是值得的,但對(duì)你的使用場(chǎng)景而言可能是過(guò)度設(shè)計(jì)。
你可以自行決定什么最適合你的應(yīng)用。但不要認(rèn)為必須將這兩者分開(kāi)管理。
更清晰的定義:
- 執(zhí)行狀態(tài)(Execution state):當(dāng)前步驟、下一步驟、等待狀態(tài)、重試次數(shù)等
- 業(yè)務(wù)狀態(tài)(Business state):智能體工作流中已發(fā)生的事件(如 OpenAI 消息列表、工具調(diào)用及結(jié)果列表等)
如果可能,盡量簡(jiǎn)化 —— 盡可能將它們統(tǒng)一起來(lái)。
實(shí)際上,你可以通過(guò)工程化設(shè)計(jì),直接從上下文窗口推斷所有執(zhí)行狀態(tài)。多數(shù)情況下,執(zhí)行狀態(tài)(當(dāng)前步驟、等待狀態(tài)等)不過(guò)是已發(fā)生事件的元數(shù)據(jù)(metadata)。
當(dāng)然,有些內(nèi)容無(wú)法放入上下文窗口(如會(huì)話(huà) ID、密碼上下文等),但你的目標(biāo)應(yīng)該是盡量減少這類(lèi)例外。通過(guò)遵循 factor 3,你可以精準(zhǔn)控制哪些信息真正輸入給 LLM。
該方法具有以下優(yōu)勢(shì):
- 簡(jiǎn)潔性:所有狀態(tài)只有一個(gè)真實(shí)來(lái)源
- 序列化:工作流可輕松實(shí)現(xiàn)序列化/反序列化
- 調(diào)試便捷:完整的歷史記錄一目了然
- 擴(kuò)展靈活:僅需新增事件類(lèi)型即可擴(kuò)展新的狀態(tài)
- 斷點(diǎn)續(xù)傳:通過(guò)加載工作流可從任意節(jié)點(diǎn)恢復(fù)執(zhí)行
- 流程復(fù)刻(Forking):可以在任何時(shí)間點(diǎn)復(fù)制工作流子集至新上下文/狀態(tài)ID,實(shí)現(xiàn)在工作流的復(fù)刻(fork)
- 人機(jī)交互和可觀(guān)測(cè)性:工作流可輕松轉(zhuǎn)換為 Markdown 文檔或可視化 Web 界面
08 factor 06:通過(guò)簡(jiǎn)單的 API 實(shí)現(xiàn)啟動(dòng)/暫停/恢復(fù)
智能體的本質(zhì)是程序,其生命周期管理應(yīng)符合我們對(duì)常規(guī)程序的預(yù)期 —— 能夠便捷地啟動(dòng)、查詢(xún)、恢復(fù)和終止。
需確保終端用戶(hù)、應(yīng)用程序、業(yè)務(wù)管道及其他智能體均可通過(guò)輕量級(jí) API 接口快速部署新智能體實(shí)例。
智能體及其編排的確定性代碼須具備長(zhǎng)時(shí)操作自暫停能力。
需支持通過(guò) Webhook 等外部觸發(fā)器實(shí)現(xiàn)智能體斷點(diǎn)續(xù)執(zhí),且無(wú)需深度對(duì)接智能體編排系統(tǒng)。
factor 6 與 factor 5 和 factor 8 存在較強(qiáng)的關(guān)聯(lián),但可獨(dú)立實(shí)現(xiàn)。
需特別注意,多數(shù)現(xiàn)有的 AI 編排系統(tǒng)雖支持暫停恢復(fù)功能,但在『工具選定』與『工具執(zhí)行』兩個(gè)狀態(tài)節(jié)點(diǎn)之間的臨界區(qū)間,多數(shù)系統(tǒng)無(wú)法保持狀態(tài)持久化能力(詳見(jiàn) factor 7 和 factor 11 的技術(shù)解析)。
09 factor 07:通過(guò)工具調(diào)用實(shí)現(xiàn)人機(jī)協(xié)同
默認(rèn)情況下,LLM API 在生成模型響應(yīng)時(shí),首先會(huì)面臨一個(gè)關(guān)鍵的、高風(fēng)險(xiǎn)的詞元選擇:是返回純文本內(nèi)容,還是返回結(jié)構(gòu)化數(shù)據(jù)?
系統(tǒng)將大量決策權(quán)重放在首個(gè)詞元的選擇上。例如在查詢(xún)“東京天氣”時(shí),首個(gè)詞元可能是:
"東京"
而在 fetch_weather(獲取天氣)功能中,則可能是表示 JSON 對(duì)象開(kāi)頭的特殊詞元。
|JSON>
更優(yōu)方案是讓大語(yǔ)言模型始終輸出 JSON 結(jié)構(gòu)化數(shù)據(jù),然后通過(guò)自然語(yǔ)言詞元(如 request_human_input 或 done_for_now)來(lái)聲明意圖,而不是使用像 check_weather_in_city 這樣的"標(biāo)準(zhǔn)"工具。
需特別注意:此方案可能不會(huì)直接提升系統(tǒng)性能指標(biāo),但必須通過(guò)持續(xù)實(shí)驗(yàn)驗(yàn)證 —— 工程師應(yīng)保留嘗試非常規(guī)手段的自由度,這是獲得最優(yōu)解的必經(jīng)之路。
后續(xù),您可能會(huì)收到來(lái)自處理 Slack、電子郵件、短信或其他事件的系統(tǒng)的 webhook 通知。
上文整合了 factor 3、4、5、8 的方案特征。
若采用 factor 3 中的類(lèi) XML 格式,那么經(jīng)過(guò)數(shù)次交互后,上下文窗口可能會(huì)是這樣的:
優(yōu)勢(shì)亮點(diǎn):
- 清晰的指令:針對(duì)不同人機(jī)交互場(chǎng)景的工具設(shè)計(jì),可大幅提升大語(yǔ)言模型(LLM)輸出的精準(zhǔn)度。
- 內(nèi)循環(huán)與外循環(huán)機(jī)制:該機(jī)制使智能體工作流突破傳統(tǒng) ChatGPT 式交互框架,支持逆向流程觸發(fā) —— 控制流與上下文初始化可由智能體主動(dòng)發(fā)起至用戶(hù)(例如:通過(guò)定時(shí)任務(wù)或事件自動(dòng)激活的智能體服務(wù))。
- 多用戶(hù)協(xié)同:依托結(jié)構(gòu)化事件機(jī)制,可高效追蹤并協(xié)調(diào)多用戶(hù)輸入數(shù)據(jù)流。
- 多智能體協(xié)作:通過(guò)輕量級(jí)抽象層設(shè)計(jì),快速擴(kuò)展智能體間的請(qǐng)求與響應(yīng)能力
- 持久化運(yùn)行:結(jié)合 factor 6 的啟停控制能力,可構(gòu)建高穩(wěn)定、可觀(guān)測(cè)的多角色持久化工作流。
有關(guān)外循環(huán)智能體(Outer Loop Agents)的更多信息,請(qǐng)點(diǎn)擊此處[12]。
與 factor 11 完美結(jié)合 —— 隨時(shí)隨地觸發(fā),滿(mǎn)足用戶(hù)需求。
10 factor 08:掌控你的控制流
如果你能掌握你的控制流,就可以實(shí)現(xiàn)更靈活、強(qiáng)大的功能。
根據(jù)具體應(yīng)用場(chǎng)景構(gòu)建專(zhuān)屬控制邏輯,精準(zhǔn)匹配業(yè)務(wù)場(chǎng)景。當(dāng)特定類(lèi)型的工具調(diào)用需要中斷循環(huán)等待人工響應(yīng)或長(zhǎng)時(shí)任務(wù)(如訓(xùn)練流水線(xiàn))時(shí),您可設(shè)計(jì)靈活的中斷機(jī)制。建議集成以下自定義功能:
- 工具調(diào)用結(jié)果的摘要與緩存
- 使用 LLM 對(duì)結(jié)構(gòu)化輸出進(jìn)行校驗(yàn)、評(píng)估
- 上下文窗口壓縮或其他內(nèi)存管理方案
- 全鏈路日志追蹤與性能監(jiān)控
- 客戶(hù)端速率限制策略
- 持久化的休眠/暫停/事件等待機(jī)制
下方示例展示了三種典型的控制流模式:
- request_clarification:模型請(qǐng)求補(bǔ)充信息時(shí),中斷當(dāng)前循環(huán)流程,等待人工響應(yīng)
- fetch_git_tags:當(dāng)模型請(qǐng)求 Git 標(biāo)簽列表時(shí),系統(tǒng)會(huì)實(shí)時(shí)獲取標(biāo)簽數(shù)據(jù)并更新上下文,直接將結(jié)果反饋給模型
- deploy_backend:模型發(fā)起后端部署請(qǐng)求時(shí),因涉及高風(fēng)險(xiǎn)操作,中斷流程等待人工審核確認(rèn)
這種模式允許你根據(jù)需要中斷和恢復(fù)智能體的工作流程,從而創(chuàng)建更自然的對(duì)話(huà)和工作流。
舉個(gè)例子,我對(duì)所有 AI 框架的首要功能需求就是:正在工作的智能體能夠中斷操作并在之后恢復(fù)運(yùn)行,特別是在工具選擇和工具調(diào)用之間的時(shí)刻。
如果缺乏這種可恢復(fù)性/精細(xì)控制能力,就無(wú)法在工具調(diào)用執(zhí)行前進(jìn)行審核(review/approve),這意味著您被迫只能選擇以下方案:
1)在等待長(zhǎng)時(shí)間任務(wù)完成時(shí),將任務(wù)及其上下文狀態(tài)(變量、堆棧等)保留在內(nèi)存中(類(lèi)似while...sleep),如果進(jìn)程中斷則必須從頭開(kāi)始
2)限制智能體只能執(zhí)行低風(fēng)險(xiǎn)、低影響的調(diào)用,如研究和摘要
3)允許智能體執(zhí)行更重要、更有用的操作,然后只能祈禱它不會(huì)搞砸
您可能會(huì)注意到,這一點(diǎn)與 factor 5 及 factor 6 密切相關(guān),但也可以獨(dú)立實(shí)現(xiàn)。
11 factor 09:將錯(cuò)誤信息壓縮至上下文窗口
這一點(diǎn)雖然簡(jiǎn)短,但值得一提。智能體的優(yōu)勢(shì)之一在于“自我修復(fù)”——對(duì)于短任務(wù),大語(yǔ)言模型(LLM)可能會(huì)調(diào)用某個(gè)失敗的工具。優(yōu)秀的 LLM 通常能夠讀取錯(cuò)誤信息或 Stack Trace 信息,并在后續(xù)工具調(diào)用中調(diào)整策略。
大多數(shù)框架已實(shí)現(xiàn)這一功能,但你也可以只做到這一點(diǎn),而無(wú)需實(shí)現(xiàn)其他 11 個(gè) factor。例如:
你可能需要為特定的工具調(diào)用實(shí)現(xiàn)一個(gè)錯(cuò)誤計(jì)數(shù)器(errorCounter),將單個(gè)工具的重試次數(shù)限制在 ~ 3次以?xún)?nèi),或者根據(jù)實(shí)際需求調(diào)整業(yè)務(wù)邏輯。
當(dāng)連續(xù)錯(cuò)誤次數(shù)達(dá)到某個(gè)閾值時(shí),無(wú)論是模型自主決策還是通過(guò)預(yù)編程規(guī)則強(qiáng)制接管控制流,都可以選擇升級(jí)至人工處理。
優(yōu)勢(shì):
- 自我修復(fù)能力:大語(yǔ)言模型能夠解讀錯(cuò)誤信息,并在后續(xù)工具調(diào)用中自動(dòng)調(diào)整執(zhí)行策略
- 持久運(yùn)行機(jī)制:?jiǎn)我还ぞ哒{(diào)用失敗不會(huì)導(dǎo)致系統(tǒng)中斷,智能體程序可持續(xù)執(zhí)行任務(wù)
需要提醒的是,智能體過(guò)度依賴(lài)這種自我修復(fù)機(jī)制時(shí),可能導(dǎo)致智能體在錯(cuò)誤處理過(guò)程中無(wú)法有效突破現(xiàn)有邏輯框架,出現(xiàn)反復(fù)報(bào)錯(cuò)的情況。
此時(shí),factor 8 和 factor 3 就派上用場(chǎng)了 —— 你不必直接把原始錯(cuò)誤丟回給系統(tǒng),而是重構(gòu)錯(cuò)誤表達(dá)方式、從上下文窗口移除冗余的歷史記錄,避免干擾后續(xù)決策,或者采用其他有效的確定性策略(只要能確保智能體程序回歸正軌)。
防范陷入錯(cuò)誤循環(huán)的最核心策略,是遵循 factor 10。
12 factor 10:小型化、功能聚焦的智能體
與其構(gòu)建試圖包辦一切的大型智能體,不如開(kāi)發(fā)專(zhuān)注于某一單一功能的小型智能體。智能體只是一個(gè)更大的、主要由確定性因素決定的系統(tǒng)中的基礎(chǔ)組件之一。
這里的關(guān)鍵之處在于大語(yǔ)言模型(LLM)的局限性:任務(wù)越龐大復(fù)雜,所需任務(wù)步驟就越多,就意味著需要更長(zhǎng)的上下文窗口。隨著上下文增長(zhǎng),大語(yǔ)言模型更容易迷失方向或偏離重點(diǎn)。通過(guò)將智能體的功能限定在特定領(lǐng)域(3-10 個(gè)步驟,最多 20 個(gè)任務(wù)步驟),我們可以保持上下文窗口的可管理性,確保大語(yǔ)言模型的高效運(yùn)行。
小型化、功能聚焦的智能體的優(yōu)勢(shì):
1)可管理的上下文:更小的上下文窗口意味著更優(yōu)的大語(yǔ)言模型表現(xiàn)
2)職責(zé)明確:每個(gè)智能體都有清晰的功能邊界和設(shè)計(jì)目標(biāo)
3)可靠性更高:在復(fù)雜的工作流程中迷失方向的可能性更低
4)更易于測(cè)試:更簡(jiǎn)單地測(cè)試和驗(yàn)證特定功能
5)調(diào)試優(yōu)化:?jiǎn)栴}發(fā)生時(shí)更容易定位和修復(fù)
12.1 如果 LLM 變得更聰明了呢?
如果大語(yǔ)言模型的智能程度足夠高,能處理 100+ 步驟的工作流,我們還需要這種設(shè)計(jì)嗎?
tl;dr:需要。雖然智能體和大模型進(jìn)步后可能自然而然地?fù)碛刑幚砀L(zhǎng)上下文的能力,這意味著能處理更多更大的 DAG。但采用小型化、功能聚焦的架構(gòu)設(shè)計(jì),既能確保你在第一時(shí)間獲得可靠的結(jié)果,又為未來(lái)大模型的上下文窗口擴(kuò)容時(shí)逐步擴(kuò)展智能體范圍做好準(zhǔn)備。(如果你重構(gòu)過(guò)大型的確定性代碼庫(kù),此刻應(yīng)該會(huì)心一笑)
有意識(shí)地確定智能體的規(guī)模/范圍,并且只在能夠保證質(zhì)量的情況下擴(kuò)展,這是關(guān)鍵所在。正如 NotebookLM 開(kāi)發(fā)團(tuán)隊(duì)所言[13]:
"在 AI 開(kāi)發(fā)中,那些最驚艷的突破時(shí)刻往往發(fā)生在我將將觸及模型能力邊界的時(shí)候"
無(wú)論這個(gè)能力邊界在哪里,如果你能找到邊界并始終如一地把握住它,你就能打造出驚艷的用戶(hù)體驗(yàn)。這個(gè)領(lǐng)域有很多技術(shù)護(hù)城河可以構(gòu)建,但一如既往,這需要嚴(yán)謹(jǐn)?shù)墓こ虒?shí)踐。
13 factor 11:智能體系統(tǒng)支持多入口觸發(fā),且響應(yīng)與觸發(fā)渠道保持一致
當(dāng)您已落實(shí) factor 6 和 factor 7 后,便可無(wú)縫集成本原則方案。
支持用戶(hù)通過(guò) Slack、郵件、短信等任意渠道喚醒智能體,并確保響應(yīng)始終在原對(duì)話(huà)流中完成。
優(yōu)勢(shì):
- 滿(mǎn)足用戶(hù)需求:打造擬人化的 AI 應(yīng)用體驗(yàn),讓用戶(hù)感受如真人協(xié)作或至少達(dá)到數(shù)字同事般的自然交互
- 外循環(huán)智能體:支持非人工觸發(fā)(系統(tǒng)事件/定時(shí)任務(wù)/故障告警等),可自主運(yùn)行5-90分鐘,關(guān)鍵決策節(jié)點(diǎn)自動(dòng)請(qǐng)求人工介入(需審批/獲取反饋/請(qǐng)求協(xié)助)
- 高風(fēng)險(xiǎn)操作授權(quán)機(jī)制:通過(guò)快速人工復(fù)核機(jī)制,可授權(quán)智能體執(zhí)行高風(fēng)險(xiǎn)操作(如外發(fā)郵件、生產(chǎn)數(shù)據(jù)更新等)。明確、標(biāo)準(zhǔn)化的管控體系既保障操作可追溯,又能提升智能體執(zhí)行復(fù)雜任務(wù)的可靠性。
14 factor 12:將智能體設(shè)計(jì)為符合“無(wú)狀態(tài)歸約器”模式
END
本期互動(dòng)內(nèi)容 ??
?文中多次強(qiáng)調(diào)“沒(méi)人知道什么是最佳實(shí)踐,但必須保留試錯(cuò)自由”。你最近在 AI Agent 項(xiàng)目中做過(guò)哪些不符常規(guī)但有效的技術(shù)決策?
文中鏈接
[1]??https://airflow.apache.org/??
[2]??https://www.prefect.io/??
[4]??https://www.inngest.com/??
[5]??https://www.windmill.dev/??
[6]??https://youtu.be/Dc99-zTMyMg?si=bcT0hIwWij2mR-40&t=73??
[7]??https://x.com/chainlit_io/status/1858613325921480922??
[8]??https://thedataexchange.media/baml-revolution-in-ai-engineering/??
[9]??https://www.boundaryml.com/blog/schema-aligned-parsing??
[10]??
[11]??https://docs.llamaindex.ai/en/stable/examples/llm/openai_json_vs_function_calling/??
[12]??https://theouterloop.substack.com/p/openais-realtime-api-is-a-step-towards??
原文鏈接:
