工程構建可自我修正的AI Agent協(xié)同系統(tǒng))
最近在嘗試將大模型能力深度集成到自動化工作流中時遇到了一個典型困境如何讓AI Agent不僅能執(zhí)行單次任務還能在復雜、多步驟的流程中基于執(zhí)行結果進行自我修正和迭代優(yōu)化這正是“循環(huán)工程”要解決的核心問題。結合GLM-5.3這類強大的國產大模型我們可以構建出更智能、更安全的自動化協(xié)同系統(tǒng)。本文將圍繞“GLM-5.3擴展編程與安全邊界循環(huán)工程重寫Agent協(xié)同”這一主題為你拆解從概念到實戰(zhàn)的全過程。無論你是想了解AI Agent開發(fā)還是希望將大模型能力安全、可控地應用于實際業(yè)務場景這篇文章都將提供一套可直接復用的技術方案和避坑指南。1. 核心概念解析GLM-5.3、Agent與循環(huán)工程在深入代碼之前我們需要統(tǒng)一對幾個核心概念的理解這有助于我們構建清晰的技術架構。1.1 GLM-5.3不只是一個大語言模型GLM-5.3是智譜AI推出的新一代基座大模型。在本文的上下文中我們主要利用其以下幾個關鍵能力強大的代碼生成與理解能力能夠根據自然語言描述生成、解釋、調試和重構多種編程語言的代碼片段。長上下文窗口能夠處理和理解較長的對話歷史和復雜的技術文檔這對于多輪交互的Agent至關重要。函數(shù)調用Function Calling這是將大模型能力“工具化”的核心。GLM-5.3可以理解用戶請求并決定調用哪個預定義的工具函數(shù)來完成任務并結構化地返回調用參數(shù)??煽氐纳膳c安全對齊經過安全訓練能在一定程度上避免生成有害或不安全的代碼與內容為構建安全的自動化系統(tǒng)提供了基礎。我們可以將其視為一個具備極強邏輯推理和代碼能力的“大腦”但它本身不具備執(zhí)行能力如運行代碼、訪問數(shù)據庫、調用API。1.2 AI Agent具備執(zhí)行能力的智能體AI Agent是一個能夠感知環(huán)境、進行決策并執(zhí)行行動以實現(xiàn)目標的系統(tǒng)。一個典型的AI Agent架構通常包含以下組件規(guī)劃模塊Planner分解目標制定分步計劃。GLM-5.3可以充當這個角色。工具集ToolsAgent可以調用的具體能力例如執(zhí)行Python代碼、進行網絡搜索、讀寫文件、查詢數(shù)據庫、調用外部API等。記憶模塊Memory存儲對話歷史、工具執(zhí)行結果、學習到的知識為后續(xù)決策提供上下文。執(zhí)行器Executor負責調用工具并處理工具返回的結果。簡單說Agent 大模型大腦 工具手腳 記憶經驗。GLM-5.3為Agent提供了“大腦”而我們需要為其構建“手腳”和“經驗”。1.3 循環(huán)工程ReAct, ReWOO, 迭代優(yōu)化這是本文的技術核心。傳統(tǒng)的一次性Prompt調用無法處理復雜任務。循環(huán)工程指的是讓Agent進入一個“觀察-思考-行動”的循環(huán)觀察接收用戶輸入和上一步的執(zhí)行結果包括成功、失敗或中間狀態(tài)。思考分析當前狀況決定下一步是繼續(xù)調用工具、修正錯誤還是認為任務已完成。行動執(zhí)行選定的工具。循環(huán)將行動結果反饋給“觀察”步驟開始新一輪循環(huán)直到任務達成或失敗退出。這種模式使得Agent能夠處理需要試錯、調試和分步驗證的復雜編程或運維任務例如“為這個存在Bug的函數(shù)編寫單元測試并修復它”。2. 環(huán)境準備與項目初始化我們將使用Python作為主要開發(fā)語言并利用一些成熟的庫來簡化Agent系統(tǒng)的構建。2.1 基礎環(huán)境與依賴確保你的Python版本在3.8以上。我們使用pip安裝核心庫。# 創(chuàng)建項目目錄并進入 mkdir glm-agent-loop cd glm-agent-loop # 創(chuàng)建虛擬環(huán)境推薦 python -m venv venv # 激活虛擬環(huán)境 # Windows: venv\Scripts\activate # Linux/Mac: source venv/bin/activate # 安裝核心依賴 pip install openai # 用于調用GLM API兼容OpenAI格式 pip install langchain-core langchain-community # LangChain核心及社區(qū)工具 pip install python-dotenv # 管理環(huán)境變量關鍵版本說明openai庫版本需1.0.0其客戶端與GLM的OpenAI兼容接口對接。langchain是一個強大的Agent框架但我們這里主要使用其工具抽象和鏈式調用思想避免過度依賴其高級封裝以保持靈活性。2.2 獲取并配置GLM API密鑰你需要訪問智譜AI開放平臺注冊并創(chuàng)建應用以獲取API Key。前往智譜AI開放平臺。在“API密鑰”管理頁面創(chuàng)建一個新的密鑰。在項目根目錄創(chuàng)建.env文件用于安全存儲密鑰。# .env 文件內容 GLM_API_KEYyour_glm_api_key_here GLM_API_BASEhttps://open.bigmodel.cn/api/paas/v4/ # GLM的API基礎地址 GLM_MODELglm-4 # 或根據可用性選擇 glm-3-turbo, glm-4v 等。GLM-5.3的API名稱請以平臺為準。安全警告務必在.env文件中配置密鑰并確保.env文件被添加到.gitignore中絕對不要將密鑰硬編碼在源代碼里或提交到版本控制系統(tǒng)。2.3 項目結構規(guī)劃一個清晰的項目結構有助于管理復雜的Agent邏輯和工具。glm-agent-loop/ ├── .env # 環(huán)境變量密鑰 ├── .gitignore # Git忽略文件 ├── requirements.txt # 項目依賴 ├── src/ │ ├── __init__.py │ ├── config.py # 配置加載 │ ├── glm_client.py # GLM客戶端封裝 │ ├── tools/ # 工具集目錄 │ │ ├── __init__.py │ │ ├── code_tool.py # 代碼執(zhí)行工具 │ │ ├── file_tool.py # 文件讀寫工具 │ │ └── web_tool.py # 網絡搜索工具示例 │ ├── agent/ # Agent核心邏輯目錄 │ │ ├── __init__.py │ │ ├── base_agent.py # Agent基類 │ │ └── loop_agent.py # 實現(xiàn)循環(huán)工程的Agent │ └── memory/ # 記憶模塊 │ ├── __init__.py │ └── simple_memory.py # 簡易對話記憶 └── main.py # 主程序入口3. 構建核心組件客戶端、工具與記憶3.1 配置與GLM客戶端封裝首先我們創(chuàng)建配置加載和GLM客戶端。# src/config.py import os from dotenv import load_dotenv load_dotenv() # 加載 .env 文件中的環(huán)境變量 class GLMConfig: API_KEY os.getenv(GLM_API_KEY) API_BASE os.getenv(GLM_API_BASE, https://open.bigmodel.cn/api/paas/v4/) MODEL os.getenv(GLM_MODEL, glm-4) classmethod def validate(cls): if not cls.API_KEY: raise ValueError(GLM_API_KEY 未在環(huán)境變量中設置。請檢查 .env 文件。) print(f配置加載成功使用模型: {cls.MODEL})# src/glm_client.py from openai import OpenAI from src.config import GLMConfig class GLMClient: 封裝GLM API調用 def __init__(self): self.client OpenAI( api_keyGLMConfig.API_KEY, base_urlGLMConfig.API_BASE, ) def chat_completion(self, messages, temperature0.1, max_tokens2000): 調用GLM聊天補全接口。 Args: messages: 對話消息列表格式 [{role: user, content: ...}, ...] temperature: 生成溫度越低越確定越高越隨機。 max_tokens: 生成的最大token數(shù)。 Returns: 模型返回的完整響應對象。 try: response self.client.chat.completions.create( modelGLMConfig.MODEL, messagesmessages, temperaturetemperature, max_tokensmax_tokens, ) return response except Exception as e: print(f調用GLM API時發(fā)生錯誤: {e}) raise def extract_content(self, response): 從響應中提取文本內容 if response and response.choices: return response.choices[0].message.content return 3.2 實現(xiàn)關鍵工具Tools工具是Agent的手腳。我們實現(xiàn)兩個最核心的工具代碼執(zhí)行和文件讀寫。# src/tools/code_tool.py import subprocess import sys import tempfile import os class CodeExecutionTool: 安全地執(zhí)行Python代碼片段 name execute_python_code description 執(zhí)行一段Python代碼并返回結果。輸入應為有效的Python代碼字符串。警告此工具會實際執(zhí)行代碼請確保代碼來源安全。 def __init__(self, timeout10): self.timeout timeout def run(self, code_str: str) - str: 在隔離的子進程中執(zhí)行代碼。 Args: code_str: 要執(zhí)行的Python代碼。 Returns: 執(zhí)行結果stdout或錯誤信息stderr。 # 安全警告在實際生產環(huán)境中需要在沙箱如Docker容器中運行不可信代碼。 # 此處為演示僅做基本隔離。 with tempfile.NamedTemporaryFile(modew, suffix.py, deleteFalse) as f: f.write(code_str) temp_file_path f.name try: # 使用子進程運行捕獲輸出 result subprocess.run( [sys.executable, temp_file_path], capture_outputTrue, textTrue, timeoutself.timeout ) output result.stdout if result.stderr: output f\n[標準錯誤輸出]:\n{result.stderr} if result.returncode ! 0: output f[進程退出代碼: {result.returncode}]\n output return output.strip() or (代碼已執(zhí)行無輸出) except subprocess.TimeoutExpired: return f錯誤代碼執(zhí)行超時{self.timeout}秒。 except Exception as e: return f執(zhí)行過程中發(fā)生意外錯誤: {e} finally: # 清理臨時文件 try: os.unlink(temp_file_path) except: pass# src/tools/file_tool.py import os class FileReadWriteTool: 讀寫本地文件限制在項目目錄內以保證安全 name read_write_file description 讀取或寫入文件內容。輸入應為JSON格式字符串例如{\action\: \read\, \filepath\: \test.txt\} 或 {\action\: \write\, \filepath\: \test.txt\, \content\: \Hello\}。文件路徑必須是當前工作目錄下的相對路徑。 def __init__(self, base_dir.): self.base_dir os.path.abspath(base_dir) # 確?;A目錄存在 os.makedirs(self.base_dir, exist_okTrue) def _resolve_path(self, filepath): 解析文件路徑確保其在允許的基目錄下 requested_path os.path.abspath(os.path.join(self.base_dir, filepath)) # 安全檢查請求的路徑必須在基礎目錄下 if not requested_path.startswith(self.base_dir): raise PermissionError(f禁止訪問基礎目錄之外的文件: {filepath}) return requested_path def run(self, input_str: str) - str: try: import json params json.loads(input_str) action params.get(action) filepath params.get(filepath) if not action or not filepath: return 錯誤輸入必須包含 action 和 filepath 字段。 resolved_path self._resolve_path(filepath) if action read: if not os.path.exists(resolved_path): return f錯誤文件不存在 - {filepath} with open(resolved_path, r, encodingutf-8) as f: content f.read() return f文件 {filepath} 的內容\n\n{content}\n elif action write: content params.get(content, ) # 確保目錄存在 os.makedirs(os.path.dirname(resolved_path), exist_okTrue) with open(resolved_path, w, encodingutf-8) as f: f.write(content) return f成功寫入文件 {filepath}。 else: return f錯誤不支持的操作 {action}僅支持 read 或 write。 except json.JSONDecodeError: return 錯誤輸入不是有效的JSON格式。 except PermissionError as e: return f安全錯誤{e} except Exception as e: return f文件操作失敗: {e}3.3 實現(xiàn)簡易記憶模塊記憶讓Agent擁有上下文感知能力。# src/memory/simple_memory.py from typing import List, Dict class SimpleConversationMemory: 簡單的對話記憶保存用戶與模型的交互歷史 def __init__(self, max_turns10): self.memory: List[Dict] [] # 存儲格式: {role: user/assistant, content: ...} self.max_turns max_turns # 最大記憶輪數(shù)防止上下文過長 def add_user_message(self, content: str): self.memory.append({role: user, content: content}) self._trim_memory() def add_assistant_message(self, content: str): self.memory.append({role: assistant, content: content}) self._trim_memory() def add_tool_message(self, tool_name: str, tool_input: str, tool_output: str): # 將工具調用和結果也作為消息加入記憶格式可以自定義 # 這里簡化處理將結果作為assistant的“觀察”加入 observation f[調用工具 {tool_name}] 輸入: {tool_input}\n輸出: {tool_output} self.memory.append({role: assistant, content: observation}) self._trim_memory() def get_conversation_history(self) - List[Dict]: 獲取用于模型輸入的對話歷史 return self.memory.copy() def clear(self): self.memory.clear() def _trim_memory(self): 修剪記憶保留最近的 max_turns*2 條消息因為一輪對話有user和assistant兩條 if len(self.memory) self.max_turns * 2: self.memory self.memory[-(self.max_turns * 2):]4. 實現(xiàn)循環(huán)工程驅動的Agent協(xié)同這是最核心的部分。我們將實現(xiàn)一個能夠自主規(guī)劃、調用工具、并根據結果決定下一步行動的Agent。4.1 定義Agent基類與工具管理# src/agent/base_agent.py from abc import ABC, abstractmethod from typing import Dict, Any, List from src.memory.simple_memory import SimpleConversationMemory class BaseAgent(ABC): Agent的抽象基類 def __init__(self, name: str GLM-Agent): self.name name self.memory SimpleConversationMemory(max_turns20) self.tools: Dict[str, Any] {} # 工具名稱 - 工具實例的映射 self._register_default_tools() def _register_default_tools(self): 注冊默認工具子類可以重寫此方法 from src.tools.code_tool import CodeExecutionTool from src.tools.file_tool import FileReadWriteTool code_tool CodeExecutionTool() file_tool FileReadWriteTool(base_dir./workspace) # 限定工作空間 self.register_tool(code_tool) self.register_tool(file_tool) def register_tool(self, tool): 注冊一個工具 self.tools[tool.name] tool def get_tools_description(self) - str: 生成所有工具的描述文本用于構造Prompt descriptions [] for name, tool_instance in self.tools.items(): desc f- {name}: {tool_instance.description} descriptions.append(desc) return \n.join(descriptions) abstractmethod def run(self, user_input: str) - str: 運行Agent處理用戶輸入返回最終響應 pass4.2 實現(xiàn)循環(huán)工程AgentReAct模式我們實現(xiàn)一個簡化版的ReActReasoning Acting模式Agent。# src/agent/loop_agent.py import json import re from src.agent.base_agent import BaseAgent from src.glm_client import GLMClient class LoopEngineeringAgent(BaseAgent): 基于循環(huán)工程ReAct模式的Agent def __init__(self, max_iterations5): super().__init__(nameLoop-Engineering-Agent) self.glm_client GLMClient() self.max_iterations max_iterations # 最大循環(huán)次數(shù)防止無限循環(huán) def run(self, user_input: str) - str: 執(zhí)行循環(huán)工程流程。 1. 將用戶輸入和工具描述發(fā)送給GLM讓其“思考”并決定行動。 2. 解析GLM的響應提取要調用的工具和參數(shù)。 3. 執(zhí)行工具。 4. 將工具結果反饋給GLM進入下一輪“思考”。 5. 直到GLM認為任務完成或達到最大迭代次數(shù)。 print(f\n 開始處理任務: {user_input} ) # 初始化循環(huán) iteration 0 final_answer None # 將初始用戶輸入加入記憶 self.memory.add_user_message(user_input) while iteration self.max_iterations: iteration 1 print(f\n--- 第 {iteration} 輪迭代 ---) # 步驟1構造Prompt讓模型“思考” prompt self._construct_react_prompt() print(f[思考Prompt]:\n{prompt[:500]}...) # 打印部分Prompt便于調試 # 調用GLM進行“思考” try: response self.glm_client.chat_completion( messages[{role: user, content: prompt}], temperature0.1, # 低溫度保證決策穩(wěn)定 max_tokens1500 ) assistant_response self.glm_client.extract_content(response) print(f[模型原始響應]:\n{assistant_response}) except Exception as e: return f調用模型失敗: {e} # 步驟2解析響應判斷是最終答案還是工具調用 if self._looks_like_final_answer(assistant_response): final_answer assistant_response self.memory.add_assistant_message(final_answer) print(f[判斷為最終答案結束循環(huán)]) break # 步驟3嘗試解析工具調用 tool_name, tool_input self._parse_tool_call(assistant_response) if tool_name and tool_name in self.tools: print(f[決定調用工具]: {tool_name} 參數(shù): {tool_input[:100]}...) # 執(zhí)行工具 tool_instance self.tools[tool_name] tool_output tool_instance.run(tool_input) print(f[工具執(zhí)行結果]:\n{tool_output[:300]}...) # 截斷長輸出 # 將工具調用和結果格式化為觀察消息加入記憶 observation f我調用了工具 {tool_name}。\n工具返回結果{tool_output} self.memory.add_assistant_message(observation) elif tool_name: # 模型想調用工具但工具未注冊 error_msg f錯誤工具 {tool_name} 未注冊或不可用。 print(error_msg) self.memory.add_assistant_message(error_msg) else: # 模型響應既不是最終答案也不是有效的工具調用可能是在“推理” # 我們將其作為普通助理消息加入記憶繼續(xù)循環(huán) print([模型響應為推理或中間步驟繼續(xù)循環(huán)]) self.memory.add_assistant_message(assistant_response) # 循環(huán)結束 if final_answer: return final_answer else: return f任務未在 {self.max_iterations} 輪內完成。最后的狀態(tài)記憶如下\n{self._format_memory_for_display()} def _construct_react_prompt(self) - str: 構造ReAct風格的Prompt tools_desc self.get_tools_description() history self.memory.get_conversation_history() # 將歷史格式化為文本 history_text for msg in history: role msg[role] content msg[content] history_text f{role.upper()}: {content}\n prompt f你是一個智能助手可以調用工具來幫助用戶解決問題。你擁有以下工具 {tools_desc} 你的任務是根據對話歷史和當前目標決定下一步行動。你必須嚴格按照以下格式回應 **格式規(guī)則** 1. 如果你想調用工具必須在一行內以 ACTION: 開頭然后是工具名稱和輸入用 | 分隔。例如 ACTION: execute_python_code | print(\Hello World\) ACTION: read_write_file | {{\action\: \read\, \filepath\: \data.txt\}} 2. 如果你認為已經收集到足夠信息可以給出最終答案則直接以 FINAL ANSWER: 開頭后面跟你的答案。 3. 如果你需要進行一些推理或解釋但暫時不調用工具可以正常書寫但不要使用 ACTION: 或 FINAL ANSWER: 前綴。 **當前對話歷史** {history_text} 請根據以上信息決定你的下一步。記住你可以進行多輪工具調用。 return prompt def _looks_like_final_answer(self, response: str) - bool: 判斷模型響應是否以 FINAL ANSWER: 開頭 return response.strip().startswith(FINAL ANSWER:) def _parse_tool_call(self, response: str): 從模型響應中解析工具調用。返回 (tool_name, tool_input) 或 (None, None) lines response.strip().split(\n) for line in lines: if line.startswith(ACTION:): # 格式: ACTION: tool_name | tool_input parts line[len(ACTION:):].strip().split(|, 1) if len(parts) 2: tool_name parts[0].strip() tool_input parts[1].strip() return tool_name, tool_input return None, None def _format_memory_for_display(self): 格式化記憶用于顯示 return \n.join([f{msg[role]}: {msg[content][:200]}... for msg in self.memory.get_conversation_history()])4.3 主程序入口與實戰(zhàn)演示讓我們創(chuàng)建一個主程序來測試這個循環(huán)工程Agent。# main.py import sys import os sys.path.append(os.path.dirname(os.path.abspath(__file__))) from src.config import GLMConfig from src.agent.loop_agent import LoopEngineeringAgent def main(): # 1. 驗證配置 try: GLMConfig.validate() except ValueError as e: print(f配置錯誤: {e}) print(請確保已創(chuàng)建 .env 文件并正確設置 GLM_API_KEY。) return # 2. 初始化Agent print(初始化循環(huán)工程Agent...) agent LoopEngineeringAgent(max_iterations8) # 允許最多8輪迭代 # 3. 示例任務讓Agent編寫一個函數(shù)并測試它 # 任務1相對簡單讀寫文件 task1 請在我的工作空間workspace目錄下創(chuàng)建一個名為 hello.txt 的文件內容為 Hello from GLM Agent!然后讀取這個文件并告訴我文件內容。 # 任務2涉及代碼生成與執(zhí)行 task2 請幫我完成以下任務 1. 編寫一個Python函數(shù) calculate_stats(numbers)接收一個數(shù)字列表返回它的總和、平均值和最大值。 2. 編寫一段測試代碼來調用這個函數(shù)使用列表 [1, 2, 3, 4, 5] 作為輸入。 3. 執(zhí)行測試代碼并告訴我結果。 # 4. 執(zhí)行任務 print(\n *50) print(執(zhí)行任務1: 文件操作) print(*50) result1 agent.run(task1) print(f\n最終結果:\n{result1}) # 可以清空記憶開始新任務 # agent.memory.clear() print(\n *50) print(執(zhí)行任務2: 代碼生成與測試) print(*50) result2 agent.run(task2) print(f\n最終結果:\n{result2}) if __name__ __main__: main()4.4 運行與結果分析在項目根目錄下確保.env文件已配置然后運行python main.py預期你會看到類似以下的輸出具體內容因模型響應而異配置加載成功使用模型: glm-4 初始化循環(huán)工程Agent... 執(zhí)行任務1: 文件操作 開始處理任務: 請在我的工作空間workspace目錄下創(chuàng)建一個名為 hello.txt 的文件... --- 第 1 輪迭代 --- [思考Prompt]: 你是一個智能助手可以調用工具來幫助用戶解決問題。你擁有以下工具 - execute_python_code: 執(zhí)行一段Python代碼并返回結果... - read_write_file: 讀取或寫入文件內容... ... [模型原始響應]: 我需要先創(chuàng)建文件然后讀取它。我將使用文件讀寫工具。 ACTION: read_write_file | {action: write, filepath: hello.txt, content: Hello from GLM Agent!} [決定調用工具]: read_write_file 參數(shù): {action: write, filepath: hello.txt, content: Hello from GLM Agent!} [工具執(zhí)行結果]: 成功寫入文件 hello.txt。 --- 第 2 輪迭代 --- [模型原始響應]: 文件已創(chuàng)建?,F(xiàn)在讀取它。 ACTION: read_write_file | {action: read, filepath: hello.txt} [決定調用工具]: read_write_file 參數(shù): {action: read, filepath: hello.txt} [工具執(zhí)行結果]: 文件 hello.txt 的內容Hello from GLM Agent!--- 第 3 輪迭代 --- [模型原始響應]: 我已經完成了創(chuàng)建和讀取文件的任務。 FINAL ANSWER: 已成功在 workspace/hello.txt 文件中寫入內容 Hello from GLM Agent!并讀取到相同內容。 [判斷為最終答案結束循環(huán)] 最終結果: FINAL ANSWER: 已成功在 workspace/hello.txt 文件中寫入內容 Hello from GLM Agent!并讀取到相同內容。對于任務2Agent會進行更多輪迭代可能首先生成函數(shù)代碼并寫入文件然后生成測試代碼并執(zhí)行最后分析執(zhí)行結果并給出最終答案。整個過程完全自動化展示了“循環(huán)工程”的威力。5. 安全邊界設計與最佳實踐構建此類自動化Agent系統(tǒng)安全是重中之重。以下是必須考慮的安全邊界和工程實踐。5.1 核心安全邊界設計安全風險防護措施本文示例中的實現(xiàn)代碼執(zhí)行逃逸沙箱隔離CodeExecutionTool在子進程中運行代碼生產環(huán)境應使用Docker容器或專用沙箱嚴格限制網絡、文件系統(tǒng)和系統(tǒng)調用。文件系統(tǒng)越權訪問路徑白名單/沙箱FileReadWriteTool通過_resolve_path方法將文件訪問限制在base_dir下。敏感信息泄露環(huán)境變量管理API密鑰等通過.env文件管理并加入.gitignore。無限循環(huán)/資源耗盡迭代次數(shù)/超時限制LoopEngineeringAgent有max_iterations參數(shù)CodeExecutionTool有timeout參數(shù)。模型濫用/惡意指令系統(tǒng)Prompt設計在_construct_react_prompt中通過嚴格的指令格式ACTION:/FINAL ANSWER:約束模型輸出降低其“自由發(fā)揮”可能。可在更前端添加內容安全過濾器。工具調用參數(shù)注入輸入驗證與清理FileReadWriteTool對輸入進行JSON解析和校驗。對于代碼執(zhí)行應避免執(zhí)行用戶直接提供的未經驗證代碼。5.2 工程最佳實踐工具設計原則單一職責每個工具只做一件事。明確接口輸入輸出格式清晰、結構化如JSON。完備的錯誤處理工具內部捕獲異常并以字符串形式返回錯誤信息供Agent分析。資源清理如CodeExecutionTool中的臨時文件清理。Agent流程控制設置明確的終止條件除了最大迭代次數(shù)還可以根據任務狀態(tài)如檢測到“任務完成”關鍵詞提前結束。狀態(tài)持久化將重要的中間狀態(tài)和記憶保存到數(shù)據庫或文件以便Agent中斷后能恢復??捎^測性像示例中一樣在關鍵步驟打印日志便于調試和監(jiān)控Agent的“思考”過程。Prompt工程優(yōu)化清晰的格式約束使用ACTION:和FINAL ANSWER:等明確的分隔符便于解析。提供示例在Prompt中給出1-2個工具調用的具體例子能極大提高模型遵循格式的準確性。分步引導對于復雜任務可以設計多階段Prompt讓Agent先規(guī)劃再執(zhí)行。性能與成本緩存對相同的工具調用請求如查詢某些靜態(tài)數(shù)據進行緩存。上下文長度管理SimpleConversationMemory的max_turns用于限制歷史長度避免超出模型上下文窗口并減少Token消耗。異步處理如果工具調用是IO密集型如網絡請求可以考慮使用異步來提高整體效率。6. 常見問題與排查思路在開發(fā)和使用此類Agent系統(tǒng)時你可能會遇到以下問題問題現(xiàn)象可能原因排查與解決思路Agent陷入無限循環(huán)1. 模型無法理解任務或工具結果。2. 終止條件不明確。3.max_iterations設置過高。1. 檢查每輪迭代的Prompt和模型響應看模型是否在“空轉”。2. 在Prompt中強化“當你認為任務完成時必須使用FINAL ANSWER:”的指令。3. 適當降低max_iterations如5-10輪。模型不按格式響應1. Prompt中格式指令不夠清晰。2. Temperature參數(shù)過高導致輸出隨機。1. 在Prompt中使用更醒目、更具體的格式說明并包含示例。2. 將temperature調低如0.1使輸出更確定。工具調用解析失敗1. 模型輸出的格式與解析邏輯不匹配。2. 工具名稱拼寫錯誤。1. 打印出模型的原始響應檢查ACTION:行格式是否正確。2. 在_parse_tool_call方法中增加更健壯的解析邏輯如正則表達式。3. 確保注冊的工具名稱與模型調用時使用的名稱完全一致。代碼執(zhí)行工具報錯或超時1. 生成的代碼存在語法錯誤。2. 代碼陷入死循環(huán)。3. 執(zhí)行環(huán)境缺少依賴。1. 讓Agent先嘗試用execute_python_code執(zhí)行import sys; print(sys.version)檢查環(huán)境。2. 在CodeExecutionTool中設置合理的timeout。3. 考慮讓Agent先運行一個簡單的代碼片段驗證環(huán)境。API調用失敗或超時1. API密鑰無效或過期。2. 網絡問題。3. 達到速率限制。1. 檢查.env文件配置和平臺API密鑰狀態(tài)。2. 在glm_client.py中添加重試機制和更詳細的錯誤日志。3. 查看GLM平臺提供的調用狀態(tài)和額度。文件操作權限錯誤1.base_dir路徑不存在或不可寫。2. 嘗試訪問base_dir之外的路徑。1. 確保FileReadWriteTool初始化時傳入的base_dir存在且有寫權限。2. 檢查_resolve_path的安全邏輯是否生效。7. 擴展方向與進階思考本文實現(xiàn)的Agent是一個基礎但完整的原型。你可以在此基礎上進行大量擴展集成更多工具網絡搜索讓Agent能獲取實時信息。數(shù)據庫查詢連接業(yè)務數(shù)據庫進行數(shù)據分析和報告生成。第三方API集成企業(yè)內部或公共API擴展能力邊界。命令行工具執(zhí)行系統(tǒng)命令需極高安全警惕。增強記憶與上下文管理向量數(shù)據庫記憶使用ChromaDB、Milvus等存儲長程記憶實現(xiàn)基于語義的檢索??偨Y性記憶在對話輪數(shù)過多時自動讓模型總結之前的對話要點替換原始長歷史以節(jié)省上下文長度。多Agent協(xié)同創(chuàng)建具有不同專長的Agent如代碼專家、測試專家、文檔專家并設計一個“協(xié)調者”Agent來分配和匯總子任務處理更復雜的項目。加入驗證與回滾機制對于關鍵操作如文件刪除、數(shù)據庫寫入可以讓Agent生成操作計劃由用戶確認后再執(zhí)行。實現(xiàn)簡單的操作日志以便在出錯時進行回滾。前端與交互使用Gradio、Streamlit構建Web界面或集成到Slack、釘釘?shù)葏f(xié)作工具中使非技術人員也能方便使用。通過GLM-5.3等大模型提供的強大認知能力結合循環(huán)工程賦予的迭代優(yōu)化和工具使用能力我們構建的Agent正從簡單的聊天機器人向能夠真正解決復雜問題的“數(shù)字員工”演進。關鍵在于始終牢記安全邊界以工程化的思維設計工具和流程讓AI的能力在可控的范圍內為我們創(chuàng)造價值。