代理 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 所示的圖形。

在第 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,應用開發者可以將執行轉移到用戶的瀏覽器中,從而獲得沙盒的安全性并防止任何跨用戶污染。

此架構的主要區別在于,應用程序在第 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 所示。

但是,應用 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' |
其次,如果代碼確實執行,則僅限于瀏覽器沙盒,這極大地限制了對最終用戶設備的任何潛在影響。

在這兩種情況下,使用 Pyodide 可改善查詢用戶的安全控制,同時降低應用資源和相鄰用戶面臨的風險。
開始使用?
使用 WebAssembly 將 LLM 生成的 Python 沙箱化提供了一種便捷的方法,只需對現有提示和架構進行少量更改即可。它通過降低計算需求實現成本效益,并提供主機和用戶隔離,同時提高服務及其用戶的安全性。它比正則表達式或受限 Python 庫更穩健,比容器或虛擬機更輕。
要開始使用 Wasm 提高代理工作流的應用程序安全性,請查看 GitHub 上的此 示例 。詳細了解 AI 代理和代理工作流 。
?