对话式人工智能

借助 WebAssembly 实现沙箱 Agentic AI 工作流

代理 AI 工作流通常 涉及执行由 大语言模型 (LLM) 生成的代码,以执行创建数据可视化等任务。但是,此代码应在安全环境中清理和执行,以降低提示 注入的风险 和返回代码中的错误。使用正则表达式和受限运行时清理 Python 是不够的,而且虚拟机的 Hypervisor 隔离需要大量的开发和资源。

本文将介绍如何使用 WebAssembly (Wasm) (一种基于堆栈的虚拟机的二进制指令格式),利用浏览器沙盒实现操作系统和用户隔离。这提高了应用的安全性,且不会产生重大开销。

确保代理工具的使用 

LLM 应用开发的近期变化之一是公开工具,即 LLM 可以调用并使用响应的函数、应用或 API。例如,如果应用需要了解特定地点的天气,它可以调用天气 API,并使用结果制定适当的响应。

Python 代码执行是用于扩展 LLM 应用的强大工具。LLM 擅长编写 Python 代码,通过执行这些代码,他们可以执行更高级的工作流程,例如数据可视化。通过扩展 Python 函数调用,基于文本的 LLM 将能够为用户生成图像绘图。但是,很难动态分析 LLM 生成的 Python,以确保其满足预期规范,并且不会引入更广泛的应用程序安全风险。如果您正在执行由 LLM 生成的 Python 来扩展代理应用程序,本文就是为您准备的。

构建智能体工作流程 

在最简单的代理工作流中,您的 LLM 可能会生成 Python,并最终传递给 eval。例如,相当于 generate the python code to make a bar chart in plotly 的提示符将返回 import plotly.graph_objects as go\n\nfig = go.Figure(data=go.Bar(x=["A", "B", "C"], y=[10, 20, 15]))\nfig.update_layout(title="Bar Chart Example")。您的代理会将其传递给 eval,以生成如图 1 所示的图形。

A flow diagram showing how the prompt flows between the user, application and the LLM.
图 1、用户、机器和 AI 模型之间最简单的代理工作流,用于使用 Python 生成图形

在第 1 步中,用户向应用程序提供提示。在第 2 步中,应用程序将为 LLM 提供任何其他提示上下文和增强功能。在第 3 步中,LLM 返回由工具调用代理执行的代码。在第 4 步中,在主机操作系统上执行该代码以生成图形,并在第 5 步中返回给用户。

请注意,第 4 步中的 eval 在服务器上执行,存在重大安全风险。为谨慎起见,应实施控制以降低服务器、应用程序和用户面临的风险。最简单的控制是在应用层,过滤和清理通常使用正则表达式和受限的 Python 运行时完成。但是,这些应用层缓解措施远远不够,通常可以绕过。

例如,正则表达式可能会尝试排除对 os 的调用,但错过 subprocess 或不确定是否有方法最终从各种依赖项内部访问这些函数。更可靠的解决方案可能是仅在微型虚拟机 (如 Firecracker ) 中执行 LLM 生成的 Python,但这需要大量资源和工程。

或者,可以考虑将执行转移到用户的浏览器中。浏览器使用沙盒将网页代码和脚本与用户的基础设施隔离开来。例如,浏览器沙盒可防止网页访问本地文件系统或未经授权查看网络摄像头。

在浏览器中使用 Python 

Pyodide 是将 CPython 移植到 Wasm 中,以创建可在现有 JavaScript 虚拟机中使用的沙盒。这意味着我们可以执行 Python 客户端,以继承浏览器沙盒的所有安全优势。

如图 2 所示,通过设计应用以提供具有 Pyodide 运行时和 LLM 生成代码的 HTML,应用开发者可以将执行转移到用户的浏览器中,从而获得沙盒的安全性并防止任何跨用户污染。

A flow diagram showing how the prompt flows between the user, application and the LLM with the final step returning HTML.
图 2、经过修改的代理工作流,可使用 Pyodide 将图形生成从服务器转移到用户浏览器

此架构的主要区别在于,应用程序在第 4 步中将 HTML 返回给用户,而不是在应用服务器上执行该工具。当用户在浏览器中查看该 HTML 时,Pyodide 会在沙盒中执行 LLM 提供的 Python 并渲染可视化效果。

由于 LLM 生成的代码通常可以模板化为静态 HTML 文档,因此此类修改应尽可能减少提示策略的更改。例如,此函数会接收 LLM 提供的代码,并在发送代码以供使用 executeCode 执行之前进行准备。

window.runCode = async (LLMCode) => {
     try {
         console.log('Starting code execution process...');
         const pyodide = await initPyodide();
                
         const wrappedCode = [
             'import plotly.graph_objects as go',
             'import json',
             'try:',
             '    ' + LLMCode.replace(/\\n/g, '\\n    '),
             '    if "fig" in locals():',
             '        plotJson = fig.to_json()',
             '    else:',
             '        raise Exception("No \\'fig\\' variable found after code execution")',
             'except Exception as e:',
             '    print(f"Python execution error: {str(e)}")',
             '    raise'
         ].join('\\n');

         await executeCode(pyodide, wrappedCode);
       ...

如果您的代码具有 Python 依赖项(例如 Plotly ),您可以使用 micropip 在客户端 Javascript 中进行安装。Micropip 支持 PyPI 中的 Python wheel,包括许多具有 C 扩展的 wheel。

await pyodide.loadPackage("micropip");
const micropip = pyodide.pyimport("micropip");
await micropip.install('plotly');

使用 Wasm 提高应用安全性 

想象一下,在这种情况下,LLM 由于提示注入或错误而返回恶意代码。在最简单的代理工作流中,对 eval 的调用会损害应用程序,并可能影响主机操作系统和其他用户,如图 3 所示。

A flow diagram showing how the prompt flows between the user, application and the LLM showing a pub propagating from the LLM to the application server.
图 3、恶意代码在服务器上执行,会影响该服务及其用户

但是,应用 Wasm 流后,图 4 显示了两种可能的情况。首先,由于无法在狭义范围的 Pyodide 运行时 (即缺失依赖项) 中执行恶意 Python 代码,因此应用程序可能会引发错误。

Error: Traceback (most recent call last): File 
     "/lib/python311.zip/_pyodide/_base.py", line 499, in eval_code 
     .run(globals, locals) ^^^^^^^^^^^^^^^^^^^^ File 
     "/lib/python311.zip/_pyodide/_base.py", line 340, in run coroutine = 
     eval(self.code, globals, locals) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File 
     "<exec>", line 2, in <module> ModuleNotFoundError: No module named 
     'pymetasploit3'

其次,如果代码确实执行,则仅限于浏览器沙盒,这极大地限制了对最终用户设备的任何潜在影响。

A flow diagram showing how the prompt flows between the user, application and the LLM with the benefits of a browser sandbox.
图 4、恶意代码传播到 HTML 中,但由于浏览器沙盒的原因,无法在用户的设备上执行或影响极小

在这两种情况下,使用 Pyodide 可改善查询用户的安全控制,同时降低应用资源和相邻用户面临的风险。

开始使用 

使用 WebAssembly 将 LLM 生成的 Python 沙箱化提供了一种便捷的方法,只需对现有提示和架构进行少量更改即可。它通过降低计算需求实现成本效益,并提供主机和用户隔离,同时提高服务及其用户的安全性。它比正则表达式或受限 Python 库更稳健,比容器或虚拟机更轻。

要开始使用 Wasm 提高代理工作流的应用程序安全性,请查看 GitHub 上的此 示例 。详细了解 AI 代理和代理工作流

 

标签