
1. 項目概述一個“活”起來的智能體是如何思考的最近和幾個做AI應用的朋友聊天大家都有一個共同的困惑我們手頭的LLM大語言模型能力越來越強API調用也方便但為什么做出來的東西總感覺“差點意思”要么是機械地一問一答要么是執行復雜任務時容易“跑偏”或“卡住”缺乏一種連貫、自主的“智能感”。這背后的核心差距往往不在于模型本身而在于我們是否為其設計了一套有效的“大腦”運行機制——也就是智能體Agent系統的控制循環。今天要聊的“感知—決策—行動—反思”循環正是這個“大腦”的核心工作流。它不是一個靜態的流程圖而是一個動態的、持續運轉的認知引擎。你可以把它想象成一個頂級外科醫生在手術中的狀態他需要持續感知手術臺上的各種生命體征數據和影像環境輸入基于專業知識和當前情況快速決策下一步最佳操作內部推理然后精準地執行手術動作調用工具并在每一步完成后反思動作效果隨時準備調整方案評估與學習。智能體的控制循環就是在軟件層面模擬這種高級的、目標導向的認知過程。這個連載系列的第三篇我們將深入這個循環的每一個環節從理論到代碼拆解如何讓一個智能體真正“活”起來能夠處理那些需要多步驟、有條件判斷、甚至能從錯誤中學習的復雜任務。無論你是想構建一個自動化的數據分析助手一個能理解需求并編寫完整程序的項目搭檔還是一個能夠自主探索解決方案的研究代理理解并實現這個控制循環都是必經之路。2. 控制循環的整體架構與設計哲學在動手寫代碼之前我們必須先想清楚整個系統應該如何架構。一個健壯的控制循環不是四個環節的簡單串聯而是一個帶有狀態管理、錯誤處理和長期記憶的復雜系統。2.1 核心循環的抽象模型最基礎的模型是一個while循環class BasicAgent: def run(self, initial_task): state self._initialize_state(initial_task) while not self._is_task_complete(state): # 1. 感知 observation self._perceive(state) # 2. 決策 action self._decide(state, observation) # 3. 行動 result self._act(action) # 4. 反思 狀態更新 state self._reflect_and_update(state, action, result) return state.final_result但這個模型過于理想化。現實中我們需要考慮感知什么如何決策行動失敗怎么辦反思的依據是什么這就需要我們引入更豐富的組件。2.2 關鍵組件的職責界定一個工業級智能體系統通常包含以下核心組件它們協同工作支撐起控制循環工作記憶Working Memory存儲當前任務相關的所有上下文信息包括原始目標、歷史對話、之前的觀察結果、執行過的動作及其結果。它是循環中不斷被更新的“狀態State”核心。感知模塊Perception Module并非指視覺感知而是泛指從工作記憶和外部環境中提取相關信息的過程。這包括解析用戶的輸入、讀取數據庫的最新記錄、監聽消息隊列的事件、解析工具執行的返回結果等。其輸出是結構化的“觀察Observation”。決策引擎Decision Engine這是智能體的“CPU”通常由LLM驅動。它接收當前的工作記憶和最新的觀察然后推理出下一步應該執行哪個“動作Action”。動作可以是一個簡單的文本回復也可以是調用一個特定工具如搜索、計算、寫文件的指令。行動執行器Action Executor負責安全、可靠地執行決策引擎發出的動作指令。它需要管理一系列“工具Tools”處理工具調用時的參數驗證、異常捕獲、結果格式化等臟活累活。反思與評估模塊Reflection Evaluation Module這是智能體具備“學習”和“調整”能力的關鍵。它評估上一次行動的結果是否有效是否朝著目標前進。如果結果不理想它可以觸發重新決策Re-planning或生成一個“反思”記錄存入長期記憶避免未來犯同樣錯誤。2.3 設計時的核心權衡在設計循環時你始終面臨幾個關鍵權衡反應式 vs. 深思熟慮式是每次循環只做一個簡單動作反應式還是允許決策引擎生成一個包含多個步驟的完整計劃深思熟慮式后者效率更高但一旦環境變化計劃容易失效。通常采用混合策略生成一個高層計劃但在每個循環步驟中根據最新觀察進行微調。狀態管理粒度工作記憶中要保存多少歷史保存完整的對話歷史雖然信息全但會導致LLM上下文快速膨脹增加成本和延遲。通常需要設計摘要機制將遙遠的、不重要的歷史壓縮成要點。錯誤處理邊界行動執行失敗時是讓反思模塊嘗試修復還是直接拋出異常終止任務一個健壯的智能體應該有分級錯誤處理機制工具級錯誤如API超時可重試邏輯級錯誤如參數不對需反饋給決策引擎重新思考目標級錯誤如任務不可能完成則應向用戶請求幫助。實操心得不要試圖在第一個版本中就實現一個完美的通用智能體框架。最好的方法是針對你的具體任務場景設計最小可行的控制循環。例如一個客服自動應答機器人的循環可能非常簡單感知用戶問題-決策知識庫檢索動作-行動并返回答案-無需復雜反思。先從簡單開始迭代優化。3. 感知模塊為智能體打開“眼睛”和“耳朵”感知模塊是智能體與外界交互的橋梁。它的任務不是簡單地傳遞數據而是進行信息篩選、結構化和融合為決策引擎提供高質量的輸入。3.1 感知的來源多模態輸入與內部狀態感知的輸入通常來自兩方面外部輸入用戶消息、API推送的事件、數據庫查詢結果、文件內容、傳感器數據在機器人領域等。內部狀態從工作記憶中提取的、與當前決策相關的歷史信息。例如之前三步做了什么得到了什么結果。3.2 結構化觀察從原始數據到決策燃料LLM擅長處理結構化的文本信息。因此感知模塊的一個重要職責是將原始輸入轉化為結構化的“觀察”對象。例如dataclass class Observation: type: Literal[“user_input”, “tool_result”, “system_event”] content: str # 原始內容或摘要 metadata: dict # 來源、時間戳、置信度等 relevance_to_goal: float # 一個簡單的相關性評分可用于后續過濾對于工具執行結果感知模塊需要做額外處理結果解析工具返回的可能是JSON、HTML、純文本或錯誤碼。需要將其解析為統一的、易于理解的描述。關鍵信息提取特別是當結果很長時如一篇網頁內容需要提取與當前任務最相關的片段。這本身就可以用一個輕量級的LLM調用來完成。狀態判斷從結果中判斷某些關鍵條件是否滿足。例如調用“查詢庫存”工具后感知模塊可以輸出觀察“庫存量為5大于0可購買”。3.3 上下文管理與歷史摘要這是感知模塊最容易被忽視但至關重要的功能。直接給LLM喂食全部歷史對話和行動記錄很快就會觸及上下文長度限制且無關信息會干擾決策。解決方案是實現一個分層級的記憶系統最新記錄保留最近N輪完整的循環記錄感知、決策、行動、結果。歷史摘要對更早的記錄由LLM生成一段簡潔的摘要例如“用戶最初想訂機票我們已搜索了航班并比較了價格用戶對時間不太滿意。”關鍵事實提取將對話中確定的、不可更改的事實如“用戶姓名是張三”“出發日期是下周五”提取出來作為獨立的事實列表存儲便于快速查詢。感知模塊在每次循環開始時負責組裝這個“上下文包”最新的觀察 最近完整記錄 歷史摘要 相關關鍵事實。這確保了決策引擎擁有“恰到好處”的背景信息。注意事項感知模塊中的信息過濾和摘要生成邏輯需要謹慎設計避免信息丟失或扭曲。一個常見的坑是摘要過于籠統丟失了關鍵細節。建議為摘要過程制定明確的規則比如“必須包含涉及數字、時間、地點和用戶明確偏好的信息”。4. 決策引擎LLM作為推理核心的實踐細節決策引擎是整個循環的“指揮官”。我們依靠LLM強大的推理和規劃能力但它不是一個黑盒需要精心的提示工程和輸出約束。4.1 提示詞工程構建清晰的決策上下文給LLM的提示Prompt必須清晰界定它的角色、可用資源和當前目標。一個典型的決策提示詞結構如下你是一個專業的{Agent角色}。你的目標是{當前最高層級任務}。 當前情況工作記憶 {由感知模塊提供的結構化上下文摘要} 你剛剛觀察到的信息 {最新的Observation內容} 你可以使用的工具Actions 1. 工具A描述。輸入格式{“param1”: type, “param2”: type} 2. 工具B描述。 ... 3. 直接回復用戶當你認為需要與用戶溝通時使用。 請基于以上信息決定下一步做什么。你的輸出必須是嚴格的JSON格式 { “thought”: “你的逐步推理過程解釋為什么選擇這個動作” “action”: “工具名或‘reply’” “action_input”: {參數對象} 或 “回復內容” }關鍵點明確工具規格必須清晰描述每個工具的作用、輸入和輸出。LLM需要知道“能做什么”。強制結構化輸出要求JSON格式并定義好Schema這是后續代碼能可靠解析的前提。包含思維鏈Chain-of-Thought要求模型輸出“thought”字段至關重要。這不僅提高了決策的可解釋性便于調試而且實踐證明讓LLM“把思考過程寫出來”能顯著提升其決策質量。4.2 動作空間的定義與擴展“動作”是智能體影響環境的唯一方式。我們需要精心設計動作空間基礎動作調用某個函數/工具。復合動作一系列基礎動作的預定義組合如“預訂航班”可能包含“查詢航班”、“選擇航班”、“填寫乘客信息”三個基礎動作。對話動作直接向用戶發送消息用于詢問、確認、匯報進度。在代碼中我們可以用一個注冊表來管理所有可用動作class ActionRegistry: def __init__(self): self._tools {} def register(self, name: str, func: Callable, description: str, schema: dict): self._tools[name] { “func”: func, “description”: description, “schema”: schema # JSON Schema用于驗證LLM生成的輸入 } def execute(self, action_name: str, action_input: dict) - str: if action_name not in self._tools: return f“Error: Unknown action ‘{action_name}’” tool self._tools[action_name] # 1. 驗證輸入參數是否符合schema if not validate_input(action_input, tool[“schema”]): return “Error: Invalid action input parameters.” # 2. 執行 try: result tool[“func”](**action_input) return str(result) except Exception as e: return f“Error executing action: {str(e)}”4.3 處理不確定性、模糊性與規劃LLM的決策并非總是確定性的。我們需要處理幾種情況決策模糊LLM可能輸出“我需要更多信息”。此時決策引擎應將其轉化為一個明確的“向用戶提問”的動作。生成多步計劃對于復雜任務可以讓LLM先生成一個初步計劃Plan作為工作記憶的一部分。在后續每個循環中決策引擎不僅決定當前動作還參考和更新這個計劃。置信度與回退可以為LLM的決策附加一個置信度評分可以通過提示詞讓其自評或通過其輸出格式的規范性來判斷。當置信度低時可以觸發反思模塊進行復核或直接采用更保守的“請求確認”動作。踩坑實錄早期我們直接讓LLM輸出“調用工具A參數是XXX”這樣的自然語言然后在代碼里用正則表達式去解析這是災難性的。任何格式的偏差都會導致解析失敗。強制結構化JSON輸出并做嚴格驗證是保證系統穩定性的生命線。同時一定要讓LLM在thought字段中“說出它的想法”這是調試時最寶貴的日志。5. 行動執行器安全、可靠地連接外部世界決策引擎發出了指令行動執行器負責將其落到實處。這個模塊的關鍵詞是魯棒性。5.1 工具的設計與封裝一個好的工具應該功能單一一個工具只做一件事。例如“搜索網絡”和“計算數學”應該是兩個獨立的工具。接口明確有清晰的輸入參數類型說明和輸出格式承諾。安全無害特別是涉及寫操作、網絡訪問或敏感信息處理的工具必須有權限檢查和沙箱機制。具備超時和重試機制外部API調用可能會失敗需要有合理的超時設置和有限次數的重試邏輯。def search_web(query: str, max_results: int 5) - str: “”“使用搜索引擎查詢信息。 Args: query: 搜索關鍵詞。 max_results: 返回的最大結果數量。 Returns: 一個格式化的字符串包含搜索結果的標題、鏈接和摘要。 ”“” # 這里集成SerpAPI、Google Search API或其他搜索服務 # 必須包含try-catch和超時處理 pass5.2 動作執行的流水線一個動作的執行并非簡單調用函數而應經過一個流水線解析與驗證解析決策引擎輸出的JSON驗證動作名稱是否存在輸入參數是否符合預定義的Schema使用如jsonschema庫。參數預處理有時需要對參數進行預處理比如將LLM生成的日期描述“下周五”轉換為具體的日期字符串。安全審查可選但重要對于高風險動作如發送郵件、執行數據庫刪除可以加入一層人工審核或二次確認邏輯。執行與超時控制在獨立的線程或異步任務中執行工具調用并設置超時。結果格式化將工具返回的原始數據可能是對象、列表等格式化為LLM容易理解的文本描述。同時將原始結果也保存下來供后續模塊使用。5.3 異常處理與反饋行動可能失敗失敗信息必須清晰、可操作并反饋給循環。工具錯誤如網絡錯誤、API密鑰無效。執行器應捕獲異常并生成標準化的錯誤信息如“Action ‘search_web’ failed: Network timeout (Exception: …)”。這將成為下一次循環中“感知模塊”的輸入。邏輯錯誤工具執行成功但結果表示業務邏輯失敗如“用戶余額不足”。這類錯誤也應被格式化后返回它對于智能體調整策略至關重要。實操心得為每一個工具編寫詳盡、示例清晰的文檔字符串并把這些文檔動態地插入到給LLM的提示詞中能極大提升工具調用的準確性。另外所有工具調用都應該有日志記錄包括輸入、輸出、耗時和錯誤信息這是后期優化和審計的基礎。6. 反思模塊實現智能體的持續學習與調整反思是區分高級智能體與簡單自動化腳本的關鍵。它讓智能體不僅“做事”還能“思考做事的效果”并據此調整。6.1 反思的觸發時機反思不是每個循環都必須的那樣效率太低。通常在以下時機觸發動作失敗后當行動執行器返回明確錯誤時。子目標達成后完成一個階段性任務時評估是否偏離主航道。陷入循環或僵局時檢測到智能體在重復相似動作或無進展超過一定步數時。用戶給出反饋時用戶說“不對”或“這不是我想要的”。6.2 反思的內容與過程反思本身也可以看作一個由LLM驅動的微循環。它的輸入是當前目標、相關的工作記憶尤其是最近失敗或低效的步驟序列、以及需要反思的具體事件。我們給反思LLM設計專門的提示詞你是一個分析員負責評估智能體最近的表現并給出改進建議。 智能體的最終目標是{主目標}。 最近發生的事件{對觸發反思事件的具體描述如‘調用工具X失敗錯誤信息是...’}。 相關的行動歷史{最近幾步的詳細記錄}。 請分析 1. 問題診斷最近的問題出在哪里是目標理解有誤、計劃不合理、工具選擇錯誤還是參數有問題 2. 修正建議接下來應該怎么做是換一種方式重試當前步驟還是需要回溯到更早的步驟重新規劃 3. 經驗總結從這個事件中可以學到什么生成一條簡短的經驗教訓以便未來避免。 請以JSON格式輸出你的分析。反思LLM的輸出會被解析并用于直接調整工作記憶和計劃例如如果反思認為“參數錯誤”決策引擎在下一次決策時會被注入“避免使用XX參數”的提示。生成長期記憶將“經驗總結”存入一個向量數據庫或知識庫未來在類似場景下感知模塊可以檢索這些經驗來輔助決策。觸發高層重規劃如果反思認為當前整個計劃都行不通它可以發出一個信號要求決策引擎拋棄原有計劃從更高層面重新思考任務。6.3 實現持續學習的簡單模式實現完整的終身學習很難但我們可以從簡單的模式開始錯誤模式庫將常見的工具錯誤如“404 Not Found”“Invalid API Key”和對應的修正建議如“請檢查資源是否存在”“請確認API密鑰配置”映射起來。當感知到這類錯誤時可以直接建議決策引擎采取修正動作無需每次都調用LLM反思。成功案例存儲當智能體完美解決一個復雜任務后可以將這個任務的目標、最終成功的行動序列作為“案例”存儲起來。未來遇到類似任務時可以通過向量檢索快速找到一個可行的起點計劃。注意事項反思模塊本身也會消耗LLM Token并增加延遲。要避免過度反思。為不同類型的觸發事件設置不同的反思“深度”和“預算”。例如對于簡單的工具調用失敗可能只需要一個快速的、基于規則的建議而對于任務陷入僵局才需要啟動深度的、由LLM驅動的分析。7. 系統集成與實戰構建一個任務執行智能體現在讓我們把以上所有模塊組合起來構建一個能執行“研究并撰寫簡報”任務的智能體。假設我們有網絡搜索、文件讀寫、文本摘要等工具。7.1 系統工作流串聯初始化用戶輸入任務“調研一下特斯拉2024年第一季度的財報亮點寫一份不超過500字的簡報。”循環開始感知工作記憶初始化為用戶任務。感知模塊無外部新觀察但將任務作為關鍵信息。決策決策引擎LLM看到任務查看工具列表搜索、總結、寫文件在thought中推理“這是一個信息檢索和總結任務。我需要先搜索最新財報信息。” 輸出決策動作search_web 輸入{“query”: “Tesla Q1 2024 earnings report highlights”}。行動行動執行器調用搜索工具獲得一系列網頁摘要和鏈接。反思此輪暫不觸發行動成功結果有效繼續。下一輪循環感知感知模塊將搜索結果的文本內容格式化并提取關鍵數據如營收數字、交付量作為新的Observation。決策LLM看到搜索結果思考“信息很多需要提煉。我可以先調用總結工具聚焦于‘亮點’。” 輸出決策動作summarize_text 輸入{“text”: [搜索結果的整合文本], “focus”: “financial highlights and key metrics”}。行動執行總結工具生成一份初步提煉的文本。反思評估總結結果是否覆蓋了“亮點”是否冗長。可能觸發一個輕量級反思認為“信息已提煉但格式不是簡報”。后續循環決策引擎可能繼續決策調用“撰寫報告”工具將總結內容格式化為簡報。最后調用“保存文件”工具輸出結果。在整個過程中如果搜索工具返回“未找到相關信息”則會觸發反思模塊分析是否查詢詞不對并建議調整搜索策略。7.2 核心代碼結構示意class TaskExecutionAgent: def __init__(self, llm_client, action_registry): self.llm llm_client self.actions action_registry self.working_memory WorkingMemory() self.reflector ReflectionModule(llm_client) def run(self, user_task: str): self.working_memory.set_goal(user_task) max_steps 20 for step in range(max_steps): # 1. 感知 observation self.perception_module.observe(self.working_memory) # 2. 決策 decision self.decision_engine.decide(self.working_memory, observation) self.working_memory.add_record(decision[“thought”], decision) # 記錄 # 3. 行動 result self.action_executor.execute(decision[“action”], decision[“action_input”]) self.working_memory.add_record(“action_result”, result) # 4. 評估與反思 if self.should_reflect(result, step): reflection self.reflector.analyze(self.working_memory, result) self.working_memory.integrate_reflection(reflection) # 將反思結論融入記憶 # 檢查任務是否完成 if self.working_memory.is_goal_achieved(): break return self.working_memory.get_final_output()7.3 性能優化與調試技巧異步執行如果動作是IO密集型的如網絡請求可以將動作執行改為異步讓智能體在等待一個動作結果的同時可能處理其他并行的子任務思考。緩存對昂貴的LLM調用如決策、反思或工具調用如搜索相同內容的結果進行緩存可以大幅降低成本和提高響應速度。可視化調試將每個循環的thought、action、result以及工作記憶的狀態變化以日志或可視化界面的形式輸出。這是理解智能體“思維過程”、定位問題的最有效手段。可以設計一個簡單的Web界面實時展示智能體的決策流。8. 常見問題與排查指南在實際構建和運行Agent控制循環時你會遇到各種各樣的問題。下面是一些典型問題及其排查思路。8.1 智能體陷入無效循環或重復動作現象智能體反復執行相同或相似的動作無法推進任務。可能原因與排查觀察信息不足或未更新檢查感知模塊是否正確地將行動結果納入了工作記憶并傳遞給了下一次決策。可能是結果解析失敗導致LLM每次看到的都是舊信息。決策提示詞缺乏約束提示詞中沒有明確要求智能體避免重復或者沒有提供足夠的上下文來區分“已嘗試過”和“未嘗試”的方案。在提示詞中加入類似“你已經嘗試過A方法但失敗了請嘗試不同的方法”的指令。缺少進展評估工作記憶中沒有“已嘗試步驟”的明確記錄和“任務完成條件”的判斷。需要在工作記憶中維護一個“已嘗試動作列表”并在決策提示詞中讓其參考。反思模塊未觸發系統可能缺少對“循環檢測”的邏輯。可以添加一個簡單的規則如果連續3個循環的動作本質相同則強制觸發深度反思。8.2 工具調用參數總是錯誤現象LLM決策時選擇的工具是對的但生成的參數格式不對、缺少必填字段或值不合理。可能原因與排查工具描述不清檢查注冊工具時提供的description和schema是否足夠清晰、示例化。LLM不理解“id”字段應該是什么格式如果你寫“用戶ID”它可能生成一個名字。應該寫成“用戶ID字符串格式例如‘user_123456’”。缺少參數預處理LLM可能生成“明天下午三點”而工具需要“2024-05-28 15:00:00”。需要在行動執行器的流水線中加入一個參數預處理步驟使用一個小的LLM調用或規則將自然語言參數轉換為規范格式。輸出格式約束不夠強雖然要求輸出JSON但可能沒有用更嚴格的方式如函數調用Function Calling、或結構化輸出Structured Outputs來約束LLM。如果所用LLM API支持優先使用這些原生結構化輸出功能比在提示詞中要求JSON更可靠。8.3 智能體“忘記”最終目標在子任務中迷失現象智能體在執行一系列子任務如不斷搜索、總結后不再回歸到主任務如撰寫簡報。可能原因與排查工作記憶中的目標被稀釋在組裝決策上下文時原始的用戶任務最高目標被埋沒在大量的歷史對話和中間結果中。解決方案在每次給決策引擎的提示詞中將“最終目標”單獨、醒目地放在最前面并可能每次循環都重復強調。缺乏高層規劃智能體只做一步決策沒有生成一個指向最終目標的頂層計劃。解決方案在任務開始時讓決策引擎先做一個規劃步驟輸出一個大致步驟列表如1. 搜索信息2. 提煉亮點3. 撰寫簡報。將這個計劃存入工作記憶并在后續每個決策步驟中都讓LLM參考這個計劃并標記當前步驟的完成情況。反思模塊未評估目標偏離反思只關注動作失敗不評估整體進展。解決方案在反思的觸發條件或反思提示詞中加入對“當前進展是否偏離最終目標”的評估。8.4 處理速度慢延遲高現象完成一個簡單任務需要數十秒甚至分鐘級。可能原因與排查順序執行與網絡延遲所有步驟LLM決策、工具調用、LLM反思都是同步順序執行且工具調用如網絡搜索可能有高延遲。優化將可以并行的操作并行化。例如如果決策是調用多個獨立的工具可以考慮讓它們同時執行。或者將LLM調用決策、反思與IO操作工具執行異步化。上下文過長工作記憶積累太多導致每次決策提示詞都非常龐大LLM處理速度變慢Token消耗激增。優化實施前文提到的分層記憶和摘要機制嚴格控制輸入LLM的上下文長度。過度反思每個循環都進行深度LLM反思。優化根據規則如只有失敗或停滯時才反思來動態控制反思的深度和頻率對于簡單確認可以使用更快的規則引擎或小模型。構建一個穩定、高效、智能的Agent系統控制循環的設計與實現是核心。它沒有一成不變的銀彈需要你根據具體的任務領域、可用的工具和性能要求不斷地迭代和調優。從最簡單的單循環開始逐步增加記憶、反思、規劃等高級功能并輔以完善的日志和監控你就能讓這個“大腦”越來越聰明真正解決那些令人頭疼的復雜自動化任務。