FastGPTFastGPT
应用构建/对话 Agent V2

虚拟机

深入了解 Agent V2 虚拟机(沙箱)的核心概念、运行设计与联调指南。

虚拟机运行环境

在 FastGPT Agent V2 中,虚拟机 是专为每个会话分配的、物理隔离且安全的轻量级 Linux 运行沙盒环境。它为 Agent 提供了真实的计算、代码执行和文件读写操作能力,使得 AI 不仅仅能“思考”,还能像人类程序员一样通过实际运行代码来解决复杂任务。


什么是虚拟机

每当用户开启“启用虚拟机”选项,系统都会在后台为每一个对话会话(Session)动态预置并绑定一个专用的沙箱容器。

启用虚拟机

有了虚拟机,Agent 可以:

  • 执行动态代码:通过代码执行器运行 Python、Node.js 甚至 Shell 脚本,自主进行复杂计算或数据处理。
  • 读写本地文件:在独立的 /workspace 目录下创建、修改和读取文件,包括生成图表、处理上传的 CSV/Excel 电子表格等。
  • 环境自定义与启动脚本:通过关联 SKILL 包,或配置自定义的 启动脚本(在虚拟机拉起后且 AI 正式开始前自动在后台执行的 Shell 命令,用于安装特定软件源、Python 依赖包或系统级工具等),动态准备专属于您应用的运行环境。

虚拟机设计

为了在多并发和多租户场景下兼顾安全性、响应速度与资源消耗,系统在底层采用了以下核心设计:

1. 会话级隔离与生命周期管理

  • 虚拟机与用户的对话会话(Session)强绑定。不同用户、不同会话之间的运行环境完全物理隔离。(注意,未来版本将会改至用户级别隔离,从而减少资源消耗)
  • 系统通过心跳(Keepalive)机制维持活动容器的存活。当会话长时间闲置(如超过数分钟无新请求)时,系统会自动回收并销毁该虚拟机实例以释放服务器资源。

2. 状态存续(Session Persistence)

在同一个会话的生命周期内,虚拟机是持续存活的。这意味着上一轮对话中下载的依赖、写入的临时文件以及配置的环境变量,在下一轮对话中依然有效,支持多轮交互的连续性。

3. 安全防逃逸与限制

  • 沙盒环境采用了严格的资源配额限制(CPU、内存、磁盘 IO)和网络防火墙策略,防止恶意脚本消耗宿主机资源或访问内部网络。
  • 所有执行的命令均通过 base64 编码在容器内安全解码运行,规避了 Shell 拼接造成的命令注入风险。

4. 一键快速重建

当用户在调试中点击“重开对话”或重新建立会话时,系统将彻底销毁当前的旧虚拟机,并为下一次请求分配一个纯净、全新的隔离容器,确保环境干净不被污染。


虚拟机使用

当您在左侧配置面板中启用了虚拟机时,调试预览窗口将自动激活以下沙盒专属调试能力:

虚拟机文件管理器

调试窗口顶部以及涉及虚拟机操作的对话气泡下方会提供“虚拟机文件管理器”入口。点击可弹出管理器弹窗,实时浏览、编辑、上传或下载容器内的文件(如图表、临时代码、HTML 预览等),实现调试闭环。

虚拟机文件气泡虚拟机文件管理器

对话上传文件自动注入

对话输入框中上传的所有测试文件,会在对话开始前自动同步注入到虚拟机的 user_files/ 目录下,使得 AI 可以通过代码以本地路径直接读取和处理这些文件。

代码执行与自我纠错

虚拟机提供了真实的代码运行环境。若代码由于依赖缺失或语法错误执行失败,报错信息会实时回传给大模型,AI 能够在多步规划中尝试自我修正并重新运行,实现闭环纠错调试。

前置拉起与状态存续

开启虚拟机后,系统会在每次对话启动前自动前置拉起并准备好沙盒环境。环境内的文件、依赖和运行状态在当前会话内跨步骤持久保留,支持连续的上下文联调。

启动状态实时展示

在对话调试过程中,气泡上方会流式展示虚拟机的创建与启动状态,方便感知沙箱所处阶段与启动耗时。

重置对话重建沙箱

点击“重开对话”按钮重置测试时,下一次交互会重新拉起并初始化一个干净、全新的虚拟机容器,避免历史测试生成的文件污染新一轮的调试。


虚拟机生命周期

在启用虚拟机后,您可以通过配置 启动脚本,在沙盒环境拉起后、AI 工作流正式开始执行前,自动执行指定的 Shell 命令。这通常用于配置环境变量、更换软件源、安装 Python 依赖(pip)或系统级工具等。

脚本配置与生命周期

在 Agent 配置面板的“虚拟机配置”中,您可以直接在 启动脚本(sh) 的代码编辑器中编写您的 Shell 脚本。

启动脚本编辑器

脚本执行顺序与范围

当一个新会话启动或虚拟机重新拉起时,系统会按顺序在后台执行相应的脚本:

  1. 应用启动脚本:即您在配置面板中自定义的 Shell 脚本。该脚本会在虚拟机的工作目录(通常为 /workspace)下执行,用于准备当前应用所需的特定运行依赖和环境。
  2. 技能入口脚本(Skill Entrypoint):若您的 Agent 关联了技能(Skills),技能发布包中自带的初始化脚本(如 entrypoint.sh)会在上述“应用启动脚本”执行完毕后,在每个技能包自身的部署目录下自动执行。
💡
技能包部署的原子性保障:技能包在解压部署时,会先在临时目录(如 .tmp-<versionId>-<random>)中解压,解压完全成功后,再以原子操作整体替换为正式版本目录,有效避免解压失败导致出现损坏的半截目录。

生命周期流程图

生命周期流程图

状态去重

为了避免每次对话交互(热启动)时重复执行命令(例如重复通过 pip install 安装依赖包)带来等待延迟,系统设计了高效的 状态去重机制

  • 运行状态记录:系统在虚拟机内部维护了一个状态文件:~/.fastgpt/agent-skill-entrypoints/state.json
  • 哈希去重(应用启动脚本):对于您手动编写的“应用启动脚本”,系统会计算其文本内容的 SHA-256 哈希特征值(Hash),并与 state.json 中已执行过的哈希值进行对比。如果脚本内容没有任何修改,系统在后续交互中将 自动跳过执行,确保实现快速启动;仅当您修改了脚本内容,或在调试预览中点击了“重开对话”触发沙盒彻底重建时,脚本才会重新执行。
  • 版本 ID 去重(技能入口脚本):关联技能对应的入口脚本则基于 技能版本 ID 进行比对去重。因为发布的技能版本是不可变的,只要绑定的技能版本未改变,其入口脚本也仅会在沙箱首次冷启动时执行一次。
  • 状态的生命周期:去重状态随虚拟机实例生命周期进行管理。当虚拟机重建(点击“重开对话”或闲置被系统回收)时,由于分配的是全新环境,所有的脚本都将在首次冷启动时重新执行。

执行限制与容错机制

为保障沙箱的稳定运行与响应时效,虚拟机启动脚本在运行时受以下系统规则约束:

  • 字符长度限制:由于前端校验与输入限制,虚拟机启动脚本最大支持 16,384 个字符(约 16KB)。超出此长度的脚本在保存时会被自动截断。对于复杂的初始化逻辑,建议编写在单独的技能入口脚本中,或在启动脚本中拉取远程脚本执行。
  • 超时终止限制:脚本执行存在超时保护限制,由系统环境变量 AGENT_SANDBOX_ENTRYPOINT_TIMEOUT_SECONDS 控制,默认超时时间为 30 秒(限制在 1 秒到 600 秒之间)。如果超过该时间脚本仍未执行完毕,系统将强制终止该进程。
  • 非阻塞主流程:即使您的启动脚本在执行时报错(退出状态码非 0)、超时终止,或是状态文件读写发生异常,系统也不会阻断主对话流程。AI 依然会继续执行后续的工作流或工具调用,但可能会因缺少特定依赖而在代码运行时抛出异常。您可以在调试预览的日志或虚拟机文件管理器中排查此类问题。
  • 日志长度截断:启动脚本标准输出(stdout)和标准错误(stderr)的最大日志输出量限制在 8KB 左右。在系统记录日志时,日志内容将被截断至 4,000 个字符,以防止过大的日志输出占用过多的系统与网络资源。