戰(zhàn))
在探索AI驅(qū)動的自動化開發(fā)流程時(shí)你是否曾面臨這樣的困境依賴閉源的云端AI服務(wù)不僅數(shù)據(jù)安全存疑高昂的API調(diào)用成本也令人卻步同時(shí)讓AI智能體直接操作生產(chǎn)環(huán)境又擔(dān)心其不可預(yù)測的行為帶來災(zāi)難性后果。構(gòu)建一個(gè)既能自主決策、又能安全執(zhí)行的自動化軟件開發(fā)工廠是許多技術(shù)團(tuán)隊(duì)夢寐以求的目標(biāo)。本文將帶你從零開始手把手搭建一個(gè)“幾乎完全自托管、沙盒化、具備智能體Agentic能力的軟件工廠”。我們將深入探討如何整合開源大語言模型LLM、代碼執(zhí)行沙箱、任務(wù)編排框架打造一個(gè)安全、可控、高效的內(nèi)部AI開發(fā)流水線。無論你是希望提升團(tuán)隊(duì)研發(fā)效能的架構(gòu)師還是對AI Agent和自動化開發(fā)感興趣的開發(fā)者都能從本文中獲得一套完整、可落地的解決方案。1. 核心概念與架構(gòu)總覽在開始動手之前我們首先需要清晰地理解這個(gè)“軟件工廠”的各個(gè)核心組件及其扮演的角色。這有助于我們在后續(xù)的搭建和配置中明確每一步的目標(biāo)。1.1 什么是“自托管、沙盒化、智能體化的軟件工廠”這是一個(gè)集成了多種技術(shù)的復(fù)合型系統(tǒng)我們可以將其拆解為三個(gè)關(guān)鍵詞來理解自托管 (Self-hosted)指系統(tǒng)的核心組件尤其是大語言模型LLM運(yùn)行在我們自己掌控的服務(wù)器或私有云上而非依賴OpenAI、Anthropic等第三方商業(yè)API。這帶來了數(shù)據(jù)隱私安全、成本可控、網(wǎng)絡(luò)依賴性低以及可定制化模型等核心優(yōu)勢。沙盒化 (Sandboxed)指為AI智能體Agent執(zhí)行代碼、訪問文件、調(diào)用命令等操作提供一個(gè)嚴(yán)格隔離的、資源受限的安全環(huán)境。即使AI的指令或生成的代碼存在惡意或錯誤也不會影響到宿主機(jī)的核心系統(tǒng)或其他關(guān)鍵服務(wù)。這是實(shí)現(xiàn)“自動化”且“安全”的基石。智能體化 (Agentic)指系統(tǒng)具備自主理解目標(biāo)、規(guī)劃步驟、使用工具如代碼編輯器、終端、瀏覽器、執(zhí)行任務(wù)并基于結(jié)果進(jìn)行迭代的能力。它不再是簡單的“一問一答”聊天機(jī)器人而是一個(gè)能夠閉環(huán)完成復(fù)雜任務(wù)的自主智能體。軟件工廠 (Software Factory)是對整個(gè)系統(tǒng)目標(biāo)的比喻。它像一條自動化生產(chǎn)線能夠接收需求如“創(chuàng)建一個(gè)用戶登錄API”經(jīng)過需求分析、技術(shù)選型、代碼編寫、測試運(yùn)行等一系列工序最終輸出可運(yùn)行的軟件代碼或可直接部署的服務(wù)。1.2 系統(tǒng)核心架構(gòu)設(shè)計(jì)基于以上概念我們設(shè)計(jì)一個(gè)分層的系統(tǒng)架構(gòu)。這個(gè)架構(gòu)清晰地將不同職責(zé)的模塊分離便于理解、開發(fā)和維護(hù)。[用戶/系統(tǒng)] 輸入自然語言任務(wù) | v ------------------------------- | 智能體編排與控制層 | | (Agent Orchestration Layer) | | - 任務(wù)規(guī)劃與分解 | | - 工具調(diào)用決策 | | - 記憶與狀態(tài)管理 | | - 與LLM核心交互 | ------------------------------- | v ------------------------------- | 本地大語言模型服務(wù)層 | | (Self-hosted LLM Service Layer)| | - 開源LLM推理API (如Ollama) | | - 模型管理與加載 | ------------------------------- | v ------------------------------- | 安全沙箱執(zhí)行層 | | (Sandboxed Execution Layer) | | ------------------------- | | | 工具集 (Tools) | | | | - 代碼執(zhí)行器 (Python) | | | | - 文件讀寫 | | | | - 命令行執(zhí)行 | | | | - Git操作 | | | ------------------------- | | || | | ------------------------- | | | 沙箱環(huán)境 (Docker) | | | | - 資源限制 (CPU/內(nèi)存) | | | | - 文件系統(tǒng)隔離 | | | | - 網(wǎng)絡(luò)訪問控制 | | | ------------------------- | ------------------------------- | v [輸出] 代碼文件、運(yùn)行結(jié)果、日志各層說明智能體編排與控制層這是系統(tǒng)的大腦。我們選擇LangChain或LlamaIndex這類成熟的AI應(yīng)用框架。它們提供了構(gòu)建智能體所需的核心抽象如Agent、Tools、Memory并能方便地連接不同的LLM。本地大語言模型服務(wù)層這是系統(tǒng)的心臟。我們使用Ollama或LocalAI來在本地運(yùn)行如Llama 3.1、Qwen2.5、CodeLlama等開源模型。它們提供了類似OpenAI的API接口使得上層框架可以無縫切換。安全沙箱執(zhí)行層這是系統(tǒng)的手和腳也是安全的關(guān)鍵。我們使用Docker為每一個(gè)任務(wù)或每一次工具調(diào)用創(chuàng)建臨時(shí)的、隔離的容器。所有代碼執(zhí)行、文件操作都被限制在這個(gè)容器內(nèi)。工具集則作為容器內(nèi)可執(zhí)行的命令或腳本。2. 環(huán)境準(zhǔn)備與工具選型工欲善其事必先利其器。在開始編碼前我們需要準(zhǔn)備好所有必要的軟件和環(huán)境。以下清單是搭建本系統(tǒng)的基礎(chǔ)。2.1 基礎(chǔ)系統(tǒng)與運(yùn)行時(shí)要求操作系統(tǒng)推薦 Ubuntu 22.04 LTS 或更高版本或任何你熟悉的Linux發(fā)行版。macOS也可用于開發(fā)和測試。本文以Ubuntu為例。Docker Docker Compose這是實(shí)現(xiàn)沙盒化的核心。確保已安裝最新穩(wěn)定版。# 安裝Docker (Ubuntu示例) sudo apt update sudo apt install docker.io docker-compose sudo systemctl start docker sudo systemctl enable docker # 將當(dāng)前用戶加入docker組避免每次sudo sudo usermod -aG docker $USER # 退出并重新登錄使組生效Python 3.10我們的主控程序?qū)⑹褂肞ython編寫。建議使用pyenv或conda管理多版本Python。sudo apt install python3-pip python3-venvGit用于版本控制和可能的代碼倉庫操作。sudo apt install git2.2 核心組件安裝與配置2.2.1 部署本地LLM服務(wù) (Ollama)Ollama是運(yùn)行和管理開源模型的利器它簡化了模型下載和提供API的過程。安裝Ollama# 一鍵安裝腳本 curl -fsSL https://ollama.com/install.sh | sh拉取并運(yùn)行一個(gè)適合編程的模型例如codellama:7b或qwen2.5:7b。模型越大能力越強(qiáng)所需資源也越多。# 拉取模型首次運(yùn)行會自動下載 ollama pull codellama:7b # 在后臺運(yùn)行模型服務(wù)并指定API端口 ollama serve # 或者直接運(yùn)行模型服務(wù)會啟動在11434端口 ollama run codellama:7b驗(yàn)證服務(wù)Ollama默認(rèn)在http://localhost:11434提供兼容OpenAI的API。我們可以用curl測試。curl http://localhost:11434/api/generate -d { model: codellama:7b, prompt: Hello, how are you?, stream: false }如果看到返回的JSON中包含生成的文本說明服務(wù)正常。2.2.2 創(chuàng)建Python虛擬環(huán)境并安裝框架我們將使用LangChain作為智能體框架。創(chuàng)建項(xiàng)目目錄和虛擬環(huán)境mkdir self-hosted-agent-factory cd self-hosted-agent-factory python3 -m venv venv source venv/bin/activate # Linux/macOS # venv\Scripts\activate # Windows安裝依賴核心是langchain和langchain-community同時(shí)需要docker的Python SDK來操控沙箱。pip install langchain langchain-community pip install docker openai # openai包用于兼容Ollama的API pip install jupyter # 可選用于在notebook中交互式開發(fā)3. 構(gòu)建安全沙箱執(zhí)行器這是整個(gè)系統(tǒng)中最關(guān)鍵的安全組件。我們將創(chuàng)建一個(gè)基于Docker的沙箱用于安全地執(zhí)行AI智能體生成的代碼或命令。3.1 設(shè)計(jì)沙箱容器我們首先需要定義一個(gè)基礎(chǔ)的Docker鏡像里面包含智能體可能需要的各種工具Python、Node.js、git、curl、基礎(chǔ)的編譯工具等。文件sandbox/Dockerfile# 使用一個(gè)輕量級但工具齊全的Linux鏡像 FROM python:3.11-slim # 安裝系統(tǒng)依賴和常用工具 RUN apt-get update apt-get install -y \ git \ curl \ wget \ build-essential \ nodejs \ npm \ default-jre-headless \ rm -rf /var/lib/apt/lists/* # 設(shè)置工作目錄 WORKDIR /workspace # 創(chuàng)建一個(gè)非root用戶以增強(qiáng)安全性可選但推薦 RUN useradd -m -u 1000 agent chown -R agent:agent /workspace USER agent # 默認(rèn)啟動命令保持容器運(yùn)行 CMD [tail, -f, /dev/null]構(gòu)建這個(gè)鏡像docker build -t agent-sandbox:latest ./sandbox3.2 實(shí)現(xiàn)Python沙箱客戶端接下來我們編寫一個(gè)Python類來管理沙箱容器的生命周期創(chuàng)建、執(zhí)行命令、銷毀和文件操作。文件sandbox_executor.pyimport docker import tarfile import io import os import logging from typing import Optional, Tuple logging.basicConfig(levellogging.INFO) logger logging.getLogger(__name__) class DockerSandbox: 基于Docker的代碼執(zhí)行沙箱。 def __init__(self, image_name: str agent-sandbox:latest, work_dir: str /workspace, mem_limit: str 512m, cpu_period: int 100000, cpu_quota: int 50000): 初始化沙箱。 Args: image_name: Docker鏡像名。 work_dir: 容器內(nèi)的工作目錄。 mem_limit: 內(nèi)存限制如 512m。 cpu_quota: CPU時(shí)間配額與cpu_period共同限制CPU使用率quota/period。 self.client docker.from_env() self.image_name image_name self.work_dir work_dir self.mem_limit mem_limit self.cpu_period cpu_period self.cpu_quota cpu_quota self.container None logger.info(f沙箱初始化使用鏡像: {image_name}) def start(self): 啟動一個(gè)新的沙箱容器。 if self.container is not None: logger.warning(容器已存在正在停止并移除舊容器。) self.stop() try: self.container self.client.containers.run( imageself.image_name, command[tail, -f, /dev/null], # 保持容器運(yùn)行 working_dirself.work_dir, detachTrue, # 后臺運(yùn)行 mem_limitself.mem_limit, cpu_periodself.cpu_period, cpu_quotaself.cpu_quota, network_disabledTrue, # 禁用網(wǎng)絡(luò)增強(qiáng)安全根據(jù)需求調(diào)整 # user: 1000 # 使用非root用戶 ) logger.info(f沙箱容器已啟動ID: {self.container.short_id}) except docker.errors.ImageNotFound: logger.error(f鏡像 {self.image_name} 未找到請先構(gòu)建。) raise except Exception as e: logger.error(f啟動容器失敗: {e}) raise def exec_command(self, command: str, timeout: int 30) - Tuple[int, str, str]: 在沙箱容器內(nèi)執(zhí)行命令。 Returns: (exit_code, stdout, stderr) if self.container is None: raise RuntimeError(沙箱容器未啟動請先調(diào)用 start() 方法。) try: logger.info(f在沙箱中執(zhí)行命令: {command}) # 使用 exec_create 和 exec_start 獲取更詳細(xì)的結(jié)果 exec_id self.client.api.exec_create( containerself.container.id, cmd[sh, -c, command], workdirself.work_dir, user1000 ) exec_output self.client.api.exec_start(exec_idexec_id[Id], streamFalse, demuxTrue) # 獲取退出碼 exec_inspect self.client.api.exec_inspect(exec_id[Id]) exit_code exec_inspect[ExitCode] stdout exec_output[0].decode(utf-8) if exec_output[0] else stderr exec_output[1].decode(utf-8) if exec_output[1] else return exit_code, stdout, stderr except Exception as e: logger.error(f執(zhí)行命令 {command} 時(shí)出錯: {e}) return -1, , str(e) def copy_to_sandbox(self, host_path: str, sandbox_path: Optional[str] None): 將主機(jī)文件/目錄復(fù)制到沙箱容器內(nèi)。 if self.container is None: raise RuntimeError(沙箱容器未啟動。) if not os.path.exists(host_path): raise FileNotFoundError(f主機(jī)路徑不存在: {host_path}) sandbox_path sandbox_path or os.path.basename(host_path) sandbox_abs_path os.path.join(self.work_dir, sandbox_path).rstrip(/) try: # 創(chuàng)建tar歸檔 tar_stream io.BytesIO() with tarfile.open(fileobjtar_stream, modew) as tar: if os.path.isdir(host_path): for root, dirs, files in os.walk(host_path): for file in files: file_path os.path.join(root, file) arcname os.path.relpath(file_path, starthost_path) tar.add(file_path, arcnameos.path.join(sandbox_path, arcname)) else: tar.add(host_path, arcnameos.path.basename(host_path)) tar_stream.seek(0) # 上傳到容器 self.container.put_archive(pathself.work_dir, datatar_stream.read()) logger.info(f已復(fù)制 {host_path} 到沙箱的 {sandbox_abs_path}) except Exception as e: logger.error(f復(fù)制文件到沙箱失敗: {e}) raise def copy_from_sandbox(self, sandbox_path: str, host_path: str): 從沙箱容器內(nèi)復(fù)制文件/目錄到主機(jī)。 # 實(shí)現(xiàn)類似 copy_to_sandbox 的邏輯使用 container.get_archive # 為簡潔起見此處省略具體實(shí)現(xiàn)原理是獲取容器的tar流并解壓到主機(jī)。 pass def stop(self): 停止并移除沙箱容器。 if self.container: try: self.container.stop() self.container.remove() logger.info(f沙箱容器 {self.container.short_id} 已停止并移除。) except Exception as e: logger.error(f停止容器時(shí)出錯: {e}) finally: self.container None def __enter__(self): 支持上下文管理器方便使用 with 語句。 self.start() return self def __exit__(self, exc_type, exc_val, exc_tb): 退出上下文時(shí)自動清理。 self.stop()這個(gè)DockerSandbox類提供了安全的命令執(zhí)行環(huán)境。關(guān)鍵安全措施包括資源限制通過mem_limit和cpu_quota限制容器能使用的最大資源。網(wǎng)絡(luò)隔離network_disabledTrue可完全禁用容器網(wǎng)絡(luò)根據(jù)任務(wù)需求可調(diào)整為限制網(wǎng)絡(luò)。非root用戶在容器內(nèi)使用非root用戶執(zhí)行命令降低權(quán)限。臨時(shí)性每個(gè)任務(wù)或會話使用獨(dú)立的容器任務(wù)完成后銷毀避免狀態(tài)殘留和交叉污染。4. 集成LangChain構(gòu)建智能體現(xiàn)在我們將沙箱執(zhí)行器包裝成LangChain可用的Tool并創(chuàng)建一個(gè)能夠使用這些工具的智能體。4.1 創(chuàng)建自定義沙箱工具文件sandbox_tools.pyfrom langchain.tools import BaseTool from langchain.callbacks.manager import CallbackManagerForToolRun from pydantic import Field from typing import Optional, Type from sandbox_executor import DockerSandbox import tempfile import os class CodeExecutionTool(BaseTool): 在安全沙箱中執(zhí)行Python代碼的工具。 name: str python_code_interpreter description: str ( 在隔離的Docker沙箱中執(zhí)行一段Python代碼。 輸入應(yīng)該是一段完整的、可執(zhí)行的Python代碼字符串。 工具將返回代碼的標(biāo)準(zhǔn)輸出、標(biāo)準(zhǔn)錯誤和退出碼。 ) sandbox: DockerSandbox Field(default_factoryDockerSandbox) timeout: int 30 def _run(self, code: str, run_manager: Optional[CallbackManagerForToolRun] None) - str: 執(zhí)行工具的主要邏輯。 # 將代碼寫入沙箱內(nèi)的臨時(shí)文件 with tempfile.NamedTemporaryFile(modew, suffix.py, deleteFalse) as f: f.write(code) host_temp_path f.name try: # 啟動沙箱如果尚未啟動 if self.sandbox.container is None: self.sandbox.start() # 復(fù)制代碼文件到沙箱 self.sandbox.copy_to_sandbox(host_temp_path, code_to_run.py) # 在沙箱中執(zhí)行代碼 exit_code, stdout, stderr self.sandbox.exec_command( fpython /workspace/code_to_run.py, timeoutself.timeout ) result f退出碼: {exit_code}\n if stdout: result f標(biāo)準(zhǔn)輸出:\n{stdout}\n if stderr: result f標(biāo)準(zhǔn)錯誤:\n{stderr}\n return result except Exception as e: return f執(zhí)行代碼時(shí)發(fā)生錯誤: {str(e)} finally: # 清理主機(jī)上的臨時(shí)文件 os.unlink(host_temp_path) # 異步方法占位按需實(shí)現(xiàn) async def _arun(self, query: str) - str: raise NotImplementedError(此工具不支持異步執(zhí)行。) class ShellCommandTool(BaseTool): 在安全沙箱中執(zhí)行Shell命令的工具。 name: str shell_command description: str ( 在隔離的Docker沙箱中執(zhí)行一個(gè)Shell命令如ls, cat, grep等。 輸入應(yīng)該是一個(gè)有效的Shell命令字符串。 用于文件操作、系統(tǒng)檢查等。請謹(jǐn)慎使用危險(xiǎn)命令。 ) sandbox: DockerSandbox Field(default_factoryDockerSandbox) timeout: int 30 def _run(self, command: str, run_manager: Optional[CallbackManagerForToolRun] None) - str: if self.sandbox.container is None: self.sandbox.start() exit_code, stdout, stderr self.sandbox.exec_command(command, timeoutself.timeout) result f命令: {command}\n退出碼: {exit_code}\n if stdout: result f標(biāo)準(zhǔn)輸出:\n{stdout}\n if stderr: result f標(biāo)準(zhǔn)錯誤:\n{stderr}\n return result async def _arun(self, query: str) - str: raise NotImplementedError(此工具不支持異步執(zhí)行。)4.2 配置本地LLM并創(chuàng)建智能體文件agent_factory.pyfrom langchain.agents import AgentExecutor, create_react_agent from langchain.memory import ConversationBufferMemory from langchain.prompts import PromptTemplate from langchain_community.llms import OllamaLLM from sandbox_tools import CodeExecutionTool, ShellCommandTool import logging logging.basicConfig(levellogging.INFO) logger logging.getLogger(__name__) def create_agentic_software_factory(): 創(chuàng)建并返回一個(gè)配置好的智能體執(zhí)行器。 # 1. 初始化本地LLM (連接Ollama服務(wù)) # 注意確保Ollama服務(wù)正在運(yùn)行 (ollama serve) llm OllamaLLM( base_urlhttp://localhost:11434, # Ollama默認(rèn)地址 modelcodellama:7b, # 使用你拉取的模型名稱 temperature0.1, # 低溫度使輸出更確定適合代碼生成 # num_predict2048, # 可調(diào)整生成的最大token數(shù) ) logger.info(f已連接本地LLM: {llm.model}) # 2. 初始化工具 # 共享一個(gè)沙箱實(shí)例使工具間可以共享工作區(qū)狀態(tài) shared_sandbox DockerSandbox(mem_limit1g, cpu_quota100000) # 分配更多資源 code_tool CodeExecutionTool(sandboxshared_sandbox) shell_tool ShellCommandTool(sandboxshared_sandbox) tools [code_tool, shell_tool] logger.info(f已加載工具: {[tool.name for tool in tools]}) # 3. 創(chuàng)建提示詞模板 # ReAct (Reasoning Acting) 是一種經(jīng)典的智能體提示框架 prompt_template PromptTemplate.from_template( 你是一個(gè)運(yùn)行在安全沙箱環(huán)境中的自主編程助手。你的目標(biāo)是幫助用戶完成軟件開發(fā)任務(wù)。 你可以使用以下工具 {tools} 請嚴(yán)格遵循以下格式 任務(wù)用戶給你的輸入任務(wù) 思考你需要分析任務(wù)并決定使用哪個(gè)工具以及如何使用 行動要執(zhí)行的動作必須是以下格式之一 - 使用 python_code_interpreter 工具時(shí)python\n# 你的代碼\n - 使用 shell_command 工具時(shí)shell\n你的命令\n 觀察工具執(zhí)行的結(jié)果 ... (這個(gè)思考/行動/觀察循環(huán)可以重復(fù)多次) 最終答案當(dāng)任務(wù)完成或你得出結(jié)論時(shí)給出最終答案。 開始 任務(wù){(diào)input} 思考{agent_scratchpad} ) # 4. 創(chuàng)建智能體 agent create_react_agent(llmllm, toolstools, promptprompt_template) # 5. 創(chuàng)建記憶可選用于多輪對話 memory ConversationBufferMemory(memory_keychat_history, return_messagesTrue) # 6. 創(chuàng)建執(zhí)行器 agent_executor AgentExecutor( agentagent, toolstools, memorymemory, verboseTrue, # 打印詳細(xì)的執(zhí)行步驟便于調(diào)試 handle_parsing_errorsTrue, # 處理智能體輸出解析錯誤 max_iterations10, # 限制最大迭代次數(shù)防止死循環(huán) early_stopping_methodgenerate, # 當(dāng)智能體認(rèn)為任務(wù)完成時(shí)停止 ) logger.info(智能體軟件工廠創(chuàng)建成功。) return agent_executor, shared_sandbox # 返回執(zhí)行器和沙箱以便后續(xù)控制 if __name__ __main__: # 快速測試 agent_executor, sandbox create_agentic_software_factory() try: # 示例任務(wù)讓智能體寫一個(gè)簡單的Python程序并運(yùn)行 task 請編寫一個(gè)Python函數(shù)計(jì)算斐波那契數(shù)列的前10個(gè)數(shù)并打印出來。 print(f執(zhí)行任務(wù): {task}) result agent_executor.invoke({input: task}) print(\n 最終結(jié)果 ) print(result[output]) except Exception as e: print(f執(zhí)行過程中出錯: {e}) finally: # 任務(wù)完成后清理沙箱 sandbox.stop()5. 運(yùn)行與實(shí)戰(zhàn)演示現(xiàn)在讓我們運(yùn)行這個(gè)系統(tǒng)看它如何實(shí)際完成一個(gè)軟件開發(fā)任務(wù)。5.1 啟動系統(tǒng)并執(zhí)行任務(wù)確保Ollama服務(wù)在運(yùn)行ollama serve 運(yùn)行我們的主程序cd /path/to/self-hosted-agent-factory source venv/bin/activate python agent_factory.py觀察執(zhí)行過程由于我們設(shè)置了verboseTrue你將在控制臺看到類似ReAct框架的詳細(xì)推理過程 進(jìn)入新的AgentExecutor鏈... 思考用戶要求我編寫一個(gè)計(jì)算斐波那契數(shù)列前10個(gè)數(shù)的Python函數(shù)并打印。我需要使用python_code_interpreter工具。 行動 python def fibonacci(n): fib_sequence [0, 1] for i in range(2, n): fib_sequence.append(fib_sequence[-1] fib_sequence[-2]) return fib_sequence[:n] result fibonacci(10) print(斐波那契數(shù)列前10項(xiàng):, result)觀察退出碼: 0 標(biāo)準(zhǔn)輸出 斐波那契數(shù)列前10項(xiàng): [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]思考我已經(jīng)成功編寫并執(zhí)行了代碼得到了正確結(jié)果。任務(wù)完成。 最終答案已成功編寫并執(zhí)行Python代碼。斐波那契數(shù)列的前10個(gè)數(shù)是[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]。鏈結(jié)束。5.2 更復(fù)雜的任務(wù)示例我們可以嘗試更復(fù)雜的任務(wù)例如讓智能體創(chuàng)建一個(gè)簡單的Flask web應(yīng)用。修改agent_factory.py中的測試任務(wù)task 請完成以下任務(wù) 1. 在沙箱的/workspace目錄下創(chuàng)建一個(gè)名為app.py的Python文件。 2. 該文件應(yīng)包含一個(gè)使用Flask框架的簡單Web服務(wù)器。 3. 該服務(wù)器有一個(gè)根路由/返回Hello, Self-hosted Agent!。 4. 確保安裝了Flask依賴。 5. 最后啟動這個(gè)Flask應(yīng)用在后臺并檢查它是否在5000端口監(jiān)聽。 智能體可能會按以下步驟執(zhí)行使用shell_command工具運(yùn)行pip install flask。使用python_code_interpreter或shell_command配合echo創(chuàng)建app.py文件并寫入代碼。使用shell_command工具執(zhí)行python app.py 來啟動服務(wù)。使用shell_command工具執(zhí)行netstat -tulpn或curl localhost:5000來驗(yàn)證服務(wù)。6. 常見問題與排查思路在搭建和運(yùn)行過程中你可能會遇到以下問題問題現(xiàn)象可能原因排查與解決思路Ollama連接失敗(ConnectionError)1. Ollama服務(wù)未啟動。2. 防火墻或端口沖突。3.base_url配置錯誤。1. 運(yùn)行ollama serve并檢查進(jìn)程。2. 運(yùn)行curl http://localhost:11434/api/tags測試API。3. 確認(rèn)agent_factory.py中的base_url與Ollama運(yùn)行地址一致。Docker權(quán)限錯誤(Permission denied)當(dāng)前用戶不在docker組。執(zhí)行sudo usermod -aG docker $USER注銷并重新登錄。沙箱容器啟動失敗(ImageNotFound)基礎(chǔ)Docker鏡像未構(gòu)建。在sandbox/目錄下執(zhí)行docker build -t agent-sandbox:latest .。智能體陷入循環(huán)或行為異常1. LLM理解偏差。2. 工具描述不清。3.max_iterations設(shè)置過大。1. 調(diào)整提示詞prompt_template給出更明確的指令和格式約束。2. 優(yōu)化工具的描述description使其更精準(zhǔn)。3. 適當(dāng)降低max_iterations如設(shè)為5并設(shè)置early_stopping_method。代碼執(zhí)行超時(shí)1. 代碼有無限循環(huán)。2.timeout參數(shù)設(shè)置過短。3. 沙箱資源不足。1. 在生成的代碼中加入超時(shí)或中斷邏輯對智能體要求高。2. 增加DockerSandbox和工具中的timeout值。3. 增加Docker容器的mem_limit和cpu_quota。無法在沙箱內(nèi)安裝軟件包容器網(wǎng)絡(luò)被禁用network_disabledTrue。對于需要聯(lián)網(wǎng)的任務(wù)在DockerSandbox初始化時(shí)將network_disabled設(shè)為False或配置內(nèi)部網(wǎng)絡(luò)。LangChain版本兼容性問題LangChain版本更新較快API可能有變。使用pip list | grep langchain查看版本。本文基于langchain0.1.0。可嘗試固定版本pip install langchain0.1.0。7. 最佳實(shí)踐與進(jìn)階優(yōu)化方向構(gòu)建一個(gè)可用于生產(chǎn)環(huán)境或更復(fù)雜場景的軟件工廠還需要考慮以下方面7.1 安全加固更嚴(yán)格的沙箱使用gVisor或Kata Containers相比普通Docker它們提供了更強(qiáng)的內(nèi)核隔離。Seccomp和AppArmor配置文件限制容器內(nèi)可執(zhí)行的系統(tǒng)調(diào)用。只讀根文件系統(tǒng)除了/workspace外將其他目錄掛載為只讀。用戶命名空間隔離在容器內(nèi)使用與宿主機(jī)完全不同的UID/GID。輸入驗(yàn)證與過濾在工具被調(diào)用前對智能體傳遞過來的命令或代碼進(jìn)行安全檢查過濾危險(xiǎn)操作如rm -rf /:(){ :\|: };:等。資源監(jiān)控與熔斷監(jiān)控沙箱的CPU、內(nèi)存使用情況超出閾值立即終止任務(wù)。7.2 系統(tǒng)功能增強(qiáng)擴(kuò)展工具集Git工具實(shí)現(xiàn)代碼克隆、提交、推送。文件編輯器工具允許智能體查看和修改特定文件。Web搜索工具需謹(jǐn)慎開放網(wǎng)絡(luò)讓智能體獲取最新信息。專用測試工具運(yùn)行pytest、unittest等。工作流與狀態(tài)管理持久化工作區(qū)將/workspace目錄掛載到宿主機(jī)持久化存儲使不同任務(wù)或會話可以繼續(xù)之前的工作。任務(wù)隊(duì)列引入Celery或Redis隊(duì)列處理并發(fā)的智能體任務(wù)。可觀測性集成日志如ELK棧和指標(biāo)監(jiān)控如Prometheus追蹤智能體的決策過程和工具使用情況。模型優(yōu)化微調(diào)專用模型使用代碼相關(guān)的數(shù)據(jù)集如GitHub代碼對開源LLM進(jìn)行微調(diào)提升其編程和工具使用能力。模型路由根據(jù)任務(wù)類型代碼生成、文本分析、規(guī)劃路由到不同的專用模型。7.3 工程化與部署容器化部署將整個(gè)智能體系統(tǒng)主控程序、Ollama用Docker Compose或Kubernetes編排實(shí)現(xiàn)一鍵部署和水平擴(kuò)展。配置化管理將模型參數(shù)、沙箱資源限制、工具開關(guān)等抽取到配置文件如config.yaml中。API化使用FastAPI或Flask將智能體封裝成HTTP API服務(wù)方便與其他系統(tǒng)集成。前端界面開發(fā)一個(gè)簡單的Web界面用于提交任務(wù)、查看執(zhí)行狀態(tài)和結(jié)果。通過以上步驟我們成功搭建了一個(gè)具備高度自主性、安全性和可控性的AI驅(qū)動軟件工廠原型。它證明了利用開源工具鏈構(gòu)建私有化、安全的企業(yè)級AI開發(fā)助手的可行性。你可以以此為基礎(chǔ)根據(jù)團(tuán)隊(duì)的具體需求擴(kuò)展工具、優(yōu)化流程、強(qiáng)化安全逐步將其打造成提升研發(fā)效能的強(qiáng)大內(nèi)部平臺。