构建安全的 AI 代码助手与自动化脚本系统
前言
代码生成是 LLM 最强大的能力之一。然而,仅仅生成代码是不够的,真正的 AI 助手需要能够执行代码、验证结果并根据错误进行自我修复。本文将探讨如何构建一个安全、可靠的代码生成与执行系统。
代码生成最佳实践
1. 结构化提示词
为了获得高质量的代码,提示词应包含:
- 任务描述:明确要实现的功能。
- 技术栈:指定语言、库和版本。
- 约束条件:性能要求、异常处理、编码规范。
- 输出格式:要求只输出代码块,不含解释。
2. 示例引导 (Few-shot)
提供高质量的代码示例可以显著提升生成代码的风格一致性。
prompt = """
你是一个高级 Python 工程师。请根据要求编写函数。
示例:
要求:计算列表的平均值,处理空列表。
代码:
def calculate_average(numbers: list[float]) -> float:
if not numbers:
return 0.0
return sum(numbers) / len(numbers)
要求:{user_request}
代码:
"""
代码解析与提取
LLM 通常返回 Markdown 格式的代码块。我们需要可靠地提取这些代码。
import re
def extract_code(text: str, language: str = "python") -> str:
"""从 Markdown 文本中提取代码块"""
pattern = rf"```{language}\n(.*?)\n```"
match = re.search(pattern, text, re.DOTALL)
if match:
return match.group(1).strip()
# 如果没有 Markdown 标记,尝试直接返回
if "def " in text or "import " in text:
return text.strip()
return ""
安全的沙箱执行
绝对不要在本地环境直接运行 LLM 生成的代码。 必须使用隔离的沙箱环境。
方案对比
| 方案 | 安全性 | 性能 | 复杂度 | 适用场景 |
|---|---|---|---|---|
| Docker | 高 | 中 | 中 | 通用后端执行 |
| E2B / Bearly | 极高 | 高 | 低 | 云端托管沙箱 |
| Piston | 中 | 高 | 低 | 快速多语言执行 |
| Pyodide (WASM) | 高 | 低 | 中 | 浏览器端执行 |
进阶实战:持久化沙箱会话 (Persistent Sessions)
在复杂的任务中,我们需要在多个对话回合中保持代码执行的状态(变量、文件、导入等),类似于 Jupyter Notebook。
1. 使用 E2B 维护持久化状态
from e2b_code_interpreter import CodeInterpreter
def run_with_e2b(code: str):
with CodeInterpreter() as sandbox:
# 执行代码
execution = sandbox.notebook.exec_cell(code)
# 处理输出(文本、图表、错误)
if execution.error:
print(f"执行错误: {execution.error.name}: {execution.error.value}")
return None, execution.error.value
# 如果生成了图表,E2B 会返回 base64 编码的图片
for result in execution.results:
if result.png:
save_chart(result.png)
return execution.text, None
---
#### 核心技术:自我修复循环 (Self-Correction Loop)
这是 AI 程序员(如 Devin 或 OpenDevin)的核心逻辑。
#### 流程
1. **生成**:LLM 生成代码。
2. **执行**:在沙箱中运行代码。
3. **反馈**:如果报错,将 **错误堆栈 (Traceback)** 和 **原始代码** 发回给 LLM。
4. **修复**:LLM 分析错误并生成修复后的版本。
5. **循环**:重复上述步骤,直到代码运行成功或达到最大重试次数。
```python
def autonomous_coder(task: str, max_retries: int = 3):
code = generate_initial_code(task)
for i in range(max_retries):
output, error = run_in_sandbox(code)
if not error:
return code, output
print(f"尝试 {i+1} 失败,正在修复...")
code = generate_fix(code, error)
raise Exception("无法修复代码")
沙箱安全深度防御
即使在 Docker 中运行,也需要多层防护:
- 网络隔离:禁用沙箱的外部网络访问,防止代码将你的 API Key 或敏感数据发送到黑客服务器(防止数据外泄)。
- 资源限制 (cgroups):限制 CPU 使用率为 10%,内存限制为 128MB,防止恶意代码(如死循环或内存炸弹)耗尽宿主机资源。
-
只读文件系统:除了
/tmp目录外,其他目录设为只读。 - 超时控制:强制执行时间不得超过 30 秒。
行业应用:AI 数据分析师
结合代码执行,LLM 可以变成一个强大的数据分析师。
- 输入:一个 CSV 文件和问题(“分析去年的销售趋势”)。
- 过程:LLM 编写 Python 代码(使用 Pandas 和 Matplotlib),在沙箱中读取 CSV,生成分析报告和可视化图表。
- 输出:文字结论 + 统计图表。
总结
代码执行赋予了 LLM “行动”的能力。
- 安全性是底线:永远使用隔离沙箱(推荐 E2B)。
- 鲁棒性是关键:建立自我修复循环。
- 状态保持是进阶:使用持久化会话处理复杂任务。
通过构建这套系统,你不仅是在做一个“会说话”的 AI,而是在做一个真正能“干活”的 AI 助手。
class PersistentSandbox: def init(self): # 创建一个持久化的沙箱实例 self.sandbox = CodeInterpreter()
def run_step(self, code: str):
"""执行代码并保持状态"""
print(f"正在执行代码块...")
execution = self.sandbox.notebook.exec_cell(code)
if execution.error:
return {"status": "error", "msg": execution.error.traceback}
# 获取标准输出和结果
return {
"status": "success",
"stdout": execution.logs.stdout,
"results": [r.to_dict() for r in execution.results]
}
def close(self):
self.sandbox.close()
示例:第一步定义变量,第二步使用变量
ps = PersistentSandbox() ps.run_step(“x = 10”) result = ps.run_step(“print(x * 2)”) # 输出: 20
#### 2. 多文件项目管理
如果任务涉及多个文件(如 Web 爬虫或小型应用),我们可以在沙箱中动态创建文件结构。
```python
def setup_project(sandbox: CodeInterpreter):
# 在沙箱中创建目录和文件
sandbox.filesystem.make_dir("src")
sandbox.filesystem.write("src/utils.py", "def add(a, b): return a + b")
sandbox.filesystem.write("main.py", "from src.utils import add\nprint(add(1, 2))")
# 执行主程序
execution = sandbox.process.start("python3 main.py")
return execution.wait().stdout
核心进阶:代码自我修复循环 (Self-Healing)
通过将执行错误反馈给 LLM,可以实现代码的自动纠错。
async def self_healing_code_gen(task: str, max_rounds: int = 3):
code = await llm.generate(f"任务: {task}")
for _ in range(max_rounds):
result = sandbox.execute(code)
if result.success:
return result.output
# 将错误信息喂回给 LLM
code = await llm.generate(f"代码执行失败,错误如下:{result.error}\n请修复代码。")
return "无法修复代码"
构建代码解释器 (Code Interpreter)
一个完整的代码解释器循环包括:生成 -> 执行 -> 报错 -> 修复。
class AICodeAssistant:
def __init__(self):
self.llm = ChatOpenAI(model="gpt-4o")
self.max_retries = 3
def solve_task(self, task: str):
current_task = task
for i in range(self.max_retries):
# 1. 生成代码
code_response = self.llm.invoke(f"编写 Python 代码完成任务:{current_task}。只输出代码。")
code = extract_code(code_response.content)
print(f"尝试 {i+1}: 执行代码...")
# 2. 执行代码
result = execute_ai_code(code)
if result["success"]:
print("✅ 执行成功!")
return result
else:
print(f"❌ 执行失败: {result['error']}")
# 3. 自我修复:将错误反馈给 LLM
current_task = f"""
之前的代码执行失败了。
任务:{task}
错误类型:{result['error']}
错误详情:{result['traceback']}
请修复代码并重新提供。
"""
return {"success": False, "message": "达到最大重试次数"}
数据可视化支持
代码执行不仅是计算,还包括生成图表。
def execute_and_get_charts(code: str):
with CodeInterpreter() as sandbox:
execution = sandbox.notebook.exec_cell(code)
# E2B 会自动捕获 matplotlib/plotly 的输出
charts = []
for result in execution.results:
if result.png:
charts.append(result.png) # Base64 编码的图片
return charts
安全性深度防御
即使在沙箱中,也需要限制资源:
- 网络限制:默认禁用网络访问,除非任务需要。
- 超时控制:设置硬性超时(如 30 秒),防止死循环。
- 内存限制:限制进程可用内存(如 512MB)。
- 文件系统隔离:只允许读写特定的临时目录。
-
敏感词过滤:在执行前检查代码中是否包含
os.environ,rm -rf /等关键词。
def security_check(code: str) -> bool:
forbidden_patterns = [
r"import\s+os",
r"import\s+subprocess",
r"open\(",
r"eval\(",
r"exec\("
]
for pattern in forbidden_patterns:
if re.search(pattern, code):
return False
return True
单元测试生成
为了确保生成的代码逻辑正确,可以让 LLM 同时生成单元测试。
test_prompt = f"""
针对以下函数编写 3 个 pytest 测试用例:
{generated_code}
要求:
1. 覆盖正常情况和边界情况。
2. 使用 assert 语句。
"""
总结
代码生成与执行是构建强大 AI Agent 的基石。通过结合结构化提示词、安全沙箱(如 E2B)以及错误反馈循环,我们可以构建出能够自主解决复杂计算和数据分析任务的智能系统。
参考资源
版权声明: 如无特别声明,本文版权归 sshipanoo 所有,转载请注明本文链接。
(采用 CC BY-NC-SA 4.0 许可协议进行授权)
本文标题:《 LLM应用开发——代码生成与沙箱执行 》
本文链接:http://localhost:3015/ai/%E4%BB%A3%E7%A0%81%E7%94%9F%E6%88%90%E4%B8%8E%E6%89%A7%E8%A1%8C.html
本文最后一次更新为 天前,文章中的某些内容可能已过时!